`git apply --ignore-whitespace` is broken

2.1k views Asked by At

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:

  1. 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
  2. git add somefile.txt
  3. cp somefile.txt somefile.orig.txt
  4. 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
  5. Create a so-called "whitespace-ignoring" diff with git diff: git diff -w somefile.txt > somefile.gitdiff
  6. 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.
  7. Optionally, for comparison: Create a truly whitespace-ignoring diff with GNU diff: diff -uw somefile.orig.txt somefile.txt > somefile.diff
  8. Reset somefile.txt to its original version: git checkout somefile.txt
  9. 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

bugs-with-git-diff-and-apply-not-ignoring-whitespace

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?
1

There are 1 answers

0
j6t On

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.