我一直在寻找同样的东西,然后发现了这个问题。谢谢你的提问!
然而我发现我在这里看到的答案似乎并不quite给出你要求的答案(或者我正在寻找的答案)——他们似乎给出了G
提交,而不是A
commit.
因此,我创建了以下树(按时间顺序分配的字母),以便我可以进行测试:
A - B - D - F - G <- "master" branch (at G)
\ \ /
C - E --' <- "topic" branch (still at E)
这看起来和你的有点不同,因为我想确保我得到了(指的是这张图,而不是你的)B,但不是A(而不是D或E)。以下是附加到 SHA 前缀和提交消息的字母(我的存储库可以从here https://www.daveltd.com/misc/stackoverflow/oldest-common-ancestor.git,如果有人对此感兴趣):
G: a9546a2 merge from topic back to master
F: e7c863d commit on master after master was merged to topic
E: 648ca35 merging master onto topic
D: 37ad159 post-branch commit on master
C: 132ee2a first commit on topic branch
B: 6aafd7f second commit on master before branching
A: 4112403 initial commit on master
So, the 目标:找到B。经过一番修改后,我发现了以下三种方法:
1. 视觉上,使用gitk:
您应该直观地看到这样的树(从 master 角度看):
或这里(从主题来看):
在这两种情况下,我都选择了提交B
在我的图表中。单击它后,其完整 SHA 将显示在图表下方的文本输入字段中。
2. 从视觉上看,但从终端来看:
git log --graph --oneline --all
(编辑/旁注:添加--decorate
也可以很有趣;它添加了分支名称、标签等的指示。不将其添加到上面的命令行中,因为下面的输出不反映其用途。)
这表明(假设git config --global color.ui auto
):
或者,用直接的文本:
* a9546a2 merge from topic back to master
|\
| * 648ca35 merging master onto topic
| |\
| * | 132ee2a first commit on topic branch
* | | e7c863d commit on master after master was merged to topic
| |/
|/|
* | 37ad159 post-branch commit on master
|/
* 6aafd7f second commit on master before branching
* 4112403 initial commit on master
无论哪种情况,我们都将 6aafd7f 提交视为最低公共点,即B
在我的图表中,或者A
在你的。
3.用贝壳魔法:
您没有在问题中指定您是否想要类似上面的内容,或者只需要一个命令即可获得一个修订版,而无需其他任何内容。嗯,这是后者:
diff -u <(git rev-list --first-parent topic) \
<(git rev-list --first-parent master) | \
sed -ne 's/^ //p' | head -1
6aafd7ff98017c816033df18395c5c1e7829960d
您也可以将其放入 ~/.gitconfig 中(注意:尾随破折号很重要;谢谢Brian https://stackoverflow.com/users/681479/brian-white为了引起人们的注意):
[alias]
oldest-ancestor = !zsh -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' -
这可以通过以下(用引号引起来的)命令行来完成:
git config --global alias.oldest-ancestor '!zsh -c '\''diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne "s/^ //p" | head -1'\'' -'
Note: zsh
本来可以很容易地bash
, but sh
will not工作——<()
原生语法不存在sh
。 (再次感谢您,@conny,让我在对此页面上另一个答案的评论中意识到这一点!)
注意:上述的替代版本:
谢谢liori https://stackoverflow.com/users/42610/liori for 指出 https://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git/4991675#comment17222398_4991675当比较相同的分支时,上面的内容可能会失败,并提出一个替代的 diff 形式,从混合中删除 sed 形式,并使这个“更安全”(即它返回一个结果(即最近的提交),即使当您将大师与大师进行比较):
作为 .git-config 行:
[alias]
oldest-ancestor = !zsh -c 'diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1' -
从外壳:
git config --global alias.oldest-ancestor '!zsh -c '\''diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1'\'' -'
因此,在我的测试树中(有一段时间不可用,抱歉;它又回来了),现在对 master 和 topic 都有效(分别给出提交 G 和 B)。再次感谢 liori 提供的替代形式。
这就是我[和 liori] 的想法。这似乎对我有用。它还允许使用额外的几个别名,这可能会很方便:
git config --global alias.branchdiff '!sh -c "git diff `git oldest-ancestor`.."'
git config --global alias.branchlog '!sh -c "git log `git oldest-ancestor`.."'
快乐 git-ing!