如何以编程方式查找 Git 合并之前的最后一次提交

How to programmatically find last commit before a Git merge

假设我有一个 Git 历史记录(归功于 this answer for the diagram, and see here 用于具有此结构的可克隆 git 回购):

A - B - D - F - G   <- "master" branch (at G)
     \   \     /
      C - E --'     <- "topic" branch (note: deleted!)

并且假设我已经删除了 topic,这样我的本地或远程存储库中就不再有它了(而且历史早已发生变化,以至于我的 reflog 没有包含它好几个月了)。

我想找到提交 F,即 master 分支中不包含任何来自主题分支的提交的最新提交。

如果有帮助,我找到了提交 C,即我开始处理主题分支的提交。

重要提示:我不能通过查看 Git 的视觉输出来做到这一点。在我的真实代码中,topic 被合并到 master 中数十次甚至数百次,然后 master 随后被开发(有许多不相关的合并)。因此,为 提出的解决方案对我不适用。

我找到了一个名为 git-when-merged 的脚本,它帮助我完成了大部分工作。在我原来的例子中,做

git when-merged C

从 master 分支找到 G,C 第一次进入 master 的合并提交。之后,只需简单地查看直接父级即可找到不在通往 C 路径上的父级。

I'd like to find … the newest commit in the master branch that does not contain any commits from the topic branch. If it helps, I've located commit C, the commit where I started working on the topic branch.

在第一个主题分支提交的祖先路径上提交:

git rev-list --ancestry-path C..master

在 master 分支的第一父历史中提交但不在 C 的历史中(即设置合理的截止):

git rev-list --first-parent C..master

master 分支的第一个父历史中的第一个提交不在任何到 C:

的 master 祖先路径上
git rev-list --first-parent C..master \
| grep -vm1 -f <(git rev-list --ancestry-path C..master)

使用您的示例存储库执行此操作:

$ git rev-list --first-parent :/first..| grep -vm1 -f <(git rev-list --ancestry-path :/first..)
e7c863d79e8918ca947fc602ebb06266374c10e6
$ lgdo
*   a9546a2 (HEAD -> master, origin/master, origin/HEAD) merge from topic back to master
|\  
| *   648ca35 (origin/topic) 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