threads / discuss / 2419

Strange merge conflicts against earlier merge.

Subject: Strange merge conflicts against earlier merge.

## tl;dr

13 messages between Nov 10, 2005 and Nov 12, 2005.

replies: 12people: 5as markdown or json

Martin Langhoff· Nov 10, 2005, 00:38 UTC · lore

We are working with a series of closely related heads, and merging among them. I am sometimes finding merge conflicts that I don't think I should be seeing. Assuming two branches, 'local' and 'remote', where local has with remote before (*), and I have no conflicting changes in local...

 1 - pull and merge from remote. The merge touches file A, B and C
 2 - on local, develop on unrelated files O,P,Q, commit
 3 - pull and merge from remote. The merge touches file B, C and D. I
am sometimes seeing conflicts on file B and C, which was never touched
on local.
* - In the case i have, the ancestry before the merge is a bit
convoluted. AFAIK, this shouldn't affect us going forward. Both
branches have a common ancestor, though, and are now merging often
from remote to local.

We are using cogito for this, although on step 3 I have also tested with git-merge.sh and I get the same result. It could still be a problem related to how the merge on step 1 is recording the merge.

For an example, clone http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti and register also the http://locke.catalyst.net.nz/git/moodle.git#mdl-local branch. Create two heads:

 master: 214e6374d49e6d014f0ba6f159d585a3fe468909
 remote: 05059be73c9e09e22b98bc796be35c595e551ed6

On git-merge 'testing merge' master remote you'll see conflicts over mod/quiz/editlib.php -- doing the same with cg-merge gets an additional conflict on mod/quiz/export.php. Neither of those files were ever modified on local -- however, both merges brought in changes to the same lines of code.

I suspect this is because the merge itself is being considered a commit on the local branch. Fair enough -- git has no way of ensuring that I haven't slipped in a few changes of mine in the merge. OTOH, it's pretty unexpected to see this on files that are not one char different from the 'remote' branch. Am I doing something wrong?

cheers,
martin
Petr Baudis· Nov 10, 2005, 10:20 UTC · re: Martin Langhoff · lore

Re: Strange merge conflicts against earlier merge.

Dear diary, on Thu, Nov 10, 2005 at 01:38:35AM CET, I got a letter where Martin Langhoff <martin.langhoff@gmail.com> said that...

Show 11 quoted lines
> We are working with a series of closely related heads, and merging
> among them. I am sometimes finding merge conflicts that I don't think
> I should be seeing. Assuming two branches, 'local' and 'remote', where
> local has with remote before (*), and I have no conflicting changes in
> local...
> 
>  1 - pull and merge from remote. The merge touches file A, B and C
>  2 - on local, develop on unrelated files O,P,Q, commit
>  3 - pull and merge from remote. The merge touches file B, C and D. I
> am sometimes seeing conflicts on file B and C, which was never touched
> on local.
Interesting. Could you check what the merge base is?
	git-merge-base local remote
It should be the merge from (1).
Show 5 quoted lines
> For an example, clone
> http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti and
> register also the
> http://locke.catalyst.net.nz/git/moodle.git#mdl-local branch. Create
> two heads:
Could you please run git-update-server-info over there?
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
Martin Langhoff· Nov 11, 2005, 04:40 UTC · re: Petr Baudis · lore

Re: Strange merge conflicts against earlier merge.

On 11/10/05, Petr Baudis <pasky@suse.cz> wrote:
Show 5 quoted lines
> Interesting. Could you check what the merge base is?
>
>         git-merge-base local remote
>
> It should be the merge from (1).
It seems to be actually one of the parents, not the merge itself.
Show 7 quoted lines
> > For an example, clone
> > http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti and
> > register also the
> > http://locke.catalyst.net.nz/git/moodle.git#mdl-local branch. Create
> > two heads:
>
> Could you please run git-update-server-info over there?
Should be fixed now...
cheers,
martin
Petr Baudis· Nov 11, 2005, 11:35 UTC · re: Martin Langhoff · lore

Re: Strange merge conflicts against earlier merge.

Dear diary, on Fri, Nov 11, 2005 at 05:40:05AM CET, I got a letter where Martin Langhoff <martin.langhoff@gmail.com> said that...

Show 10 quoted lines
> On 11/10/05, Petr Baudis <pasky@suse.cz> wrote:
> > > For an example, clone
> > > http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti and
> > > register also the
> > > http://locke.catalyst.net.nz/git/moodle.git#mdl-local branch. Create
> > > two heads:
> >
> > Could you please run git-update-server-info over there?
> 
> Should be fixed now...
I still have trouble cloning:

