1つのブランチのどのコミットが他のブランチにないかを確認するにはどうすればよいですか?


180

私は2つの支店develとを持っていnextます。開発では、多かれ少なかれ膨大な量のコミットがあります。コミットの一部はで厳選されていnextます。また、にマージされる次のコミットをいくつか追加しましたdevel

次に、に何が欠けているのかを確認したいnextので、変更をもたらす前に変更を詳細にテストできnextます。私の質問は今、どのコミットがdevel次のコミットではないのかをどのように確認できますか?



比較したいのは両方のブランチの先端であるため、タイトルは少し誤解を招く可能性があります。2つのブランチの特定の(異なる)コミットを比較するソリューションを探してここに来ました
thebugfinder

回答:


210

ほとんど使用されgit cherryていないコマンドは、まだ選択されていないコミットを表示します。のドキュメントgit cherryこちらですが、簡単に言うと次のことができるはずです。

git checkout devel
git cherry next

...そして、次のような出力が表示されます。

+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9

で始まるコミットは、まだ選択していない+ものになります。この場合、私はこれまでに1つのコミットのみを厳選しました。コマンドにパラメータを追加すると、各コミットの件名行も出力されるようになります。next-vgit cherry


すばらしい、これは私が必要としたものです。テストの簡単な説明を取得しておくとよいでしょうが、これをスクリプト化することができます。
Sascha Effert、2011

29
あなたがする必要はありませんgit checkout devel、あなたはただすることができますgit cherry next devel
Robin Winslow

21
「追加したいかもしれません-v?なしのチェリー-vは、lsなしのようなもの-laです。; -J
Slipp D. Thompson 2014

1
またcherry、同等のコミットをマークまたは除外する方法を知らないでしょうか? cherry配管コマンドのように見えますが、(多くの場合)多くのオプションを提供していません。私が現在真ん中にいるものについては、git cherry偽陽性を与えますが、@ sehe git log --cherry-pickは以前に選択/リベースされたコミットを正しく除外します。
Slipp D. Thompson 2014

ドキュメントは具体的な例を提供します:git-scm.com/docs/git-cherry#_concrete_example
ams

107

また、あなたは使うことができます

git log --left-right --graph --cherry-pick --oneline devel...next

ブランチ間で共有されていない実際の異なるコミットの一覧を取得する。

手術の言葉は --cherry-pick

--cherry-pick

コミットのセットが対称的な違いで制限されている場合は、「反対側」で別のコミットと同じ変更を導入するコミットを省略します。たとえば、AとBの2つのブランチがある場合、それらの片側だけですべてのコミットをリストする通常の方法は、そのオプションの説明の上記の例のように、--left-rightを使用することです。ただし、他のブランチからチェリーピックされたコミットを示しています(たとえば、「3rd on b」はブランチAからチェリーピックされている可能性があります)。このオプションを使用すると、そのようなコミットのペアは出力から除外されます。

更新コメントで述べたように、最近のバージョンのgitが追加されました--cherry-mark

--cherry-mark

--cherry-pick(下記参照)に似ていますが、同等のコミットを省略せずに=でマークし、同等でないコミットを+でマークします。


1
これは私にはうまくいきませんでした。私のバージョンのgitは知りません-1行なので、削除しました。次に、develとnextを交換する必要がありましたが、うまくいきました。非常に素晴らしい!
Sascha Effert、2011

@SaschaEffert:develとnextを切り替える必要はありませんでした(2つではなく3つのドットに注意してください)。とは言っても、古いバージョンのgit(?)を使用した場合は状況が異なる可能性がありますが、その場合、3つのドットでrev-parseエラーが発生するはずです。
sehe

2
おもしろいことに、2006年7月に '...'(対称差)rev-parse構文が追加され、そのドキュメントが2008年6月に更新されたことを確認しました。オープンソースの喜び!
sehe

1
'gls --first-parent --cherry-mark --left-only develop ... next'ここで、glsはすべてのきれいなフォーマットのgitログエイリアスです。チェリーマークは、チェリーがピックされたコミットとチェリーがピックされていないコミットの両方を開発時に表示しますが、マークは異なります。
angularsen 2014年

1
add --no-
merges

51

あなたはgit logのサブセットを試すことができます:

git log --oneline devel ^next

4
これは私の意見では最良の解決策です(@seheの回答は、開発中ではない次のコミットも示しています-OPのコンテキストではありませんが、私のものではあります-使用し--left-onlyた方がよかったでしょう)。ただし、--no-mergesマージコミットを省略して追加することで、これを少し改善できます(たとえば、機能またはホットフィックスブランチがdevelとnextの両方に(個別に)マージされた場合)。もちろん、厳密に言うと、マージでの競合解決により他の違いが生じる可能性がありますが、通常はそうではありません。この--no-mergesオプションは、他の回答にも有効に適用できます。
Alex Dupuy 2014年

27

いかがですか

git log next..devel

結果はByranの回答(コミットの順序が異なる)に似ていますが、どちらの回答でも、ブランチ間で異なるコミットが生成され、一方のブランチにあるものだけが示され、もう一方のブランチにはないものが表示されます。


4
現在そのブランチを使用している場合は、2番目のブランチを省略することもできます。iegit log next..
jmaxyz

btw 'git log next..devel'は 'git log devel..next'とは異なります
Eugene

1

リリースブランチに統合されていないコミットのリストを取得するには(次)、次のコマンドを使用できます。

git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt

詳細については、git-rev-listを確認してください。


この回答のコマンドには、問題の実際のブランチがありません。つまり、next...devel
Alex Dupuy

@AlexDupuyええ、それはかなり中途半端な答えです。また、これは最も単純な答えではなく、このアプローチの方が良い理由を説明していないので、-1にします。
Slipp D. Thompson 2014

