8

Preface

This question is about understanding the basic unified diff output format. Three way diffing and merging is probably something best done from the comfort of a proper GUI merge tool, or at the very least, vim diff mode with plugins like fugitive.vim.

Question

I find that running git diff while merging a conflict produces a diff view that has two columns of pluses and minuses.

It's clear that in comparing three different versions of the same data we'll need more information than when comparing just two. But what do these columns actually mean? There are clearly now a lot more combinations for the possible "bucket" that a given line now belongs to. It used to just be either blank (same), + (added) or - (deleted), and now we have blank, ++, --, + ,  +, - , and  -. And possibly even more that I hadn't seen.

Steven Lu
  • 41,389
  • 58
  • 210
  • 364
  • This answer has a lengthy explanation of git diff output: http://stackoverflow.com/questions/2529441/how-to-work-with-diff-representation-in-git – Klas Mellbourn May 29 '13 at 17:58
  • 1
    @KlasMellbourn Does not cover the extended two-column plus/minus format. It's pretty easy to figure out how the regular format works by just looking at it. – Steven Lu May 29 '13 at 18:44
  • Speaking of combined diff, there is now (Git 2.x+) an interesting commit to optimize it: see [my answer below](http://stackoverflow.com/a/24391987/6309) – VonC Jun 24 '14 at 16:41

2 Answers2

3

You are referring to the 'combined diff format'. This extension of the original uni-diff format deals with two or more files as input and one file as the result merge. This format is described in details as part of the 'combined diff format' section of the git-diff command manual.

hbogert
  • 4,198
  • 5
  • 24
  • 38
Dan Aloni
  • 3,968
  • 22
  • 30
1

Note that the git diff "combined diff format", with one column for each of fileN is prepended to the output line to note how X's line is different from it, can be costly to generate.

The recent commit 72441af (April 2014) from Kirill Smelkov is very instructive on how such a diff will now be optimized (for Git 2.x, Q3 2014)

D(A,P2) is huge, because, if merge-base of A and P2 is several dozens of merges (from A, via first parent) below, that D(A,P2) will be diffing sum of merges from several subsystems to 1 subsystem.

The solution is to avoid computing n 1-parent diffs, and to find changed-to-all-parents paths via scanning A's and all Pi's trees simultaneously, at each step comparing their entries, and based on that comparison, populate paths result, and deduce we could skip recursing into subdirectories, if at least for 1 parent, sha1 of that dir tree is the same as in A.
That would save us from doing significant amount of needless work.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • What's a situation where N > 3? – Steven Lu Jun 24 '14 at 20:51
  • @StevenLu the commit I linked described what happens when N is greater than 3, and how you need to combined (faster) those diff into one unified result. – VonC Jun 25 '14 at 05:32
  • I think you misunderstood my comment, I said what's **a** situation, as in what kind of situation would be one in which I would encounter an N > 3 diff? I cannot conceive of one. A mega-merge with multiple parents? Is that something that's even possible? – Steven Lu Jun 26 '14 at 21:05
  • Yes, octopus merges are a feature Git supports. I've never seen one in real life, personally; but an inordinate amount of effort in Git's development seems to go into supporting them. >,> – ELLIOTTCABLE Dec 20 '15 at 16:02