git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* needs merge
@ 2006-01-07  8:32 Len Brown
  2006-01-07  8:41 ` Junio C Hamano
  2006-01-07  8:57 ` Len Brown
  0 siblings, 2 replies; 7+ messages in thread
From: Len Brown @ 2006-01-07  8:32 UTC (permalink / raw)
  To: git

a merge results in multiple conflict files.

some of the files are resolved by editing and picking changes from both branches.

but some files I want to ignore the new changes and keep what was originally there.
However, if I restore what was originally in the destination
either by editing the destination and ending up with what i started with,
or via git checkout on the file, i get

$ git commit
my-file needs merge

how do i tell git that there is no merge to do and the (unchanged) working file is what
i want to keep as the result of the merge?

i recall running into this a long time ago and i added blank line to the destination file
and that made git happy, but maybe i shouldn't have to resort to that, yes?

thanks,
-Len

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: needs merge
  2006-01-07  8:32 needs merge Len Brown
@ 2006-01-07  8:41 ` Junio C Hamano
  2006-01-07  8:57 ` Len Brown
  1 sibling, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2006-01-07  8:41 UTC (permalink / raw)
  To: Len Brown; +Cc: git

Len Brown <len.brown@intel.com> writes:

> $ git commit
> my-file needs merge
>
> how do i tell git that there is no merge to do and the (unchanged) working file is what
> i want to keep as the result of the merge?

Do you mean running

    $ git update-index my-file

to mark the path resolved?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: needs merge
  2006-01-07  8:32 needs merge Len Brown
  2006-01-07  8:41 ` Junio C Hamano
@ 2006-01-07  8:57 ` Len Brown
  2006-01-07 10:28   ` Junio C Hamano
  1 sibling, 1 reply; 7+ messages in thread
From: Len Brown @ 2006-01-07  8:57 UTC (permalink / raw)
  To: git

> git-update-index my-file

yes, that allowed the git commit to complete, thanks.

however, when i then merged that branch into another there seem to
be some phantom conflicts on the very same files.
Do I understand all this output to mean that git attempted two
different merges, and discarded the 1st attempt in favor of the second?

thanks,
-Len

$ /lab/bin/git.merge acpica test
Merging test with ed03f430cdc8c802652467e9097606fedc2c7abc
Merging:
e3627f3165301a7d946c2dc40be93f744f441c30 Auto-update from upstream
ed03f430cdc8c802652467e9097606fedc2c7abc Pull pnpacpi into acpica branch
found 2 common ancestor(s):
0aec63e67c69545ca757a73a66f5dcf05fa484bf [PATCH] Fix posix-cpu-timers sched_time accumulation
ed349a8a0a780ed27e2a765f16cee54d9b63bfee [ACPI] fix pnpacpi regression resulting from ACPICA 20051117
  Merging:
  0aec63e67c69545ca757a73a66f5dcf05fa484bf [PATCH] Fix posix-cpu-timers sched_time accumulation
  ed349a8a0a780ed27e2a765f16cee54d9b63bfee [ACPI] fix pnpacpi regression resulting from ACPICA 20051117
  found 1 common ancestor(s):
  927fe18397b3b1194a5b26b1d388d97e391e5fd2 Pull 5165 into release branch
  Auto-merging arch/i386/kernel/mpparse.c
  Auto-merging include/asm-x86_64/mpspec.h
  Auto-merging arch/ia64/pci/pci.c
  Auto-merging drivers/acpi/utilities/utmisc.c
  CONFLICT (content): Merge conflict in drivers/acpi/utilities/utmisc.c
  Auto-merging include/acpi/acglobal.h
  CONFLICT (content): Merge conflict in include/acpi/acglobal.h
  Auto-merging drivers/acpi/scan.c
  Auto-merging drivers/acpi/pci_link.c

Merge bfaa3a0777f0fc3b82831cb1daf286f8ac3b4c8d, made by recursive.
 drivers/pnp/pnpacpi/rsparser.c |   48 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 44 insertions(+), 4 deletions(-)
$

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: needs merge
  2006-01-07  8:57 ` Len Brown
