我正在编写一个脚本,需要检查特定提交是否是合并/恢复提交,我想知道是否有一个git技巧。
到目前为止我提出的(我绝对不想依赖于提交消息)是检查HASH^2
并查看我是否没有收到错误,是否有更好的方法?
答案 0 :(得分:41)
确定某些东西是否合并很容易。这是所有提交多个父母。要检查这一点,您可以这样做,例如
$ git cat-file -p $commit_id
如果输出中有多个“父”行,则表示已合并。
为了恢复它并不容易。通常,恢复只是正常的提交,恰好反向应用前一个提交的差异,有效地删除了引入的提交更改。除此之外别无选择。
如果使用git revert $commit
创建了还原,那么git通常会生成一个提交消息,指示还原以及它还原的提交。但是,很有可能以其他方式进行恢复,或者仅更改git revert
生成的提交的提交消息。
寻找那些生成的恢复提交消息可能已经是一个足够好的启发式,以满足您的目标。如果没有,你必须实际查看其他提交,将它们的差异相互比较,看一个是另一个的完全相反的操作。但即使这不是一个好的解决方案。通常,足够的恢复与它们恢复的提交的反向略有不同,例如,以适应提交和恢复之间发生的代码更改。
答案 1 :(得分:15)
以下说明将转出仅父哈希值。需要更少的过滤......
git show --no-patch --format="%P" <commit hash>
答案 2 :(得分:9)
使用git cat-file
的答案是使用git “plumbing”命令,这通常更适合构建脚本,因为输出格式不太可能改变。使用git show
和git rev-parse
的用户可能需要在使用porcelain命令时进行更改。
我长期使用的bash功能使用git rev-list
:
gitismerge () {
local sha="$1"
msha=$(git rev-list -1 --merges ${sha}~1..${sha})
[ -z "$msha" ] && return 1
return 0
}
瓷器/管道命令列表可以在顶级 git命令的文档中找到。
此代码使用git-rev-list和特定gitrevisions查询${sha}~1..${sha}
,以打印SHA的第二个父项(如果存在),如果不存在,则使用任何内容,这是确切的合并提交的定义。
具体来说,SHA~1..SHA
表示包括可从SHA访问的提交,但不包括那些可到达的SHA~1,这是SHA的第一个父。
结果存储在$ msha中,并使用bash [ -z "$msha" ]
失败(如果为空则返回1)或者如果非空则传递(返回0)来测试空虚。
答案 3 :(得分:2)
测试合并提交的一种方法:
$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT
至于git revert提交,我同意@rafl,最现实的方法是在提交消息中查找revert消息样板;如果有人改变它,那么检测就会非常复杂。
答案 4 :(得分:1)
测试合并提交的简便方法:
git show --summary HEAD | grep -q ^Merge:
这将为合并提交返回0,为非合并提交返回1。用您想要的提交替换HEAD进行测试。
使用示例:
if git show --summary some-branch | grep -q ^Merge: ; then
echo "some-branch is a merge"
fi
答案 5 :(得分:0)
还有另一种方式来查找提交的父母:
git show -s --pretty=%p <commit>
使用%P
进行完整散列。这会显示HEAD
有多少父母:
git show -s --pretty=%p HEAD | wc -w
答案 6 :(得分:0)
我正在找到所有关于复杂甚至不可靠的答案。
尤其是如果您想对合并和常规提交执行不同的操作。
IMO最佳解决方案是使用第二个父表达式git rev-parse
调用^2
,然后检查错误:
git rev-parse HEAD^2 >/dev/null 2>/dev/null && echo "is merge" || echo "regular commit"
这对我来说非常有效。上面的大多数示例只是一种装饰,它只会丢弃不需要的输出。
对于Windows cmd
,它也可以很好地工作:
git rev-parse "HEAD^2" >nul 2>nul && echo is merge || echo regular commit
注释引号字符
答案 7 :(得分:0)
要检查它是否是合并提交,
# Use the FULL commit hash because -q checks if the entire line is matched.
git rev-list --merges --all | grep -qx <FULL_commit_hash>
echo $? # 0 if it's a merge commit and non-zero otherwise
要检查它是否是还原提交,您必须查看其他答案。
答案 8 :(得分:0)
如果以下命令的输出为 1,则表示这是一次单独的提交。如果不是,则为合并提交
git cat-file -p $commitID | grep -o -i parent | wc -l