detached HEAD詳解

admin發表於2018-07-17

關於HEAD基本內容可以參閱Git HEAD是什麼一章節。

HEAD是一個指標,通常情況下,它指向當前所在分支,而分支又指向一個commit提交。

HEAD並不總指向一個分支,某些時候僅指向某個commit提交,這就形成detached HEAD。

一.產生原因:

(1).使用git checkout指令切換到指定commit提交。

(2).使用git checkout指令切換到遠端分支。

(3).Rebase操作也會產生detached HEAD狀態。

二.狀態分析:

1.git checkout切換到指定commit:

不要把detached HEAD想的很特別,其實就是HEAD指向某個commit提交,而這個提交恰巧沒有被分支指向。

首先看一下當前master分支提交歷史:

[Shell] 純文字檢視 複製程式碼
$ git log --oneline

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092055tqozsfse9oqeefo9.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

共有四個commit提交,下面通過git checkout命令切換到c2提交:

[Shell] 純文字檢視 複製程式碼
$ git checkout 2bc214d

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092140oimbmh3t71gpgbi1.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以見當前HEAD已經指向2bc214d提交,但是此commit提交沒有分支指向它,處於detached HEAD狀態。

下面我們修改一下檔案,然後進行一次新的提交,這時它的表現與普通分支無異,HEAD指標會繼續向前推進。但是HEAD並沒有指向一個分支,也就是新的提交併沒有被分支指向。

[Shell] 純文字檢視 複製程式碼
$ git commit -m "detached HEAD"

進行上述提交後,檢視當前狀態:

[Shell] 純文字檢視 複製程式碼
$ git status

程式碼執行截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092243m1ty0c36m0cy1j6j.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到HEAD依然處於detached HEAD狀態。

在detached HEAD狀態提交的commit與普通分支提交commit相比,當切換到其他分支後不容易被找到。

(1).要麼記住提交的sha-1值。

(2).或者通過git reflog查詢。

(3).如果提交長期沒有被再次使用,就會被資源回收機制收回。

如果想要保留這個提交,可以在此提交的基礎上建立一個分支:

[Shell] 純文字檢視 複製程式碼
$ git branch newBr

因為HEAD當前指向426ad27提交,上面程式碼與如下等同:

[Shell] 純文字檢視 複製程式碼
$ git branch newBr 426ad27

2.git checkout切換到遠端分支:

首先下載遠端分支到本地,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git clone https://github.com/githubantzone/myGit.git remoteN

下面來檢視一下遠端分支,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git branch --remote

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092437qlzook9gp6643lcc.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

下面切換到origin/newBr分支,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git checkout origin/newBr

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092513l3bqbocbphddqmtf.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

由此可以看到,更準確的說,detached HEAD狀態是因為HEAD沒有指向"本地"的分支導致。

當然在本地建立與遠端分支對應的本地分支,切換到本地分支自然就不會產生detached HEAD狀態。

克隆遠端分支的時候,Git會自動在本地建立一個master分支來跟蹤origin/master分支,但是不會在本地自動建立其他分支來跟蹤遠端伺服器上除master分支外的其他分支,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git branch

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092557boq9pxpxuuzkzzaa.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

只在本地自動建立了master分支,下面建立一個本地分支跟蹤origin/newBr,程式碼如下:

[Shell] 純文字檢視 複製程式碼
$ git checkout -t origin/newBr

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201807/17/092637yvzlvwnrj79visu2.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

更多遠端分支內容,可以參閱Git遠端分支一章節。

相關文章