簡體   English   中英

在與主要提交相同的提交上分離 HEAD?

[英]Detached HEAD on same commit as main?

我不太確定在這種情況下我是如何獲得我的存儲庫的,這甚至不再是一個問題,但我想了解發生了什么,所以下次我不會感到如此迷茫。

拉動時,我被警告說我處於分離的 HEAD 狀態。 git status顯示如下(截圖):

HEAD detached at 44422b7

所以我跑了git log來找出我離 main 有多遠,它顯示了(截圖):

commit 44422b74b6826291479ee7a17fe18bb4acca6355 (HEAD, main)

這對我來說沒有多大意義,因為我似乎與主分支在同一個提交中,但是為了解決問題,我運行了git checkout main ,然后顯示下一個git log截圖),

commit 44422b74b6826291479ee7a17fe18bb4acca6355 (HEAD -> main)

一切都開始按照我最初的預期工作。

所以我試圖理解git log在我第一次和第二次運行它時顯示的區別(帶有箭頭的那個與只有一個逗號的那個),也許了解我是如何遇到這種情況的第一名。

感謝我能得到的任何幫助。

分支是指向提交的標簽。

HEAD 總是指向當前簽出的提交。

commit 44422b74b6826291479ee7a17fe18bb4acca6355 (HEAD, main)

commit 44422b74b6826291479ee7a17fe18bb4acca6355 (HEAD -> main)

兩者都說你在提交 44422b74b6826291479ee7a17fe18bb4acca6355。 兩者都說 HEAD 和該提交​​的要點。 但是HEAD -> main說 main 是當前簽出的分支。

當您運行git commit時,會創建一個新的提交,並且當前簽出的分支和 HEAD 會被移至它。

可能沒有簽出分支,這是一個分離的 HEAD 狀態。 在這種情況下,當你git commit只有 HEAD 移動。 沒有分支正在跟蹤您的提交。 如果你git checkoutgit switch away,將(幾乎)沒有任何東西提到那些分離的提交。

有很多方法可以進入分離的 HEAD 狀態,最基本的是檢查提交 ID。 git checkout 4ba97c6ffc71f88a4de4ed88b188dbec2e5ff325

您可以通過檢查分支來擺脫分離的 HEAD 狀態,就像您所做的那樣。 或者你可以在你所在的地方建立一個新的分支。

確保使用git switch main ,而不是git checkout main

通過使用git switch ,您可以降低以分離的 HEAD結尾的風險,因為您會收到錯誤消息(切換到提交或遠程分支時)

fatal: a branch is expected, got remote branch 'origin/master'

您需要顯式添加--detach選項才能得到一個分離的 HEAD。

這實際上是兩個獨立的問題:

  1. 試圖了解 git log 在我第一次和第二次運行它時顯示的內容之間的區別(帶有箭頭的那個與只有一個逗號的那個),

  2. 首先要了解我是如何陷入這種境地的。

問題 2 的答案是為什么我的 Git 存儲庫進入了分離的 HEAD 狀態?

問題 1 的答案更簡單:第一個顯示 detached-HEAD 狀態,第二個帶有箭頭的顯示attached-HEAD 狀態。 但是我們可以稍微解釋一下:特別是“分離 HEAD”的整個概念首先有點奇特。 不過,在我們描述它之前,我們必須知道附加的 HEAD 是什么! 從某種意義上說,它是顯而易見的——它與分離的 HEAD 相反——但這只是循環推理。 我們需要一些更基本的東西,這在於Git 如何找到提交

首先,請記住每個 Git 提交都有一個唯一的哈希 ID:

 commit 44422b74b6826291479ee7a17fe18bb4acca6355

那一大串難看的字母和數字是一個數字,用十六進制表示 (十進制是 389687007142770230305517186390235637298437448533,這實際上並沒有更好。😀事實上,Git 必須使用十六進制或二進制,因為它在數據庫中通過前綴查找這些信息的方式,部分使用了各種大小的 2 次冪。)此哈希 ID 用作簡單鍵值數據庫中的鍵; 該值是提交的內部 Git 表示。

所以 Git需要這個提交哈希 ID 才能找到這個提交。 您必須為 Git 提供哈希 ID:這是 Git 查找提交的唯一方法。 但是誰想一遍又一遍地輸入44422b74b6826291479ee7a17fe18bb4acca6355呢? 你甚至會做對嗎? 如果你可以只說main並且 Git 可以在輔助鍵值存儲中查找main ——或者,技術上, refs/heads/main ——並找到44422b74b6826291479ee7a17fe18bb4acca6355怎么辦? 那不是更好嗎?

是的,它實際上更好,這就是我們所做的:我們輸入mainv1.2origin/develop ,Git 在這個輔助數據庫中查找它以獲取原始哈希 ID。 從那里,Git 找到我們想要的提交。

當您“在分支上”時,正如git status所說,這意味着您所做的每個提交都會更新當前分支名稱 因此,如果您on branch main並且您進行了的提交並且其哈希 ID 為a123456...或其他任何內容,Git 將存儲提交的哈希 ID a123456...或其他名稱,名稱為main (舊的 commit-hash-ID 44422b74b6826291479ee7a17fe18bb4acca6355 - 進入新的提交,因此它現在是倒數第二個提交。)

反過來,意味着 Git 需要始終知道哪個分支名稱是它應該在您進行新提交時更新的名稱。 為了記住該分支名稱,Git 將特殊名稱HEAD “附加”分支名稱。

(當前的實現是 Git 將ref: refs/heads/main寫入.git/HEAD 。但是,這個實現在未來可能會發生變化。當前的實現已經與之前的不同,並且已經有所改變處理添加的工作樹,因為現在它有時根本不是.git/HEAD :那只是用於工作樹。)

所以這是一個附加的HEAD,因此......

附加的 HEAD是指 HEAD 包含分支的名稱。 HEAD 中包含分支名稱是當前分支。 分支名稱本身,在充滿名稱到哈希 ID 映射的數據庫中,包含當前提交的哈希 ID。 所以HEAD提供了兩條信息:

  • 當前分支名稱,和
  • 當前提交哈希 ID(間接)。

分離HEAD,Git 只需將某個提交(任何現有提交)的原始哈希 ID 寫入HEAD 現在.git/HEAD包含一個原始哈希 ID,沒有當前分支名稱,但仍然有一個當前提交哈希 ID 只是HEAD現在直接持有了。 無需在名稱數據庫中查找名稱。

你所做的一切仍然和以前一樣工作:特別是,如果你創建一個的提交,新的提交會連接(向后,就像提交一樣)到你創建新提交時當前提交; 現在新的提交就是當前的提交,即 Git 已將其哈希 ID 存儲在HEAD中。

如果您確實進行了這樣的提交並運行git log ,您將看到:

commit a123456... (HEAD)
[your new commit]

commit 44422b74b6826291479ee7a17fe18bb4acca6355 (main)
[your old commit]

由於git log當前提交開始並向后工作,因此一次提交一個。 但是由於您沒有創建新的,因此名稱HEAD名稱main均表示“提交 44422b74b6826291479ee7a17fe18bb4acca6355”,因此您得到:

commit 44422b74b6826291479ee7a17fe18bb4acca6355 (HEAD, main)

附加HEAD后,Git 會使用該向前箭頭符號打印它(因為 Git 2.10:在 2.10.0 之前,Git 打印HEAD, main兩種情況)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM