1

在最新的存储库中,我们执行以下操作:

git checkout HEAD~5

然后使用GitPython,我们可以获得head commit,它是分离的:

import git

repo = git.Repo('.')
head = repo.head
head_commit = head.commit
print(head.is_detached)
> True

GitPython 中有没有办法获取分支中的最后一次提交?

我正在考虑以下内容:

last = repo.active_branch.last_commit  # active_branch will throw an error when head is detached.

或者

last = head_commit
# I dont even know if talking about child commits makes sense in git.
while last.child is not None:
    last = last.child
4

1 回答 1

1

任何分支中的最后一次提交由存储在分支名称中的提交哈希 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

练习(按顺序进行)

  1. 我会给你两个原始的提交哈希 ID,前提是第一个提交的哈希 ID 可以通过从第二个提交开始并向后走,沿着这些向后指向的箭头一次一步。例如,我可能会给你 commitF的哈希 ID 和 commit 的哈希 ID K。你如何使用这些信息来查找 commit G?(考虑从提交开始K并遵循每个箭头,同时保留每个访问过的提交的某种日志。)

  2. 提交之后下一个提交是什么?为了找到下一次提交,您还需要哪些其他信息?请记住,提交同时存在于和上。IIbr1br2

于 2019-11-17T21:40:47.370 回答