Sam*_*una 33 git git-merge git-commit git-hash
我正在编写一个脚本,需要检查特定提交是否是合并/恢复提交,我想知道是否有一个git技巧.
到目前为止我提出的(我绝对不想依赖于提交消息)是检查HASH^2并查看我是否没有收到错误,是否有更好的方法?
raf*_*afl 47
弄清楚某些东西是否合并很容易.这是所有提交多个父母.例如,要检查这一点,您可以这样做
$ git cat-file -p $commit_id
Run Code Online (Sandbox Code Playgroud)
如果输出中有多个"父"行,则会找到合并.
为了恢复它并不容易.通常,恢复只是正常的提交,恰好反向应用前一个提交的差异,有效地删除了引入的提交更改.除此之外别无选择.
如果创建了一个revert git revert $commit,那么git通常会生成一个提交消息,指示revert以及它恢复的提交.但是,很有可能以其他方式进行恢复,或者只更改生成的提交的提交消息git revert.
寻找那些生成的恢复提交消息可能已经是一个足够好的启发式,你想要实现的目标.如果没有,你必须实际查看其他提交,将它们的差异相互比较,看一个是另一个的完全相反的操作.但即使这不是一个好的解决方案.通常,足够的恢复与它们恢复的提交的反向略有不同,例如,为了适应提交和恢复之间发生的代码更改.
使用的答案git cat-file是使用git "plumbing"命令,这通常更适合构建脚本,因为输出格式不太可能改变.那些使用git show并且git rev-parse可能需要随着时间的推移而改变,因为他们正在使用瓷器命令.
我一直使用的bash函数用了很长时间git rev-list:
gitismerge () {
local sha="$1"
msha=$(git rev-list -1 --merges ${sha}~1..${sha})
[ -z "$msha" ] && return 1
return 0
}
Run Code Online (Sandbox Code Playgroud)
瓷器/管道命令列表可以在顶级git命令的文档中找到.
此代码使用带有特定gitrevisions查询的git-rev-list,以打印SHA的第二个父项(如果存在),如果不存在则不存在任何内容,这是合并提交的确切定义.${sha}~1..${sha}
具体来说,SHA~1..SHA意味着包括可从SHA访问的提交,但不包括可访问的SHA~1,这是SHA的第一个父级.
结果存储在$ msha中,并使用bash [ -z "$msha" ]失败(返回1)(如果为空)或传递(返回0)(如果非空)来测试空虚.
我发现所有答案都很复杂,有些甚至不可靠。
特别是如果您想为合并和常规提交执行不同的操作。
IMO 最佳解决方案是git rev-parse使用第二个父表达式调用^2,然后检查错误:
git rev-parse HEAD^2 >/dev/null 2>/dev/null && echo "is merge" || echo "regular commit"
Run Code Online (Sandbox Code Playgroud)
这对我来说非常有效。上面的大部分例子只是一个装饰,只是丢弃不需要的输出。
对于 Windows,cmd这也很好用:
git rev-parse "HEAD^2" >nul 2>nul && echo is merge || echo regular commit
Run Code Online (Sandbox Code Playgroud)
注意引号字符
测试合并提交的一种方法:
$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT
Run Code Online (Sandbox Code Playgroud)
至于 git revert 提交,我同意@rafl 的观点,最现实的方法是在提交消息中查找 revert 消息样板;如果有人改变了它,检测起来会非常复杂。