git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Inconsistent handling of corrupt patches based on line endings

From
René Scharfe <l.s.r@web.de>
Date
Oct 28, 2024, 22:07 UTC
Message-ID
<d74232a4-126d-4bd8-8f60-a3fac80492d5@web.de>
In-Reply-To
<CABPp-BFB+eG7WVJFm3EBfgKzuspAYn9KpDHodpgKuFmWefARBw@mail.gmail.com>
Am 28.10.24 um 19:39 schrieb Elijah Newren:
Show 42 quoted lines
> On Mon, Oct 28, 2024 at 11:11 AM Taylor Blau <me@ttaylorr.com> wrote:
>>
>> On Mon, Oct 28, 2024 at 05:57:54PM +0100, Peregi Tamás wrote:
>>> Hi all,
>>>
>>> I might've found an inconsistency in how git-apply treats corrupt patches
>>> (representing empty context lines with completely empty lines instead of
>>> lines containing a single space - usually a result of a "trim trailing
>>> whitespace" editor setting) based on whether the patch file uses
>>> Windows-style line endings (CRLF) or Unix-style line endings (LF only).
>
> I believe this behavior was caused by:
>
> $ git log -1 b507b465f7831612b9d9fc643e3e5218b64e5bfa
> commit b507b465f7831612b9d9fc643e3e5218b64e5bfa
> Author: Linus Torvalds <torvalds@linux-foundation.org>
> Date:   Thu Oct 19 19:26:08 2006 -0700
>
>     git-apply: prepare for upcoming GNU diff -u format change.
>
>     The latest GNU diff from CVS emits an empty line to express
>     an empty context line, instead of more traditional "single
>     white space followed by a newline".  Do not get broken by it.
>
>     Signed-off-by: Linus Torvalds <torvalds@osdl.org>
>     Signed-off-by: Junio C Hamano <junkio@cox.net>
>
> That code special-cased a line containing '\n' but not a line
> containing only '\r\n'.
>
> As to whether that's correct, personally I'd rather only special case
> workaround important existing clients.  Back in 2006, working with GNU
> diff was incredibly important, and I'd say is still important today.
> I can see Peregi's comment that this make line ending slightly
> inconsistent, but I feel like the blank-line handling is a workaround
> for an existing client we want to interoperate with and absent a
> similar important client with mis-behaving '\r\n'-only lines, I
> wouldn't be interested in adding support for it.  But that's just my
> off-the-cuff feeling and I don't feel strongly about it.  Further, all
> but one of my contributions above were mere header changes, so if
> others have other opinions, they should probably be weighted more
> heavily than mine on this topic.
What would the patch(1) do?

The first column is the exit code of the subsequent command (0: success, 1: one or more rejected lines, 2: failure):

0 patch -p1 --dry-run original-unix.txt <corrupt-unix.patch 0 patch -p1 --dry-run original-unix.txt <intact-unix.patch 0 patch -p1 --dry-run original-win.txt <intact-win.patch 0 patch --ignore-whitespace -p1 --dry-run original-unix.txt <corrupt-unix.patch 0 patch --ignore-whitespace -p1 --dry-run original-unix.txt <intact-unix.patch 0 patch --ignore-whitespace -p1 --dry-run original-unix.txt <intact-win.patch 0 patch --ignore-whitespace -p1 --dry-run original-win.txt <corrupt-unix.patch 0 patch --ignore-whitespace -p1 --dry-run original-win.txt <intact-unix.patch 0 patch --ignore-whitespace -p1 --dry-run original-win.txt <intact-win.patch 1 patch -p1 --dry-run original-unix.txt <intact-win.patch 1 patch -p1 --dry-run original-win.txt <corrupt-unix.patch 1 patch -p1 --dry-run original-win.txt <intact-unix.patch 2 patch -p1 --dry-run original-unix.txt <corrupt-win.patch 2 patch -p1 --dry-run original-win.txt <corrupt-win.patch 2 patch --ignore-whitespace -p1 --dry-run original-unix.txt <corrupt-win.patch 2 patch --ignore-whitespace -p1 --dry-run original-win.txt <corrupt-win.patch

So basically the same as git apply?
What does current GNU diff do?

diff -u <(printf 'a\n\n') <(printf 'b\n\n') | tail -1 | od -a 0000000 sp nl 0000002 diff -u --suppress-blank-empty <(printf 'a\n\n') <(printf 'b\n\n') | tail -1 | od -a 0000000 nl 0000001 diff -u <(printf 'a\r\n\r\n') <(printf 'b\r\n\r\n') | tail -1 | od -a 0000000 sp cr nl 0000003 diff -u --suppress-blank-empty <(printf 'a\r\n\r\n') <(printf 'b\r\n\r\n') | tail -1 | od -a 0000000 sp cr nl 0000003

So it omits the space only if --suppress-blank-empty is given and the blank line ends with \n, not with \r\n.

Anyway, I agree with Elijah: The targeted support for GNU diff's eccentricity is fine, and we're in good company with that. We could remove it, since it doesn't seem to be the default (anymore?), but I don't see much of a benefit. We could add support for blank context lines that end in CRLF if there's a notable source of that kind of that deviation from the original format.

René
Previous: Elijah NewrenNext: Junio C Hamano
Message 4 of 6 in “Inconsistent handling of corrupt patches based on line endings”
  1. Peregi TamásOct 28, 2024
  2. Taylor BlauOct 28, 2024
  3. Elijah NewrenOct 28, 2024
  4. René ScharfeOct 28, 2024
  5. Junio C HamanoOct 28, 2024
  6. Torsten BögershausenOct 29, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.