Gitはスナップショットの [〜#〜] dag [〜#〜] であり、グラフ上の各ノードはコミットを表します。各コミットは「n」個の親コミットを持つことができます。
2つのコミットがある場合、DAGでこれら2つのコミットの「順序」を識別する単一の簡潔な方法はありますか。 git rev-list
が最も有望なようですが、適切な呪文を見つけることができません。
理想的には、私は次のようなものを持っているでしょう
$ git related hash1 hash2
hash1 is ancestor of hash2
OR
hash2 is ancestor of hash1
OR
hash1 unrelated to hash2
OR
hash1 is equal to hash2
git merge-base --is-ancestor <commit1> <commit2>
を使用これに対する答えを見つける方法は複数あります。最も簡単なのは使用することです
git merge-base --is-ancestor <commit> <commit>
git merge-base
のドキュメントから:
--is-ancestor
最初の
<commit>
が2番目の<commit>
の祖先であるかどうかを確認し、trueの場合はステータス0で終了し、そうでない場合はステータス1で終了します。エラーは、1以外のゼロ以外のステータスによって通知されます。
...
表記のgitログもう1つのオプションは、git log
を使用し、トリプルドット表記...
を使用して、Gitに子コミットのセットユニオンからセットインターセクションを差し引いて出力するように指示することです。基本的に、コミットのセットが互いにどのように分かれているかを示します。
$ git log --oneline --graph --left-right \
--first-parent --decorate <commit1>...<commit2>
上記のコマンドは、commit1
またはcommit2
から到達可能なコミットを示しますが、セット操作に関しては両方ではありません。つまり、C1 UNION C2-C1 INTERSECTION C2です。
どちらのコミットも他方の親でない場合は、両方の子コミットが表示されますが、一方が他方の祖先である場合は、祖先がパスに含まれているため、子孫コミットの出力のみが表示されます子孫の、したがって、出力から除外されます。
git log
とトリプルドット表記の詳細については、次のリソースをご覧ください。
git-rev-list(1) は、これに答えるために使用できるようです。別の方法は、テストするコミットに一時的なブランチラベルを添付し、次に--contains
オプションを git branch
に使用することです。
git branch --contains <commit-to-test>
出力は、コミットツリーのどこかにコミットを含むすべてのブランチになるため、他のコミットで一時ブランチを使用することで、テストしているコミットが祖先であるかどうかを確認できます。
ドキュメントから:
--contains [<commit>]
指定されたコミット(指定されていない場合はHEAD)を含むブランチのみをリストします。
次のシェルスクリプトは、トリックを行う可能性があります。
if git rev-list $SHA1 | grep -q $SHA2 ; then echo "$SHA2 is ancestor of $SHA1"
Elif git rev-list $SHA2 | grep -q $SHA1 ; then echo "$SHA1 is ancestor of $SHA2"
else echo "$SHA1 unrelated to $SHA2" ; fi
または、それをgitエイリアスにきれいにまとめます:
git config --global alias.related '!function git_related() { if git rev-list $1 | grep -q $2 ; then echo "$2 is ancestor of $1" ; Elif git rev-list $2 | grep -q $1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'
if (( $(git rev-list $1..$2|wc -l) == 0 )); then echo "$2 is ancestor of $1"
Elif (( $(git rev-list $2..$1|wc -l) == 0 )); then echo "$1 is ancestor of $2"
else echo "$1 and $2 are unrelated"
fi
git log --oneline -1 OLD_SHA..NEW_SHA
これによりログが提供される場合、OLD_SHAはNEW_SHAの親です。
@helmbertの優れたgit related
エイリアス、これはブランチID(またはHEADなど))を引数として受け入れるだけでなく、IDをコミットするバージョンです。
git config --global alias.related '!function git_related() { commit1=`git log -n 1 --format="%h" $1` ; commit2=`git log -n 1 --format="%h" $2` ; if git rev-list $commit1 | grep -q $commit2 ; then echo "$2 is ancestor of $1" ; Elif git rev-list $commit2 | grep -q $commit1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'