14

Standard linux patch hard-coded only for unix text files.

PS: I do no want convert ALL to unix and then convert result back.

Braiam
  • 1
  • 11
  • 47
  • 78
vitaly.v.ch
  • 2,485
  • 4
  • 26
  • 36

5 Answers5

18

I've run into this problem before a few times. This is what I've discovered:

  • The Linux patch command will not recognize a patchfile that has CRLF in the patch 'meta-lines'.
  • The line-endings of the actual patch content must match the line endings of files being patched.

So this is what I did:

  1. Use dos2unix to convert patch files to LF line-endings only.
  2. Use dos2unix to convert the files being patched to LF line-endings only.
  3. Apply patch.

You can use unix2dos to convert patched files back to CRLF line-endings if you want to maintain that convention.

cscrimge
  • 385
  • 2
  • 9
18

Use the --binary option. Here is the relevant snippet from the man page:

  --binary
      Write all files in binary mode, except for standard output and /dev/tty.  When reading, disable
      the heuristic for transforming CRLF line endings into LF line endings.  This option  is  needed
      on  POSIX systems when applying patches generated on non-POSIX systems to non-POSIX files.  (On
      POSIX systems, file reads and writes never transform line endings. On Windows, reads and writes
      do  transform  line  endings  by default, and patches should be generated by diff --binary when
      line endings are significant.)
Ben in Seattle
  • 189
  • 1
  • 2
  • This seems like the best option. +1. Too bad there isn't (?) something like: try to patch without the binary flag, and for those that fail retry with binary the binary flag. – Qtax Dec 09 '14 at 13:10
  • Seems weird that "patch < file.patch" and "patch -R < file.patch" does not restore the files back to their original state. What were the authors of diff and patch thinking when they decided that was the way to go? Thank you though, "patch --binary < file.patch" and "patch -R --binary < file.patch" does restore the files back to their original state, line endings and all. – Samuel Feb 09 '15 at 23:43
11

Combined:

dos2unix patchfile.diff
dos2unix $(grep 'Index:' patchfile.diff | awk '{print $2}')
patch --verbose -p0 -i patchfile.diff
unix2dos $(grep 'Index:' patchfile.diff | awk '{print $2}')

The last line depends on whether you want to keep the CRLFs or not.

M.

PS. This should've been a reply to cscrimge's post. DS.

Martin
  • 111
  • 2
1

This is a solution one of our guys came up with in our office, so I'm not taking credit for it but it works for me here.

We have a situation of mixed linux and windows line endings in the same file sometimes, and we also create patch files from windows and apply them on linux.

If you are experience a patch problem after creating your patch file on windows or you have mixed line endings then do this:

dos2unix patch-file dos2unix $(sed -n 's/^Index: //p' patch-file) patch -p0 -i patch-file

0

perl -i.bak -pe's/\R/\n/g' inputfile to convert any line ending to the standard.

Anonymous
  • 49,213
  • 1
  • 25
  • 19