$ cg-clone http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti defaulting to local storage area warning: templates not found /home/xpasky/share/git-core/templates/ 12:13:31 URL:http://locke.catalyst.net.nz/git/moodle.git/refs/heads/mdl-artena-tairawhiti [41/41] -> ".git/refs/heads/.origin-fetching" [1] progress: 3 objects, 860 bytes Getting alternates list progress: 4 objects, 1934 bytes Getting pack list progress: 19 objects, 12532 bytes error: The requested URL returned error: 404 error: Unable to find 214e6374d49e6d014f0ba6f159d585a3fe468909 under http://locke.catalyst.net.nz/git/moodle.git/

Cannot obtain needed commit 214e6374d49e6d014f0ba6f159d585a3fe468909 while processing commit 6d32aa8241387e58ffd0e18862114add0d20d686. cg-fetch: objects fetch failed cg-clone: fetch failed

PS: Do I understand it right that git-clone can't clone just a single
head?
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
Fredrik Kuivinen· Nov 11, 2005, 07:52 UTC · re: Martin Langhoff · lore

Re: Strange merge conflicts against earlier merge.

On Thu, Nov 10, 2005 at 01:38:35PM +1300, Martin Langhoff wrote:
Show 42 quoted lines
> We are working with a series of closely related heads, and merging
> among them. I am sometimes finding merge conflicts that I don't think
> I should be seeing. Assuming two branches, 'local' and 'remote', where
> local has with remote before (*), and I have no conflicting changes in
> local...
> 
>  1 - pull and merge from remote. The merge touches file A, B and C
>  2 - on local, develop on unrelated files O,P,Q, commit
>  3 - pull and merge from remote. The merge touches file B, C and D. I
> am sometimes seeing conflicts on file B and C, which was never touched
> on local.
> 
> * - In the case i have, the ancestry before the merge is a bit
> convoluted. AFAIK, this shouldn't affect us going forward. Both
> branches have a common ancestor, though, and are now merging often
> from remote to local.
> 
> We are using cogito for this, although on step 3 I have also tested
> with git-merge.sh and I get the same result.  It could still be a
> problem related to how the merge on step 1 is recording the merge.
> 
> For an example, clone
> http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti and
> register also the
> http://locke.catalyst.net.nz/git/moodle.git#mdl-local branch. Create
> two heads:
> 
>  master: 214e6374d49e6d014f0ba6f159d585a3fe468909
>  remote: 05059be73c9e09e22b98bc796be35c595e551ed6
> 
> On git-merge 'testing merge' master remote you'll see conflicts over
> mod/quiz/editlib.php -- doing the same with cg-merge gets an
> additional conflict on mod/quiz/export.php. Neither of those files
> were ever modified on local -- however, both merges brought in changes
> to the same lines of code.
> 
> I suspect this is because the merge itself is being considered a
> commit on the local branch. Fair enough -- git has no way of ensuring
> that I haven't slipped in a few changes of mine in the merge. OTOH,
> it's pretty unexpected to see this on files that are not one char
> different from the 'remote' branch. Am I doing something wrong?
> 
This merge has two common ancestors, 
    $ git-merge-base --all master remote
    3b12fc6420c26a6556c2d806fca79dd96e8e22b9
    2163a9076d9515f00494ba9df7dbc85c9804790f

This may explain the results you get with cg-merge, as that script seems to use 'git-merge-base' without the '--all' flag.

It really seems to be the case that there is a real conflict in mod/quiz/editlib.php, this can be visualized nicely with

    gitk master remote -- mod/quiz/editlib.php
- Fredrik
Petr Baudis· Nov 11, 2005, 11:45 UTC · re: Fredrik Kuivinen · lore

Re: Strange merge conflicts against earlier merge.

Dear diary, on Fri, Nov 11, 2005 at 08:52:57AM CET, I got a letter where Fredrik Kuivinen <freku045@student.liu.se> said that...

