diff mbox series

Combined diff format: Show all filenames by default?

Message ID CADDzAfNz3R5yj1SdJYbBe0f8m3Sp-R+X6dRpYoJ8Foj6zijcDA@mail.gmail.com (mailing list archive)
State New, archived
Headers show
Series Combined diff format: Show all filenames by default? | expand

Commit Message

Kang-Che Sung May 3, 2024, 2:06 a.m. UTC
Dear Git developers,

I have a humble feature request, perhaps to address a usability
problem that annoyed me a lot.

When Git shows merge commits, it often present a diff called a
"combined diff" format. The documentation has an example
(https://git-scm.com/docs/diff-format#_combined_diff_format)

```
+++ b/describe.c
@@@ -98,10 -98,8 +98,10 @@@
return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
 }

- static void describe(char *arg)
-static void describe(struct commit *cmit, int last_one)
++static void describe(char *arg, int last_one)
 {
+ unsigned char sha1[20];
+ struct commit *cmit;
struct commit_list *list;
static int initialized = 0;
struct commit_name *n;
```

The from-file/to-file header is my main concern. It shows two lines by default:

```
--- a/describe.c
+++ b/describe.c
```

Although the documentation says it allows `--combined-all-paths`
option to show all N+1 lines:

```
--- a/file
--- a/file
--- a/file
+++ b/file
```

Why isn't this the default? I am requesting it to show the filenames
of all parent by default, for the line-by-line combined diff format.

My reason for making it default:

1. When the format is an N-way diff format, we can make it obvious
that the comparison is N-way, not two-way, by listing more than two
filenames.

2. Even though the duplicated `--- a/file` filename lines might look
redundant, it's the _number_ of those lines that matters - how many
files are involved in a diff comparison. (In contrast, showing only
two filenames is confusing.)

As the "combined diff" format is likely to last for a long time, it
would be good for Git to set a right default for presenting this
format.

Thank you.

Comments

Junio C Hamano May 3, 2024, 2:57 p.m. UTC | #1
Kang-Che Sung <explorer09@gmail.com> writes:

> My reason for making it default:
> ...
> As the "combined diff" format is likely to last for a long time, it
> would be good for Git to set a right default for presenting this
> format.

As the format HAS ALREADY lasted for a long time since its
introduction in d8f4790e (diff-tree --cc: denser combined diff
output for a merge commit., 2006-01-24), it is too late to change
the default.

If a scripted use wants to parse out all the pathnames, it can write
the option on the command line just once in the script file and
forget about it.

For interactive use, the standard answer is "you can alias only for
yourself in ~/.git/config", but unfortunately, because the alias
works at the command level (e.g., an alias that allows "git lc" to
work as "git log --cc --combined-all-paths" can be written), an
optional behaviour like --combined-all-paths that is shared across a
family of commands (e.g., "log" and "show" both would benefit) is a
bit awkward to handle.  

I wonder if introducing an "aliases for options" mechanism would
improve the situation.  Take an otherwise unused character sequence,
say, cccc, and when you say "git <cmd> --cccc", pretend as if you
said "git <cmd> --cc --combined-all-paths" from the command line.
Kang-Che Sung May 3, 2024, 7:11 p.m. UTC | #2
Hello.

On Fri, May 3, 2024 at 10:57 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Kang-Che Sung <explorer09@gmail.com> writes:
>
> > My reason for making it default:
> > ...
> > As the "combined diff" format is likely to last for a long time, it
> > would be good for Git to set a right default for presenting this
> > format.
>
> As the format HAS ALREADY lasted for a long time since its
> introduction in d8f4790e (diff-tree --cc: denser combined diff
> output for a merge commit., 2006-01-24), it is too late to change
> the default.

I wonder what things would break if we change the default behavior of this?

> If a scripted use wants to parse out all the pathnames, it can write
> the option on the command line just once in the script file and
> forget about it.
>
> For interactive use, the standard answer is "you can alias only for
> yourself in ~/.git/config", but unfortunately, because the alias
> works at the command level (e.g., an alias that allows "git lc" to
> work as "git log --cc --combined-all-paths" can be written), an
> optional behaviour like --combined-all-paths that is shared across a
> family of commands (e.g., "log" and "show" both would benefit) is a
> bit awkward to handle.

Well, I won't expect the default to be changed for uses in scripts or
GUI frontends. I wish to change the default for interactive, terminal
uses, so that usability comes in "out of the box".

And I don't want the "alias command" workaround for a few reasons:

1. It seems like the `--combined-all-paths` would also affect the
"file-by-file" diff output ("git diff-index", "git diff-tree" and
like), and I am not requesting to change the default of this one.
2. The combined diff format is used in many places - including "git
diff" when there is a conflict, and a "git show" of a merge commit
when the merge was not trivial and human merging was involved.
3. And this diff output style should ideally be a "git config" option
that users can tweak it for personal preference (including reverting
to the old, "`--no-combined-all-paths`" behavior when needed).

I know there would be compatibility problems with GUIs and scripts if
we change the default like this, but the GUIs and scripts should fix
them, as git is already able to output three filename header lines for
the merge/combined diff. I just request to make it the default.
Junio C Hamano May 3, 2024, 7:42 p.m. UTC | #3
Kang-Che Sung <explorer09@gmail.com> writes:

>> As the format HAS ALREADY lasted for a long time since its
>> introduction in d8f4790e (diff-tree --cc: denser combined diff
>> output for a merge commit., 2006-01-24), it is too late to change
>> the default.
>
> I wonder what things would break if we change the default behavior of this?

Human users who rarely if ever rename files will start complaining
for wasted vertical screen real estates taken by the extra lines.

Nothing is broken, and you are proposing to break things.  Be more
gentle to existing users; "what would break if we change?" is an
absolutely wrong attitude to approach this.

> Well, I won't expect the default to be changed for uses in scripts or
> GUI frontends. I wish to change the default for interactive, terminal
> uses, so that usability comes in "out of the box".

How would a script that is running by interactive users whose
standard input and output streams are connected to a terminal adjust
to sudden change of the default?  The "git" invocation in such an
environment would not be able to tell if you typed it or if you
typed the name of the script.
Kang-Che Sung May 3, 2024, 10:25 p.m. UTC | #4
On Sat, May 4, 2024 at 3:42 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> >> As the format HAS ALREADY lasted for a long time since its
> >> introduction in d8f4790e (diff-tree --cc: denser combined diff
> >> output for a merge commit., 2006-01-24), it is too late to change
> >> the default.
> >
> > I wonder what things would break if we change the default behavior of this?
>
> Human users who rarely if ever rename files will start complaining
> for wasted vertical screen real estates taken by the extra lines.
>
> Nothing is broken, and you are proposing to break things.  Be more
> gentle to existing users; "what would break if we change?" is an
> absolutely wrong attitude to approach this.

I would disagree with this.

1. Most uses of diff command are on a scrollable terminal screen (with
"less", "vi", or another text editor). It's just one line of vertical
screen taken - very subtle unless you have 4-way or more diffs. And
it's not just about renames. It's a much easier indicator that the
diff is a multi-way comparison.
2. It's a usability problem - like an Ok/Cancel dialog that took years
to realize they are badly designed. I consider the two filename only
header lines a "paper cut" usability bug. Git is able to output more
than two filenames; it just doesn't have a way to make it the default
(even as a per-user default option).

>
> > Well, I won't expect the default to be changed for uses in scripts or
> > GUI frontends. I wish to change the default for interactive, terminal
> > uses, so that usability comes in "out of the box".
>
> How would a script that is running by interactive users whose
> standard input and output streams are connected to a terminal adjust
> to sudden change of the default?  The "git" invocation in such an
> environment would not be able to tell if you typed it or if you
> typed the name of the script.
>

How is it _not_ possible to tell? If user runs "git diff" from the
script, then it would just print to standard output without running a
"less" pager. If I want to execute a set of commands with
interactivity, I would write a script and then "source my-script-name"
rather than "./my-script-name", so it's still possible to tell.
diff mbox series

Patch

diff --combined describe.c
index fabadb8,cc95eb0..4866510
--- a/describe.c