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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html