Show 52 quoted lines
> On Thu, Nov 10, 2005 at 01:38:35PM +1300, Martin Langhoff wrote:
> > We are working with a series of closely related heads, and merging
> > among them. I am sometimes finding merge conflicts that I don't think
> > I should be seeing. Assuming two branches, 'local' and 'remote', where
> > local has with remote before (*), and I have no conflicting changes in
> > local...
> > 
> >  1 - pull and merge from remote. The merge touches file A, B and C
> >  2 - on local, develop on unrelated files O,P,Q, commit
> >  3 - pull and merge from remote. The merge touches file B, C and D. I
> > am sometimes seeing conflicts on file B and C, which was never touched
> > on local.
> > 
> > * - In the case i have, the ancestry before the merge is a bit
> > convoluted. AFAIK, this shouldn't affect us going forward. Both
> > branches have a common ancestor, though, and are now merging often
> > from remote to local.
> > 
> > We are using cogito for this, although on step 3 I have also tested
> > with git-merge.sh and I get the same result.  It could still be a
> > problem related to how the merge on step 1 is recording the merge.
> > 
> > For an example, clone
> > http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-tairawhiti and
> > register also the
> > http://locke.catalyst.net.nz/git/moodle.git#mdl-local branch. Create
> > two heads:
> > 
> >  master: 214e6374d49e6d014f0ba6f159d585a3fe468909
> >  remote: 05059be73c9e09e22b98bc796be35c595e551ed6
> > 
> > On git-merge 'testing merge' master remote you'll see conflicts over
> > mod/quiz/editlib.php -- doing the same with cg-merge gets an
> > additional conflict on mod/quiz/export.php. Neither of those files
> > were ever modified on local -- however, both merges brought in changes
> > to the same lines of code.
> > 
> > I suspect this is because the merge itself is being considered a
> > commit on the local branch. Fair enough -- git has no way of ensuring
> > that I haven't slipped in a few changes of mine in the merge. OTOH,
> > it's pretty unexpected to see this on files that are not one char
> > different from the 'remote' branch. Am I doing something wrong?
> > 
> 
> This merge has two common ancestors, 
> 
>     $ git-merge-base --all master remote
>     3b12fc6420c26a6556c2d806fca79dd96e8e22b9
>     2163a9076d9515f00494ba9df7dbc85c9804790f
> 
> This may explain the results you get with cg-merge, as that script
> seems to use 'git-merge-base' without the '--all' flag.
Hmm. So what should I do with that? :-)

I wondered about adding multi-base merge support to Cogito, but it seems to be a bit funny, and totally undocumented. Especially, is it right that I would end up with _four_ stages in case of two-base "three"-way merge? That would mean complete rewrite of the one-file merger, right? And it seems git-merge-index would overflow and crash. :-)

I guess I really don't want to do that, but instead choose one of the bases. Hmm. Well, I suppose it's as good as anything to leave this decision on the user. Kind of:

	if [ $(wc -l merge-bases) -ge 1 ]; then
		echo "Multiple merge bases, please select one by the -b parameter:" >&2
		cat merge-bases
		echo -n "The most conservative base (but likely a lot of conflicts):" >&2
		while true; do
			git-merge-base --all $(cat merge-bases) >merge-bases~
			mv merge-bases~ merge-bases
			[ $(wc -l merge-bases) -eq 1 ] && break
		done
		cat merge-bases
		exit 1
	fi

Does core GIT have support for multibase merges, except for the recursive merge strategy? How do you do it?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
Petr Baudis· Nov 11, 2005, 13:12 UTC · re: Petr Baudis · lore

Re: Strange merge conflicts against earlier merge.

Dear diary, on Fri, Nov 11, 2005 at 12:45:11PM CET, I got a letter where Petr Baudis <pasky@suse.cz> said that...

Show 16 quoted lines
> I guess I really don't want to do that, but instead choose one of the
> bases. Hmm. Well, I suppose it's as good as anything to leave this
> decision on the user. Kind of:
> 
> 	if [ $(wc -l merge-bases) -ge 1 ]; then
> 		echo "Multiple merge bases, please select one by the -b parameter:" >&2
> 		cat merge-bases
> 		echo -n "The most conservative base (but likely a lot of conflicts):" >&2
> 		while true; do
> 			git-merge-base --all $(cat merge-bases) >merge-bases~
> 			mv merge-bases~ merge-bases
> 			[ $(wc -l merge-bases) -eq 1 ] && break
> 		done
> 		cat merge-bases
> 		exit 1
> 	fi

I just did something in this style. Since I'm unable to get the repository, could someone please test it?

I'll try to come up with some automated testcase later.
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
Junio C Hamano· Nov 11, 2005, 17:29 UTC · re: Petr Baudis · lore

Re: Strange merge conflicts against earlier merge.

Petr Baudis <pasky@suse.cz> writes:
> Does core GIT have support for multibase merges, except for the
> recursive merge strategy? How do you do it?

There were lengthy discussion on this and a lot of work that went into the resolution. We do three things.

 - The first implementation does a trial read-tree 3-way using
   each of the base candidates without smudging the working
   tree, and counts paths that need file-level merges, to guess
   the best base, and uses that base.  This is in the 'stupid'
   stratagy.
 - The above turned out to have a risky corner case, especially
   when one side reverted a patch and the other one did not.  To
   address this, read-tree was rewritten and 3-way form of
   read-tree can take more than three trees these days, letting
   you feed it all the merge base candidates.  This code is used
   in 'resolve' strategy.
 - The 'recursive' strategy tries to come up with a merge of the
   candidate bases and uses it as the base of the final merge.
Petr Baudis· Nov 11, 2005, 17:32 UTC · re: Junio C Hamano · lore

Re: Strange merge conflicts against earlier merge.

