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

Re: git-apply that handles rejects like merge conflicts

From
Jeff King <peff@peff.net>
Date
Nov 8, 2011, 16:10 UTC
Message-ID
<20111108161014.GA14049@sigill.intra.peff.net>
In-Reply-To
<CAKPyHN1cqG9-g1Q4iGbUOtfiXLc6EPcFH2cWNCep3af4cTdzSg@mail.gmail.com>
On Tue, Nov 08, 2011 at 09:52:26AM +0100, Bert Wesarg wrote:
Show 10 quoted lines
> On Mon, Nov 7, 2011 at 23:55, Jeff King <peff@peff.net> wrote:
> > In the general case, you can't represent all failed hunks with conflict
> > markers, can you? I'm thinking something where we couldn't find any
> > relevant context. You know the lines from the original patch from the
> > hunk header, so you can drop the failed content from the patch in the
> > right spot. But how do you know how big a conflict marker to make for
> > the "current" side? The same number of lines as were in the hunk?
> > I think you'd end up with confusing conflict markers.
> 
> GNU patch can produce conflict markers with the --merge option.

Hmm. Yeah, it does work, but as I feared, it can produce pretty awful conflicts. Try this fairly straightforward setup (3 lines changed in the middle of a file):

  git init &&
  seq 1 10 >file && git add file && git commit -m base &&
  sed -i '3,5s/$/ master/' file && git commit -a -m master &&
  git checkout -b other HEAD^ &&
  sed -i '3,5s/$/ other/' file && git commit -a -m other
You can see what a real merge looks like:
  git merge master &&
  $EDITOR file
which is:
  1
  2
  <<<<<<< HEAD
  3 other
  4 other
  5 other
  =======
  3 master
  4 master
  5 master
  >>>>>>> master
  6
  7
  8
  9
  10

If you use "patch --merge", you get the same thing. Which is good. But now try it with 10 lines changed out of 100:

  rm -rf .git
  git init &&
  seq 1 100 >file && git add file && git commit -m base &&
  sed -i '50,60s/$/ master/' file && git commit -a -m master &&
  git checkout -b other HEAD^ &&
  sed -i '50,60s/$/ other/' file && git commit -a -m other

Doing a merge will get you the same sensible results. But "patch --merge" produces:

 ...
 45
 46
 <<<<<<<
 =======
 47
 48
 49
 50 master
 ...
 60 master
 61
 62
 63
 >>>>>>>
 47
 48
 49
 50 other
 51 other
 52 other
 53 other
 ...

which is not that helpful. Interestingly, I think it _should_ be able to do the same thing here as it did on the 3-line case. So I'm not sure why it doesn't.

But there are even more complex cases, like say "other" had added new lines of new content at the beginning of the file, and messed up the context lines that the patch was using. So I think in the general case, you will end up with patches like the latter one. Just shoving the patch hunk into the file with an empty preimage section. And that can even still be useful, but you are relying on line counts then. If they're off, it's going ot be quite confusing.

-Peff
Previous: Bert Wesarg
Message 10 of 10 in “git-apply that handles rejects like merge conflicts”
  1. Ori AvtalionNov 7, 2011
  2. Jeff KingNov 7, 2011
  3. Ori AvtalionNov 7, 2011
  4. Junio C HamanoNov 7, 2011
  5. Jeff KingNov 8, 2011
  6. Junio C HamanoNov 8, 2011
  7. Ori AvtalionNov 8, 2011
  8. Jeff KingNov 8, 2011
  9. Bert WesargNov 8, 2011
  10. Jeff KingNov 8, 2011

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.