2010-09-29 152 views
25

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

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

回答

29

搞清楚是否合并很容易。这是所有提交超过一个家长。要检查是否存在,你可以做,例如

$ git cat-file -p $commit_id 

如果有输出超过一个'父”行,你找到了合并。

恢复它并不容易。通常,还原仅仅是正常的提交,恰好相反地应用了先前提交的差异,有效地消除了引入的提交的更改。没有其他特别的。

如果使用git revert $commit创建恢复,那么git通常会生成一条提交消息,指示恢复以及恢复的提交。但是,很可能以其他方式进行恢复,或者更改由git revert生成的提交的提交消息。

寻找那些生成的回复提交消息可能已经是一个很好的尝试你想实现的启发式。如果不是,你必须实际查看其他提交,比较彼此的差异,看一个是另一个提交的确切的反向操作。但即使这不是一个好的解决方案。通常,足够的回复与其正在恢复的提交的反转略有不同,例如,以适应在提交和回复之间发生的代码更改。

+0

修正。谢谢! – rafl 2010-09-29 23:17:09

8

使用git cat-file的答案是使用git “管道”命令,由于输出格式不可能发生变化,因此通常更适合构建脚本。使用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)(如果非空),测试其是否为空。来测试合并

+0

你的意思是什么*瓷器*?你指的是什么答案? – knocte 2017-02-27 04:12:10

+0

嗨@knocte我给链接添加了一些文字,HTH。 – qneill 2017-02-27 23:58:07

+0

感谢您的更新;还有两个问题:'[-z foo]'实际上做了什么?我想知道这一点,因为我有兴趣使用这个而不是bash脚本......另外,与'cat-file'相比,你的解决方案有什么缺点和好处?欢呼 – knocte 2017-02-28 04:34:50

2

一种方式提交:

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

至于混帐复归承诺,我同意@rafl,最现实的做法是寻找提交信息的复归消息样板;如果有人改变它,检测将会非常复杂。

+1

'test -z'做了什么?这个问题没有要求bashisms ... – knocte 2017-02-28 06:06:01

+0

空洞的测试,请参阅https://stackoverflow.com/questions/18096670/what-does-z-mean-in-bash – qneill 2017-12-06 23:56:26

14

以下指令将仅转储出父散列。较少的滤波需要...

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

0

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

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 
+1

这似乎是一个很好的解决方案给我,因为如果有人在正常(非合并)提交中使用单词“合并”,那么您将有一个** false positive ** – knocte 2017-02-27 04:11:04

+0

@knocte正则表达式中的插入符号(^):它搜索合并_在行_的开头。提交消息由几个空格缩进,所以即使它包含合并,它也不会匹配。差异本身的内容(除了缩进之外)都没有显示出来,这是由 - 小结标志提供的。我知道它看起来很糟糕,但这就是Git :)这个解决方案没有误报。 – hraban 2017-02-28 00:37:51

+0

好的谢谢澄清;正如你所说,它看起来很糟糕...... – knocte 2017-02-28 06:05:17