Re: core.autocrlf=true causes `git apply` to fail on patch generated with `git diff-index HEAD --patch`
- From
Torsten Bögershausen <tboegi@web.de>
- Date
- Aug 1, 2017, 20:47 UTC
- Message-ID
- <287407ac-b0d0-ef24-4950-0982a2db9bed@web.de>
- In-Reply-To
- <CA+dzEBmsgUjmf5fUmeiwS=Q81OgpL6K5p=8dBuTjuZ4XE1V5SA@mail.gmail.com>
On 08/01/2017 08:24 PM, Anthony Sottile wrote:
Show 69 quoted lines
> Here's my minimal reproduction -- it's slightly far-fetched in that it
> involves*committing crlf* and
> then using `autocrlf=true` (commit lf, check out crlf).
>
> ```
> #!/bin/bash
> set -ex
>
> rm -rf foo
> git init foo
> cd foo
>
> # Commit crlf into repository
> git config --local core.autocrlf false
> python3 -c 'open("foo", "wb").write(b"1\r\n2\r\n")'
> git add foo
> git commit -m "Initial commit with crlf"
>
> # Change whitespace mode to autocrlf, "commit lf, checkout crlf"
> git config --local core.autocrlf true
> python3 -c 'open("foo", "wb").write(b"1\r\n2\r\n\r\n\r\n\r\n")'
>
> # Generate a patch, check it out, restore it
> git diff --ignore-submodules --binary --no-color --no-ext-diff > patch
> python3 -c 'print(open("patch", "rb").read())'
> git checkout -- .
> # I expect this to succeed, it fails
> git apply patch
> ```
>
> And here's the output:
>
> ```
> + rm -rf foo
> + git init foo
> Initialized empty Git repository in/tmp/foo/.git/
> + cd foo
> + git config --local core.autocrlf false
> + python3 -c 'open("foo", "wb").write(b"1\r\n2\r\n")'
> + git add foo
> + git commit -m 'Initial commit with crlf'
> [master (root-commit) 02d3246] Initial commit with crlf
> 1 file changed, 2 insertions(+)
> create mode 100644 foo
> + git config --local core.autocrlf true
> + python3 -c 'open("foo", "wb").write(b"1\r\n2\r\n\r\n\r\n\r\n")'
> + git diff --ignore-submodules --binary --no-color --no-ext-diff
> + python3 -c 'print(open("patch", "rb").read())'
> b'diff --git a/foo b/foo\nindex bd956ea..fbf7936 100644\n---
> a/foo\n+++ b/foo\n@@ -1,2 +1,5 @@\n 1\r\n 2\r\n+\r\n+\r\n+\r\n'
> + git checkout -- .
> + git apply patch
> patch:8: trailing whitespace.
>
> patch:9: trailing whitespace.
>
> patch:10: trailing whitespace.
>
> error: patch failed: foo:1
> error: foo: patch does not apply
> ```
>
> I also tried with `git apply --ignore-whitespace`, but this causes the
> line endings of the existing contents to be changed to*lf* (there may
> be two bugs here?)
>
> Thanks,
>
> AnthonyI can reproduce you test case here.
The line
git apply patch
would succeed, if you temporally (for the runtime of the apply command) set core.autocrlf to false:
git -c core.autocrlf=false apply patch
So this seems to be a bug (in a corner case ?):
Typically repos which had been commited with CRLF should be normalized, which means that the CRLF in the repo are replaced by LF. So you test script is a corner case, for which Git has not been designed, It seems as if "git apply" gets things wrong here. Especially, as the '\r' is not a whitespace as a white space. but part of the line ending. So in my understanding the "--ignore-whitespace" option shouldn't affect the line endings at all.
Fixes are possible, does anyone have a clue, why the '\r' is handled like this in apply ?
And out of interest: is this a real life problem ?