Merge branch 'so/diff-merges-dd'

"git log" and friends learned "--dd" that is a short-hand for
"--diff-merges=first-parent -p".

* so/diff-merges-dd:
  completion: complete '--dd'
  diff-merges: introduce '--dd' option
  diff-merges: improve --diff-merges documentation
This commit is contained in:
Junio C Hamano 2023-10-23 13:56:37 -07:00
commit 755fb09163
5 changed files with 73 additions and 49 deletions

View file

@ -37,66 +37,79 @@ endif::git-diff[]
endif::git-format-patch[]
ifdef::git-log[]
--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc|remerge|r)::
-m::
Show diffs for merge commits in the default format. This is
similar to '--diff-merges=on', except `-m` will
produce no output unless `-p` is given as well.
-c::
Produce combined diff output for merge commits.
Shortcut for '--diff-merges=combined -p'.
--cc::
Produce dense combined diff output for merge commits.
Shortcut for '--diff-merges=dense-combined -p'.
--dd::
Produce diff with respect to first parent for both merge and
regular commits.
Shortcut for '--diff-merges=first-parent -p'.
--remerge-diff::
Produce remerge-diff output for merge commits.
Shortcut for '--diff-merges=remerge -p'.
--no-diff-merges::
Synonym for '--diff-merges=off'.
--diff-merges=<format>::
Specify diff format to be used for merge commits. Default is
{diff-merges-default} unless `--first-parent` is in use, in which case
`first-parent` is the default.
{diff-merges-default} unless `--first-parent` is in use, in
which case `first-parent` is the default.
+
--diff-merges=(off|none):::
--no-diff-merges:::
The following formats are supported:
+
--
off, none::
Disable output of diffs for merge commits. Useful to override
implied value.
+
--diff-merges=on:::
--diff-merges=m:::
-m:::
This option makes diff output for merge commits to be shown in
the default format. `-m` will produce the output only if `-p`
is given as well. The default format could be changed using
`log.diffMerges` configuration parameter, which default value
on, m::
Make diff output for merge commits to be shown in the default
format. The default format could be changed using
`log.diffMerges` configuration variable, whose default value
is `separate`.
+
--diff-merges=first-parent:::
--diff-merges=1:::
This option makes merge commits show the full diff with
respect to the first parent only.
first-parent, 1::
Show full diff with respect to first parent. This is the same
format as `--patch` produces for non-merge commits.
+
--diff-merges=separate:::
This makes merge commits show the full diff with respect to
each of the parents. Separate log entry and diff is generated
for each parent.
separate::
Show full diff with respect to each of parents.
Separate log entry and diff is generated for each parent.
+
--diff-merges=remerge:::
--diff-merges=r:::
--remerge-diff:::
With this option, two-parent merge commits are remerged to
create a temporary tree object -- potentially containing files
with conflict markers and such. A diff is then shown between
that temporary tree and the actual merge commit.
combined, c::
Show differences from each of the parents to the merge
result simultaneously instead of showing pairwise diff between
a parent and the result one at a time. Furthermore, it lists
only files which were modified from all parents.
+
dense-combined, cc::
Further compress output produced by `--diff-merges=combined`
by omitting uninteresting hunks whose contents in the parents
have only two variants and the merge result picks one of them
without modification.
+
remerge, r::
Remerge two-parent merge commits to create a temporary tree
object--potentially containing files with conflict markers
and such. A diff is then shown between that temporary tree
and the actual merge commit.
+
The output emitted when this option is used is subject to change, and
so is its interaction with other options (unless explicitly
documented).
+
--diff-merges=combined:::
--diff-merges=c:::
-c:::
With this option, diff output for a merge commit shows the
differences from each of the parents to the merge result
simultaneously instead of showing pairwise diff between a
parent and the result one at a time. Furthermore, it lists
only files which were modified from all parents. `-c` implies
`-p`.
+
--diff-merges=dense-combined:::
--diff-merges=cc:::
--cc:::
With this option the output produced by
`--diff-merges=combined` is further compressed by omitting
uninteresting hunks whose contents in the parents have only
two variants and the merge result picks one of them without
modification. `--cc` implies `-p`.
--
--combined-all-paths::
This flag causes combined diffs (used for merge commits) to

View file

@ -120,11 +120,11 @@ By default, `git log` does not generate any diff output. The options
below can be used to show the changes made by each commit.
Note that unless one of `--diff-merges` variants (including short
`-m`, `-c`, and `--cc` options) is explicitly given, merge commits
`-m`, `-c`, `--cc`, and `--dd` options) is explicitly given, merge commits
will not show a diff, even if a diff format like `--patch` is
selected, nor will they match search options like `-S`. The exception
is when `--first-parent` is in use, in which case `first-parent` is
the default format.
the default format for merge commits.
:git-log: 1
:diff-merges-default: `off`

View file

@ -2053,7 +2053,7 @@ __git_log_shortlog_options="
"
# Options accepted by log and show
__git_log_show_options="
--diff-merges --diff-merges= --no-diff-merges --remerge-diff
--diff-merges --diff-merges= --no-diff-merges --dd --remerge-diff
"
__git_diff_merges_opts="off none on first-parent 1 separate m combined c dense-combined cc remerge r"

View file

@ -131,6 +131,9 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
} else if (!strcmp(arg, "--cc")) {
set_dense_combined(revs);
revs->merges_imply_patch = 1;
} else if (!strcmp(arg, "--dd")) {
set_first_parent(revs);
revs->merges_imply_patch = 1;
} else if (!strcmp(arg, "--remerge-diff")) {
set_remerge_diff(revs);
revs->merges_imply_patch = 1;

View file

@ -473,6 +473,14 @@ test_expect_success 'log --diff-merges=on matches --diff-merges=separate' '
test_cmp expected actual
'
test_expect_success 'log --dd matches --diff-merges=1 -p' '
git log --diff-merges=1 -p master >result &&
process_diffs result >expected &&
git log --dd master >result &&
process_diffs result >actual &&
test_cmp expected actual
'
test_expect_success 'deny wrong log.diffMerges config' '
test_config log.diffMerges wrong-value &&
test_expect_code 128 git log