@ 2006-01-07 10:28   ` Junio C Hamano
  0 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2006-01-07 10:28 UTC (permalink / raw)
  To: Len Brown; +Cc: git

Len Brown <len.brown@intel.com> writes:

> however, when i then merged that branch into another there seem to
> be some phantom conflicts on the very same files.

First of all, does the final merge result look correct, without
conflict markers?  I've slurped from your tree and tried the
merge myself and it seems that both branches and the merge
result of these branches have the conflicting path the same way,
so I think it did the right thing for you, but I am just trying
to make sure.

> Do I understand all this output to mean that git attempted two
> different merges, and discarded the 1st attempt in favor of the second?

Not really.  This is Fredrik's "recursive" merge in action.

acpica (ed03f4) is merged into test (e3627f), but these two
branches have criss-cross merge history and there are two
equally valid common ancestors, 0aec63 and ed349a.

What it did was first to find a merge between these two common
ancestors, during which it found conflicting merge on those
paths.

It then used this merge result (with conflict markers still in
them!) as the "virtual common ancestor" to merge the ed03f4 and
e3627f commits; because both branches have resolved the
conflicting part the same way earlier, this three-way merge
cancels out the part that are marked with conflict markers in
the virtual common ancestor (this is the cutest part of Fredrik
merge algorithm).

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: needs merge
@ 2006-01-07 10:33 Brown, Len
  2006-01-07 21:06 ` Junio C Hamano
  0 siblings, 1 reply; 7+ messages in thread
From: Brown, Len @ 2006-01-07 10:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

yes, it did the right thing to the source.

as a user, "cute" isn't the first word that comes to mind:-)

thanks,
-Len 

>-----Original Message-----
>From: git-owner@vger.kernel.org 
>[mailto:git-owner@vger.kernel.org] On Behalf Of Junio C Hamano
>Sent: Saturday, January 07, 2006 5:29 AM
>To: Brown, Len
>Cc: git@vger.kernel.org
>Subject: Re: needs merge
>
>Len Brown <len.brown@intel.com> writes:
>
>> however, when i then merged that branch into another there seem to
>> be some phantom conflicts on the very same files.
>
>First of all, does the final merge result look correct, without
>conflict markers?  I've slurped from your tree and tried the
>merge myself and it seems that both branches and the merge
>result of these branches have the conflicting path the same way,
>so I think it did the right thing for you, but I am just trying
>to make sure.
>
>> Do I understand all this output to mean that git attempted two
>> different merges, and discarded the 1st attempt in favor of 
>the second?
>
>Not really.  This is Fredrik's "recursive" merge in action.
>
>acpica (ed03f4) is merged into test (e3627f), but these two
>branches have criss-cross merge history and there are two
>equally valid common ancestors, 0aec63 and ed349a.
>
>What it did was first to find a merge between these two common
>ancestors, during which it found conflicting merge on those
>paths.
>
>It then used this merge result (with conflict markers still in
>them!) as the "virtual common ancestor" to merge the ed03f4 and
>e3627f commits; because both branches have resolved the
>conflicting part the same way earlier, this three-way merge
>cancels out the part that are marked with conflict markers in
>the virtual common ancestor (this is the cutest part of Fredrik
>merge algorithm).
>
>-
>To unsubscribe from this list: send the line "unsubscribe git" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: needs merge
  2006-01-07 10:33 Brown, Len
@ 2006-01-07 21:06 ` Junio C Hamano
  2006-01-10  5:21   ` Daniel Barkalow
  0 siblings, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2006-01-07 21:06 UTC (permalink / raw)
  To: Brown, Len; +Cc: git, Daniel Barkalow

"Brown, Len" <len.brown@intel.com> writes:

> yes, it did the right thing to the source.
>
> as a user, "cute" isn't the first word that comes to mind:-)

Fair enough.  I agree that it is rather unnerving from the
user's point of view, especially because the "recursive merging
of the ancestors" part is not trivially obvious why it works.

The issue it tries to address (and the other merge strategy,
"resolve", addresses a bit differently) is to detect when two
sides of criss-cross merged branches resolved the same conflicts
differently in the past.  When merging E and F in this ancestry
graph:

             A----C---E----?
            / \  /        /
           /   \/        /
          /    /\       /
         /    /  \     /
        O----B----D---F

suppose that A and B made conflicting modifications on path P, C
and D resolved the conflicts by taking its own side, and E and F
further made independent changes to the path.  

When we try to merge E and F, if we happen to pick B as the
merge base, normal three-way merge between E and F using B as
base would say that E has change between B and C while F's
version stayed the same in the area that change touches, and you
would end up with merge result that is diff(D,F) on top of E.
If we used A, then the result would be diff(C,E) on top of F.
Doing either of these silently is not desirable [*1*].

When we use a tree that is an automerge (with conflict markers)
between A and B as the merge base for E and F, what happens is
that the three-way merge notices the part with conflict markers
as a whole is rewritten to one version in E and to another in F,
removes the original (which is the conflicting merge between A
and B) and replaces that with conflicts between E and F with its
own conflict markers, so decision to resolve the conflicting
merge between A and B which C and D resolved differently is
given to the user who tries to merge E and F.

