如何找到合并之前的最后一次git提交

28

当我使用Git从一个工作分支合并到主分支后,有时候我想查找合并发生之前在主分支上的最后一次提交。我该怎么做?


1
你可以尝试使用 git log -1 命令,它会显示所选分支的最后一次提交的详细信息。同样,git log -2 命令会显示最近两次提交的详细信息。 - Abhi
还可以尝试使用gitk来可视化结构,并检查任何命令脚本,以防万一它们没有得到正确的合并基础(分叉点)。 - Philip Oakley
10个回答

20

确定合并后的提交的快捷方式是使用reflog

假设最后执行的操作是合并,则:

git log HEAD@{1} -1

HEAD@{1} 指代上一次操作之前的 HEAD,因此您可以使用日志和 reflog 来引用它。

git log 显示当前分支中提交的序列,所以在合并后它总是一个合并提交,在它之前是来自合并分支的提交。git reflog 显示仓库中操作的序列(例如合并、变基)。正如文档中所解释的:

引用日志或 "reflogs" 记录本地仓库中分支和其他引用的 tip 在何时被更新。在各种 Git 命令中,reflogs 非常有用,可以指定引用的旧值。


4
当我尝试这个操作时,它显示的是已合并的分支上最后一次提交,而不是在该分支合并之前主分支上的最后一次提交。 - Obromios
@Obromios,git reflog --oneline 显示了什么?列表中有哪些操作?在合并之前应选择下一个(即如果 HEAD@{0} -- merge,则为 HEAD@{1}),我认为合并不是最后一次操作。 - 2oppin
只是一个警告,如果您的主要本地分支长时间没有更新,它将会给出错误的结果。 - Manish Bansal

17

一个快速的方法是输入

git log --pretty=format:'%h : %s' --graph

然后只需沿着右侧图表向下查找,直到找到合并点。你也可以这样做

git log --pretty=format:'%h : %s' --graph > temp.txt

将输出放入一个名为temp.txt的文件中,您可以在编辑器中打开该文件并使用搜索功能查找类似于"merge"的文本。

这种方法对于回答关于您最新提交的谱系的许多其他问题都很有用,因此我已经采用了这种方法。

alias git_graph="git log --pretty=format:'%h : %s' --graph"

我在我的.bash_profile文件中添加了以下代码,这样我就可以使用```git_log```命令来查看这些信息。


1
为什么不使用 git log -1 - mallaudin
@mallaudin:我认为Obromios指的是合并落后于'master'分支顶端的多个甚至许多次提交的情况。也就是说,'git log -1'只会显示一个非合并提交。 - torek
是的,没错。我现在也这么想。 - mallaudin
1
这里提供的信息太多了,大多数人只是想要2oppin回答中描述的内容。 - ldog
你可以使用 'git log ... --graph | less' 代替 '... --graph > temp.txt',并按下斜杠 '/' 搜索短语(无需创建任何文件或编辑器操作)。 - bloody
至今仍然相关! - danu

6
如果您已经将branch合并到master中,那么以下是一种找到合并提交的方法:
#   With the ancestry-path option, 'git rev-list branch..master' (or git log)
#   will only list commits which are parents of 'master'
#   *and* children of 'branch'
#
#   If 'branch' was merged into 'master', the last commit in this list
#   is the merge commit :
$ git rev-list --ancestry-path branch..master | tail -1

在合并之前,master的状态是此提交的第一个父级:
$ h=`git rev-list --ancestry-path branch..master | tail -1`
$ git log $h^

我已经检查过了,谢谢。不过我会接受我的答案,即 stackoverflow.com/a/41628915/1299362,因为它更普遍适用。如果合并是很久以前的事情,我可以考虑使用你的答案。 - Obromios

4
以下是一个编程解决方案。我们查询以下内容以获取合并之前的上一个主提交哈希值:
git merge-base master master~1

如果最后一个合并请求是一个合并操作,那么master~1指的是该合并请求的归属分支。使用merge-base获取共同祖先的SHA值时,因为PR的结构,它将是前一个主分支提交的SHA值。
如果最后一个合并请求是一个压缩操作,那么master~1位于主分支上且正是我们想要的。这次 master~1master的父提交,所以用 git merge-base master master~1 获取共同祖先并正确返回master~1的SHA值。
通过 SHA 值,我们可以使用git log等命令获取提交的其他详细信息。
请注意,如果有许多 PR 合并操作没有首先重新定位到最新主分支,这可能不会给出最后一个主分支提交。然而,这与 OP 所想要的最后一个主分支提交“在合并之前”的定义是一致的。

3

要获取仅合并点的提交ID:

最初的回答:

git rev-list origin..HEAD --max-parents=1 --max-count=1

2

1
虽然您已经选择了一个答案(并且在5年之后对git更加熟悉),但我想添加一个尚未出现的答案。
如果您刚刚合并,那么“快速而简单”的方法是使用“git show”,答案将是Merge: abcdefg 1234567中第一个(abcdefg )值。
找到当前头部的父分支,该分支是被合并到中的子分支的规范方法是 git rev-parse HEAD^^=^1,第一个父级)。例如,如果您执行git checkout master,然后git merge other-branch,那么git rev-parse HEAD^ 将是master的上一个HEAD。(其中git rev-parse HEAD^git show HEAD^git log HEAD^ -1在使用上下文HEAD^时是等效的)。
这可以扩展 ~ 即,如果要仅查看主分支的历史记录,则逻辑扩展是HEAD^HEAD^^HEAD^^^,...,这可以通过向git log 添加--first-parent来实现 ~ 因此,如果您只想查看master的先前HEAD的顺序,则可以这样做。
git log master --oneline --first-parent --pretty=format:'%H : %s'

我个人认为这些作为别名非常有用。
alias mainline="git log master --oneline --first-parent --pretty=format:'%H : %T'"
alias maindiff="git diff $(git rev-parse master^1)..$(git rev-parse master) --stat"

0

当前合并的分支的最后提交SHA:

git rev-list HEAD^1..HEAD --max-parents=1 --max-count=1

0
如果您知道合并提交的顺序,可以使用以下方法:
$ git log -n 1 --pretty | grep Merge | head -1 | awk '{print $2}'

https://git-scm.com/docs/git-log

如果提交是合并的,并且如果漂亮格式不是oneline、email或raw,则在Author:行之前插入一行附加行。该行以"Merge:"开头,后面跟着祖先提交的sha1值,用空格分隔。

0

我也在研究这个问题,以下是我的结论:

git log --merges -1 --format='%p' | awk '{print $2}'

说明:

  • --merges – 仅显示合并提交(即父节点数为2的提交)
  • -1 – 仅显示最后一行日志
  • --format='%p' – 显示缩写的父提交哈希值

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接