diff mbox series

[6/6] diff-merges: let -m imply -p

Message ID 20210510153451.15090-7-sorganov@gmail.com (mailing list archive)
State Superseded
Headers show
Series diff-merges: let -m imply -p | expand

Commit Message

Sergey Organov May 10, 2021, 3:34 p.m. UTC
Fix long standing inconsistency between -c/--cc that do imply -p, on
one side, and -m that did not imply -p, on the other side.

After this patch

  git log -m

will start to produce diffs without need to provide -p as well, that
improves both consistency and usability. It gets even more useful if
one sets "log.diffMerges" configuration variable to "first-parent" to
force -m produce usual diff with respect to first parent only.

Previous semantics of -m could still be accessed using
--diff-merges=separate option.

Change documentation accordingly.

Signed-off-by: Sergey Organov <sorganov@gmail.com>
---
 Documentation/diff-options.txt | 8 ++++----
 diff-merges.c                  | 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)

Comments

Junio C Hamano May 11, 2021, 4:14 a.m. UTC | #1
Sergey Organov <sorganov@gmail.com> writes:

> Fix long standing inconsistency between -c/--cc that do imply -p, on
> one side, and -m that did not imply -p, on the other side.
>
> After this patch
>
>   git log -m
>
> will start to produce diffs without need to provide -p as well, that
> improves both consistency and usability. It gets even more useful if
> one sets "log.diffMerges" configuration variable to "first-parent" to
> force -m produce usual diff with respect to first parent only.

Please make sure that you clearly state that you do not blindly
force --patch output in the proposed log message.  Explicitly
mentioning that "git log --stat -m" would not give a patch but just
diffstat would be assuring.

Also this needs a test to ensure that is what happens.  Having a
test for "log -m" and another for "log -m --stat" would be
sufficient.

And in the context of this step, the rename of the member in the
previous step makes quite a lot of sense.

Thanks for working on this topic.
Junio C Hamano May 11, 2021, 4:56 a.m. UTC | #2
Junio C Hamano <gitster@pobox.com> writes:

> Sergey Organov <sorganov@gmail.com> writes:
>
>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>> one side, and -m that did not imply -p, on the other side.
>>
>> After this patch
>>
>>   git log -m
>>
>> will start to produce diffs without need to provide -p as well, that
>> improves both consistency and usability. It gets even more useful if
>> one sets "log.diffMerges" configuration variable to "first-parent" to
>> force -m produce usual diff with respect to first parent only.
>
> Please make sure that you clearly state that you do not blindly
> force --patch output in the proposed log message.  Explicitly
> mentioning that "git log --stat -m" would not give a patch but just
> diffstat would be assuring.

Also, avoid "-p" in the title.  "let -m imply diff generation" might
be a good compromise.

What --cc/-c implies is to show some kind of diff for merges
(dense_combined_merges, combine_merges and !ignore_merges are the
members of the revs field that controls how merge commits) and they
ask for specific kind of diff is shown.  So "-c/--cc imply -p" is
quite wrong (you never get straight --patch output for merges when
you give -c/--cc---you get combined diff).  In a sense, you could
say -c/--cc implies -m (i.e. do show some kind of diff for merges).

Taken together, perhaps:

    Subject: diff: let -m imply diff generation

    The "-c/--cc" options to "git log" asks for merges to be shown
    with patch-like output, implicitly enabling the "-m" option
    (which is used to tell "do not ignore merge commits when showing
    patches).  However, the opposite is not true; giving "-m" alone
    does not tell "git log" that the user wants some form of patches.
    
    Make "-m" imply "we want some form of diff output", so that "git
    log -m" would behave identically to "git log -m -p".  When the
    user explicitly asks for what kind of diff output is desired,
    e.g. "git log -m --stat", there is no need to imply anything,
    specifically, do NOT blindly turn on the "-p: option to turn it
    into "git log -m --stat -p:.

or something like that.

If we enable "some kind of diff" for "-m", I actually think that by
default "git log -m" should be turned into "log --cc".  As you told
Alex in your response, "log -m -p" is a quite unpleasant format to
read---it is there only because it was the only thing we had before
we invented "-c/--cc".

But that might be outside the scope of this series.  I dunno, but if
there is no other constraints (like backward compatibility issues),
I have a moderately strong preference to use "--cc" over "-m -p"
from the get go for unconfigured people, rather than forcing
everybody to configure

> Also this needs a test to ensure that is what happens.  Having a
> test for "log -m" and another for "log -m --stat" would be
> sufficient.
>
> And in the context of this step, the rename of the member in the
> previous step makes quite a lot of sense.
>
> Thanks for working on this topic.
Sergey Organov May 11, 2021, 2:03 p.m. UTC | #3
Junio C Hamano <gitster@pobox.com> writes:

> Junio C Hamano <gitster@pobox.com> writes:

[...]

> If we enable "some kind of diff" for "-m", I actually think that by
> default "git log -m" should be turned into "log --cc".  As you told
> Alex in your response, "log -m -p" is a quite unpleasant format to
> read---it is there only because it was the only thing we had before
> we invented "-c/--cc".

Please, no! --cc has unfortunate feature of outputting exactly nothing
for a lot of merge commits, causing even more confusion than historical
"-m -p" format.

The best default for -m output is --diff-merges=first-parent. Everybody
is familiar with it, and it's useful.

> But that might be outside the scope of this series.  I dunno, but if
> there is no other constraints (like backward compatibility issues),
> I have a moderately strong preference to use "--cc" over "-m -p"
> from the get go for unconfigured people, rather than forcing
> everybody to configure

I rather have strong preference for --diff-merges=first-parent. --cc is
only suitable for Git experts, and they know how to get what they want
anyway. Yep, by using --cc. Why spare yet another short option for that?

Overall, let's rather make -m give diff to the first parent by default.
Simple. Useful. Not confusing.

Thanks,
-- Sergey Organov
Sergey Organov May 11, 2021, 4:29 p.m. UTC | #4
Junio C Hamano <gitster@pobox.com> writes:

