変更されたすべてのファイルが親の1つと一致する場合でも、diff出力を組み合わせたマージコミットを「git show」する方法


186

「単純な」マージ(競合のないマージ)を実行した後、git show通常は次のようなものだけが表示されます

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

これは、マージでgit showは、親バージョンのいずれかと一致するファイルを省略した結合diff形式を使用するためです。

gitに強制的にdiffモードの違いをすべて表示する方法はありますか?

実行git show -mすると違いが表示されます(新しいバージョンとすべての親バージョンのペアごとの差分をそれぞれ使用します)が、結合モードのように、それぞれの列で+/-でマークされた違いがあるようにしたいと思います。


1
@ Tilman Vogel:承認された回答を確認してください-より良い回答があるようです
Jayan

1
@Jayan他の回答は有用なヒントを含んでいるためより人気がありますが、実際には双方向の差分を行うだけなので、問題に近づきません。3方向の差分を探していました。
Tilman Vogel

回答:


-3

いいえ、これをで行う方法はありませんgit show。しかし、それは時々確かにいいでしょう、そしておそらくgitソースコードで実装するのは比較的簡単でしょう(結局、あなたはそれが無関係な出力であると思うものを切り取らないようにそれを言わなければなりません)、それでそうするためのパッチおそらくgitメンテナに受け入れられるでしょう。

ただし、何を望んでいるかには注意してください。3か月前に分岐された1行の変更でブランチをマージすると、メインラインと比較して大きな差分が残るため、このような完全な差分はほとんどまったく役に立ちません。これがgitが表示しない理由です。


12
「これを行う方法はありません」と明確に考えられるので、他の回答を参照してください。これは非常に誤解を招きやすいと言えます。
kgadek 2017

1
git show HEAD ^ ... HEAD; #@hesham_EEのソリューションごと。
マイケルディミット

git show HEAD〜1 ... HEAD〜0-名前のみ; #より良い構文。prを反復するため。
Michael Dimmitt、

256

コミットメッセージを見てください:

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

行に注意してください:

Merge: fc17405 ee2de56

これらの2つのコミットIDを取り、それらを逆にします。したがって、必要な差分を取得するには、次のようにします。

git diff ee2de56..fc17405

変更されたファイルの名前だけを表示するには:

git diff --name-only ee2de56..fc17405

それらを抽出するには、これをgitconfigに追加します:

exportfiles = !sh -c 'git diff $0 --name-only | "while read files; do mkdir -p \"$1/$(dirname $files)\"; cp -vf $files $1/$(dirname $files); done"'

次に、次のようにして使用します。

git exportfiles ee2de56..fc17405 /c/temp/myproject

提案をありがとう、しかしそれは私の問題を解決しないと思います。コメントのマークアップとフォーマットが制限されているため、私のコメントに回答を追加しました。そのために残念!表示されるまで、ピアレビューを受ける必要があります。
Tilman Vogel

6
私の編集は拒否されたようです。要約:あなたの差分はどの追加がどのブランチから来たかを示していません。また、変更が2番目のブランチで追加されたか、最初のブランチで削除されたかを区別することはできません。
Tilman Vogel

45
より良い解決策はgit diff fc17405...ee2de56-これはfc17405でのコミットから到達可能なee2de56のすべての変更を表示します。2つのドットではなく3つのドットに注意してください。
Kris Nuttycombe 2013

1
@KrisNuttycombe 3つのドットと順序。そして、あなたのコメントは私が探していたものであり、それはOPが望んでいたものに似ていると思います。
イズカタ2013年

@KrisNuttycombeこれはどういうわけかで動作しません。バリアントのgit logように、すべてのコミットが表示されます.......同じですがlogdiff違います!?このブランチにマージされたコミットのリストを取得するにはどうすればよいですか?
Rudie、2015

77

より良い解決策(@KrisNuttycombeで言及):

git diff fc17405...ee2de56

マージコミットの場合:

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

ee2de56コミットから到達可能なすべての変更を表示しfc17405ます。コミットハッシュの順序に注意してください-それはマージ情報に示されているものと同じです:Merge: fc17405 ee2de56

...2つではなく3つの点にも注意してください

変更されたファイルのリストについては、以下を使用できます。

git diff fc17405...ee2de56 --name-only

これはまさに私が+1した後のことです。
geedoubleya 2017年

これは実際にはマージ競合の結果を示していますが、他の答えはそうではありません。
ポッド

12

マージする前に、HEADを1つのコミットに設定してブランチを作成できます。その後、次のことができます。

git merge --squash testing

これはマージされますが、コミットされません。次に:

git diff

5

ここで答えたようです:https//public-inbox.org/git/7vd392ezhx.fsf@alter.siamese.dyndns.org/

同様に、実行中

$ git diff --cc $ M $ M ^ 1 $ M ^ 2 $(git merge-base $ M ^ 1 $ M ^ 2)

親とマージベースに記録された状態に関連して$ Mの状態を説明する結合パッチを表示する必要があります。


