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

Re: more merge strategies : feature request

From
Jeff King <peff@peff.net>
Date
Dec 2, 2008, 15:30 UTC
Message-ID
<20081202153036.GC15134@coredump.intra.peff.net>
In-Reply-To
<81bfc67a0812020628l53c209a6yca5a619d211b6bfc@mail.gmail.com>
On Tue, Dec 02, 2008 at 09:28:41AM -0500, Caleb Cushing wrote:
Show 12 quoted lines
> I'm afraid I don't fully understand your example
> 
> 
> lets say git merge foo bar
> foo          bar
> 1             1
> 2              8
> 3              3
> 4              4
> 5              5
> 6
> 7

I notice that you don't have a "merge base" here, which is an important part of determining conflicts. So if you are proposing to not look at the history at all, and just show all differences, then that is different from what I thought you meant.

Show 23 quoted lines
> lines 6 and 7 are new in foo line 2 has a conflict because the other
> head has an 8, history wise because of an early merge the other
> direction and fix, there was the 8 in foo and it was changed to a 2,
> when I merge back it will overwrite the 8 with  a 2. however I need
> the 8 to be the 8 and the 2 to be the 2. but I want the 6 and 7 in
> both.
>
> conflict would create a conflict
> 
> such as
> 
> foo
> 1
> <<<<<< bar
> 8
> ======
> 2
> >>>>>>  foo
> 3
> 4
> 5
> 6
> 7

OK, so assume we throw away history and just look at the diff between the two branches. How do we know that a conflict should be created for the 2 vs 8, but not for the added "6 7" at the end? I think you have to create a conflict marker for both and fix them up manually. Like:

    1
    <<<<<<< foo
    2
    =======
    8
    >>>>>>> bar
    3
    4
    5
    <<<<<<< foo
    6
    7
    =======
    >>>>>>> bar

The script below munges a diff into conflict markers (and created the output you see above). Note that it is very hacky and not very tested. And note that at this point this really has nothing to do with _git_ specifically, since we aren't even using history. This just generates conflict markers from two files. There may be a more mature tool that can accomplish the same thing (personally, I would use something like xxdiff to do an interactive merge in your case).

You can try it with:
  git config merge.conflict.driver 'perl /path/to/conflict.pl %A %B'
  echo '* merge=conflict' >.gitattributes

-->8 conflict.pl 8<-- #!/usr/bin/perl

use strict; use warnings qw(all FATAL);

my $fn1 = shift; my $fn2 = shift;

open(my $diff, '-|', qw(diff -U 999999), $fn1, $fn2)
  or die "unable to run diff: $!";
open(my $tmp, '>', "$fn1.tmp")
  or die "unable to open temporary file: $!";
select $tmp;
while(<$diff>) {
  last if /^@/;
}
sub start   { print "<<<<<<< $fn1\n" }
sub divider { print "=======\n" }
sub end     { print ">>>>>>> $fn2\n" }
my $conflict = 0;
while(<$diff>) {
  if (/^ (.*)/) {
    if    ($conflict == 0) { }
    elsif ($conflict == 1) { divider; end }
    elsif ($conflict == 2) { end }
    print $1, "\n";
    $conflict = 0;
  }
  elsif(/^-(.*)/) {
    if    ($conflict == 0) { start }
    elsif ($conflict == 1) { }
    elsif ($conflict == 2) { end; start }
    print $1, "\n";
    $conflict = 1;
  }
  elsif(/^\+(.*)/) {
    if    ($conflict == 0) { start; divider }
    elsif ($conflict == 1) { divider }
    elsif ($conflict == 2) { }
    print $1, "\n";
    $conflict = 2;
  }
}

if ($conflict == 0) { } elsif ($conflict == 1) { divider; end } elsif ($conflict == 2) { end }

close($tmp); rename "$fn1.tmp", $fn1; exit 1;

Previous: Caleb CushingNext: Leo Razoumov
Message 6 of 13 in “more merge strategies : feature request”
  1. Caleb CushingNov 29, 2008
  2. Andreas EricssonDec 1, 2008
  3. Caleb CushingDec 2, 2008
  4. Jeff KingDec 2, 2008
  5. Caleb CushingDec 2, 2008
  6. Jeff KingDec 2, 2008
  7. Leo RazoumovDec 2, 2008
  8. Caleb CushingDec 2, 2008
  9. Leo RazoumovDec 3, 2008
  10. Nanako ShiraishiDec 3, 2008
  11. Caleb CushingDec 3, 2008
  12. Junio C HamanoDec 4, 2008
  13. Nanako ShiraishiDec 4, 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.