git 查找包含特定提交的合并提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8475448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:28:23  来源:igfitidea点击:

Find merge commit which include a specific commit

git

提问by Guillaume Morin

Imagine the following history:

想象以下历史:

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

How can I find when commit "c" has been merged into master (ie, find merge commit "h") ?

我怎样才能找到提交“c”何时被合并到主(即,找到合并提交“h”)?

采纳答案by Gauthier

Your example shows that the branch featureis still available.

您的示例显示该分支feature仍然可用。

In that case his the last result of:

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

git log master ^feature --ancestry-path


If the branch featureis not available anymore, you can show the merge commits in the history line between cand master:

如果分支feature不再可用,您可以在c和之间的历史记录行中显示合并提交master

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

This will however also show all the merges that happened after h, and between eand gon feature.

然而,这将同时显示所有之后发生的合并h,以及之间e以及gfeature



Comparing the result of the following commands:

比较以下命令的结果:

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

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

will give you the SHA-1 of has the last row in common.

会给你 SHA-1h作为最后一行的共同点。

If you have it available, you can use comm -1 -2on these results. If you are on msysgit, you can use the following perl code to compare:

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

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

(perl code from http://www.cyberciti.biz/faq/command-to-display-lines-common-in-files/, which took it from "someone at comp.unix.shell news group").

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

See process substitutionif you want to make it a one-liner.

如果您想使其成为单行程序,请参阅流程替换

回答by robinst

Add this to your ~/.gitconfig:

将此添加到您的~/.gitconfig

[alias]
    find-merge = "!sh -c 'commit=
# current branch
git find-merge <SHA-1>
# specify master
git find-merge <SHA-1> master
&& 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
pip install git-get-merge
git get-merge <SHA-1>
) && [ -n \"$merge\" ] && git show $merge'"

Then you can use the aliases like this:

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

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

To see the merge commit's message and other details, use git show-mergewith the same arguments.

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

(Based on Gauthier's answer. Thanks to Rosen Matevand javabrettfor correcting a problem with sort.)

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

回答by Jian

git-get-mergewill locate and show the merge commit you're looking for:

git-get-merge将定位并显示您正在寻找的合并提交:

git rev-list <SHA>..master --ancestry-path | grep -f <(git rev-list <SHA>..master --first-parent) | tail -1

The command follows the children of the given commit until a merge intoanother branch (presumably master) is found.

该命令跟随给定提交的子项,直到找到合并另一个分支(可能是主分支)。

回答by Totor

That is, to summarize Gauthier's post:

也就是说,总结 Gauthier 的帖子:

function git-find-merge() {
  git rev-list ..master --ancestry-path | grep -f <(git rev-list ..master --first-parent) | tail -1
}

EDIT: because this uses process substitution"<()", it is not POSIX compatible, and it may not work with your shell. It works with bashor zshthough.

编辑:因为这使用了进程替换<()”,它与 POSIX 不兼容,并且它可能不适用于您的 shell。它适用于bashzsh

回答by Alex Dupuy

I needed to do this, and somehow found git-when-merged(which actually references this SO question, but Michael Haggerty never added a reference to his very nice Python script here). So now I have.

我需要这样做,并以某种方式发现git-when-merged(实际上引用了这个 SO question,但 Michael Haggerty 从未在此处添加对他非常好的 Python 脚本的引用)。所以现在我有了。

回答by evilstreak

Building on Gauthier's great answer, we don't need to use commto compare the lists. Since we're looking for the last result in --ancestry-pathwhich is also in --first-parent, we can simply grep for the latter in the output of the former:

基于 Gauthier 的精彩答案,我们不需要使用comm来比较列表。由于我们正在寻找--ancestry-path也是 in的最后一个结果--first-parent,我们可以在前者的输出中简单地 grep 后者:

$ gem install git-whence
$ git whence 1234567
234557 Merge pull request #203 from branch/pathway

Or for something snappy and reusable, here's a function to pop into .bashrc:

或者对于一些活泼且可重用的东西,这里有一个弹出的函数.bashrc

#!/bin/bash

commit=
if [ -z $commit ]; then
    echo 1>&2 "fatal: commit is required"
    exit 1
fi
commit=$(git rev-parse $commit)
branch=${2-@}

# if branch points to commit (both are same), then return commit
if [ $commit == $(git rev-parse $branch) ]; then
    git log -1 $commit
    exit
fi

# if commit is a merge commit on first-parent path of branch,
# then return commit
# if commit is a NON-merge commit on first-parent path of branch,
# then return branch as it's either a ff merge or commit is only on branch
# and there is not a good way to figure out the right commit
if [[ $(git log --first-parent --pretty='%P' $commit..$branch | \
    cut -d' ' -f1 | \
    grep $commit | wc -l) -eq 1 ]]; then
    if [ $(git show -s --format="%P" $commit | wc -w) -gt 1 ]; then
        # if commit is a merge commit
        git log -1 $commit
    else
        # if commit is a NON-merge commit
        echo 1>&2 ""
        echo 1>&2 "error: returning the branch commit (ff merge or commit only on branch)"
        echo 1>&2 ""
        git log -1 $branch
    fi
    exit
fi

# 1st common commit from bottom of first-parent and ancestry-path
merge=$(grep -f \
    <(git rev-list --first-parent  $commit..$branch) \
    <(git rev-list --ancestry-path $commit..$branch) \
        | tail -1)
if [ ! -z $merge ]; then
    git log -1 $merge
    exit
fi

# merge commit not found
echo 1>&2 "fatal: no merge commit found"
exit 1

回答by steel

For the Ruby crowd, there's git-whence. Very easy.

对于 Ruby 人群,有git-whence。好简单。

(master)
$ git find-merge <commit>    # to find when commit merged to current branch
$ git find-merge <branch>    # to find when branch merged to current branch
$ git find-merge <commit> pu # to find when commit merged to pu branch

回答by hIpPy

I use below bash script which I place at path ~/bin/git-find-merge. It's based on Gauthier's answerand evilstreak's answerwith few tweaks to handle corner cases. commthrows when the inputs are not sorted. grep -fworks perfectly.

我使用下面放置在 path 的 bash 脚本~/bin/git-find-merge。它基于Gauthier 的回答evilstreak 的回答,并进行了一些调整以处理极端情况。comm当输入未排序时抛出。grep -f完美地工作。

Corner cases:

角落案例:

  • If commit is a merge commit on first-parent path of branch, then return commit.
  • If commit is a NON-merge commit on first-parent path of branch, then return branch. It's either a ff merge or commit is only on branch and there is not a good way to figure out the right commit.
  • If commit and branch are same, then return commit.
  • 如果提交是分支的第一父路径上的合并提交,则返回提交。
  • 如果提交是分支的第一父路径上的非合并提交,则返回分支。它要么是 ff 合并,要么是仅在分支上提交,并且没有找到正确提交的好方法。
  • 如果提交和分支相同,则返回提交。

~/bin/git-find-mergescript:

~/bin/git-find-merge脚本:

git log --topo-order

Which lets me do this:

这让我可以这样做:

commit = ARGV[0]
master = ARGV[1] || 'origin/master'

unless commit
  puts "Usage: find-commit.rb commit [master-branch]"
  puts "Will show commit that merged <commit> into <master-branch>"
  exit 1
end

parents = `git rev-list #{commit}..#{master} --reverse --first-parent --merges`.split("\n")
ancestry = `git rev-list #{commit}..#{master} --reverse --ancestry-path --merges`.split("\n")
merge = (parents & ancestry)[0]

if merge
  system "git show #{merge}"
else
  puts "#{master} doesn't include #{commit}"
  exit 2
end

This script is also available on my github.

这个脚本也可以在我的 github 上找到

回答by Roman

ruby find-commit.rb SHA master

Then look for the first merge before the commit.

然后在提交之前寻找第一个合并。

回答by Kaplan Ilya

My ruby version of @robinst's idea, works twice faster (which is important when searching for very old commit).

我的@robinst 想法的 ruby​​ 版本,工作速度快了两倍(这在搜索非常旧的提交时很重要)。

find-commit.rb

find-commit.rb

##代码##

You can just use it like this:

你可以像这样使用它:

##代码##