如果Git提交是Merge / Revert提交则告诉

时间:2010-09-29 17:03:39

标签: git git-merge git-commit git-hash

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

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

9 个答案:

答案 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 showgit 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