Skip to content

Commit 59bb0aa

Browse files
committed
Merge branch 'so/log-diff-merge'
"git log" learned "--diff-merges=<style>" option, with an associated configuration variable log.diffMerges. * so/log-diff-merge: doc/diff-options: document new --diff-merges features diff-merges: introduce log.diffMerges config variable diff-merges: adapt -m to enable default diff format diff-merges: refactor set_diff_merges() diff-merges: introduce --diff-merges=on
2 parents 8e97852 + 364bc11 commit 59bb0aa

File tree

7 files changed

+95
-21
lines changed

7 files changed

+95
-21
lines changed

Documentation/config/log.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ log.excludeDecoration::
2424
the config option can be overridden by the `--decorate-refs`
2525
option.
2626

27+
log.diffMerges::
28+
Set default diff format to be used for merge commits. See
29+
`--diff-merges` in linkgit:git-log[1] for details.
30+
Defaults to `separate`.
31+
2732
log.follow::
2833
If `true`, `git log` will act as if the `--follow` option was used when
2934
a single <path> is given. This has the same limitations as `--follow`,

Documentation/diff-options.txt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ endif::git-diff[]
3434
endif::git-format-patch[]
3535

3636
ifdef::git-log[]
37-
--diff-merges=(off|none|first-parent|1|separate|m|combined|c|dense-combined|cc)::
37+
--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc)::
3838
--no-diff-merges::
3939
Specify diff format to be used for merge commits. Default is
4040
{diff-merges-default} unless `--first-parent` is in use, in which case
@@ -45,17 +45,24 @@ ifdef::git-log[]
4545
Disable output of diffs for merge commits. Useful to override
4646
implied value.
4747
+
48+
--diff-merges=on:::
49+
--diff-merges=m:::
50+
-m:::
51+
This option makes diff output for merge commits to be shown in
52+
the default format. `-m` will produce the output only if `-p`
53+
is given as well. The default format could be changed using
54+
`log.diffMerges` configuration parameter, which default value
55+
is `separate`.
56+
+
4857
--diff-merges=first-parent:::
4958
--diff-merges=1:::
5059
This option makes merge commits show the full diff with
5160
respect to the first parent only.
5261
+
5362
--diff-merges=separate:::
54-
--diff-merges=m:::
55-
-m:::
5663
This makes merge commits show the full diff with respect to
5764
each of the parents. Separate log entry and diff is generated
58-
for each parent. `-m` doesn't produce any output without `-p`.
65+
for each parent.
5966
+
6067
--diff-merges=combined:::
6168
--diff-merges=c:::

