Skip to content

Commit aac006a

Browse files
committed
Merge branch 'so/log-diff-merge'
"git log" learned a new "--diff-merges=<how>" option. * so/log-diff-merge: (32 commits) t4013: add tests for --diff-merges=first-parent doc/git-show: include --diff-merges description doc/rev-list-options: document --first-parent changes merges format doc/diff-generate-patch: mention new --diff-merges option doc/git-log: describe new --diff-merges options diff-merges: add '--diff-merges=1' as synonym for 'first-parent' diff-merges: add old mnemonic counterparts to --diff-merges diff-merges: let new options enable diff without -p diff-merges: do not imply -p for new options diff-merges: implement new values for --diff-merges diff-merges: make -m/-c/--cc explicitly mutually exclusive diff-merges: refactor opt settings into separate functions diff-merges: get rid of now empty diff_merges_init_revs() diff-merges: group diff-merge flags next to each other inside 'rev_info' diff-merges: split 'ignore_merges' field diff-merges: fix -m to properly override -c/--cc t4013: add tests for -m failing to override -c/--cc t4013: support test_expect_failure through ':failure' magic diff-merges: revise revs->diff flag handling diff-merges: handle imply -p on -c/--cc logic for log.c ...
2 parents 30b29f0 + af04d8f commit aac006a

21 files changed

+893
-116
lines changed

Documentation/diff-generate-patch.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ Combined diff format
8181
Any diff-generating command can take the `-c` or `--cc` option to
8282
produce a 'combined diff' when showing a merge. This is the default
8383
format when showing merges with linkgit:git-diff[1] or
84-
linkgit:git-show[1]. Note also that you can give the `-m` option to any
85-
of these commands to force generation of diffs with individual parents
86-
of a merge.
84+
linkgit:git-show[1]. Note also that you can give suitable
85+
`--diff-merges` option to any of these commands to force generation of
86+
diffs in specific format.
8787

8888
A "combined diff" format looks like this:
8989

Documentation/diff-options.txt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,57 @@ endif::git-diff[]
3333
show the patch by default, or to cancel the effect of `--patch`.
3434
endif::git-format-patch[]
3535

36+
ifdef::git-log[]
37+
--diff-merges=(off|none|first-parent|1|separate|m|combined|c|dense-combined|cc)::
38+
--no-diff-merges::
39+
Specify diff format to be used for merge commits. Default is
40+
{diff-merges-default} unless `--first-parent` is in use, in which case
41+
`first-parent` is the default.
42+
+
43+
--diff-merges=(off|none):::
44+
--no-diff-merges:::
45+
Disable output of diffs for merge commits. Useful to override
46+
implied value.
47+
+
48+
--diff-merges=first-parent:::
49+
--diff-merges=1:::
50+
This option makes merge commits show the full diff with
51+
respect to the first parent only.
52+
+
53+
--diff-merges=separate:::
54+
--diff-merges=m:::
55+
-m:::
56+
This makes merge commits show the full diff with respect to
57+
each of the parents. Separate log entry and diff is generated
58+
for each parent. `-m` doesn't produce any output without `-p`.
59+
+
60+
--diff-merges=combined:::
61+
--diff-merges=c:::
62+
-c:::
63+
With this option, diff output for a merge commit shows the
64+
differences from each of the parents to the merge result
65+
simultaneously instead of showing pairwise diff between a
66+
parent and the result one at a time. Furthermore, it lists
67+
only files which were modified from all parents. `-c` implies
68+
`-p`.
69+
+
70+
--diff-merges=dense-combined:::
71+
--diff-merges=cc:::
72+
--cc:::
73+
With this option the output produced by
74+
`--diff-merges=combined` is further compressed by omitting
75+
uninteresting hunks whose contents in the parents have only
76+
two variants and the merge result picks one of them without
77+
modification. `--cc` implies `-p`.
78+
79+
--combined-all-paths::
80+
This flag causes combined diffs (used for merge commits) to
81+
list the name of the file from all parents. It thus only has
82+
effect when `--diff-merges=[dense-]combined` is in use, and
83+
is likely only useful if filename changes are detected (i.e.
84+
when either rename or copy detection have been requested).
85+
endif::git-log[]
86+
3687
-U<n>::
3788
--unified=<n>::
3889
Generate diffs with <n> lines of context instead of

Documentation/git-log.txt

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -107,47 +107,15 @@ DIFF FORMATTING
107107
By default, `git log` does not generate any diff output. The options
108108
below can be used to show the changes made by each commit.
109109

110-
Note that unless one of `-c`, `--cc`, or `-m` is given, merge commits
111-
will never show a diff, even if a diff format like `--patch` is
112-
selected, nor will they match search options like `-S`. The exception is
113-
when `--first-parent` is in use, in which merges are treated like normal
114-
single-parent commits (this can be overridden by providing a
115-
combined-diff option or with `--no-diff-merges`).
116-
117-
-c::
118-
With this option, diff output for a merge commit
119-
shows the differences from each of the parents to the merge result
120-
simultaneously instead of showing pairwise diff between a parent
121-
and the result one at a time. Furthermore, it lists only files
122-
which were modified from all parents.
123-
124-
--cc::
125-
This flag implies the `-c` option and further compresses the
126-
patch output by omitting uninteresting hunks whose contents in
127-
the parents have only two variants and the merge result picks
128-
one of them without modification.
129-
130-
--combined-all-paths::
131-
This flag causes combined diffs (used for merge commits) to
132-
list the name of the file from all parents. It thus only has
133-
effect when -c or --cc are specified, and is likely only
134-
useful if filename changes are detected (i.e. when either
135-
rename or copy detection have been requested).
136-
137-
-m::
138-
This flag makes the merge commits show the full diff like
139-
regular commits; for each merge parent, a separate log entry
140-
and diff is generated. An exception is that only diff against
141-
the first parent is shown when `--first-parent` option is given;
142-
in that case, the output represents the changes the merge
143-
brought _into_ the then-current branch.
144-
145-
--diff-merges=off::
146-
--no-diff-merges::
147-
Disable output of diffs for merge commits (default). Useful to
148-
override `-m`, `-c`, or `--cc`.
110+
Note that unless one of `--diff-merges` variants (including short
111+
`-m`, `-c`, and `--cc` options) is explicitly given, merge commits
112+
will not show a diff, even if a diff format like `--patch` is
113+
selected, nor will they match search options like `-S`. The exception
114+
is when `--first-parent` is in use, in which case `first-parent` is
115+
the default format.
149116

150117
:git-log: 1
118+
:diff-merges-default: `off`
151119
include::diff-options.txt[]
152120

153121
include::diff-generate-patch.txt[]

Documentation/git-show.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,13 @@ include::pretty-options.txt[]
4545
include::pretty-formats.txt[]
4646

4747

48-
COMMON DIFF OPTIONS
49-
-------------------
48+
DIFF FORMATTING
49+
---------------
50+
The options below can be used to change the way `git show` generates
51+
diff output.
5052

5153
:git-log: 1
54+
:diff-merges-default: `dense-combined`
5255
include::diff-options.txt[]
5356

5457
include::diff-generate-patch.txt[]

Documentation/rev-list-options.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit).
130130
this option allows you to ignore the individual commits
131131
brought in to your history by such a merge.
132132

133+
ifdef::git-log[]
134+
This option also changes default diff format for merge commits
135+
to `first-parent`, see `--diff-merges=first-parent` for details.
136+
endif::git-log[]
137+
133138
--not::
134139
Reverses the meaning of the '{caret}' prefix (or lack thereof)
135140
for all following revision specifiers, up to the next `--not`.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@ LIB_OBJS += date.o
860860
LIB_OBJS += decorate.o
861861
LIB_OBJS += delta-islands.o
862862
LIB_OBJS += diff-delta.o
863+
LIB_OBJS += diff-merges.o
863864
LIB_OBJS += diff-lib.o
864865
LIB_OBJS += diff-no-index.o
865866
LIB_OBJS += diff.o

