判断 Git 提交是否是合并/还原提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3824050/
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-19 04:36:47  来源:igfitidea点击:

Telling if a Git commit is a Merge/Revert commit

gitgit-mergegit-commitgit-hash

提问by Samer Buna

I am writing a script that requires checking whether a particular commit is a Merge/Revert commit or not, and I am wondering if there is a git trick for that.

我正在编写一个脚本,需要检查特定提交是否是合并/还原提交,我想知道是否有 git 技巧。

What I came up with so far (and I definitely don't want to depend on the commit message here) is to check HASH^2and see if I don't get an error, is there a better way?

到目前为止我想出的(我绝对不想依赖这里的提交消息)是检查HASH^2我是否没有收到错误,有没有更好的方法?

回答by rafl

Figuring out if something is a merge is easy. That's all commits with more than one parent. To check for that, you can do, for example

确定某事是否合并很容易。这就是对不止一位父母的所有承诺。要检查这一点,你可以做,例如

$ git cat-file -p $commit_id

If there's more than one `parent' line in the output, you found a merge.

如果输出中有多个“父”行,则您发现了合并。

For reverts it's not as easy. Generally reverts are just normal commits that happen to apply the diff of a previous commit in reverse, effectively removing the changes that commit introduced. There're not special otherwise.

对于恢复来说,这并不容易。通常,还原只是正常的提交,恰好相反地应用了先前提交的差异,从而有效地删除了提交引入的更改。其他没什么特别的。

If a revert was created with git revert $commit, then git usually generates a commit message indication the revert and what commit it reverted. However, it's quite possible to do reverts in other ways, or to just change the commit message of a commit generated by git revert.

如果使用创建了还原git revert $commit,则 git 通常会生成一条提交消息,指示还原以及它还原的提交。但是,很有可能以其他方式进行还原,或者只是更改由git revert.

Looking for those generated revert commit message might already be a good enough heuristic for what you're trying to achieve. If not, you'd have to actually look through other commits, comparing their diffs against each other, looking of one is the exact reverse operation of another. But even that isn't a good solution. Often enough reverts are slightly different than just the reverse of the commit they're reverting, for example to accomodate for code changes that happened between the commit and the revert.

寻找那些生成的还原提交消息可能已经是一个足够好的启发式方法,可以满足您要实现的目标。如果没有,您必须实际查看其他提交,将它们的差异相互比较,查看一个是另一个完全相反的操作。但即使这样也不是一个好的解决方案。通常,足够的还原与它们正在还原的提交的反转略有不同,例如,为了适应在提交和还原之间发生的代码更改。

回答by Dave

The following instruction will dump out onlythe parent hashes. Less filtering needed...

以下指令将转储父哈希。需要更少的过滤...

git show --no-patch --format="%P" <commit hash>

git show --no-patch --format="%P" <commit hash>

回答by qneill

The answer using git cat-fileis using a git "plumbing"command, which is generally better for building scripts as the output format is not likely to change. The ones using git showand git rev-parsemay need to change over time as they are using porcelaincommands.

使用的答案git cat-file是使用 git "plumbing"命令,这通常更适合构建脚本,因为输出格式不太可能改变。使用git show和的那些git rev-parse可能需要随着时间的推移而改变,因为他们正在使用瓷器命令。

The bash function I've been using for a long time uses git rev-list:

我使用了很长时间的 bash 函数使用git rev-list

gitismerge () {
    local sha=""
    msha=$(git rev-list -1 --merges ${sha}~1..${sha})
    [ -z "$msha" ] && return 1
    return 0
}

The list of porcelain/plumbing commands can be found in the docs for the top level gitcommand.

可以在顶级git命令的文档中找到瓷器/管道命令的列表。

This code uses git-rev-listwith a specific gitrevisionsquery ${sha}~1..${sha}in a way that prints a SHA's second parent if it exists, or nothing if it is not present, which is the exact definition of a merge commit.

此代码将git-rev-list与特定的gitrevisions查询${sha}~1..${sha}一起使用,如果存在则打印 SHA 的第二个父级,如果不存在则不打印,这是合并提交的确切定义。

Specifically, SHA~1..SHAmeans include commits that are reachable from SHA but exclude those that are reachable SHA~1, which is the first parent of SHA.

具体来说,SHA~1..SHA意味着包括可从 SHA 到达的提交,但排除那些可到达 SHA~1 的提交,它是 SHA 的第一个父级

The results are stored in $msha and tested for emptiness using bash [ -z "$msha" ]failing (returning 1) if empty, or passing (returning 0) if non-empty.

结果存储在 $msha 中,并使用 bash[ -z "$msha" ]失败(返回 1)(如果为空)或传递(返回 0)(如果非空)来测试是否为空。

回答by ctrueden

One way to test for a merge commit:

测试合并提交的一种方法:

$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT

As for git revert commits, I agree with @raflthat the most realistic approach is to look for the revert message boilerplate in the commit message; if someone changed it, detecting so would be very involved.

至于 git revert 提交,我同意@rafl 的观点,即最现实的方法是在提交消息中查找恢复消息样板;如果有人更改了它,那么检测将非常复杂。

回答by hraban

Easy way to test for merge commit:

测试合并提交的简单方法:

git show --summary HEAD | grep -q ^Merge:

This will return 0 for merge commits, 1 for non-merge commits. Replace HEAD by your desired commit to test.

这将为合并提交返回 0,为非合并提交返回 1。将 HEAD 替换为您想要的测试提交。

Example usage:

用法示例:

if git show --summary some-branch | grep -q ^Merge: ; then
    echo "some-branch is a merge"
fi

回答by Marek R

I'm finding all answer over complicated and some even not reliable.
Especially if you want to do different actions for merge and regular commit.

我发现所有答案都很复杂,有些甚至不可靠。
特别是如果您想为合并和常规提交执行不同的操作。

IMO best solutions is to call git rev-parseusing second parent expression ^2and then check for an errors:

IMO 最佳解决方案是git rev-parse使用第二个父表达式调用^2,然后检查错误:

git rev-parse HEAD^2 >/dev/null 2>/dev/null && echo "is merge" || echo "regular commit" 

This works perfectly for me. Most of example above is just a decoration which just discards unwanted output.

这对我来说非常有效。上面的大部分例子只是一个装饰,只是丢弃不需要的输出。

And for windows cmdthis works nicely too:

对于 Windows,cmd这也很好用:

git rev-parse "HEAD^2" >nul 2>nul && echo is merge || echo regular commit

note quote characters

注意引号字符

回答by c-neves

Yet another way to find a commit's parents:

另一种找到提交的父母的方法:

git show -s --pretty=%p <commit>

Use %Pfor full hash. This prints how many parents HEADhas:

使用%P了完整的哈希值。这会打印出有多少父母HEAD

git show -s --pretty=%p HEAD | wc -w