Skip to content

range-diff: add --matched-only to skip one-sided commits - #2401

Open
HaraldNordgren wants to merge 1 commit into
git:masterfrom
HaraldNordgren:range-diff-matched-only
Open

range-diff: add --matched-only to skip one-sided commits#2401
HaraldNordgren wants to merge 1 commit into
git:masterfrom
HaraldNordgren:range-diff-matched-only

Conversation

@HaraldNordgren

@HaraldNordgren HaraldNordgren commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Add git range-diff --matched-only to only show commits that correspond between the two ranges, skipping ones that were only added or only removed.

Changes in v2:

  • Update docs and commit message.
  • Use die_for_incompatible_opt3.

@gitgitgadget-git

Copy link
Copy Markdown

There is an issue in commit 223eea0:
range-diff: add --matched-only to skip one-sided commits

  • Commit not signed off

@HaraldNordgren
HaraldNordgren force-pushed the range-diff-matched-only branch 5 times, most recently from aaf8cca to edb4471 Compare September 11, 2026 14:55
@HaraldNordgren

Copy link
Copy Markdown
Contributor Author

/submit

@gitgitgadget-git

Copy link
Copy Markdown

Submitted as pull.2401.git.git.1789144877632.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2401/HaraldNordgren/range-diff-matched-only-v1

To fetch this version to local tag pr-git-2401/HaraldNordgren/range-diff-matched-only-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2401/HaraldNordgren/range-diff-matched-only-v1

@HaraldNordgren
HaraldNordgren force-pushed the range-diff-matched-only branch 2 times, most recently from 38e9de9 to 22e5bee Compare September 11, 2026 19:01
@gitgitgadget-git

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes:

> diff --git a/Documentation/git-range-diff.adoc b/Documentation/git-range-diff.adoc
> index 5cc5e2ed56..58e59e8e3b 100644
> --- a/Documentation/git-range-diff.adoc
> +++ b/Documentation/git-range-diff.adoc
> @@ -10,7 +10,8 @@ SYNOPSIS
>  [synopsis]
>  git range-diff [--color=[<when>]] [--no-color] [<diff-options>]
>  	[--no-dual-color] [--creation-factor=<factor>]
> -	[--left-only | --right-only] [--diff-merges=<format>]
> +	[--left-only | --right-only | --matched-only]
> +	[--diff-merges=<format>]
>  	[--remerge-diff] [--no-notes | --notes[=<ref>]]
>  	( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> )
>  	[[--] <path>...]
> @@ -82,6 +83,13 @@ to revert to color all lines according to the outer diff markers
>  	Suppress commits that are missing from the second specified range
>  	(or the "right range" when using the `<rev1>...<rev2>` form).
>  
> +`--matched-only`::
> +	Only emit commits that have a corresponding commit in the other
> +	range, suppressing any commit that exists on only one side. This is
> +	the same as using `--left-only` and `--right-only` together. Useful
> +	to skip added or removed commits when reviewing how the commits
> +	that survived a rebase changed.

While conceptually it is the same as giving "--hide-right-only"
(which would have hidden the right-only entry) and
"--hide-left-only" at the same time, because the existing two
options are not defined in terms of "hiding" entries that have only
one side (which would have logically allowed combining) but instead
showing "only" one side (which makes it impossible to give them
together, and indeed that is the first thing
range-diff.c:show_range_diff() checks and yields an error), this
description is not accurate.

I wonder if the implementation actually can be more like

 - give "--hide-left-only" and "--hide-right-only" as synonyms to
   "--right-only" and "--left-only", and deprecate the original;

 - allow them to be given together, which will give the new
   behaviour you are introducing, i.e., skip steps without both
   sides from the output;

 - give a short-hand synonym, "--matched-only", to truly behave the
   same as giving "--hide-{left,right}-only" together.

which would allow the above explanation to be more accurate?  I
dunno.

> +	if (range_diff_opts->left_only + range_diff_opts->right_only +
> +	    range_diff_opts->matched_only > 1)
> +		res = error(_("options '%s', '%s', or '%s' cannot be used together"),
> +			    "--left-only", "--right-only", "--matched-only");

Don't we have die_for_incompatible_opt3() to do this?

The basic idea sounds good.  The unmatched entries do serve as a
strong hint that a greater --creation-factor may help.  For example,

> +		git range-diff -s --abbrev=7 combined-old...combined-new >actual &&
> +		cat >expect <<-EOF &&
> +		1:  $old_only_oid < -:  ------- c-old-only
> +		-:  ------- > 1:  $new_only_oid c-new-only
> +		2:  $common_old_oid = 2:  $common_new_oid c-common
> +		EOF
> +		test_cmp expect actual &&

the above clearly shows that the command might compare c-old-only
and c-new-only with a better creation factor settings.

But because the entries are numbered, gaps in the numbers, like this
output

> +		git range-diff -s --abbrev=7 --matched-only combined-old...combined-new \
> +			>actual &&
> +		echo "2:  $common_old_oid = 2:  $common_new_oid c-common" >expect &&
> +		test_cmp expect actual