builtin/log.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@ static int git_log_config(const char *var, const char *value, void *cb)
481481
decoration_style = 0; /* maybe warn? */
482482
return 0;
483483
}
484+
if (!strcmp(var, "log.diffmerges"))
485+
return diff_merges_config(value);
484486
if (!strcmp(var, "log.showroot")) {
485487
default_show_root = git_config_bool(var, value);
486488
return 0;

diff-merges.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
#include "revision.h"
44

5+
typedef void (*diff_merges_setup_func_t)(struct rev_info *);
6+
static void set_separate(struct rev_info *revs);
7+
8+
static diff_merges_setup_func_t set_to_default = set_separate;
9+
510
static void suppress(struct rev_info *revs)
611
{
712
revs->separate_merges = 0;
@@ -29,10 +34,10 @@ static void set_m(struct rev_info *revs)
2934
{
3035
/*
3136
* To "diff-index", "-m" means "match missing", and to the "log"
32-
* family of commands, it means "show full diff for merges". Set
37+
* family of commands, it means "show default diff for merges". Set
3338
* both fields appropriately.
3439
*/
35-
set_separate(revs);
40+
set_to_default(revs);
3641
revs->match_missing = 1;
3742
}
3843

@@ -50,33 +55,52 @@ static void set_dense_combined(struct rev_info *revs)
5055
revs->dense_combined_merges = 1;
5156
}
5257

53-
static void set_diff_merges(struct rev_info *revs, const char *optarg)
58+
static diff_merges_setup_func_t func_by_opt(const char *optarg)
5459
{
55-
if (!strcmp(optarg, "off") || !strcmp(optarg, "none")) {
56-
suppress(revs);
57-
/* Return early to leave revs->merges_need_diff unset */
58-
return;
59-
}
60-
60+
if (!strcmp(optarg, "off") || !strcmp(optarg, "none"))
61+
return suppress;
6162
if (!strcmp(optarg, "1") || !strcmp(optarg, "first-parent"))
62-
set_first_parent(revs);
63-
else if (!strcmp(optarg, "m") || !strcmp(optarg, "separate"))
64-
set_separate(revs);
63+
return set_first_parent;
64+
else if (!strcmp(optarg, "separate"))
65+
return set_separate;
6566
else if (!strcmp(optarg, "c") || !strcmp(optarg, "combined"))
66-
set_combined(revs);
67+
return set_combined;
6768
else if (!strcmp(optarg, "cc") || !strcmp(optarg, "dense-combined"))
68-
set_dense_combined(revs);
69-
else
69+
return set_dense_combined;
70+
else if (!strcmp(optarg, "m") || !strcmp(optarg, "on"))
71+
return set_to_default;
72+
return NULL;
73+
}
74+
75+
static void set_diff_merges(struct rev_info *revs, const char *optarg)
76+
{
77+
diff_merges_setup_func_t func = func_by_opt(optarg);
78+
79+
if (!func)
7080
die(_("unknown value for --diff-merges: %s"), optarg);
7181

72-
/* The flag is cleared by set_xxx() functions, so don't move this up */
73-
revs->merges_need_diff = 1;
82+
func(revs);
83+
84+
/* NOTE: the merges_need_diff flag is cleared by func() call */
85+
if (func != suppress)
86+
revs->merges_need_diff = 1;
7487
}
7588

7689
/*
7790
* Public functions. They are in the order they are called.
7891
*/
7992

93+
int diff_merges_config(const char *value)
94+
{
95+
diff_merges_setup_func_t func = func_by_opt(value);
96+
97+
if (!func)
98+
return -1;
99+
100+
set_to_default = func;
101+
return 0;
102+
}
103+
80104
int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
81105
{
82106
int argcount = 1;

diff-merges.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
struct rev_info;
1111

12+
int diff_merges_config(const char *value);
13+
1214
int diff_merges_parse_opts(struct rev_info *revs, const char **argv);
1315

1416
void diff_merges_suppress(struct rev_info *revs);

t/t4013-diff-various.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,37 @@ diff-tree --stat --compact-summary initial mode
452452
diff-tree -R --stat --compact-summary initial mode
453453
EOF
454454

455+
test_expect_success 'log --diff-merges=on matches --diff-merges=separate' '
456+
git log -p --diff-merges=separate master >result &&
457+
process_diffs result >expected &&
458+
git log -p --diff-merges=on master >result &&
459+
process_diffs result >actual &&
460+
test_cmp expected actual
461+
'
462+
463+
test_expect_success 'deny wrong log.diffMerges config' '
464+
test_config log.diffMerges wrong-value &&
465+
test_expect_code 128 git log
466+
'
467+
468+
test_expect_success 'git config log.diffMerges first-parent' '
469+
git log -p --diff-merges=first-parent master >result &&
470+
process_diffs result >expected &&
471+
test_config log.diffMerges first-parent &&
472+
git log -p --diff-merges=on master >result &&
473+
process_diffs result >actual &&
474+
test_cmp expected actual
475+
'
476+
477+
test_expect_success 'git config log.diffMerges first-parent vs -m' '
478+
git log -p --diff-merges=first-parent master >result &&
479+
process_diffs result >expected &&
480+
test_config log.diffMerges first-parent &&
481+
git log -p -m master >result &&
482+
process_diffs result >actual &&
483+
test_cmp expected actual
484+
'
485+
455486
test_expect_success 'log -S requires an argument' '
456487
test_must_fail git log -S
457488
'

t/t9902-completion.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,6 +2306,7 @@ test_expect_success 'git config - variable name' '
23062306
test_completion "git config log.d" <<-\EOF
23072307
log.date Z
23082308
log.decorate Z
2309+
log.diffMerges Z
23092310
EOF
23102311
'
23112312

@@ -2327,6 +2328,7 @@ test_expect_success 'git -c - variable name' '
23272328
test_completion "git -c log.d" <<-\EOF
23282329
log.date=Z
23292330
log.decorate=Z
2331+
log.diffMerges=Z
23302332
EOF
23312333
'
23322334

@@ -2348,6 +2350,7 @@ test_expect_success 'git clone --config= - variable name' '
23482350
test_completion "git clone --config=log.d" <<-\EOF
23492351
log.date=Z
23502352
log.decorate=Z
2353+
log.diffMerges=Z
23512354
EOF
23522355
'
23532356

0 commit comments

Comments
 (0)