Gitを使用して、自分のブランチの1つのコミットが別のコミットの子孫であるかどうかを確認するにはどうすればよいですか?
--is-ancestor
ソリューションを気に入っています。
Gitを使用して、自分のブランチの1つのコミットが別のコミットの子孫であるかどうかを確認するにはどうすればよいですか?
--is-ancestor
ソリューションを気に入っています。
回答:
これをプログラムで(たとえばスクリプトで)チェックする場合git merge-base A B
は、が等しいgit rev-parse --verify A
(BからAに到達できる)か、またはgit rev-parse --verify B
(BがAから到達できる)かどうかをチェックできます。 git rev-parse
ここでは、コミット名からコミットSHA-1 /コミットIDに変換する必要があります。
VonC回答のgit rev-list
ように使用することも可能です。
編集:最近のGitでは、このクエリがの形式で明示的にサポートされていますgit merge-base --is-ancestor
。
質問しているコミットの1つがブランチのヒントである場合は、非プログラム的な解決策であるgit branch --contains <commit>
か、git branch --merged <commit>
そうでない可能性があります。
git checkout -b quickcheck <more-recent-commit-ID>
、その後、git branch --contains <older-commit-ID>
(その後、git branch -D quickcheck
一時的な枝を取り除くために)。
git merge-base --is-ancestor
2年前のものです。
git branch --contains <commit>
し、git merge-base --is-ancestor ...
:0.14s対3m40s
Git 1.8.0以降、これは次のオプションとしてサポートされますmerge-base
。
git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>
manページから:
--is-ancestor
最初が2番目の祖先であるかどうかを確認し、trueの場合はステータス0で終了し、そうでない場合はステータス1で終了します。エラーは、1以外のゼロ以外のステータスによって通知されます。
例えば:
git merge-base --is-ancestor origin/master master; echo $?
git merge-base THING --is-ancestor OF_THING && echo yes || echo no
例:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit commit
は私の側でgit
2.1.4(Debian / Devuan 7.10 jessie)と1.9.1(Ubuntu 14.04 trusty)のハッシュに対して機能します。Debian wheezyでも機能しますsudo apt-get install git/wheezy-backports
。
この種の操作は、SOの質問で詳しく説明されている一連のリビジョンの概念に依存しています。「「git log origin / master」と「git log origin / master ..」の違い」
git rev-list
コミットから到達可能であれば別のコミットまで戻ることができるはずです。
だから私は試してみます:
git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20
(境界コミットには接頭辞-
)
表示された最後のコミットがgit rev-list
コマンドの最初のコミットと同じ場合、2番目のコミットから到達可能なコミットです。
最初のコミットが2番目のコミットから到達できない場合、git rev-list
何も返さないはずです。
git rev-list --boundary A..B
終了するA
場合、A
から到達可能なB
ます。
以下と同じです。
git rev-list --boundary B --not A
と正の基準、および陰性参照。
それはから始まり、から到達可能なリビジョンに遭遇するまでグラフをウォークバックします。から直接到達できる
場合は、それ自体に遭遇する(そしてオプションにより表示される)と私は主張します。B
A
B
A
A
B
--boundary
A
-85e54e2...
スニペットのマイナス記号があるのですか?また、タイプミスの可能性もあります:「...は最初のコミットと同じ...」
-
は境界コミットであることを意味します。回答をより明確にするために編集し、ドキュメントリンクを更新して、この5年前の回答のタイプミスを修正しました。
もう1つの方法はgit log
、およびを使用することgrep
です。
git log --pretty=format:%H abc123 | grep def456
これは、commit def456がcommit abc123の祖先である場合は1行の出力を生成し、それ以外の場合は出力を生成しません。
通常は--pretty
引数を省略してもかまいませんが、ログコメントなどではなく、実際のコミットハッシュのみを検索するようにする場合に必要です。
--pretty
--onelineを使用する代わりに:git log --oneline ce2ee3d | grep ec219cc
うまく機能します
https://stackoverflow.com/a/13526591/895245はそれについて言及していますが、今ではより人に優しいものにしています:
git-is-ancestor() (
if git merge-base --is-ancestor "$1" "$2"; then
echo 'ancestor'
elif git merge-base --is-ancestor "$2" "$1"; then
echo 'descendant'
else
echo 'unrelated'
fi
)
alias giia='git-is-ancestor'
使用している場合 git merge-base --is-ancestor
、必ずGit 2.28(2020年第3四半期)を使用してください。
Git 2.28(2020年第3四半期)では、struct commit
常に存在する必要のない" "のいくつかのフィールドが、スラブをコミットするために移動されました。
参照c752ad0をコミットし、c49c82aをコミットし、4844812をコミットし、6da43d9をコミットすることで(2020年6月17日)アビシェーク・クマール(abhishekkumar2718
)。
(合併によりJunio C浜野- gitster
-でコミットd80bea4、2020年7月6日)
commit-graph
: 導入するcommit_graph_data_slab
サインオフ:Abhishek Kumar
commit構造体は多くのコンテキストで使用されます。ただし、メンバー
generation
とgraph_pos
は、コミットグラフ関連の操作にのみ使用され、それ以外の場合はメモリを浪費します。現在の32ビットではなく64ビットの世代番号を使用する世代番号v2に移行すると、この浪費はより顕著になります。
一緒にアクセスされることが多いので、構造体
commit_graph_data
を導入してcommit_graph_data
スラブに移動しましょう。全体的なテストスイートはと同じくらい高速に実行されますが
master
(シリーズ:26分48秒、master
27分34秒、2.87%高速)、などの特定のコマンドはSzederGáborによって発見されたようgit merge-base --is-ancestor
に40%遅くなりました。 commit-slabアクセスを最小化した後、速度低下は持続しますが、20%に近づきます。Derrick Stoleeは、速度の低下はコミットスラブアクセスの遅さではなく、基になるアルゴリズムに起因するものであると考えており、後のシリーズでフォローアップします。