Home > Back-end >  why I can't apply git patch when a file uses CRLF?
why I can't apply git patch when a file uses CRLF?

Time:03-12

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.

  •  Tags:  
  • git
  • Related