According to the official git docs:
git apply
--ignore-space-change, --ignore-whitespace
When applying a patch, ignore changes in whitespace in context lines if necessary.
Context lines will preserve their whitespace, and they will not undergo whitespace fixing
regardless of the value of the --whitespace option. New lines will still be fixed, though.
However, a basic test shows that this is a damned lie.
Reproduction steps:
- Create
somefile.txt
with the following contents:- Line 1: Any text you want
- Line 2: Any non-zero number of spaces
- Line 3: Any text you want
git add somefile.txt
cp somefile.txt somefile.orig.txt
- Modify
somefile.txt
:- Line 1: Make any change you want
- Line 2: Remove all the spaces (will now be an empty line)
- Line 3: Do not change this line
- Create a so-called "whitespace-ignoring" diff with git diff:
git diff -w somefile.txt > somefile.gitdiff
- Note that due to an apparent bug with
git diff -w
, the.gitdiff
produced will have no whitespace on Line 2 (the line after the changed line) which appears as a context line. - Optionally, for comparison: Create a truly whitespace-ignoring diff with GNU diff:
diff -uw somefile.orig.txt somefile.txt > somefile.diff
- Reset
somefile.txt
to its original version:git checkout somefile.txt
- Attempt to apply the
gitdiff
patch we created in Step 5:git apply --ignore-whitespace somefile.gitdiff
Expected result:
Again, in the exact words of the git apply
docs:
When applying a patch, ignore changes in whitespace in context lines if necessary.
Here we have exactly that: a patch with a change in whitespace in a context line. So the expectation is that git apply
will do what it says on the tin and actually ignore this context line's whitespace-only difference and apply the patch successfully and cleanly, without any fuzz or error. However...
Actual result:
Applying the patch fails: error: patch failed ... patch does not apply
It should be noted that using patch --ignore-whitespace -p1 < somefile.gitdiff
works just fine, applying the patch successfully with no fuzz nor error.
A pretty table to help illustrate
diff -w
and patch --ignore-whitespace
work perfectly. Not so with git
's equivalents.
Note: I have tested and encountered the same results using both git v. 2.15.1
and git v. 2.25.1
Questions:
- Am I missing something? Or am I really the first person to notice/bother with raising this issue, in 2021?
- Is there any clever/slick workaround for this?
As you can see in the cited documentation, the options
--ignore-whitespace
and--ignore-space-change
are aliases. The behavior of the option is to ignore changes in whitespace, not to ignore all whitespace.A change in whitespace is when whitespace characters are added, changed between space and tab characters, or removed. But a removal of all whitespace is more than just a change in whitespace; it is a substantial change.
In the provided example, where all whitespace is removed from a line, it is the same as if all whitespace had been removed between two words. Such a change is not just a "change in whitespace", but is a substantial change of the text. Hence, it is not ignored.