判断 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
Telling if a Git commit is a Merge/Revert commit
提问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^2
and 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-file
is 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 show
and git rev-parse
may 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..SHA
means 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-parse
using second parent expression ^2
and 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 cmd
this 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 %P
for full hash. This prints how many parents HEAD
has:
使用%P
了完整的哈希值。这会打印出有多少父母HEAD
:
git show -s --pretty=%p HEAD | wc -w