Dear diary, on Fri, Nov 11, 2005 at 06:29:10PM CET, I got a letter where Junio C Hamano <junkio@cox.net> said that...

Show 6 quoted lines
>  - The above turned out to have a risky corner case, especially
>    when one side reverted a patch and the other one did not.  To
>    address this, read-tree was rewritten and 3-way form of
>    read-tree can take more than three trees these days, letting
>    you feed it all the merge base candidates.  This code is used
>    in 'resolve' strategy.

Yes, but what I didn't find out is whether the additional trees result in additional stages, what are the trivial merging rules, how does it play together with git-merge-index, etc. Doesn't seem to be documented either.

Thanks,
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
Petr Baudis· Nov 11, 2005, 21:56 UTC · lore

Re: Strange merge conflicts against earlier merge.

Dear diary, on Fri, Nov 11, 2005 at 07:38:19PM CET, I got a letter where Junio C Hamano <junkio@cox.net> said that...

Show 7 quoted lines
> Petr Baudis <pasky@suse.cz> writes:
> > Yes, but what I didn't find out is whether the additional trees result
> > in additional stages, what are the trivial merging rules, how does it
> > play together with git-merge-index, etc. Doesn't seem to be documented
> > either.
> 
> Documentation/technical/ perhaps?

This contains the merge resolution tables, which is very useful - thanks for that.

However, it still doesn't seem to answer my question - do the additional trees result in additional stages? Let's take e.g.:

	16    anc1/anc2 anc1    anc2      no merge

What ends up in the index at this moment as "stage 1"? anc1? anc2? Two stage 1 entries? And what does git-merge-index do about this?

Thanks,
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
Junio C Hamano· Nov 11, 2005, 22:39 UTC · re: Petr Baudis · lore

Re: Strange merge conflicts against earlier merge.

Petr Baudis <pasky@ucw.cz> writes:
> 	16    anc1/anc2 anc1    anc2      no merge
>
> What ends up in the index at this moment as "stage 1"? anc1? anc2?
> Two stage 1 entries? And what does git-merge-index do about this?

I think we decided there is no single sensible resolution, and we leave stage 1 empty.

Come to think of it, we should signal that we are punting by either exiting non-zero, or stuffing 0{40} SHA1 in stage1, so that we can distinguish the case with two sides adding things differently. Daniel, what do you think?

Daniel Barkalow· Nov 11, 2005, 23:33 UTC · re: Junio C Hamano · lore

Re: Strange merge conflicts against earlier merge.

On Fri, 11 Nov 2005, Junio C Hamano wrote:
Show 14 quoted lines
> Petr Baudis <pasky@ucw.cz> writes:
> 
> > 	16    anc1/anc2 anc1    anc2      no merge
> >
> > What ends up in the index at this moment as "stage 1"? anc1? anc2?
> > Two stage 1 entries? And what does git-merge-index do about this?
> 
> I think we decided there is no single sensible resolution, and
> we leave stage 1 empty.
> 
> Come to think of it, we should signal that we are punting by
> either exiting non-zero, or stuffing 0{40} SHA1 in stage1, so
> that we can distinguish the case with two sides adding things
> differently.  Daniel, what do you think?

Probably don't want to exit non-zero, since we can deal with the rest of the paths sensibly. All 0 SHA1 would work, if we want to identify this case. On the other hand, I think the desired behavior at present is to tell the user to pick the correct version of the two, which is the same as if it's new in both sides, which is why I had it like that.

Someday, we ought to do a combined merge-base and read-tree, which would be able to correctly handle revert wars, but it's too very exciting currently, since the multi-base merge cases have generally turned out to be user error (i.e., the user didn't actually mean to merge those things).

	-Daniel
*This .sig left intentionally blank*
Junio C Hamano· Nov 12, 2005, 00:50 UTC · re: Daniel Barkalow · lore

Re: Strange merge conflicts against earlier merge.

Daniel Barkalow <barkalow@iabervon.org> writes:
Show 12 quoted lines
> On Fri, 11 Nov 2005, Junio C Hamano wrote:
>
>> Come to think of it, we should signal that we are punting by
>> either exiting non-zero, or stuffing 0{40} SHA1 in stage1, so
>> that we can distinguish the case with two sides adding things
>> differently.  Daniel, what do you think?
>
> Probably don't want to exit non-zero, since we can deal with the rest of 
> the paths sensibly. All 0 SHA1 would work, if we want to identify this 
> case. On the other hand, I think the desired behavior at present is to 
> tell the user to pick the correct version of the two, which is the same as 
> if it's new in both sides, which is why I had it like that.

Yeah, and I have an updated merge-one-file in "pu" that tries to do a bit more interesting thing than just punting and asking the user, when both sides added different contents. I did not want to trigger that logic when we are doing case #16, and that was what my comment was about.

← back to recent threads