If C and D resolved the conflicting merge the same way, the
"phantom conflict" you observed still happens while merging A
and B to come up with the merge base tree, but the part will be
rewritten the same way in both E and F, so the result will merge
cleanly.

[Footnote]

*1* While I was trying out the above scenario, I noticed that
resolve strategy does not notice this and ended up picking one
ancestor at random.  I think this is because case #16 covers
only the case where the path P is not changed between C and E
and D and F, and case #11 must pick an ancestor and picks one at
random.  Daniel, any thoughts on this?

-- >8 --
#!/bin/sh

unset GIT_DIR GIT_OBJECT_DIRECTORY
test -d .git || {
	echo Run this in a newly created empty directory please.
	exit 1
}

: <<\EOF

	Criss Cross Merge

             A----C---E----?
            / \  /        /
           /   \/        /
          /    /\       /
         /    /  \     /
        O----B----D---F

EOF

git init-db

for l in a b c d e f g h i j k l m n o p q r s t u v w x y z
do
	echo $l
done >testfile
git add testfile
git commit -m 'Initial'
git tag O
git branch bottom
git checkout -b top
cp testfile testfile.orig
tr 'm-p' 'M-P' <testfile.orig >testfile
git update-index testfile
git commit -m A
git tag A
git checkout bottom
tr 'm-p' 'A-D' <testfile.orig >testfile
git update-index testfile
git commit -m B
git tag B
git merge -s ours 'D=A+B=B' HEAD A
git tag D
git checkout top
git merge -s ours 'C=A+B=A' HEAD B
git tag C
mv testfile j; tr 'a' 'A' <j >testfile; rm -f j
git update-index testfile
git commit -m E
git tag E
git checkout bottom
mv testfile j; tr 'z' 'Z' <j >testfile; rm -f j
git update-index testfile
git commit -m F
git tag F

rm -f testfile.orig

git checkout master
git reset --hard A
git merge -s resolve V HEAD B
git update-index testfile
git commit -m 'V'
git tag V

git show-branch

git checkout top
echo "** RECURSIVE **"
git merge -s recursive recursive HEAD F
echo theirs
git diff --theirs
echo ours
git diff --ours

git reset --hard
echo "** RESOLVE **"
git merge -s resolve resolve HEAD F

echo theirs
git diff HEAD^2
echo ours
git diff HEAD^

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: needs merge
  2006-01-07 21:06 ` Junio C Hamano
@ 2006-01-10  5:21   ` Daniel Barkalow
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel Barkalow @ 2006-01-10  5:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Brown, Len, git

On Sat, 7 Jan 2006, Junio C Hamano wrote:

> *1* While I was trying out the above scenario, I noticed that
> resolve strategy does not notice this and ended up picking one
> ancestor at random.  I think this is because case #16 covers
> only the case where the path P is not changed between C and E
> and D and F, and case #11 must pick an ancestor and picks one at
> random.  Daniel, any thoughts on this?

Right; in this case, we really want to use a merge program that takes 
multiple ancestors and handles the equivalent to case #16 at the hunk 
level, but we don't have such a program available. Such a program would be 
able to identify whether case #16 ever actually occurs for a hunk, which 
is important because there will generally be a bunch of case #11s at the 
file level, even if there aren't any reverts (if the common ancestors 
disagreed before, and the two branches both changed the file to something 
entirely new, with no reverts, either ancestor is correct to use and the 
merge result will be useful; we only need to be careful if there were 
reverts somewhere, which leads to the possibility of false sharing between 
a branch and an ancestor, and thereby to ignoring the revert, and my 
feeling is that rejecting case #11 with divergant ancestors would lead to 
too many conflicts to make crossing merges useable).

One possibility, actually, is to steal a trick from the recursive 
strategy, and have a multi-ancestor merge program which merges all of the 
ancestors with a merge-style diff (i.e., merge output, but on diff instead 
of diff3, with all differences being conflicts), and then uses the result 
as the ancestor for the three-way merge. It seems to me that this would 
capture the central advantage of the recursive strategy without quite so 
much work. Or I might be completely wrong; I'm kind of worn out, and may 
not be thinking clearly.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-01-10  5:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-07  8:32 needs merge Len Brown
2006-01-07  8:41 ` Junio C Hamano
2006-01-07  8:57 ` Len Brown
2006-01-07 10:28   ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2006-01-07 10:33 Brown, Len
2006-01-07 21:06 ` Junio C Hamano
2006-01-10  5:21   ` Daniel Barkalow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).