builtin/diff-files.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "cache.h"
88
#include "config.h"
99
#include "diff.h"
10+
#include "diff-merges.h"
1011
#include "commit.h"
1112
#include "revision.h"
1213
#include "builtin.h"
@@ -69,9 +70,9 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
6970
* was not asked to. "diff-files -c -p" should not densify
7071
* (the user should ask with "diff-files --cc" explicitly).
7172
*/
72-
if (rev.max_count == -1 && !rev.combine_merges &&
73+
if (rev.max_count == -1 &&
7374
(rev.diffopt.output_format & DIFF_FORMAT_PATCH))
74-
rev.combine_merges = rev.dense_combined_merges = 1;
75+
diff_merges_set_dense_combined_if_unset(&rev);
7576

7677
if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
7778
perror("read_cache_preload");

builtin/diff.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "blob.h"
1414
#include "tag.h"
1515
#include "diff.h"
16+
#include "diff-merges.h"
1617
#include "diffcore.h"
1718
#include "revision.h"
1819
#include "log-tree.h"
@@ -216,8 +217,8 @@ static int builtin_diff_combined(struct rev_info *revs,
216217
if (argc > 1)
217218
usage(builtin_diff_usage);
218219

219-
if (!revs->dense_combined_merges && !revs->combine_merges)
220-
revs->dense_combined_merges = revs->combine_merges = 1;
220+
diff_merges_set_dense_combined_if_unset(revs);
221+
221222
for (i = 1; i < ents; i++)
222223
oid_array_append(&parents, &ent[i].item->oid);
223224
diff_tree_combined(&ent[0].item->oid, &parents, revs);
@@ -265,9 +266,9 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
265266
* dense one, --cc can be explicitly asked for, or just rely
266267
* on the default).
267268
*/
268-
if (revs->max_count == -1 && !revs->combine_merges &&
269+
if (revs->max_count == -1 &&
269270
(revs->diffopt.output_format & DIFF_FORMAT_PATCH))
270-
revs->combine_merges = revs->dense_combined_merges = 1;
271+
diff_merges_set_dense_combined_if_unset(revs);
271272

272273
setup_work_tree();
273274
if (read_cache_preload(&revs->diffopt.pathspec) < 0) {

builtin/log.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "color.h"
1313
#include "commit.h"
1414
#include "diff.h"
15+
#include "diff-merges.h"
1516
#include "revision.h"
1617
#include "log-tree.h"
1718
#include "builtin.h"
@@ -607,15 +608,10 @@ static int show_tree_object(const struct object_id *oid,
607608
static void show_setup_revisions_tweak(struct rev_info *rev,
608609
struct setup_revision_opt *opt)
609610
{
610-
if (rev->ignore_merges < 0) {
611-
/* There was no "-m" variant on the command line */
612-
rev->ignore_merges = 0;
613-
if (!rev->first_parent_only && !rev->combine_merges) {
614-
/* No "--first-parent", "-c", or "--cc" */
615-
rev->combine_merges = 1;
616-
rev->dense_combined_merges = 1;
617-
}
618-
}
611+
if (rev->first_parent_only)
612+
diff_merges_default_to_first_parent(rev);
613+
else
614+
diff_merges_default_to_dense_combined(rev);
619615
if (!rev->diffopt.output_format)
620616
rev->diffopt.output_format = DIFF_FORMAT_PATCH;
621617
}
@@ -736,12 +732,8 @@ static void log_setup_revisions_tweak(struct rev_info *rev,
736732
rev->prune_data.nr == 1)
737733
rev->diffopt.flags.follow_renames = 1;
738734

739-
/* Turn --cc/-c into -p --cc/-c when -p was not given */
740-
if (!rev->diffopt.output_format && rev->combine_merges)
741-
rev->diffopt.output_format = DIFF_FORMAT_PATCH;
742-
743-
if (rev->first_parent_only && rev->ignore_merges < 0)
744-
rev->ignore_merges = 0;
735+
if (rev->first_parent_only)
736+
diff_merges_default_to_first_parent(rev);
745737
}
746738

747739
int cmd_log(int argc, const char **argv, const char *prefix)

builtin/merge.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "lockfile.h"
1515
#include "run-command.h"
1616
#include "diff.h"
17+
#include "diff-merges.h"
1718
#include "refs.h"
1819
#include "refspec.h"
1920
#include "commit.h"
@@ -409,7 +410,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead
409410
printf(_("Squash commit -- not updating HEAD\n"));
410411

411412
repo_init_revisions(the_repository, &rev, NULL);
412-
rev.ignore_merges = 1;
413+
diff_merges_suppress(&rev);
413414
rev.commit_format = CMIT_FMT_MEDIUM;
414415

415416
commit->object.flags |= UNINTERESTING;

0 commit comments

Comments
 (0)