任何分支中的最后一次提交由存储在分支名称中的提交哈希 ID 给出。
就是这样——真的就是这么简单。Git 仅向后提交链接,从子级到父级。因此,每个分支名称都必须存储其最后一次提交的哈希 ID。
在最新的存储库中,我们执行以下操作:
git checkout HEAD~5
完成此操作后,正如您在标题中所说,您拥有一个“分离的 HEAD”。这意味着您不再在任何分支上。“最后一次提交”的问题变得毫无意义:HEAD
直接指向一个提交,并且根据定义,该提交就是当前提交。您可以检查您喜欢的任何提交,例如,通过提供git checkout
原始提交哈希 ID,您将继续处于分离的 HEAD 上,但处于不同的提交上。
效果是你现在在一个匿名分支(一个没有名字的分支)上,它的最后一次提交是当前提交。此时创建一个指向该提交的新分支会导致该分支存在。它的最后一次提交是当前提交,所以现在新创建的分支上的最后一次提交是当前提交。
给定一系列提交,例如:
... <-F <-G <-H <-I <-- br1
\
J <-K <-- br2
所有的提交I
都打开了br2
,即使I
也是最后一次提交,br1
所以所有的提交I
都打开了br1
。它们在两个分支上。提交J
并且K
仅在. _br2
如果我们删除名称 br1
,所有的提交仍然可以通过名称找到br2
。Git 通过从(所有)分支名称和其他此类名称中读取每个哈希 ID 来查找(所有)提交,然后从这些提交向后工作到它们的父级和父级的父级,依此类推。
如果此时您git checkout br1
创建一个新提交,您将获得:
L <-- br1 (HEAD)
/
... <-F <-G <-H <-I
\
J <-K <-- br2
请注意,HEAD
现在附加到 branch br1
。CommitL
是该分支中的最后一次提交;通过提交I
在两个分支中。
如果您现在分离HEAD
并移动它以提交I
,您将获得:
L <-- br1
/
... <-F <-G <-H <-I <-- HEAD
\
J <-K <-- br2
练习(按顺序进行)
我会给你两个原始的提交哈希 ID,前提是第一个提交的哈希 ID 可以通过从第二个提交开始并向后走,沿着这些向后指向的箭头一次一步。例如,我可能会给你 commitF
的哈希 ID 和 commit 的哈希 ID K
。你如何使用这些信息来查找 commit G
?(考虑从提交开始K
并遵循每个箭头,同时保留每个访问过的提交的某种日志。)
提交之后的下一个提交是什么?为了找到下一次提交,您还需要哪些其他信息?请记住,提交同时存在于和上。I
I
br1
br2