首页 > 解决方案 > 根据 git,一个提交是另一个提交的祖先,但也不是

问题描述

所以我有一个奇怪的情况,一些 git log 命令声称一个提交是另一个提交的祖先,但其他命令声称它不是。然后再次合并提交后它是正确的。

所以它肯定是在历史上:

> git log 533f43d27f1a937d43dc00cf33684efeeeea6f58 | grep 25303646749f814a64339845fef830d60236b47c
commit 25303646749f814a64339845fef830d60236b47c
> git log --oneline --graph 533f43d27f1a937d43dc00cf33684efeeeea6f58 | grep 253036467
| | * | | | | | | | | | | | | | | | | | | 25303646749 [commit message stripped]

但它也不是:

> git log 533f43d27f1a937d43dc00cf33684efeeeea6f58..25303646749f814a64339845fef830d60236b47c | grep commit
commit 25303646749f814a64339845fef830d60236b47c
> git log --oneline --graph 533f43d27f1a937d43dc00cf33684efeeeea6f58..c4353c35b7233c4cab8e63817aac28dda5dbf8bc | grep 25303646749
| * 25303646749 [commit message stripped]

我无法合并它:

((533f43d27f1...))> git merge 25303646749f814a64339845fef830d60236b47c
Already up to date.

但我可以合并其他包含它的东西:

((533f43d27f1...))> git log --no-merges  ..c4353c35b7233c4cab8e63817aac28dda5dbf8bc | grep commit
commit 0f3704bf5a6428940ee0b1f1df36ebbe807cca99
commit 25303646749f814a64339845fef830d60236b47c
((533f43d27f1...))> git merge c4353c35b7233c4cab8e63817aac28dda5dbf8bc
Merge made by the 'recursive' strategy.

然后它不再出现在 git log 中:

((c474a8be528...))> git log ..25303646749f814a64339845fef830d60236b47c
((c474a8be528...))>

到目前为止,我还无法通过任何其他提交来重现这一点。关于可能导致这种情况的任何想法?

标签: git

解决方案


首先:
您正在使用grep的输出git log,它还可以显示出现在任何地方的行。

难道是提交533f43d27(或其父母之一)包含一行说明:

commit 25303646749f814a64339845fef830d60236b47c

在它的信息中?

第二:
您检查历史记录533f43d27,但问题中的命令未验证活动提交 ( HEAD) 的值是什么:

git rev-parse HEAD

grep 提交 ID:使用git rev-list而不是git log.

要在终端中查看您的仓库的历史记录,我建议:

git log --oneline --graph

# can be combined with any other parameters for git log :
git log --oneline --graph 533f43d2
git log --oneline --graph 533f43d2..25303646
git log --oneline --graph --no-merges ..c4353c3
# etc ...

要为其设置快捷方式:

git config --global alias.lol 'log --oneline --graph'

# usage :
git lol 533f43d2..25303646
git lol --no-merges ..c4353c3

在你的情况下,看看:

git lol 533f43d2 c4353c3

检查是否A是 的祖先的命令B

git merge-base A B
# if it displays A : A is an ancestor of B
# if it displays B : B is an ancestor of A
# if it displays something else : A and B forked, and aren't ancestors or descendants

推荐阅读