web-dev-qa-db-ja.com

Gitコミットがマージ/復帰コミットかどうかを確認する

特定のコミットがマージ/復帰コミットであるかどうかを確認する必要があるスクリプトを書いていますが、そのためのgitトリックがあるかどうか疑問に思っています。

私がこれまでに思いついたのは(そしてここでのコミットメッセージに絶対に依存したくない)、HASH^2をチェックして、エラーが発生しないかどうかを確認することです。もっと良い方法はありますか?

37
Samer Buna

何かがマージであるかどうかを判断するのは簡単です。これで、複数の親とのコミットがすべて完了しました。それを確認するには、たとえば、

$ git cat-file -p $commit_id

出力に複数の「親」行がある場合は、マージが見つかりました。

復帰の場合、それはそれほど簡単ではありません。通常、元に戻すは、前のコミットの差分を逆に適用する通常のコミットであり、コミットによって導入された変更を効果的に削除します。それ以外に特別なことはありません。

復帰がgit revert $commitで作成された場合、gitは通常、復帰とそれが復帰したコミットを示すコミットメッセージを生成します。ただし、他の方法で元に戻すことや、git revertによって生成されたコミットのコミットメッセージを変更することは可能です。

生成された元に戻すコミットメッセージを探すことは、達成しようとしていることに対してすでに十分なヒューリスティックである可能性があります。そうでない場合は、実際に他のコミットを調べて、それらの差分を相互に比較する必要があります。一方を探すことは、もう一方のまったく逆の操作です。しかし、それでも良い解決策ではありません。多くの場合、十分な復帰は、たとえば、コミットと復帰の間に発生したコードの変更に対応するために、復帰するコミットの逆とはわずかに異なります。

47
rafl

次の命令は、親ハッシュをダンプしますのみ。必要なフィルタリングが少なくなります...

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

18
Dave

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 query ${sha}~1..${sha}とともに使用し、SHAの2番目の親が存在する場合はそれを出力し、存在する場合は何も出力しません。存在しません。これは、マージコミットの正確な定義です。

具体的には、SHA~1..SHASHAから到達可能なコミットを含みますが、SHAの最初の親であるSHA〜1に到達可能なコミットは除外しますを意味します。

結果は$ mshaに格納され、bash [ -z "$msha" ]が空の場合は失敗(1を返す)、空でない場合は合格(0を返す)を使用して空をテストします。

10
qneill

マージコミットをテストする1つの方法:

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

Git revert commitについては、 @ rafl に同意します。最も現実的なアプローチは、コミットメッセージで元に戻すメッセージの定型文を探すことです。誰かがそれを変更した場合、それを検出することは非常に複雑になります。

2
ctrueden

マージコミットをテストする簡単な方法:

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
hraban

コミットの親を見つけるさらに別の方法:

git show -s --pretty=%p <commit>

使用する %P完全なハッシュの場合。これは、HEADが持っている親の数を出力します。

git show -s --pretty=%p HEAD | wc -w
0
c-neves

私はすべての答えを複雑で信頼できないものさえ見つけています。
特に、マージと通常のコミットに対して異なるアクションを実行する場合。

IMOの最善の解決策は、2番目の親式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

引用符に注意してください

0
Marek R