may be sufficient (we can tell that 1 was omitted), except that
somehow we at least need to be aware that there were only 2 commits
on both sides (it may be hiding commits 3 thru 99 as unmatching
pairs and we lose that hint from the new output), which is not a
huge downside.

Thanks.

@gitgitgadget-git

Copy link
Copy Markdown

Harald Nordgren wrote on the Git mailing list (how to reply to this email):

> I wonder if the implementation actually can be more like
>
>  - give "--hide-left-only" and "--hide-right-only" as synonyms to
>    "--right-only" and "--left-only", and deprecate the original;
>
>  - allow them to be given together, which will give the new
>    behaviour you are introducing, i.e., skip steps without both
>    sides from the output;
>
>  - give a short-hand synonym, "--matched-only", to truly behave the
>    same as giving "--hide-{left,right}-only" together.

Seems like a big change, and deprecated options are a pain in the neck
because we can never actually remove them.

If we decide to go this way, we might name them "--hide-{left,right}"
and just not introduce a condition that makes them incompatible. Then
"--matched-only" would be pure syntactic sugar and wouldn't even be
100% necessary to have to achieve this.


Harald

@gitgitgadget-git

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Harald Nordgren <haraldnordgren@gmail.com> writes:

>> I wonder if the implementation actually can be more like
>>
>>  - give "--hide-left-only" and "--hide-right-only" as synonyms to
>>    "--right-only" and "--left-only", and deprecate the original;
>>
>>  - allow them to be given together, which will give the new
>>    behaviour you are introducing, i.e., skip steps without both
>>    sides from the output;
>>
>>  - give a short-hand synonym, "--matched-only", to truly behave the
>>    same as giving "--hide-{left,right}-only" together.
>
> Seems like a big change, and deprecated options are a pain in the neck
> because we can never actually remove them.
>
> If we decide to go this way, we might name them "--hide-{left,right}"
> and just not introduce a condition that makes them incompatible. Then
> "--matched-only" would be pure syntactic sugar and wouldn't even be
> 100% necessary to have to achieve this.

Or we can just keep the code and fix the documentation.  I think
that would be much less impact.

@gitgitgadget-git

Copy link
Copy Markdown

Harald Nordgren wrote on the Git mailing list (how to reply to this email):

> > Seems like a big change, and deprecated options are a pain in the neck
> > because we can never actually remove them.
> >
> > If we decide to go this way, we might name them "--hide-{left,right}"
> > and just not introduce a condition that makes them incompatible. Then
> > "--matched-only" would be pure syntactic sugar and wouldn't even be
> > 100% necessary to have to achieve this.
>
> Or we can just keep the code and fix the documentation.  I think
> that would be much less impact.

I agree.


Harald

@gitgitgadget-git

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Harald Nordgren <haraldnordgren@gmail.com> writes:

>> > Seems like a big change, and deprecated options are a pain in the neck
>> > because we can never actually remove them.
>> >
>> > If we decide to go this way, we might name them "--hide-{left,right}"
>> > and just not introduce a condition that makes them incompatible. Then
>> > "--matched-only" would be pure syntactic sugar and wouldn't even be
>> > 100% necessary to have to achieve this.
>>
>> Or we can just keep the code and fix the documentation.  I think
>> that would be much less impact.
>
> I agree.
>
>
> Harald

I thought I'd try my own version, but it seems that we can simply
remove the misleading sentence and the remainder already is very
easy to read and understand ;-)

`--matched-only`::
	Only emit commits that have a corresponding commit in the other
	range, suppressing any commit that exists on only one side.  Useful
	to skip added or removed commits when reviewing how the commits
	that survived a rebase changed.

Reviewing a range-diff often means scrolling past commits that were
simply added or dropped, when only the ones that correspond between
the two ranges are of interest.

--left-only and --right-only already each suppress one of those
one-sided groups, but they are defined as "only show this side" and
so cannot be given together, which is exactly why show_range_diff()
already rejected that combination. Give the "show only the commits
that correspond on both sides" behavior its own name, --matched-only,
instead of asking users to reach for a combination that errors out.

Extend the existing '--left-only'/'--right-only' conflict check to
also reject any combination with --matched-only, since all three
narrow the output in ways that cannot be combined.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
@HaraldNordgren

Copy link
Copy Markdown
Contributor Author

/submit

@gitgitgadget-git

Copy link
Copy Markdown

Submitted as pull.2401.v2.git.git.1789160138305.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2401/HaraldNordgren/range-diff-matched-only-v2

To fetch this version to local tag pr-git-2401/HaraldNordgren/range-diff-matched-only-v2:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2401/HaraldNordgren/range-diff-matched-only-v2

@gitgitgadget-git

Copy link
Copy Markdown

This branch is now known as hn/range-diff-matched-only.

@gitgitgadget-git

Copy link
Copy Markdown

This patch series was integrated into seen via a6977c8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant