Re: [BUG] "git diff --word-diff" gives a diff while they are only space changes
14 messages between May 12, 2026 and Jun 8, 2026, from Michael Montalbo, Vincent Lefevre, Junio C Hamano, Phillip Wood, Johannes Sixt, Chris Torek.
Plain Markdown or JSON for tools and agents.
Michael MontalboMay 12, 2026, 20:56 UTC on loreOn Sat, 9 May 2026 17:55:26 +0200, Vincent Lefevre wrote:
Show 7 quoted lines
> For wdiff, it is just described as "display word differences between
> text files", and it does exactly that. For instance, if there are no
> differences in words, it shows no differences.
>
> For git with the --word-diff, there is actually no documentation,
> except the use of "changed words" and "word diff". No mention of
> line diff at all! So this is quite confusing.
Maybe something like this would be worth adding to the docs:
-- >8 --
diff --git a/Documentation/diff-options.adoc b/Documentation/diff-options.adoc
index 8a63b5e164..665473e61a 100644
--- a/Documentation/diff-options.adoc
+++ b/Documentation/diff-options.adoc
@@ -457,6 +457,11 @@ endif::git-diff[]
+
Note that despite the name of the first mode, color is used to
highlight the changed parts in all modes if enabled.
++
+Word diff works by finding word-level changes within each hunk of
+the line-level diff. The line-level alignment determines which
+changed lines are compared to each other, which can affect the
+word-level output.
`--word-diff-regex=<regex>`::
Use _<regex>_ to decide what a word is, instead of considering
-- >8 --
On 2026-05-12 13:56:19 -0700, Michael Montalbo wrote:
> Maybe something like this would be worth adding to the docs:
> +Word diff works by finding word-level changes within each hunk of
> +the line-level diff. The line-level alignment determines which
> +changed lines are compared to each other, which can affect the
> +word-level output.
[...]
Yes, this would be useful.
--
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)
On 2026-05-12 21:17 UTC, Vincent Lefevre wrote:
> Yes, this would be useful.
I've submitted a patch for this: https://lore.kernel.org/git/pull.2113.git.1778686956622.gitgitgadget@gmail.com/T/#u
On Tue, May 12, 2026 at 2:17 PM Vincent Lefevre <vincent@vinc17.net> wrote:
Show 16 quoted lines
>
> On 2026-05-12 13:56:19 -0700, Michael Montalbo wrote:
> > Maybe something like this would be worth adding to the docs:
> [...]
> > +Word diff works by finding word-level changes within each hunk of
> > +the line-level diff. The line-level alignment determines which
> > +changed lines are compared to each other, which can affect the
> > +word-level output.
> [...]
>
> Yes, this would be useful.
>
> --
> Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
> Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)
Michael Montalbo <mmontalbo@gmail.com> writes:
Show 9 quoted lines
> @@ -457,6 +457,11 @@ endif::git-diff[]
> +
> Note that despite the name of the first mode, color is used to
> highlight the changed parts in all modes if enabled.
> ++
> +Word diff works by finding word-level changes within each hunk of
> +the line-level diff. The line-level alignment determines which
> +changed lines are compared to each other, which can affect the
> +word-level output.
The added text may not say anything wrong, but I am not sure how it helps the end user to know the way machinery works internally.
On 2026-05-14 16:37:39 +0900, Junio C Hamano wrote:
Show 14 quoted lines
> Michael Montalbo <mmontalbo@gmail.com> writes:
>
> > @@ -457,6 +457,11 @@ endif::git-diff[]
> > +
> > Note that despite the name of the first mode, color is used to
> > highlight the changed parts in all modes if enabled.
> > ++
> > +Word diff works by finding word-level changes within each hunk of
> > +the line-level diff. The line-level alignment determines which
> > +changed lines are compared to each other, which can affect the
> > +word-level output.
>
> The added text may not say anything wrong, but I am not sure how it
> helps the end user to know the way machinery works internally.
Perhaps only the first sentence should be kept and that the following should be added: "Because of that, using the --ignore-space-change option is recommended."
Note: Earlier in the discussion, Johannes Sixt suggested -w
(--ignore-all-space), but this is wrong, as
git diff --word-diff -w <(printf foo) <(printf "f o o")
gives no differences while one has 1 word "foo" vs 3 words "f o o".
However, --ignore-space-change is actually not even sufficient since
git diff --ignore-space-change <(printf "foo bar") <(printf "foo\nbar")
finds differences though there are only space changes (thus this may affect hunks in case --word-diff would be used too). However, I suppose that the cases where --word-diff --ignore-space-change would not give a "real word diff" would be quite rare in practice.
--
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)
On 14/05/2026 10:55, Vincent Lefevre wrote:
Show 36 quoted lines
> On 2026-05-14 16:37:39 +0900, Junio C Hamano wrote:
>> Michael Montalbo <mmontalbo@gmail.com> writes:
>>
>>> @@ -457,6 +457,11 @@ endif::git-diff[]
>>> +
>>> Note that despite the name of the first mode, color is used to
>>> highlight the changed parts in all modes if enabled.
>>> ++
>>> +Word diff works by finding word-level changes within each hunk of
>>> +the line-level diff. The line-level alignment determines which
>>> +changed lines are compared to each other, which can affect the
>>> +word-level output.
>>
>> The added text may not say anything wrong, but I am not sure how it
>> helps the end user to know the way machinery works internally.
>
> Perhaps only the first sentence should be kept and that the following
> should be added: "Because of that, using the --ignore-space-change
> option is recommended."
>
> Note: Earlier in the discussion, Johannes Sixt suggested -w
> (--ignore-all-space), but this is wrong, as
>
> git diff --word-diff -w <(printf foo) <(printf "f o o")
>
> gives no differences while one has 1 word "foo" vs 3 words "f o o".
>
> However, --ignore-space-change is actually not even sufficient
> since
>
> git diff --ignore-space-change <(printf "foo bar") <(printf "foo\nbar")
>
> finds differences though there are only space changes (thus this
> may affect hunks in case --word-diff would be used too). However,
> I suppose that the cases where --word-diff --ignore-space-change
> would not give a "real word diff" would be quite rare in practice.
I'm a bit wary of recommending -w unconditionally in case it gives unexpected results. I've not really found there to be a problem using --word-diff when reviewing code patches. In the examples you gave we'd ideally fix the problem by computing a single word-diff per hunk from the line based diff rather than splitting the hunk at each context line. I think we'd probably want to exclude the leading and trailing context to keep the hunk header accurate but we'd get better results by calculating the word diff of everything in the hunk between the first changed line and the last changed line.
Thanks
Phillip
On Thu, May 14, 2026 at 12:37 AM Junio C Hamano <gitster@pobox.com> wrote:
Show 16 quoted lines
>
> Michael Montalbo <mmontalbo@gmail.com> writes:
>
> > @@ -457,6 +457,11 @@ endif::git-diff[]
> > +
> > Note that despite the name of the first mode, color is used to
> > highlight the changed parts in all modes if enabled.
> > ++
> > +Word diff works by finding word-level changes within each hunk of
> > +the line-level diff. The line-level alignment determines which
> > +changed lines are compared to each other, which can affect the
> > +word-level output.
>
> The added text may not say anything wrong, but I am not sure how it
> helps the end user to know the way machinery works internally.
>
I see what you mean. Maybe the doc should focus more on calling out the user-facing implication:
`--word-diff` finds word-level changes within each hunk of the
line-level diff, so changes that only affect whitespace may still
appear in the output.
I've intentionally omitted a whitespace workaround recommendation for now given the ongoing discussion in the thread.
Am 18.05.26 um 05:30 schrieb Michael Montalbo:
Show 24 quoted lines
> On Thu, May 14, 2026 at 12:37 AM Junio C Hamano <gitster@pobox.com> wrote:
>>
>> Michael Montalbo <mmontalbo@gmail.com> writes:
>>
>>> @@ -457,6 +457,11 @@ endif::git-diff[]
>>> +
>>> Note that despite the name of the first mode, color is used to
>>> highlight the changed parts in all modes if enabled.
>>> ++
>>> +Word diff works by finding word-level changes within each hunk of
>>> +the line-level diff. The line-level alignment determines which
>>> +changed lines are compared to each other, which can affect the
>>> +word-level output.
>>
>> The added text may not say anything wrong, but I am not sure how it
>> helps the end user to know the way machinery works internally.
>>
>
> I see what you mean. Maybe the doc should focus more on calling out
> the user-facing implication:
>
> `--word-diff` finds word-level changes within each hunk of the
> line-level diff, so changes that only affect whitespace may still
> appear in the output.
I don't know what this paragraph is trying to explain. I don't see how this would explain Vincent's observed word-diff.
The thing is, "word-diff" is such a descriptive name for the operation that it is difficult to find a description that is even better. The manual page doesn't even give it a try. It defers to --word-diff-regex right away, which then only talks about low-level details and doesn't attempt to give a higher-level description what a word-diff is.
I don't think you can summarize the algorithm in a single sentence. But then I have to ask: why write it down anyway? How does it help the reader? Only so that they are able to derive an explanation for a particular observed output? Would it have saved Vincent to write a bug report?
If we document the algorithm in such detail, we cast it in stone. I wouldn't want to paint ourselves into that corner.
-- Hannes
On Mon, May 18, 2026 at 12:30 AM Johannes Sixt <j6t@kdbg.org> wrote:
Show 29 quoted lines
>
> Am 18.05.26 um 05:30 schrieb Michael Montalbo:
> > On Thu, May 14, 2026 at 12:37 AM Junio C Hamano <gitster@pobox.com> wrote:
> >>
> >> Michael Montalbo <mmontalbo@gmail.com> writes:
> >>
> >>> @@ -457,6 +457,11 @@ endif::git-diff[]
> >>> +
> >>> Note that despite the name of the first mode, color is used to
> >>> highlight the changed parts in all modes if enabled.
> >>> ++
> >>> +Word diff works by finding word-level changes within each hunk of
> >>> +the line-level diff. The line-level alignment determines which
> >>> +changed lines are compared to each other, which can affect the
> >>> +word-level output.
> >>
> >> The added text may not say anything wrong, but I am not sure how it
> >> helps the end user to know the way machinery works internally.
> >>
> >
> > I see what you mean. Maybe the doc should focus more on calling out
> > the user-facing implication:
> >
> > `--word-diff` finds word-level changes within each hunk of the
> > line-level diff, so changes that only affect whitespace may still
> > appear in the output.
> I don't know what this paragraph is trying to explain. I don't see how
> this would explain Vincent's observed word-diff.
>
Yeah, I was trying to explain the difference Vincent saw compared to wdiff, but I agree with your criticism. In "beating around the bush" regarding implementation details / making a direct comparison to wdiff, it has been hard to craft a meaningful message.
Show 15 quoted lines
> The thing is, "word-diff" is such a descriptive name for the operation
> that it is difficult to find a description that is even better. The
> manual page doesn't even give it a try. It defers to --word-diff-regex
> right away, which then only talks about low-level details and doesn't
> attempt to give a higher-level description what a word-diff is.
>
> I don't think you can summarize the algorithm in a single sentence. But
> then I have to ask: why write it down anyway? How does it help the
> reader? Only so that they are able to derive an explanation for a
> particular observed output? Would it have saved Vincent to write a bug
> report?
>
> If we document the algorithm in such detail, we cast it in stone. I
> wouldn't want to paint ourselves into that corner.
>
I also agree with this sentiment. I haven't been able to come up with a message that threads the needle appropriately, so I'm open to dropping the patch or reworking it if others have suggestions.
> -- Hannes
>
On Mon, May 18, 2026 at 7:11 PM Michael Montalbo <mmontalbo@gmail.com> wrote:
> Yeah, I was trying to explain the difference Vincent saw compared to wdiff,
> but I agree with your criticism. In "beating around the bush" regarding
> implementation details / making a direct comparison to wdiff, it has been
> hard to craft a meaningful message.
My opinion is: don't do that, just get right to it.
> > If we document the algorithm in such detail, we cast it in stone. I
> > wouldn't want to paint ourselves into that corner.
> I also agree with this sentiment. I haven't been able to come up with a
> message that threads the needle appropriately, so I'm open to dropping
> the patch or reworking it if others have suggestions.
Call it an "implementation note" (or, if you like, a "practical consideration"?). Something along these lines might work...
Implementation Note
The --word-diff option currently operates by taking the same
line by line diff that you get without the option, then massaging
the result into a word-by-word difference. This may cause an
unnecessarily-larger diff than you would see with a more-clever
implementation. If and when Git acquires a more-clever
implementation, the output may change. Note that this is
similar to the --diff-algorithm option, which may change the
output.
Regardless of which algorithm is used, _any_ diff simply shows
_a_ way to achieve some particular change. It's impossible for
any algorithm to tell whether someone deleted two lines and
then put one back exactly as it appeared earlier, saving the
resulting text, vs deleting a single line, for instance. Only a
keystroke-by-keystroke logger would be able to tell what the
human operator actually typed into some editor. Git does
not have that information, and having it is not desired.
Chris
Chris Torek <chris.torek@gmail.com> writes:
Show 25 quoted lines
> Call it an "implementation note" (or, if you like, a "practical
> consideration"?).
> Something along these lines might work...
>
> Implementation Note
>
> The --word-diff option currently operates by taking the same
> line by line diff that you get without the option, then massaging
> the result into a word-by-word difference. This may cause an
> unnecessarily-larger diff than you would see with a more-clever
> implementation. If and when Git acquires a more-clever
> implementation, the output may change. Note that this is
> similar to the --diff-algorithm option, which may change the
> output.
>
> Regardless of which algorithm is used, _any_ diff simply shows
> _a_ way to achieve some particular change. It's impossible for
> any algorithm to tell whether someone deleted two lines and
> then put one back exactly as it appeared earlier, saving the
> resulting text, vs deleting a single line, for instance. Only a
> keystroke-by-keystroke logger would be able to tell what the
> human operator actually typed into some editor. Git does
> not have that information, and having it is not desired.
>
> Chris
I understand your frustration in the second paragraph ;-) but let's not go there. The first paragraph is excellent. It gives readers a clear enough explanation to understand what is happening and stop complaining where there is nothing to complain about (which is already hinted by the "Note that" at the end).
On Mon, May 18, 2026 at 8:11 PM Junio C Hamano <gitster@pobox.com> wrote:
Show 35 quoted lines
>
> Chris Torek <chris.torek@gmail.com> writes:
>
> > Call it an "implementation note" (or, if you like, a "practical
> > consideration"?).
> > Something along these lines might work...
> >
> > Implementation Note
> >
> > The --word-diff option currently operates by taking the same
> > line by line diff that you get without the option, then massaging
> > the result into a word-by-word difference. This may cause an
> > unnecessarily-larger diff than you would see with a more-clever
> > implementation. If and when Git acquires a more-clever
> > implementation, the output may change. Note that this is
> > similar to the --diff-algorithm option, which may change the
> > output.
> >
> > Regardless of which algorithm is used, _any_ diff simply shows
> > _a_ way to achieve some particular change. It's impossible for
> > any algorithm to tell whether someone deleted two lines and
> > then put one back exactly as it appeared earlier, saving the
> > resulting text, vs deleting a single line, for instance. Only a
> > keystroke-by-keystroke logger would be able to tell what the
> > human operator actually typed into some editor. Git does
> > not have that information, and having it is not desired.
> >
> > Chris
>
> I understand your frustration in the second paragraph ;-) but let's
> not go there. The first paragraph is excellent. It gives readers a
> clear enough explanation to understand what is happening and stop
> complaining where there is nothing to complain about (which is
> already hinted by the "Note that" at the end).
>
Thanks for the ideas, Chris. Here is my attempt at synthesizing Chris' suggestions and Junio's feedback:
The `--word-diff` option operates by taking the same line-by-line
diff that is produced without the option and computing
word-by-word changes within each hunk. This may produce a
larger diff than a dedicated word-diff tool would. If Git
acquires a different implementation in the future, the output
may change. Note that this is similar to the `--diff-algorithm`
option, which may also change the output.
Does this work?
On Wed, May 20, 2026 at 1:21 PM Michael Montalbo <mmontalbo@gmail.com> wrote:
Show 50 quoted lines
>
> On Mon, May 18, 2026 at 8:11 PM Junio C Hamano <gitster@pobox.com> wrote:
> >
> > Chris Torek <chris.torek@gmail.com> writes:
> >
> > > Call it an "implementation note" (or, if you like, a "practical
> > > consideration"?).
> > > Something along these lines might work...
> > >
> > > Implementation Note
> > >
> > > The --word-diff option currently operates by taking the same
> > > line by line diff that you get without the option, then massaging
> > > the result into a word-by-word difference. This may cause an
> > > unnecessarily-larger diff than you would see with a more-clever
> > > implementation. If and when Git acquires a more-clever
> > > implementation, the output may change. Note that this is
> > > similar to the --diff-algorithm option, which may change the
> > > output.
> > >
> > > Regardless of which algorithm is used, _any_ diff simply shows
> > > _a_ way to achieve some particular change. It's impossible for
> > > any algorithm to tell whether someone deleted two lines and
> > > then put one back exactly as it appeared earlier, saving the
> > > resulting text, vs deleting a single line, for instance. Only a
> > > keystroke-by-keystroke logger would be able to tell what the
> > > human operator actually typed into some editor. Git does
> > > not have that information, and having it is not desired.
> > >
> > > Chris
> >
> > I understand your frustration in the second paragraph ;-) but let's
> > not go there. The first paragraph is excellent. It gives readers a
> > clear enough explanation to understand what is happening and stop
> > complaining where there is nothing to complain about (which is
> > already hinted by the "Note that" at the end).
> >
>
> Thanks for the ideas, Chris. Here is my attempt at synthesizing Chris'
> suggestions and Junio's feedback:
>
> The `--word-diff` option operates by taking the same line-by-line
> diff that is produced without the option and computing
> word-by-word changes within each hunk. This may produce a
> larger diff than a dedicated word-diff tool would. If Git
> acquires a different implementation in the future, the output
> may change. Note that this is similar to the `--diff-algorithm`
> option, which may also change the output.
>
> Does this work?
Updated the patch with the revised wording: https://lore.kernel.org/git/pull.2113.git.1778686956622.gitgitgadget@gmail.com/T/#t
Please feel free to pick up, modify, or drop as appropriate.
On 2026-05-28 12:25:01 -0700, Michael Montalbo wrote:
Show 17 quoted lines
> > Thanks for the ideas, Chris. Here is my attempt at synthesizing Chris'
> > suggestions and Junio's feedback:
> >
> > The `--word-diff` option operates by taking the same line-by-line
> > diff that is produced without the option and computing
> > word-by-word changes within each hunk. This may produce a
> > larger diff than a dedicated word-diff tool would. If Git
> > acquires a different implementation in the future, the output
> > may change. Note that this is similar to the `--diff-algorithm`
> > option, which may also change the output.
> >
> > Does this work?
>
> Updated the patch with the revised wording:
> https://lore.kernel.org/git/pull.2113.git.1778686956622.gitgitgadget@gmail.com/T/#t
>
> Please feel free to pick up, modify, or drop as appropriate.
Just to say that this new text is fine for me.
--
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)