I noticed that when I have, in my git repository, a file with CRLF line endings, and I try to create and apply a patch which changes this file, it fails.
This is a simple way to reproduce the problem:
$ git init
$ echo -en "foo\r\nbar\r\n" > a.txt
$ git add a.txt
$ git commit -m 'first commit'
$ echo -en "abcd\r\n" >> a.txt
$ git commit -a -m 'second commit'
$ git format-patch -1 HEAD
$ git checkout HEAD~
$ git am 0001-second-commit.patch
Applying: second commit
error: patch failed: a.txt:1
error: a.txt: patch does not apply
Patch failed at 0001 second commit
hint: Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
What causes this problem? How can I avoid it?
CodePudding user response:
TL;DR: use git am --keep-cr
.
The patch itself, in 0001-second-commit.patch
, says, in effect: expect the last line to read bar
plus a carriage return; add after that another line, also with a carriage return, but the "mail splitting" process that git am
uses on a mailbox removes both carriage returns. Hence the internal git apply
step that git am
runs at this point effectively goes: Whoa, wait, hold on a minute! The original text here doesn't match! I'd better fail and make the human help out.
To fix this, tell git am
to invoke the mail splitting process differently. By default, git mailsplit
treats carriage returns at ends of lines as mistakes made by some email software, and removes them. The --keep-cr
option tells git mailsplit
that no, it's not a mistake: please keep those carriage turns. This option is also offered by git am
itself, and git am
(but not git mailsplit
) has a configuration knob to turn it on by default: am.keepcr
can be set to true
.
If you've configured am.keepcr
to true
and want to override it temporarily, git am
has --no-keep-cr
as well.