特定のコミットが Merge/Revert コミットであるかどうかを確認する必要があるスクリプトを書いていますが、そのための git トリックがあるかどうか疑問に思っています。
これまでに思いついたのは (そして、ここでコミット メッセージに依存したくないことは間違いありません) HASH^2
、エラーが発生しないかどうかを確認することです。より良い方法はありますか?
特定のコミットが Merge/Revert コミットであるかどうかを確認する必要があるスクリプトを書いていますが、そのための git トリックがあるかどうか疑問に思っています。
これまでに思いついたのは (そして、ここでコミット メッセージに依存したくないことは間違いありません) HASH^2
、エラーが発生しないかどうかを確認することです。より良い方法はありますか?
何かがマージされているかどうかを判断するのは簡単です。それはすべて、複数の親を持つコミットです。それを確認するには、たとえば次のようにします
$ git cat-file -p $commit_id
出力に複数の「親」行がある場合は、マージが見つかりました。
リバートの場合は、それほど簡単ではありません。一般に、元に戻すとは、前のコミットの差分を逆に適用する通常のコミットであり、コミットが導入した変更を効果的に削除します。他に特別なことはありません。
元に戻すが で作成された場合、git revert $commit
git は通常、元に戻すことと元に戻したコミットを示すコミット メッセージを生成します。ただし、他の方法で元に戻したり、 によって生成されたコミットのコミット メッセージを変更したりすることは十分に可能ですgit revert
。
生成された revert commit メッセージを探すことは、あなたが達成しようとしていることに対してすでに十分なヒューリスティックかもしれません。そうでない場合は、実際に他のコミットを調べて、それらの差分を互いに比較する必要があります。1 つを見ることは、別のコミットとまったく逆の操作です。しかし、それでも良い解決策ではありません。多くの場合、コミットとリバートの間に発生したコード変更に対応するためなど、リバートするコミットのリバースとはわずかに異なるリバートがあります。
次の命令は、親ハッシュのみをダンプします。必要なフィルタリングが少ない...
git show --no-patch --format="%P" <commit hash>
使用する答え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
}
磁器/配管コマンドのリストは、最上位のgitコマンドのドキュメントにあります。
このコードは、特定のgitrevisionsクエリでgit-rev-listを使用して、存在する場合は SHA の 2 番目の親を出力し、存在しない場合は何も出力しません。これは、マージ コミットの正確な定義です。${sha}~1..${sha}
具体的には、 SHA から到達可能なコミットを含め、 SHA の最初の親である SHA~1 に到達可能なコミットを除外することをSHA~1..SHA
意味します。
結果は $msha に格納され、空の場合は bash の[ -z "$msha" ]
失敗 (1 を返す)、空でない場合は合格 (0 を返す) を使用して空かどうかがテストされます。
マージ コミットをテストする 1 つの方法:
$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT
git revert コミットに関しては、@raflに同意します。最も現実的なアプローチは、コミット メッセージで revert メッセージのボイラープレートを探すことです。誰かがそれを変更した場合、その検出は非常に複雑になります。
受け入れられた回答は、結果の手動検査にはうまく機能しますが、スクリプトには致命的な欠陥があります。コミットメッセージ自体に「親」で始まる行が含まれている可能性があり、上部のメタデータではなく、誤ってそれをキャッチする可能性があります出力。
より信頼できる代替手段は次のとおりです。
git show --summary <commit>
行が で始まるかどうかを確認しMerge:
ます。これは git cat-file に似ていますが、コミット メッセージの前にスペースが追加されるため、スクリプトで安全に grep できます。
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
これは、コミット メッセージ自体に 4 つのスペースがプレフィックスとして付けられているため、「Merge:」で始まる行が含まれていたとしても、のように見え Merge:..
、正規表現はそれをキャッチしないためです。^
行の先頭と一致する正規表現の先頭にある に注意してください。
コミットの親を見つけるさらに別の方法:
git show -s --pretty=%p <commit>
%P
完全なハッシュに使用します。HEAD
これは、親が何人いるかを出力します。
git show -s --pretty=%p HEAD | wc -w