そのようなdiffを並べて表示するように構成できるツールがあるかどうかを知っていますか(IntelliJマージ競合解決ウィンドウのように)いくつかの列に表示される可能性がありますか?あなたの答えはまさに私が探していたものです
Max

@Maxいいえ、私はしていません。グーグル "n-way visual diff"はいくつかのリンクを提供するので、私はそれらを試しました。
max630

4

「git show -c $ ref」が必要なだけだと思います。a8e4a59のgitリポジトリでこれを試してみると、diffの組み合わせが表示されます(2つの列のいずれかにプラス/マイナスの文字)。git-showマニュアルで言及されているように、これらはgit diff-treeにほとんど委任されているため、これらのオプションは便利に見えます。


3
いいえ、「単純な」マージの場合、git show -c $ref私が引用したのと同じ出力、つまり違いはありません。-c選択「--cc」、参照マージコミットのデフォルトモードと非常によく似た複合差分モードであるgit help showgit help diff-tree。どちらも、そのファイルの親バージョンのいずれかに一致するファイルを完全に省略します。
Tilman Vogel

a8e4a59確かに、マージコミットのカテゴリには分類されません。このマージコミットには、実際には、両方の親バージョンとは異なる1つのファイルが含まれています。Documentation/git-fast-import.txtある親から追加されたものと、別の親から追加されたものがあります。これにより、からの空でない出力が生成されgit diff-tree --ccます。ただし、この「矛盾する」ケースの変更のみが表示されます。「クリーン」なマージ結果git show -m a8e4a59はすべて表示されていますが、まったく表示されていません。
Tilman Vogel、

1
@TilmanVogel:「興味のない」ファイルのマージはgit show -c出力から除外されていることを指摘していただきありがとうございます。(man git-diff-tree「さらに、すべての親から変更されたファイルのみが一覧表示されます。」とありますが、私は確かにそれを発見していませんでした。)
Paul Whittaker

3

あなたの場合、あなたがする必要があるのは

git diff HEAD^ HEAD^2

またはコミットするためのハッシュ:

git diff 0e1329e55^ 0e1329e55^2

4
いいえ、これは2つの親の間の単純な双方向の差分を行うだけです。私が求めていたことは、同時に間の差分を示すモードだったgit merge-base HEAD^ HEAD^2HEAD^し、HEAD^2紛争と合併したファイルに対して行われているのと同じスタイルでは。
Tilman Vogel

3

上記のように、マージコミットがcommit 0e1329e5の場合、このマージに含まれていた差分を次のようにして取得できます。

git diff 0e1329e5^..0e1329e5

これが役に立てば幸いです!


3

あなたがマージコミットに座っているなら、これは差分を表示します:

git diff HEAD~1..HEAD

マージコミットでない場合は、HEADをマージコミットに置き換えます。この方法は、最も簡単で直感的な方法のようです。


1
これは「結合されたdiff」出力ではありません。ここでは、ペアの親とHEADの違いを取得することは問題になりません。
Tilman Vogel

2

-cフラグを指定してdiff-treeコマンドを使用できます。このコマンドは、マージコミットで変更されたファイルを示します。

git diff-tree -c {merged_commit_sha}

私はGit-Scmから-cフラグの説明を得ました:

このフラグは、マージコミットの表示方法を変更します(つまり、コマンドにoneまたは--stdinが指定されている場合にのみ役立ちます)。これは、親と結果のペアごとの差分を一度に1つずつ表示するのではなく、各親からマージ結果への違いを同時に示します(-mオプションが行うことです)。さらに、すべての親から変更されたファイルのみがリストされます。


2
このトピックに関する良い記事のように見えます:haacked.com/archive/2014/02/21/reviewing-merge-commitsそして多分これも:longair.net/blog/2009/04/16/git-fetch-and-merge
Devin G Rhode

1

マージのコミットでさまざまな操作を行うための汎用的なアプローチを構築しました。

ステップ1:編集してエイリアスをgitに追加します~/.gitconfig

[alias]
  range = "!. ~/.githelpers && run_on_merge_range"

ステップ2:で~/.githelpers、bash関数を定義します。

run_on_merge_range() {
  cmd=$1; shift
  commit=$1; shift
  range=$(git show $commit | grep Merge: | awk '{print $2 "..." $3}')
  echo "git $cmd $range $@"
  if [ -z $range ]; then
    echo "No merge detected"
    exit 1
  fi
  git $cmd $range $@
}

ステップ3:利益!

git range log <merge SHA> --oneline
git range diff <merge SHA> --reverse -p
git range diff <merge SHA> --name-only

おそらくここには改善の余地がたくさんあります。私はこれをまとめて、煩わしい状況を乗り越えました。bashの構文やロジックを自由にモック化してください。


あなたは何が必要に応じて、 『AWK』ビットの変化を「...」「..」にしたいことがあり、何をあなたはしているが、実行中のコマンドのことに注意してください:stackoverflow.com/questions/462974/...
Nerdmaster
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.