想象一下下面的历史:

       c---e---g--- feature
      /         \
-a---b---d---f---h--- master

我怎么能找到当提交“c”已合并到主(即,找到合并提交“h”)?


当前回答

这是在master中找到commit的最好方法:

[alias]
    find-merge = !"f() { git rev-list $1..master --ancestry-path --merges --reverse | head -1; }; f"

其他回答

我需要这样做,并以某种方式找到了git-when-merged(它实际上引用了这个SO问题,但Michael Haggerty从未在这里添加对他非常出色的Python脚本的引用)。现在我有了。

添加到~/.gitconfig:

[alias]
    find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
    show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"

然后你可以像这样使用别名:

# current branch
git find-merge <SHA-1>
# specify master
git find-merge <SHA-1> master

要查看合并提交的消息和其他细节,请使用带有相同参数的git show-merge。

(基于Gauthier的回答。感谢Rosen Matev和javabrett用sort纠正了一个问题。)

你可以尝试这样做。这个想法是遍历所有的合并提交,看看是否可以从其中一个提交“c”到:

$ git log --merges --format='%h' master | while read mergecommit; do
  if git log --format='%h' $mergecommit|grep -q $c; then
    echo $mergecommit;
    break
  fi
done

您的示例显示分支特性仍然可用。

在这种情况下,h是最后的结果:

git log master ^feature --ancestry-path

如果分支特性不再可用,你可以在c和master之间的历史行中显示合并提交:

git log <SHA-1_for_c>..master --ancestry-path --merges

然而,这也将显示所有发生在h之后的合并,以及在e和g之间的特征。


比较以下命令的结果:

git rev-list <SHA-1_for_c>..master --ancestry-path

git rev-list <SHA-1_for_c>..master --first-parent

会得到h的SHA-1作为最后一行。

如果有可用的,可以在这些结果上使用comm -1 -2。如果你在msysgit上,你可以使用下面的perl代码进行比较:

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2

(perl代码来自http://www.cyberciti.biz/faq/command-to-display-lines-common-in-files/,这是从“comp.com .unix.shell新闻组的某人”)。

如果要使其成为一行程序,请参阅流程替换。

也就是说,总结一下Gauthier的文章:

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' <(git rev-list --ancestry-path <SHA-1_for_c>..master) <(git rev-list --first-parent <SHA-1_for_c>..master) | tail -n 1

EDIT:因为它使用进程替换“<()”,所以它不兼容POSIX,并且它可能无法与您的shell一起工作。不过,它适用于bash或zsh。