44

I am trying to create a patch with the command

git diff sourcefile >/var/lib/laymab/overlay/category/ebuild/files/thepatch.patch

when I apply the patch, it gives me

$ patch -v
GNU patch 2.7.5

$ /usr/bin/patch -p1 </var/lib/laymab/overlay/category/ebuild/files/thepatch.patch
patching file sourcefile
Hunk #1 FAILED at 1 (different line endings).
Hunk #2 FAILED at 23 (different line endings).
Hunk #3 FAILED at 47 (different line endings).
Hunk #4 FAILED at 65 (different line endings).
Hunk #5 FAILED at 361 (different line endings).
5 out of 5 hunks FAILED -- saving rejects to file sourcefile.rej

I tried to apply dos2unix to both src file and patch file, but the message don't gone...

UPD: --ignore-whitespace doesn't help too

PATCH COMMAND:  patch -p1 -g0 -E --no-backup-if-mismatch --ignore-whitespace --dry-run -f < '/var/lib/layman/dotnet/dev-dotnet/slntools/files/remove-wix-project-from-sln-file-v2.patch'

=====================================================
checking file Main/SLNTools.sln
Hunk #1 FAILED at 14 (different line endings).
Hunk #2 FAILED at 49 (different line endings).
Hunk #3 FAILED at 69 (different line endings).
Hunk #4 FAILED at 102 (different line endings).
4 out of 4 hunks FAILED

UPD: found a very good article: https://stackoverflow.com/a/4425433/1709408

2
  • Try sed -i.bak -e 's/\r$//g' something. I don't think dos2unix handles mixed end-of-lines as aggressively as you may want. Commented Oct 29, 2015 at 18:57
  • 1
    Outright evil; if you have your patch with CF-LF line endings, same as files, it will first happily strip the CR from your patch, then throw a fit that line endings (which it just broke) don't match.
    – SF.
    Commented Feb 8, 2019 at 15:24

6 Answers 6

20

I had the same problem using the patchcommand that comes with MSYS2 on Windows. In my case both the source file and the patch had CRLF line-ending, and converting both to LF didn't work either. What worked was the following:

$ dos2unix patch-file.patch
$ patch -p1 < patch-file.patch
$ unix2dos modified-files...

patch will convert the line-endings to LF on all the patched files, so it's necessary to convert them back to CRLF.

Obs: the patch version I'm using is 2.7.5

3
  • 5
    This didn't work for me in Cygwin. What worked is applying dos2unix on a target file that was to be patched.
    – Danijel
    Commented Feb 4, 2020 at 10:32
  • 1
    For me it worked to just to apply unix2dos to the patch file before applying the patch. Commented Feb 19, 2021 at 16:01
  • 1
    it is working but it is very ugly.... It means that I have to do a script that extracts all files modified by the patch to apply the unix2dos command on each modified file. this is very sad. Commented Jun 29, 2022 at 16:21
11

You can usually work around this using the -l option:

use the -l or --ignore-whitespace option, which makes patch compare blank characters (i.e. spaces and tabs) loosely so that any nonempty sequence of blanks in the patch file matches any nonempty sequence of blanks in the input files

This is a standard feature (see POSIX patch description).

However, OP amended the question to comment on How line ending conversions work with git core.autocrlf between different operating systems, and added an example hinting that the problem is seen with files on Windows (in contrast to the Unix-style example). While patch tries to accommodate mismatches between CRLF and LF line-endings, it has a bias to presume that the latter is used. If the patch file had CRLF endings, while the files to be patched did not, it would recover as in this example log:

(Stripping trailing CRs from patch.)
patching file xterm.log.html
(Stripping trailing CRs from patch.)
patching file xterm.man
(Stripping trailing CRs from patch.)
patching file xtermcfg.hin

Checking the source code, in the similar function, GNU patch treats whitespace as space and Tab, with some special handling according to whether the lines have a trailing LF. CR is not mentioned. It does pay attention in check_line_endings, but uses that information only as part of a message to help diagnose a rejection. It strips the trailing CRs in pget_line unless the --binary option is given.

GNU patch does not have an option to tell it to transform a patch with LF endings into CRLF to apply to files whose line-endings are CRLF. To use it reliably for this case, the choices are

  • convert all of the files to use LF endings, or
  • convert all of the files to use CRLF endings and add the --binary option.
2
  • 5
    --ignore-whitespace (no second dash) doesn't help too, i updated question Commented Dec 3, 2015 at 9:39
  • 1
    Thanks, Thomas. Using your guidance, I ended up splitting my patch into files that have LF line endings and files that have CRLF line endings. Then used the patch --binary flag for the patch with CRLF. Context: creating a patch for the TCL 8.4.20 source when compiling with Visual Studio 2019 on Windows 10. The TCL source has a mixture of files with CRLF endings (e.g. Visual Studio project files and nmake makefiles) and files with LF endings (*.c and *.h files, etc.).
    – buzz3791
    Commented Jun 1, 2020 at 18:56
1

I tried all the solutions but they failed for some reason. Instead, I did the inverse by changing the line endings on the file I was trying to patch, patching, and then changing the line endings back in the file I patched.

dos2unix <file I was trying to patch>
patch <any flags you need -- I was just using -p1> < patchfile
unix2dos <file I was trying to patch>

Depending on your situation, you may need to do kind of the opposite:

unix2dos <file I was trying to patch>
patch <any flags you need -- I was just using -p1> < patchfile
dos2unix <file I was trying to patch>
-1

I had a similar problem on Cygwin. In my case the fix was to use -i flag instead of reading from the stdin.

The following failed with different line endings error:

patch -t -N -r - -p0 < patchfile

But the following succeeded:

patch -t -N -r - -p0 -i patchfile

I'm unsure of the cause, but leaving this here in case someone has the same issue.

1
  • 1
    Didn't work for me, on Cygwin too.
    – Danijel
    Commented Feb 4, 2020 at 10:33
-1

In my case it turned out that patch was called from a Strawberry Perl installation on this machine which came first in %PATH% (and patch was not installed in Cygwin at all).

In summary, I tried to apply a patch with another patch binary than the one the patch was created with.

I installed patch in Cygwin and called explicitly /usr/bin/patch - worked.

-1

I had the similar issue running Ubuntu on WSL.

The problem was, there were wrong line endings in the *.tar.gz archived files (CRLF instead of LF), and this archive was being extracted during the process and then the patch was being applied on the extracted files.

dos2unix didn't work on *.tar.gz archive, so I had to extract it manually, run dos2unix on the extracted files and then pack it again so it could be used by *NIX in my case... Pretty simple, took me only 2 days to figure out XD

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .