上下文:我正试图有一个"清洁";主分支,所以我使用选项git merge --squash
和git rebase -i HEAD~x
,但我遇到了问题(主要是因为我真的不懂git):
what I have:
C - D - E
/
A - B - - - - - F
和我想看到一个"干净"的;日志记录:
A - B - F
我终于发现我可以操纵日志输出,而不是改变历史,我认为这是伟大的:
使用git log --first-parent master
给我(简化):
F "merged commit"
B "second commit"
A "first commit"
但有一些我不明白的:如果我用git commit amend -m "third commit"
更改F
的提交消息,我仍然会得到:
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这样做时,它会更新一个分支名,特别是当前的git log --graph
那样将它们与较新的提交画在顶部:C--D--E <-- your-branch
/
A--B---------F <-- master (HEAD)
master
作为当前名称,因此git log --graph --first-parent master
将显示您提交的F
,然后B
,然后A
,但git log --graph
也将没有分支名称master
。C--D--E <-- your-branch
/
A--B---------F <-- dev (HEAD), master
git log --graph --first-parent master
将从提交F
开始,然后跳转到提交B
—跳过第二个父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'
,然后是B
,然后是A
,按此顺序。但是git commit --amend
唯一更新的名称是dev
,而不是master
。因此,git log --graph --first-parent master
将显示提交F
-原始的,实际上没有任何修改的提交-然后是B
,然后是A
。
这对你来说意味着你必须非常小心使用git commit --amend
。它需要和git rebase
一样的注意,也是通过将现有的提交复制到新的、据说是改进的替代提交来工作的。原始提交始终保留。任何提交都不能被更改,甚至Git本身也不能!如果再也没有人看到原来的提交,看起来好像旧的提交已经被更改为新的提交,只要您从不查看原始哈希id。1但是它们没有:原始的提交仍然在那里,具有原始的哈希id。我们只是使用更新后的名称来查找新的提交而不是旧的。
需要注意,因为有些人(在这种情况下,甚至可能是您自己)仍然会使用指向旧的、未改进的提交的名称。当使用这些名称来查找提交时,他们将看到旧的提交。
1谁会这么做呢?