git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Combined diff format documentation

From
Jakub Narebski <jnareb@gmail.com>
Date
Oct 25, 2006, 22:22 UTC
Message-ID
<ehoo2k$1g6$1@sea.gmane.org>

In Documentation/diff-format.txt we can find the following information about combined diff format:

 combined diff format
 --------------------
 
 git-diff-tree and git-diff-files can take '-c' or '--cc' option
 to produce 'combined diff', which looks like this: 
 ------------
 diff --combined describe.c
 @@@ +98,7 @@@
    return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
   }
 
 - static void describe(char *arg)
  -static void describe(struct commit *cmit, int last_one)
 ++static void describe(char *arg, int last_one)
   {
  +     unsigned char sha1[20];
  +     struct commit *cmit;
 ------------

And it further goes how to read combined diff format, and how --cc (condensed combined) differs from --combined.

There is no note about which of extended headers functions with combined diff format, how they change, how chunk header changes.

From what I gathered, there are the following differences as compared to ordinary (diff --git) git extended headers:

1. "git diff" header which looked like this
      diff --git a/file1 b/file2
    is now
      diff --combined file2
    (where instead of --combined we might have --cc). Not described in
    documentation.
2. the "index" extended header line changes from
     index <hash>..<hash> <mode>
   to
   
     index <hash>,<hash>..<hash>
   Mode information is put in separate line, only if mode changes, for
   example
     mode <mode>,<mode>..<mode>
   <mode> can be 000000 if file didn't exist in particular parent; if file
   was cerated by merge we have
     new file mode <mode>
   I haven't checked what happens if file is deleted, either by branch or by
   merge commit itself. Not described in documentation, I'm not sure about
   how this (wrt modes) works.
3. The "rename/copy" headers seems to be never present; see below.
4. From file/to file header _seems_ to function exactly like in ordinary
   diff format, namely
     --- a/file1
     +++ b/file2
   But it seems to function rather like in ordinary "git diff" header,
   i.e. we have a/file1 instead of /dev/null even for files created by
   merge. I have not checked if and how rename detection work here.
5. Hunk header is also modified: in ordinary diff we have
     @@ <from range> <to range> @@
   where <from range> is -<start line>,<number of lines>, and <to range>
   is +<start line>,<number of lines>. In combined diff format it changes
   similarly to "index" extended header, namely
     @@@ <from range> <from range> <to range> @@@
   It might be not obvoious that we have (number of parents + 1) '@'
   characters in chunk header for combined dif format.
   BTW. it is not mentioned in documentation that git diff uses hunk section
   indicator, and what regexp/expression it uses (and is it configurable).
   Not described in documentation.
6. Documentation/diff-format.txt explains combined and condensed combined
   format quite well, although it doesn't tell us if we can have plusses and
   minuses together in one line...
=====================================================================

Combined diff format an renames detection -----------------------------------------

We have the following situation: $ git ls-tree -r --abbrev HEAD 100644 blob 1ce3f81 greetings/goodbye.txt 100644 blob 980a0d5 greetings/hello.txt $ git ls-tree -r --abbrev HEAD^1 100644 blob 980a0d5 greetings/hello.txt $ git ls-tree -r --abbrev HEAD^2 100644 blob 1ce3f81 data/goodbye.txt 100644 blob 980a0d5 data/hello.txt

Below there are following diffs: with first parent, merge (with all parents) with renames detection, combined, combined with rename detection. Is it all expected?

$ git diff-tree -p HEAD^1 HEAD
diff --git a/greetings/goodbye.txt b/greetings/goodbye.txt
new file mode 100644
index 0000000..1ce3f81
--- /dev/null
+++ b/greetings/goodbye.txt
@@ -0,0 +1 @@
+Goodbye World!

$ git diff-tree -p -M -m HEAD
d0fdd886e3b768678832c8d826bb8b70f2ef7b8e
diff --git a/greetings/goodbye.txt b/greetings/goodbye.txt
new file mode 100644
index 0000000..1ce3f81
--- /dev/null
+++ b/greetings/goodbye.txt
@@ -0,0 +1 @@
+Goodbye World!
d0fdd886e3b768678832c8d826bb8b70f2ef7b8e
diff --git a/data/goodbye.txt b/greetings/goodbye.txt
similarity index 100%
rename from data/goodbye.txt
rename to greetings/goodbye.txt
diff --git a/data/hello.txt b/greetings/hello.txt
similarity index 100%
rename from data/hello.txt
rename to greetings/hello.txt

$ git diff-tree -p -c HEAD
d0fdd886e3b768678832c8d826bb8b70f2ef7b8e
diff --combined greetings/goodbye.txt
index 0000000,0000000..1ce3f81
new file mode 100644
--- a/greetings/goodbye.txt
+++ b/greetings/goodbye.txt
@@@ -1,0 -1,0 +1,1 @@@
++Goodbye World!

$ git diff-tree -p -c -M HEAD
d0fdd886e3b768678832c8d826bb8b70f2ef7b8e
diff --combined greetings/goodbye.txt
index 0000000,1ce3f81..1ce3f81
mode 000000,100644..100644
--- a/greetings/goodbye.txt
+++ b/greetings/goodbye.txt
@@@ -1,0 -1,1 +1,1 @@@
+ Goodbye World!

And to compare, latest with --cc (condensed combined) instead of -c:
$ git diff-tree -p --cc -M HEAD
d0fdd886e3b768678832c8d826bb8b70f2ef7b8e
diff --cc greetings/goodbye.txt
index 0000000,1ce3f81..1ce3f81
mode 000000,100644..100644
--- a/greetings/goodbye.txt
+++ b/greetings/goodbye.txt
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Next: Junio C Hamano
Message 1 of 10 in “Combined diff format documentation”
  1. Jakub NarebskiOct 25, 2006
  2. Junio C HamanoOct 25, 2006
  3. Jakub NarebskiOct 25, 2006
  4. Junio C HamanoOct 25, 2006
  5. Junio C HamanoOct 25, 2006
  6. Jakub NarebskiOct 25, 2006
  7. diff-format.txt: Combined diff format documentation supplementJakub Narebski, Oct 26, 2006
  8. Junio C HamanoOct 26, 2006
  9. Junio C HamanoOct 26, 2006
  10. Junio C HamanoOct 26, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.