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

Re: Parsing diff --git lines

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Mar 9, 2008, 04:04 UTC
Message-ID
<alpine.LFD.1.00.0803081955110.5896@woody.linux-foundation.org>
In-Reply-To
<F4D3B820-CCF4-4212-BF32-700EFD448143@mac.com>
On Sat, 8 Mar 2008, Simon Fraser wrote:
> 
> However, I don't see a reliable way to identify the two files
> from a "diff --git" line. Here's a (deliberately pathological)
> example:
See how "git-apply" does it.
The rule is:
 - if the filenames are different, you should ignore the filenames on the 
   "diff --git" line, and trust the ones on the "renamed from/to" ones 
   (which are unambiguous because they only have one filename per line)
 - if the filenames aren't different, then you can unambiguously know how 
   to parse it by simply making sure they are the same.
So to take your example:
> diff --git a/a / b/file with spaces.txt b/a / b/file with spaces.txt

Here, you can *know* that the filename is "a / b/file with spaces.txt", because it must match the pattern "a/$filename b/$filename", and no other split at a space would ever do that!

See in particular "git_header_name()" in builtin-apply.c. See the comments both at the top of the function and there in the middle to reflect the above rule:

/*
 * This is to extract the same name that appears on "diff --git"
 * line.  We do not find and return anything if it is a rename
 * patch, and it is OK because we will find the name elsewhere.
 * We need to reliably find name only when it is mode-change only,
 * creation or deletion of an empty file.  In any of these cases,
 * both sides are the same name under a/ and b/ respectively.
 */
...
        /*
         * Accept a name only if it shows up twice, exactly the same
         * form.
         */
> What would make this possible would be either to always quote
> file paths containing spaces, or use a character other than
> a space (e.g. a \t) between the two file names.

Well, git didn't originally ever quote filenames at all, and I actually wanted the "diff --git" line to look as much like a regular "diff -urN" line as possible (which has spaces between the names)

These days, we could quote, but hey, anybody who parses diff lines needs to be able to handle the non-quoted form *anyway*, so quoting doesn't really help anybody in the end.

			Linus
Previous: Simon FraserNext: Jakub Narebski
Message 2 of 4 in “Parsing diff --git lines”
  1. Simon FraserMar 9, 2008
  2. Linus TorvaldsMar 9, 2008
  3. Jakub NarebskiMar 9, 2008
  4. Johannes SchindelinMar 9, 2008

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.