> Junio C Hamano <gitster@pobox.com> writes:
>
>> Sergey Organov <sorganov@gmail.com> writes:
>>
>>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>>> one side, and -m that did not imply -p, on the other side.
>>>
>>> After this patch
>>>
>>>   git log -m
>>>
>>> will start to produce diffs without need to provide -p as well, that
>>> improves both consistency and usability. It gets even more useful if
>>> one sets "log.diffMerges" configuration variable to "first-parent" to
>>> force -m produce usual diff with respect to first parent only.
>>
>> Please make sure that you clearly state that you do not blindly
>> force --patch output in the proposed log message.  Explicitly
>> mentioning that "git log --stat -m" would not give a patch but just
>> diffstat would be assuring.
>
> Also, avoid "-p" in the title.  "let -m imply diff generation" might
> be a good compromise.
>
> What --cc/-c implies is to show some kind of diff for merges
> (dense_combined_merges, combine_merges and !ignore_merges are the
> members of the revs field that controls how merge commits) and they
> ask for specific kind of diff is shown.  So "-c/--cc imply -p" is
> quite wrong (you never get straight --patch output for merges when
> you give -c/--cc---you get combined diff).  In a sense, you could
> say -c/--cc implies -m (i.e. do show some kind of diff for merges).
>
> Taken together, perhaps:
>
>     Subject: diff: let -m imply diff generation
>
>     The "-c/--cc" options to "git log" asks for merges to be shown
>     with patch-like output, implicitly enabling the "-m" option
>     (which is used to tell "do not ignore merge commits when showing
>     patches).  However, the opposite is not true; giving "-m" alone
>     does not tell "git log" that the user wants some form of patches.
>     
>     Make "-m" imply "we want some form of diff output", so that "git
>     log -m" would behave identically to "git log -m -p".  When the
>     user explicitly asks for what kind of diff output is desired,
>     e.g. "git log -m --stat", there is no need to imply anything,
>     specifically, do NOT blindly turn on the "-p: option to turn it
>     into "git log -m --stat -p:.
>
> or something like that.


Fine with me, will do, thanks!

-- Sergey Organov
Sergey Organov May 11, 2021, 4:30 p.m. UTC | #5
Junio C Hamano <gitster@pobox.com> writes:

> Sergey Organov <sorganov@gmail.com> writes:
>
>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>> one side, and -m that did not imply -p, on the other side.
>>
>> After this patch
>>
>>   git log -m
>>
>> will start to produce diffs without need to provide -p as well, that
>> improves both consistency and usability. It gets even more useful if
>> one sets "log.diffMerges" configuration variable to "first-parent" to
>> force -m produce usual diff with respect to first parent only.
>
> Please make sure that you clearly state that you do not blindly
> force --patch output in the proposed log message.  Explicitly
> mentioning that "git log --stat -m" would not give a patch but just
> diffstat would be assuring.
>
> Also this needs a test to ensure that is what happens.  Having a
> test for "log -m" and another for "log -m --stat" would be
> sufficient.

OK, will do, thanks!

-- Sergey Organov
Alex Henrie May 11, 2021, 5:13 p.m. UTC | #6
On Tue, May 11, 2021 at 8:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>
> Junio C Hamano <gitster@pobox.com> writes:
>
> > Junio C Hamano <gitster@pobox.com> writes:
>
> [...]
>
> > If we enable "some kind of diff" for "-m", I actually think that by
> > default "git log -m" should be turned into "log --cc".  As you told
> > Alex in your response, "log -m -p" is a quite unpleasant format to
> > read---it is there only because it was the only thing we had before
> > we invented "-c/--cc".
>
> Please, no! --cc has unfortunate feature of outputting exactly nothing
> for a lot of merge commits, causing even more confusion than historical
> "-m -p" format.
>
> The best default for -m output is --diff-merges=first-parent. Everybody
> is familiar with it, and it's useful.
>
> > But that might be outside the scope of this series.  I dunno, but if
> > there is no other constraints (like backward compatibility issues),
> > I have a moderately strong preference to use "--cc" over "-m -p"
> > from the get go for unconfigured people, rather than forcing
> > everybody to configure
>
> I rather have strong preference for --diff-merges=first-parent. --cc is
> only suitable for Git experts, and they know how to get what they want
> anyway. Yep, by using --cc. Why spare yet another short option for that?
>
> Overall, let's rather make -m give diff to the first parent by default.
> Simple. Useful. Not confusing.

Honestly --diff-merges=separate is fine. Two weeks ago, when I started
this discussion, I was trying to use `git log -m` and `git show -m` to
find which merge commit introduced a particular change. Extremely
verbose diff output would have been great for that, the confusing part
was just that `git show -m` produced diff output and `git log -m` did
not.

Maybe what we really want is a new short option like `git log -m1`
which would both enable diff output and set --diff-merges=1.

But again, I don't have a strong opinion on which particular diff
output is "the best", so I'm happy to leave that decision to the
experts.

-Alex
Elijah Newren May 11, 2021, 6:31 p.m. UTC | #7
On Tue, May 11, 2021 at 7:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>
> Junio C Hamano <gitster@pobox.com> writes:
>
> > Junio C Hamano <gitster@pobox.com> writes:
>
> [...]
>
> > If we enable "some kind of diff" for "-m", I actually think that by
> > default "git log -m" should be turned into "log --cc".  As you told
> > Alex in your response, "log -m -p" is a quite unpleasant format to
> > read---it is there only because it was the only thing we had before
> > we invented "-c/--cc".
>
> Please, no! --cc has unfortunate feature of outputting exactly nothing
> for a lot of merge commits, causing even more confusion than historical
> "-m -p" format.
>
> The best default for -m output is --diff-merges=first-parent. Everybody
> is familiar with it, and it's useful.
>
> > But that might be outside the scope of this series.  I dunno, but if
> > there is no other constraints (like backward compatibility issues),
> > I have a moderately strong preference to use "--cc" over "-m -p"
> > from the get go for unconfigured people, rather than forcing
> > everybody to configure
>
> I rather have strong preference for --diff-merges=first-parent. --cc is
> only suitable for Git experts, and they know how to get what they want
> anyway. Yep, by using --cc. Why spare yet another short option for that?

Interesting.  I have a strong preference for --diff-merges=remerge
(yeah, I know it's not upstream, but it's been ready to submit for
months, but just backed up behind the other ort changes.  Sorry, I
can't push those through any faster).  I've had others using it for
about 9 months now.

I think --cc is a lot better than -m for helping you find what users
changed when they did the merge, but I agree the format is somewhat
difficult for many users to understand.  (--diff-merges=remerge, or
--remerge-diff, fixes these problems, IMO.)  I think
--diff-merges=first-parent, while fine when explicitly requested on
the command line, would be wildly misleading as a default because it
would attribute changes to a merge commit that were made elsewhere.

> Overall, let's rather make -m give diff to the first parent by default.
> Simple. Useful. Not confusing.

I think it's confusing.
Sergey Organov May 11, 2021, 6:46 p.m. UTC | #8
Alex Henrie <alexhenrie24@gmail.com> writes:

> On Tue, May 11, 2021 at 8:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>>
>> Junio C Hamano <gitster@pobox.com> writes:
>>
>> > Junio C Hamano <gitster@pobox.com> writes:
>>
>> [...]
>>
>> > If we enable "some kind of diff" for "-m", I actually think that by
>> > default "git log -m" should be turned into "log --cc".  As you told
>> > Alex in your response, "log -m -p" is a quite unpleasant format to
>> > read---it is there only because it was the only thing we had before
>> > we invented "-c/--cc".
>>
>> Please, no! --cc has unfortunate feature of outputting exactly nothing
>> for a lot of merge commits, causing even more confusion than historical
>> "-m -p" format.
>>
>> The best default for -m output is --diff-merges=first-parent. Everybody
>> is familiar with it, and it's useful.
>>
>> > But that might be outside the scope of this series.  I dunno, but if
>> > there is no other constraints (like backward compatibility issues),
>> > I have a moderately strong preference to use "--cc" over "-m -p"
>> > from the get go for unconfigured people, rather than forcing
>> > everybody to configure
>>
>> I rather have strong preference for --diff-merges=first-parent. --cc is
>> only suitable for Git experts, and they know how to get what they want
>> anyway. Yep, by using --cc. Why spare yet another short option for that?
>>
>> Overall, let's rather make -m give diff to the first parent by default.
>> Simple. Useful. Not confusing.
>
> Honestly --diff-merges=separate is fine. Two weeks ago, when I started
> this discussion, I was trying to use `git log -m` and `git show -m` to
> find which merge commit introduced a particular change. Extremely
> verbose diff output would have been great for that, the confusing part
> was just that `git show -m` produced diff output and `git log -m` did
> not.

This is not a case in favor of "separate" over "first-parent" as the
default for "-m", right?

"Which merge commit introduced particular change" is exactly what
--diff-merges=1 achieves, so "--diff-merges=separate" was not in fact
needed, as I see it. Moreover, it could have produced wrong positives.
Looks like --diff-merges=1 is a better fit.

> Maybe what we really want is a new short option like `git log -m1`
> which would both enable diff output and set --diff-merges=1.

Hopefully this will be simply "-m" soon. "-m1" is no-go as optional
arguments to short options is a bad idea. It could have been "--m1", but
I believe that's not needed.

>
> But again, I don't have a strong opinion on which particular diff
> output is "the best", so I'm happy to leave that decision to the
> experts.

There is no "the best", and at least "first-parent" and "dense-combined"
are to survive, and "dense-combined" already has its "--cc" rather short
variant, so it's logical to give -m the other one, especially as it
already has this meaning when --first-parent is provided as well.

Also, I'm not sure if -c is being in use, and if it isn't, then it could
be changed to produce dense-combined format, especially as one still
have --diff-merges=condensed nowadays anyway, so that -m and -c will
finally give 2 most useful formats.

Overall, I still find a lot of sense in giving "-m" exactly first-parent
default meaning.

Thanks,
-- Sergey Organov

P.S. If generic options machinery were in use, it could have been
possible to say:

  git log -pm

reducing the issue to consistency only. I wonder if anybody have plans
to convert setup_revisions() to parse_options() utility?
Sergey Organov May 11, 2021, 7 p.m. UTC | #9
Elijah Newren <newren@gmail.com> writes:

> On Tue, May 11, 2021 at 7:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>>
>> Junio C Hamano <gitster@pobox.com> writes:
>>
>> > Junio C Hamano <gitster@pobox.com> writes:
>>
>> [...]
>>
>> > If we enable "some kind of diff" for "-m", I actually think that by
>> > default "git log -m" should be turned into "log --cc".  As you told
>> > Alex in your response, "log -m -p" is a quite unpleasant format to
>> > read---it is there only because it was the only thing we had before
>> > we invented "-c/--cc".
>>
>> Please, no! --cc has unfortunate feature of outputting exactly nothing
>> for a lot of merge commits, causing even more confusion than historical
>> "-m -p" format.
>>
>> The best default for -m output is --diff-merges=first-parent. Everybody
>> is familiar with it, and it's useful.
>>
>> > But that might be outside the scope of this series.  I dunno, but if
>> > there is no other constraints (like backward compatibility issues),
>> > I have a moderately strong preference to use "--cc" over "-m -p"
>> > from the get go for unconfigured people, rather than forcing
>> > everybody to configure
>>
>> I rather have strong preference for --diff-merges=first-parent. --cc is
>> only suitable for Git experts, and they know how to get what they want
>> anyway. Yep, by using --cc. Why spare yet another short option for that?
>
> Interesting.  I have a strong preference for --diff-merges=remerge
> (yeah, I know it's not upstream, but it's been ready to submit for
> months, but just backed up behind the other ort changes.  Sorry, I
> can't push those through any faster).  I've had others using it for
> about 9 months now.

Once somebody uses it for 9 months and starts to understand what it is
and really loves it, she can still set log.diffMerges=remerge (new
feature) and have fun.

>
> I think --cc is a lot better than -m for helping you find what users
> changed when they did the merge,

Yes, but it doesn't mean it should be the default.

In my workflows, the first thing that matters is what commit did what
changes on the current branch. I don't typically care what the user
changed during the merge operation, only about the result. If I do care,
then only after I find the merge commit is responsible, and I can then
use --cc if I want to.

> but I agree the format is somewhat difficult for many users to
> understand. (--diff-merges=remerge, or --remerge-diff, fixes these
> problems, IMO.) I think --diff-merges=first-parent, while fine when
> explicitly requested on the command line, would be wildly misleading
> as a default because it would attribute changes to a merge commit that
> were made elsewhere.

No, it's exactly this merge commit that made these changes to the
current branch. The changes you refer to have been made on another
branch, and not by this particular merge commit, and we fortunately have
the reference to those commits through the second parent of this one.

>
>> Overall, let's rather make -m give diff to the first parent by default.
>> Simple. Useful. Not confusing.
>
> I think it's confusing.

I think it isn't, once you accept that merge commit does introduce
changes to the branch, by itself.

Thanks,
-- Sergey Organov
Alex Henrie May 11, 2021, 7:53 p.m. UTC | #10
On Tue, May 11, 2021 at 12:46 PM Sergey Organov <sorganov@gmail.com> wrote:
>
> Alex Henrie <alexhenrie24@gmail.com> writes:
>
> > On Tue, May 11, 2021 at 8:03 AM Sergey Organov <sorganov@gmail.com> wrote:
> >>
> >> Junio C Hamano <gitster@pobox.com> writes:
> >>
> >> > Junio C Hamano <gitster@pobox.com> writes:
> >>
> >> [...]
> >>
> >> > If we enable "some kind of diff" for "-m", I actually think that by
> >> > default "git log -m" should be turned into "log --cc".  As you told
> >> > Alex in your response, "log -m -p" is a quite unpleasant format to
> >> > read---it is there only because it was the only thing we had before
> >> > we invented "-c/--cc".
> >>
> >> Please, no! --cc has unfortunate feature of outputting exactly nothing
> >> for a lot of merge commits, causing even more confusion than historical
> >> "-m -p" format.
> >>
> >> The best default for -m output is --diff-merges=first-parent. Everybody
> >> is familiar with it, and it's useful.
> >>
> >> > But that might be outside the scope of this series.  I dunno, but if
> >> > there is no other constraints (like backward compatibility issues),
> >> > I have a moderately strong preference to use "--cc" over "-m -p"
> >> > from the get go for unconfigured people, rather than forcing
> >> > everybody to configure
> >>
> >> I rather have strong preference for --diff-merges=first-parent. --cc is
> >> only suitable for Git experts, and they know how to get what they want
> >> anyway. Yep, by using --cc. Why spare yet another short option for that?
> >>
> >> Overall, let's rather make -m give diff to the first parent by default.
> >> Simple. Useful. Not confusing.
> >
> > Honestly --diff-merges=separate is fine. Two weeks ago, when I started
> > this discussion, I was trying to use `git log -m` and `git show -m` to
> > find which merge commit introduced a particular change. Extremely
> > verbose diff output would have been great for that, the confusing part
> > was just that `git show -m` produced diff output and `git log -m` did
> > not.
>
> This is not a case in favor of "separate" over "first-parent" as the
> default for "-m", right?
>
> "Which merge commit introduced particular change" is exactly what
> --diff-merges=1 achieves, so "--diff-merges=separate" was not in fact
> needed, as I see it. Moreover, it could have produced wrong positives.
> Looks like --diff-merges=1 is a better fit.

I didn't know which branch the change came from. If the change came
from the first branch, it would not have appeared under the merge
commit with --diff-merges=first-parent. But the change would
definitely appear with --diff-merges=separate, which enabled me to
identify the merge commit that included it. So yes, this is a case in
favor of "separate" over "first-parent", but it's probably not a
common enough scenario to demand keeping "separate" for -m.

On Tue, May 11, 2021 at 12:31 PM Elijah Newren <newren@gmail.com> wrote:
>
> Interesting.  I have a strong preference for --diff-merges=remerge
> (yeah, I know it's not upstream, but it's been ready to submit for
> months, but just backed up behind the other ort changes.  Sorry, I
> can't push those through any faster).  I've had others using it for
> about 9 months now.

--diff-merges=remerge is the default I would expect when no options
have been configured or passed on the command line (although it would
not have helped in the scenario I described above). I look forward to
using it!

-Alex
Elijah Newren May 11, 2021, 7:56 p.m. UTC | #11
On Tue, May 11, 2021 at 12:00 PM Sergey Organov <sorganov@gmail.com> wrote:
>
> Elijah Newren <newren@gmail.com> writes:
>
> > On Tue, May 11, 2021 at 7:03 AM Sergey Organov <sorganov@gmail.com> wrote:
> >>
> >> Junio C Hamano <gitster@pobox.com> writes:
> >>
> >> > Junio C Hamano <gitster@pobox.com> writes:
> >>
> >> [...]
> >>
> >> > If we enable "some kind of diff" for "-m", I actually think that by
> >> > default "git log -m" should be turned into "log --cc".  As you told
> >> > Alex in your response, "log -m -p" is a quite unpleasant format to
> >> > read---it is there only because it was the only thing we had before
> >> > we invented "-c/--cc".
> >>
> >> Please, no! --cc has unfortunate feature of outputting exactly nothing
> >> for a lot of merge commits, causing even more confusion than historical
> >> "-m -p" format.
> >>
> >> The best default for -m output is --diff-merges=first-parent. Everybody
> >> is familiar with it, and it's useful.
> >>
> >> > But that might be outside the scope of this series.  I dunno, but if
> >> > there is no other constraints (like backward compatibility issues),
> >> > I have a moderately strong preference to use "--cc" over "-m -p"
> >> > from the get go for unconfigured people, rather than forcing
> >> > everybody to configure
> >>
> >> I rather have strong preference for --diff-merges=first-parent. --cc is
> >> only suitable for Git experts, and they know how to get what they want
> >> anyway. Yep, by using --cc. Why spare yet another short option for that?
> >
> > Interesting.  I have a strong preference for --diff-merges=remerge
> > (yeah, I know it's not upstream, but it's been ready to submit for
> > months, but just backed up behind the other ort changes.  Sorry, I
> > can't push those through any faster).  I've had others using it for
> > about 9 months now.
>
> Once somebody uses it for 9 months and starts to understand what it is
> and really loves it, she can still set log.diffMerges=remerge (new
> feature) and have fun.
>
> >
> > I think --cc is a lot better than -m for helping you find what users
> > changed when they did the merge,
>
> Yes, but it doesn't mean it should be the default.

I didn't say it should be.

> In my workflows, the first thing that matters is what commit did what
> changes on the current branch. I don't typically care what the user
> changed during the merge operation, only about the result. If I do care,
> then only after I find the merge commit is responsible, and I can then
> use --cc if I want to.
>
> > but I agree the format is somewhat difficult for many users to
> > understand. (--diff-merges=remerge, or --remerge-diff, fixes these
> > problems, IMO.) I think --diff-merges=first-parent, while fine when
> > explicitly requested on the command line, would be wildly misleading
> > as a default because it would attribute changes to a merge commit that
> > were made elsewhere.
>
> No, it's exactly this merge commit that made these changes to the
> current branch. The changes you refer to have been made on another
> branch, and not by this particular merge commit, and we fortunately have
> the reference to those commits through the second parent of this one.

If you only care about "what introduced these changes to the current
branch", then it's not only the diff against second parent that is
irrelevant: ALL commits that are part of the history only via the
second or later parents are also irrelevant and thus you should be
using --first-parent when asking this question.  That changes both
history traversal and the diff output.  It's a reasonable question,
sure, but I didn't see you suggest that -m should change both.
Perhaps you did mean that, in which case I think that's a proposal
that would make -m become useful.  It'd be a drastically different
option than what -m is today, which would normally make me wonder if
it'd be considered a backward compatibility issue, but given how
useless -m has been and since Junio apparently even suggested changing
-m, this might be okay.

> >> Overall, let's rather make -m give diff to the first parent by default.
> >> Simple. Useful. Not confusing.
> >
> > I think it's confusing.
>
> I think it isn't, once you accept that merge commit does introduce
> changes to the branch, by itself.

Asking what commits introduced changes to the branch is a useful
question, but one which requires changing history traversal.  Unless
making -m imply --first-parent is part of the proposal, I still find
it somewhat confusing.

Granted, "what changes were introduced to the branch?" is certainly
not the only question you might be looking for answers to.  Others
include "what changes were people making in each commit" or "who added
calls to this function and why" (e.g. with git log S$function -p
$maybe_some_merge_diff_flag) or "who caused this function to end up
the way it is" (e.g. with git log -L :<funcname>:<file> -p
$some_diff_merge_flag).  For any of those, a first parent diff is
pretty terrible and highly misleading.  A separate diff is no better.
--cc would often be useful, with some caveats -- the biggest of which
is just how esoteric combined-diffs are.  --remerge-diff is way more
natural for each of these questions I'm coming up with.  Are there
other questions that -m helps us answer where first-parent diffs make
sense and are generally correct without also needing --first-parent?
I'm not thinking of any right now.
Sergey Organov May 11, 2021, 8:27 p.m. UTC | #12
Alex Henrie <alexhenrie24@gmail.com> writes:

> On Tue, May 11, 2021 at 12:46 PM Sergey Organov <sorganov@gmail.com> wrote:
>>
>> Alex Henrie <alexhenrie24@gmail.com> writes:
>>
>> > On Tue, May 11, 2021 at 8:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>> >>
>> >> Junio C Hamano <gitster@pobox.com> writes:
>> >>
>> >> > Junio C Hamano <gitster@pobox.com> writes:
>> >>
>> >> [...]
>> >>
>> >> > If we enable "some kind of diff" for "-m", I actually think that by
>> >> > default "git log -m" should be turned into "log --cc".  As you told
>> >> > Alex in your response, "log -m -p" is a quite unpleasant format to
>> >> > read---it is there only because it was the only thing we had before
>> >> > we invented "-c/--cc".
>> >>
>> >> Please, no! --cc has unfortunate feature of outputting exactly nothing
>> >> for a lot of merge commits, causing even more confusion than historical
>> >> "-m -p" format.
>> >>
>> >> The best default for -m output is --diff-merges=first-parent. Everybody
>> >> is familiar with it, and it's useful.
>> >>
>> >> > But that might be outside the scope of this series.  I dunno, but if
>> >> > there is no other constraints (like backward compatibility issues),
>> >> > I have a moderately strong preference to use "--cc" over "-m -p"
>> >> > from the get go for unconfigured people, rather than forcing
>> >> > everybody to configure
>> >>
>> >> I rather have strong preference for --diff-merges=first-parent. --cc is
>> >> only suitable for Git experts, and they know how to get what they want
>> >> anyway. Yep, by using --cc. Why spare yet another short option for that?
>> >>
>> >> Overall, let's rather make -m give diff to the first parent by default.
>> >> Simple. Useful. Not confusing.
>> >
>> > Honestly --diff-merges=separate is fine. Two weeks ago, when I started
>> > this discussion, I was trying to use `git log -m` and `git show -m` to
>> > find which merge commit introduced a particular change. Extremely
>> > verbose diff output would have been great for that, the confusing part
>> > was just that `git show -m` produced diff output and `git log -m` did
>> > not.
>>
>> This is not a case in favor of "separate" over "first-parent" as the
>> default for "-m", right?
>>
>> "Which merge commit introduced particular change" is exactly what
>> --diff-merges=1 achieves, so "--diff-merges=separate" was not in fact
>> needed, as I see it. Moreover, it could have produced wrong positives.
>> Looks like --diff-merges=1 is a better fit.
>
> I didn't know which branch the change came from. If the change came
> from the first branch, it would not have appeared under the merge
> commit with --diff-merges=first-parent.

The change in question either came from this merge, or it didn't. If it
came from this merge, it will be there in --diff-merges=first-parent
even if you have octopus merge and multiple parents, in which case it
will be cumulative change from all the side parents.

> But the change would definitely appear with --diff-merges=separate,
> which enabled me to identify the merge commit that included it.

The second part of --diff-merges=separate, that is absent in
--diff-merges=first-parent, shows the diff that this merge would have
made to the side branch, if you had considered the result of merge the
tip of that branch, and you didn't. This second part just makes no sense
at all when you care about changes to your files in any typical git
workflow, as far as I can tell.

> So yes, this is a case in favor of "separate" over "first-parent", but
> it's probably not a common enough scenario to demand keeping
> "separate" for -m.

To me it looks like it rather only shows how deeply confusing
--diff-merges=separate actually is. I'd just kill it.


Thanks,

-- Sergey Organov
Sergey Organov May 11, 2021, 8:32 p.m. UTC | #13
Elijah Newren <newren@gmail.com> writes:

> On Tue, May 11, 2021 at 12:00 PM Sergey Organov <sorganov@gmail.com> wrote:
>>
>> Elijah Newren <newren@gmail.com> writes:
>>
>> > On Tue, May 11, 2021 at 7:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>> >>
>> >> Junio C Hamano <gitster@pobox.com> writes:
>> >>
>> >> > Junio C Hamano <gitster@pobox.com> writes:
>> >>
>> >> [...]
>> >>
>> >> > If we enable "some kind of diff" for "-m", I actually think that by
>> >> > default "git log -m" should be turned into "log --cc".  As you told
>> >> > Alex in your response, "log -m -p" is a quite unpleasant format to
>> >> > read---it is there only because it was the only thing we had before
>> >> > we invented "-c/--cc".
>> >>
>> >> Please, no! --cc has unfortunate feature of outputting exactly nothing
>> >> for a lot of merge commits, causing even more confusion than historical
>> >> "-m -p" format.
>> >>
>> >> The best default for -m output is --diff-merges=first-parent. Everybody
>> >> is familiar with it, and it's useful.
>> >>
>> >> > But that might be outside the scope of this series.  I dunno, but if
>> >> > there is no other constraints (like backward compatibility issues),
>> >> > I have a moderately strong preference to use "--cc" over "-m -p"
>> >> > from the get go for unconfigured people, rather than forcing
>> >> > everybody to configure
>> >>
>> >> I rather have strong preference for --diff-merges=first-parent. --cc is
>> >> only suitable for Git experts, and they know how to get what they want
>> >> anyway. Yep, by using --cc. Why spare yet another short option for that?
>> >
>> > Interesting.  I have a strong preference for --diff-merges=remerge
>> > (yeah, I know it's not upstream, but it's been ready to submit for
>> > months, but just backed up behind the other ort changes.  Sorry, I
>> > can't push those through any faster).  I've had others using it for
>> > about 9 months now.
>>
>> Once somebody uses it for 9 months and starts to understand what it is
>> and really loves it, she can still set log.diffMerges=remerge (new
>> feature) and have fun.
>>
>> >
>> > I think --cc is a lot better than -m for helping you find what users
>> > changed when they did the merge,
>>
>> Yes, but it doesn't mean it should be the default.
>
> I didn't say it should be.
>
>> In my workflows, the first thing that matters is what commit did what
>> changes on the current branch. I don't typically care what the user
>> changed during the merge operation, only about the result. If I do care,
>> then only after I find the merge commit is responsible, and I can then
>> use --cc if I want to.
>>
>> > but I agree the format is somewhat difficult for many users to
>> > understand. (--diff-merges=remerge, or --remerge-diff, fixes these
>> > problems, IMO.) I think --diff-merges=first-parent, while fine when
>> > explicitly requested on the command line, would be wildly misleading
>> > as a default because it would attribute changes to a merge commit that
>> > were made elsewhere.
>>
>> No, it's exactly this merge commit that made these changes to the
>> current branch. The changes you refer to have been made on another
>> branch, and not by this particular merge commit, and we fortunately have
>> the reference to those commits through the second parent of this one.
>
> If you only care about "what introduced these changes to the current
> branch", then it's not only the diff against second parent that is
> irrelevant: ALL commits that are part of the history only via the
> second or later parents are also irrelevant and thus you should be
> using --first-parent when asking this question.  That changes both
> history traversal and the diff output.

No, it's exactly why I don't always want --first-parent. I want to
traverse *all* the history, yet to see what's changed by every commit on
*this* branch in the process of traversal, be it a merge on not a merge
commit.

Thanks,

-- Sergey Organov
Junio C Hamano May 11, 2021, 8:43 p.m. UTC | #14
Elijah Newren <newren@gmail.com> writes:

> On Tue, May 11, 2021 at 7:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>> ...
> I think --cc is a lot better than -m for helping you find what users
> changed when they did the merge, but I agree the format is somewhat
> difficult for many users to understand.  (--diff-merges=remerge, or
> --remerge-diff, fixes these problems, IMO.)  I think
> --diff-merges=first-parent, while fine when explicitly requested on
> the command line, would be wildly misleading as a default because it
> would attribute changes to a merge commit that were made elsewhere.
>
>> Overall, let's rather make -m give diff to the first parent by default.
>> Simple. Useful. Not confusing.
>
> I think it's confusing.

I do not think it is particularly confusing---after all, it shows
"here is a comparison between two trees" the users are familiar with
in a single strand of pearls.

But I do think that it is an utterly misleading option to show
merges in general.  When "log" is used with the "--first-parent"
traversal, "compare with the first parent to show everything the
side branch did" is an acceptable alternative, but even there, it is
far less suitable than the "remerge" or "cc", I would think, as the
default format.

Thanks.
Sergey Organov May 11, 2021, 9:38 p.m. UTC | #15
Junio C Hamano <gitster@pobox.com> writes:

> Elijah Newren <newren@gmail.com> writes:
>
>> On Tue, May 11, 2021 at 7:03 AM Sergey Organov <sorganov@gmail.com> wrote:
>>> ...
>> I think --cc is a lot better than -m for helping you find what users
>> changed when they did the merge, but I agree the format is somewhat
>> difficult for many users to understand.  (--diff-merges=remerge, or
>> --remerge-diff, fixes these problems, IMO.)  I think
>> --diff-merges=first-parent, while fine when explicitly requested on
>> the command line, would be wildly misleading as a default because it
>> would attribute changes to a merge commit that were made elsewhere.
>>
>>> Overall, let's rather make -m give diff to the first parent by default.
>>> Simple. Useful. Not confusing.
>>
>> I think it's confusing.
>
> I do not think it is particularly confusing---after all, it shows
> "here is a comparison between two trees" the users are familiar with
> in a single strand of pearls.

Moreover, it's comparison between two most natural trees, the same trees
as for non-merge commits.

>
> But I do think that it is an utterly misleading option to show
> merges in general.  When "log" is used with the "--first-parent"
> traversal, "compare with the first parent to show everything the
> side branch did" is an acceptable alternative, but even there, it is
> far less suitable than the "remerge" or "cc", I would think, as the
> default format.

What I still fail to see is why somebody wants to mix traversal rules
with representation of merge commits, sorry.

If I want to see merges in --cc, I want them in --cc, no matter which
way I get to particular commit through the DAG. If I want to see them in
--diff-merges=1, I want them this way, no matter how I happened to get
to particular commit.

Is it more likely that I want to see merges in --diff-merges=1 when I
use --first-parent? Yes, of course! That's why --first-parent implies
--diff-merges=1. Vice versa? No, why?

Thanks,

-- Sergey Organov
Junio C Hamano May 11, 2021, 11:40 p.m. UTC | #16
Sergey Organov <sorganov@gmail.com> writes:

>> But I do think that it is an utterly misleading option to show
>> merges in general.  When "log" is used with the "--first-parent"
>> traversal, "compare with the first parent to show everything the
>> side branch did" is an acceptable alternative, but even there, it is
>> far less suitable than the "remerge" or "cc", I would think, as the
>> default format.
>
> What I still fail to see is why somebody wants to mix traversal rules
> with representation of merge commits, sorry.

It is not about "mixing".

What I meant was that diff between the pre-merge state and the merge
result as two-tree comparison may be an acceptable view of "what did
this _merge_ contribute to the history" and that is in line is what
the first-parent traversal is trying to show the reader of the
history, which is "this merge contributed to the history, and then
this other merge contributed to the history, ...".  It also may make
sense when one is inspecting a merge in isolation, i.e. "git show M".

When one is viewing individual commits without omitting commits on
the side branch, however, showing "what did the side branch as a
whole contributed to the history at this merge" makes little sense
and is misleading.  Such a patch given for a merge mostly overlaps
with what the reader sees immediately after seeing the merge
(i.e. the commits on the side branch, with their own patches, each
of which has already been shown in the first-parent comparison of
the merge).  In other words, "git log --no-first-parent" is about
contribution of each single commit (whether it is a merge or a
non-merge) makes, and the --diff-merges=1 presentation is not in
line with that worldview, in which the contribution to the history
the merge alone makes is what --cc or remerge tries to show,
i.e. "what did the merge do, on top of what the commits on the side
branch contributed to the history?"

So, it is not like two unrelated things are mixed together.  It is
more like showing the result of a merge as a diff relative to its
first-parent is tied to and consistent with the viewpoint of history
as single strand of pearls that is a series of merges into the
first-parent chain, but not with non-first-parent presentation of
the history.
Felipe Contreras May 12, 2021, 1:16 a.m. UTC | #17
Sergey Organov wrote:
> Alex Henrie <alexhenrie24@gmail.com> writes:
> 
> > I didn't know which branch the change came from. If the change came
> > from the first branch, it would not have appeared under the merge
> > commit with --diff-merges=first-parent.
> 
> The change in question either came from this merge, or it didn't. If it
> came from this merge, it will be there in --diff-merges=first-parent
> even if you have octopus merge and multiple parents, in which case it
> will be cumulative change from all the side parents.

Precisely.

The primary thing I care about is what is the status of the branch
*after* the merge. In other words; if I rewind history and I hadn't done
the merge, what would be diffent?

That in my mind is the actual content of the merge.
Sergey Organov May 17, 2021, 12:57 p.m. UTC | #18
Junio C Hamano <gitster@pobox.com> writes:

> Junio C Hamano <gitster@pobox.com> writes:
>
>> Sergey Organov <sorganov@gmail.com> writes:
>>
>>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>>> one side, and -m that did not imply -p, on the other side.
>>>
>>> After this patch
>>>
>>>   git log -m
>>>
>>> will start to produce diffs without need to provide -p as well, that
>>> improves both consistency and usability. It gets even more useful if
>>> one sets "log.diffMerges" configuration variable to "first-parent" to
>>> force -m produce usual diff with respect to first parent only.
>>
>> Please make sure that you clearly state that you do not blindly
>> force --patch output in the proposed log message.  Explicitly
>> mentioning that "git log --stat -m" would not give a patch but just
>> diffstat would be assuring.
>
> Also, avoid "-p" in the title.  "let -m imply diff generation" might
> be a good compromise.
>
> What --cc/-c implies is to show some kind of diff for merges
> (dense_combined_merges, combine_merges and !ignore_merges are the
> members of the revs field that controls how merge commits) and they
> ask for specific kind of diff is shown.  So "-c/--cc imply -p" is
> quite wrong (you never get straight --patch output for merges when
> you give -c/--cc---you get combined diff).  In a sense, you could
> say -c/--cc implies -m (i.e. do show some kind of diff for merges).
>
> Taken together, perhaps:
>
>     Subject: diff: let -m imply diff generation
>
>     The "-c/--cc" options to "git log" asks for merges to be shown
>     with patch-like output, implicitly enabling the "-m" option
>     (which is used to tell "do not ignore merge commits when showing
>     patches).  However, the opposite is not true; giving "-m" alone
>     does not tell "git log" that the user wants some form of patches.
>     
>     Make "-m" imply "we want some form of diff output", so that "git
>     log -m" would behave identically to "git log -m -p".  When the
>     user explicitly asks for what kind of diff output is desired,
>     e.g. "git log -m --stat", there is no need to imply anything,
>     specifically, do NOT blindly turn on the "-p: option to turn it
>     into "git log -m --stat -p:.
>
> or something like that.

While working on this, I've added more tests and explanations to the
next re-roll as I've promised, but I didn't change the subject nor did I
try to explain that much, as my original subject is consistent with
current Git documentation, concise, and straight to the point.

"<opt> implies -p" -- that's how current Git manual describes the
behavior, and that's how I described it in these patches. Whatever
"imply" actually means for -c/--cc, it now means for -m as well, and
that's the essence of the patches, so I stand for my original subject.

I think that if we realize that "<opt> implies -p" is not precise enough
description of actual behavior, it should be a separate topic of
documentation improvements, and doesn't belong to these series anyway.

Thanks,
-- Sergey Organov
Jonathan Nieder May 19, 2021, 9:44 p.m. UTC | #19
Hi,

Elijah Newren wrote:

> Interesting.  I have a strong preference for --diff-merges=remerge
> (yeah, I know it's not upstream, but it's been ready to submit for
> months, but just backed up behind the other ort changes.  Sorry, I
> can't push those through any faster).  I've had others using it for
> about 9 months now.

I agree.  The --diff-merges=remerge behavior has also been the default
in Gerrit since time immemorial, and when I first started using Gerrit
it was one of my favorite things about it.

That is because it shows the human content of the merge: it shows
exactly what changes were made after the automated part was done.

I don't have a strong opinion about what the default for -m should be.

> I think --cc is a lot better than -m for helping you find what users
> changed when they did the merge, but I agree the format is somewhat
> difficult for many users to understand.

My experience in training new users has been that --cc is quite
counterintuitive for them.  Like you're hinting, I suspect it's
fundamentally just meant to be a fast approximation to
--diff-merges=remerge.

Thanks,
Jonathan
Jonathan Nieder May 19, 2021, 9:48 p.m. UTC | #20
Sergey Organov wrote:

> Fix long standing inconsistency between -c/--cc that do imply -p, on
> one side, and -m that did not imply -p, on the other side.
>
> After this patch
>
>   git log -m
>
> will start to produce diffs without need to provide -p as well,

Personally I don't ever use -m without -p and --first-parent, so in
that sense this feels like a change in the right direction.

Does this also affect the plumbing command "git diff-tree"?  I'm
guessing "no" because diff-tree already generates a diff by default,
but it seems worth spelling out in the commit message to prevent
worries about the effect on scripts that expect stable plumbing
behavior.

Thanks,
Jonathan
Sergey Organov May 19, 2021, 10:03 p.m. UTC | #21
Jonathan Nieder <jrnieder@gmail.com> writes:

> Sergey Organov wrote:
>
>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>> one side, and -m that did not imply -p, on the other side.
>>
>> After this patch
>>
>>   git log -m
>>
>> will start to produce diffs without need to provide -p as well,
>
> Personally I don't ever use -m without -p and --first-parent, so in
> that sense this feels like a change in the right direction.
>
> Does this also affect the plumbing command "git diff-tree"?  I'm
> guessing "no" because diff-tree already generates a diff by default,
> but it seems worth spelling out in the commit message to prevent
> worries about the effect on scripts that expect stable plumbing
> behavior.

Well, here are existing relevant tests:

diff-tree master
diff-tree -p master
diff-tree -p -m master

that all still pass after the patches, and I believe

diff-tree -m master

does change the behavior, but provided it's useless before these
patches, it should be OK to have this change.

Thanks,
-- Sergey Organov
Junio C Hamano May 19, 2021, 11:32 p.m. UTC | #22
Jonathan Nieder <jrnieder@gmail.com> writes:

> Sergey Organov wrote:
>
>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>> one side, and -m that did not imply -p, on the other side.
>>
>> After this patch
>>
>>   git log -m
>>
>> will start to produce diffs without need to provide -p as well,
>
> Personally I don't ever use -m without -p and --first-parent, so in
> that sense this feels like a change in the right direction.
>
> Does this also affect the plumbing command "git diff-tree"?  I'm
> guessing "no" because diff-tree already generates a diff by default,
> but it seems worth spelling out in the commit message to prevent
> worries about the effect on scripts that expect stable plumbing
> behavior.

This is about "log" from the "rev-list" family, not "diff" to
compare two endpoints, so "git diff" won't be affected, and "git
diff-tree" is not affected, either.
Sergey Organov May 20, 2021, 1:14 p.m. UTC | #23
Junio C Hamano <gitster@pobox.com> writes:

> Jonathan Nieder <jrnieder@gmail.com> writes:
>
>> Sergey Organov wrote:
>>
>>> Fix long standing inconsistency between -c/--cc that do imply -p, on
>>> one side, and -m that did not imply -p, on the other side.
>>>
>>> After this patch
>>>
>>>   git log -m
>>>
>>> will start to produce diffs without need to provide -p as well,
>>
>> Personally I don't ever use -m without -p and --first-parent, so in
>> that sense this feels like a change in the right direction.
>>
>> Does this also affect the plumbing command "git diff-tree"?  I'm
>> guessing "no" because diff-tree already generates a diff by default,
>> but it seems worth spelling out in the commit message to prevent
>> worries about the effect on scripts that expect stable plumbing
>> behavior.
>
> This is about "log" from the "rev-list" family, not "diff" to
> compare two endpoints, so "git diff" won't be affected, and "git
> diff-tree" is not affected, either.

You are right. I've added a test for "git diff-tree -m", and the changes
don't break it.

Can easily re-roll if you think the test worth it.

Thanks,
-- Sergey Organov
Jonathan Nieder May 20, 2021, 6:50 p.m. UTC | #24
Sergey Organov wrote:
> Junio C Hamano <gitster@pobox.com> writes:

>> This is about "log" from the "rev-list" family, not "diff" to
>> compare two endpoints, so "git diff" won't be affected, and "git
>> diff-tree" is not affected, either.
>
> You are right. I've added a test for "git diff-tree -m", and the changes
> don't break it.

Good.

> Can easily re-roll if you think the test worth it.

I care more about the commit message than the test --- i.e. mentioning
that this doesn't affect commands like

	git rev-list HEAD~5..HEAD | git diff-tree --stdin -m

Thanks,
Jonathan
Sergey Organov May 20, 2021, 7:38 p.m. UTC | #25
Jonathan Nieder <jrnieder@gmail.com> writes:

> Sergey Organov wrote:
>> Junio C Hamano <gitster@pobox.com> writes:
>
>>> This is about "log" from the "rev-list" family, not "diff" to
>>> compare two endpoints, so "git diff" won't be affected, and "git
>>> diff-tree" is not affected, either.
>>
>> You are right. I've added a test for "git diff-tree -m", and the changes
>> don't break it.
>
> Good.
>
>> Can easily re-roll if you think the test worth it.
>
> I care more about the commit message than the test --- i.e. mentioning
> that this doesn't affect commands like
>
> 	git rev-list HEAD~5..HEAD | git diff-tree --stdin -m

OK, re-roll to follow...

Thanks,
-- Sergey Organov
Sergey Organov May 20, 2021, 8:39 p.m. UTC | #26
Hi,

Jonathan Nieder <jrnieder@gmail.com> writes:

> Hi,
>
> Elijah Newren wrote:
>
>> Interesting.  I have a strong preference for --diff-merges=remerge
>> (yeah, I know it's not upstream, but it's been ready to submit for
>> months, but just backed up behind the other ort changes.  Sorry, I
>> can't push those through any faster).  I've had others using it for
>> about 9 months now.
>
> I agree.  The --diff-merges=remerge behavior has also been the default
> in Gerrit since time immemorial, and when I first started using Gerrit
> it was one of my favorite things about it.

Due to previous set of diff-merges patches you now can set
log.diffMerges=remerge and have fun having it as the default for "-m" in
pure Git. I've introduced log.diffMerges exactly because I do realize
that different people and different workflows might have different
preferences here.

> That is because it shows the human content of the merge: it shows
> exactly what changes were made after the automated part was done.

No, in fact it shows what additional changes were to be made if the
merge had been achieved using particular automated merge algorithm you
apply right now. Provided you utilize no external knowledge, you have no
idea how merge has been in fact achieved, as core Git (fortunately)
neither cares nor stores such information.

Contrary to your view, and I believe more inline with Git core
philosophy, I (usually) don't care *how* particular changes were
achieved, I rather care *what* they are, so pure diff to the first
parent is the best basic format for me. Only if I need to see *why* the
changes are this particular way, I'd use advanced tools and formats to
get to the best *guess*, and that's where these advanced formats get
handy.

In other words, for me merge commit is mostly *commit*, and only then
it's *merge*: "here are the changes, and, by the way, here is where
these changes came from."

That said, please don't get me wrong: I'm all for advanced features such
as --diff-merges=remerge, as I do understand how and when they are
useful, I just personally won't make them active by default.

>
> I don't have a strong opinion about what the default for -m should be.
>
>> I think --cc is a lot better than -m for helping you find what users
>> changed when they did the merge, but I agree the format is somewhat
>> difficult for many users to understand.

I do have strong opinion. --diff-merges=1 is the only sensible
factory-default. Not only it has no implicit assumptions about how given
commit has been achieved, it's also the only format even entire Git
newbie might already be familiar with.

Then, --cc and I suspect "remerge" too, give exactly empty output most
of times, that'd cause even more surprises when one of them is the
default: you enable diff for merges, but still get nothing. OTOH,
--diff-merges=1 will give empty output if and only if given commit
actually brings no changes to the branch, exactly as any commit out
there. No surprises at all.

Principle of least surprise is still a good thing to follow.

Thanks,
-- Sergey Organov
Felipe Contreras May 21, 2021, 6:14 p.m. UTC | #27
Sergey Organov wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:

> > I don't have a strong opinion about what the default for -m should be.
> >
> >> I think --cc is a lot better than -m for helping you find what users
> >> changed when they did the merge, but I agree the format is somewhat
> >> difficult for many users to understand.
> 
> I do have strong opinion. --diff-merges=1 is the only sensible
> factory-default. Not only it has no implicit assumptions about how given
> commit has been achieved, it's also the only format even entire Git
> newbie might already be familiar with.

I agree.

> Principle of least surprise is still a good thing to follow.

I could not agree more.
diff mbox series

Patch

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 530d1159141f..32e6dee5ac3b 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -49,10 +49,9 @@  ifdef::git-log[]
 --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
+	the default format. The default format could be changed using
 	`log.diffMerges` configuration parameter, which default value
-	is `separate`.
+	is `separate`. `-m` implies `-p`.
 +
 --diff-merges=first-parent:::
 --diff-merges=1:::
@@ -62,7 +61,8 @@  ifdef::git-log[]
 --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.
+	for each parent. This is the format that `-m` produced
+	historically.
 +
 --diff-merges=combined:::
 --diff-merges=c:::
diff --git a/diff-merges.c b/diff-merges.c
index 211c99482cac..a827482a97ff 100644
--- a/diff-merges.c
+++ b/diff-merges.c
@@ -98,6 +98,7 @@  int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
 
 	if (!strcmp(arg, "-m")) {
 		set_to_default(revs);
+		revs->merges_imply_patch = 1;
 	} else if (!strcmp(arg, "-c")) {
 		set_combined(revs);
 		revs->merges_imply_patch = 1;