git log --first-parent 显示 "wrong" 提交信息

git log --first-parent shows "wrong" commit message

context :我试图拥有一个“干净”的主分支,所以我使用了 git merge --squashgit rebase -i HEAD~x 选项,但是对于这两个我都遇到了问题(主要是因为我没有真懂git) :

我有什么 :

      C - D - E
     /         \
A - B - - - - - F

我希望看到“干净”的日志历史记录:

A - B     -     F

我终于发现我可以操纵日志输出而不是改变历史,我觉得这很棒:

使用 git log --first-parent master 给我(简化):

F "merged commit"
B "second commit"
A "first commit"

但有些事情我不明白:如果我将 F 的提交消息更改为 git commit amend -m "third commit",我仍然会得到:

F "merged commit"
B "second commit"
A "first commit"

即使 git log --graph 输出:

* F "third commit"
|\
| |
| * E "feature third commit"
| |
| * D "feature second commit"
| |
| * C "feature first commit"
| |
|/
* B "second commit"
|
|
* A "first commit"

所以,为什么 git log --first-parent master 没有向我显示修改后的消息?

git commit --amend 选项不会更改 提交。它进行了 新的和不同的 提交。当 Git 执行此操作时,它会更新 one 分支名称,特别是 current 分支名称。

假设原始的提交顺序是这样的。注意:我倾向于将它们水平绘制,并将较新的提交向右,而不是 git log --graph 将它们与较新的提交绘制到顶部:

     C--D--E   <-- your-branch
    /       \
A--B---------F   <-- master (HEAD)

也就是说,您使用名称 master 作为 当前 名称,因此 git log --graph --first-parent master 将显示您的提交 F ,然后是 B,然后是 A,但是没有分支名称 master.

git log --graph 也是如此

现在假设不是上面的,我们有这个:

     C--D--E   <-- your-branch
    /       \
A--B---------F   <-- dev (HEAD), master

这与 graph 相同,因此 git log --graph --first-parent master 将从提交 F 开始,然后跳回到提交 B——跳过second-parent E 及其祖先——并向您展示您的期望。

现在,使用相同的设置,让我们 运行 git commit --amend 并注意它不会 更改 提交 F根本。相反,它创建了一个新的(据说是改进的)F',它类似于 F,但其中有一些不同之处:在这种情况下,我们更改了日志消息。所以现在我们有:

     C--D--E   <-- your-branch
    /      |\
A--B-------\-F   <-- master
    \       \
     --------F'  <-- dev (HEAD)

运行 git log --graph --first-parent,您会依次看到新的 F'BA。但是 git commit --amend 更新的唯一 namedev,而不是 master。所以 git log --graph --first-parent master 将显示提交 F——原始的 not-actually-amended-at-all 提交——然后是 B 然后是 A.

这对您来说意味着您必须非常小心 git commit --amend。它需要与 git rebase 一样的小心, 通过将现有提交复制到 new-and-supposedly-improved 替换提交来工作。 原始提交始终保留。任何提交都不能更改,即使 Git 本身也不能更改! 如果没有人再看到原始提交,看起来好像旧提交已经变成了新提交,前提是你从不看原始哈希 ID。1 但它们没有:原始提交仍然存在,并带有原始哈希 ID。我们只是使用更新后的名称来查找 new 提交 而不是 旧的。

需要小心,因为有些人——在这种情况下,甚至可能是你自己——的名字仍然会引用 old,un-improved 提交。当使用这些名称查找提交时,他们将看到旧的提交。


1到底是谁干的?