-1

@Mark Longairは彼の答えでここに釘付けにしましたが、もう少し洞察を加えたいと思います。

大規模なプルリクエスト(PR)を分割する方法に関する質問への回答。特に、masterがfeature_branchに1つ以上マージされているため、コミットを破棄することが実用的でない場合

私の状況:30回のコミットで
ビッグを作成し、feature_branchGitHubでプルリクエスト(PR)を開いてにマージしましたmaster。ブランチmasterは私の下でトンを変え、私のfeature_branch持っていなかった200のコミットを受け取りました。解決の競合に私がやったgit checkout feature_branchgit merge masterマージするmaster私にの変更をfeature_branch。私は最新のマスターmergeではなく選択したrebaseので、潜在的に30回ではなく1回だけ競合を解決する必要があります(コミットごとに1回)。最初に30のコミットを1に押しつぶし、次に最新のものにリベースしたくありませんでしたmasterこれは、PRのGitHubレビューコメント履歴を消去する可能性があるためです。そこで、masterを機能ブランチにマージし、競合を1回解決しました。すべてが順調でした。しかし、私のPRは大きすぎて同僚がレビューするには大きすぎました。分割する必要がありました。私は30のコミットとOH NO!彼らはどこにいる?それらはすべて混在にしているmaster私がマージされているため、今の200回の最近のコミットmaster私にfeature_branch!私は何をしますか?

git cherrygit cherry-pick個々のコミットを試したい場合の使用法:

git cherry 救助に(一種)!

あるすべてのコミットを参照するにfeature_branchはありませんでmaster、私が行うことができますが。

git checkout feature_branch
git cherry master

または、feature_branch次のgit cherry [upstream_branch] [feature_branch]ようにすることで、最初にオンになっていることを確認せずに、任意のブランチからのコミットをチェックできます。繰り返しますが、これは、どのコミットfeature_branchが含まれているのかupstream_branchmasterこの場合は含まれていないのか)を確認します。

git cherry master feature_branch

追加する-vと、コミットメッセージの件名も表示されます。

git cherry -v master

「word count」「-lines」(wc -l)へのパイプは、コミットの数をカウントします。

git cherry master | wc -l

この数をGithHub PRに表示されるコミット数と比較して、実際に機能していることをよりよく理解できますgit cherry。gitハッシュを1つずつ比較して、git cherryとGitHubが一致することを確認することもできます。注git cherryあなたがマージされた任意のマージコミットはカウントされませんmasterにしfeature_branchますが、GitHubのWILL。したがって、カウントにわずかな不一致が見られる場合は、GitHub PRコミットページで「マージ」という単語を検索すると、おそらくそれがに表示されていない原因であることがわかりますgit cherry。例:「Merge branch 'master' into feature_branch」というタイトルのコミットはGitHub PRに表示されますが、を実行すると表示されませんgit cherry master feature_branch。これで問題ありません。

だから、今私はこの差分を分割するために新しい機能ブランチにチェリーピックしたいかもしれないdiffを見つける手段を持っています:git cherry master feature_branchローカルで使うか、GitHub PRでコミットを見ることができます。

スカッシュがどのように役立つか-スカッシュできた場合のみ:

ただし、私の大きな差分を分割する別の方法は、30のコミットすべてを1つにまとめ、新しい機能ブランチにパッチを適用し、パッチコミットをソフトリセットしてgit guiから、ピースをファイルごとに、チャンクごとに追加するか、または1行ずつ。サブ機能を1つ取得したら、追加した内容をコミットし、新しいブランチをチェックアウトし、さらに追加し、コミットし、新しいブランチをチェックアウトするなどして、大きな機能をいくつかのサブ機能に分割します。 。問題は、私の30回のコミットが原因私に他の人から他の200のコミットと混在していることであるgit merge master私にfeature_branch、私は再注文に230回のコミットを取捨選択し、私の30回のコミットをつぶす必要があるだろうと、そうリベースは、したがって、非現実的です。

スカッシュのはるかに簡単な置き換えとしてパッチファイルを使用する方法:

回避策は、30のコミットすべての「スカッシュ相当」を含むパッチファイル取得し、それをmaster(新しいサブ機能ブランチ)の新しいフォークにパッチして、そこから次のように作業することです。

git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master 
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch

これで、30コミットパッチがすべてローカルに適用されましたが、ステージングもコミットもされていません。

git guiファイル、チャンク、および/または行を追加し、大きなPRまたは「差分」を分割するために使用します。

がない場合はgit gui、Ubuntuに簡単にインストールできますsudo apt install git-gui

git gui(git GUIプログラムで右クリックして)ファイル、チャンク、および/または行を実行して追加を開始し、上記のように30のコミット機能ブランチをサブブランチに分割し、繰り返し追加、コミット、フォークすることができます。すべての変更がサブ機能ブランチに追加され、30コミット機能が3つまたは4つのサブ機能に正常に分割されるまで、新しい機能ブランチとこのサイクルを繰り返します。ここで、これらのサブ機能ごとに個別のPRを開くことができます。これにより、私のチームが簡単に確認できるようになります。

参照:

  1. gitリポジトリからパッチまたはdiffファイルを作成し、別の異なるgitリポジトリに適用します

今日はこの回答を参照する必要がありましたが、すぐに見つけることができませんでした。幸いなことに、見つけやすくするための反対票があったため、画面の右上にあるアワードカップアイコンをクリックするだけで、最近2ポイントを失った場所が表示され、それをクリックすると、ここに戻ることができます。ここで私自身の答えを参照してください!うまくいけば、もうダウン投票はできませんが、誤って私を助けてくれたサービスに感謝して、ダウン投票に感謝します!
ガブリエルステープルズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.