merge between two branches fails

Bug #244115 reported by Steve Kowalik
2
Affects Status Importance Assigned to Milestone
Bazaar
Confirmed
Undecided
Unassigned
Breezy
Triaged
Low
Unassigned

Bug Description

I tried to merge two branches that I thought were the same, and turns out they aren't the same at all. Attaching version-info for both branches, and the output of bzr merge.

steven@liquified:.../libmokoui2/ubuntu% bzr version-info
revision-id: <email address hidden>
date: 2008-04-19 03:00:27 +1000
build-date: 2008-06-30 13:32:23 +1000
revno: 10
branch-nick: ubuntu

steven@liquified:.../libmokoui2/trunk% bzr version-info
revision-id: <email address hidden>
date: 2008-04-10 14:45:39 +0000
build-date: 2008-06-30 13:32:32 +1000
revno: 61
branch-nick: trunk

steven@liquified:.../libmokoui2/ubuntu% bzr merge -r 60..61 ../trunk
+N ChangeLog.OTHER
+N libmokoui/
+N libmokoui/moko-finger-scroll.c.OTHER
R libmokoui/ => libmokoui.moved/
Contents conflict in ChangeLog
Conflict adding files to libmokoui. Created directory.
Conflict because libmokoui is not versioned, but has versioned children. Versioned directory.
Conflict adding file libmokoui. Moved existing file to libmokoui.moved.
Contents conflict in libmokoui/moko-finger-scroll.c
5 conflicts encountered.
zsh: exit 1 bzr merge -r 60..61 ../trunk

Tags: merge
Revision history for this message
Martin Pool (mbp) wrote :

What did you expect would happen?

If the branches are public could you please attach their url?

Changed in bzr:
status: New → Incomplete
Revision history for this message
Robert Collins (lifeless) wrote :

Its these lines here:
Conflict adding files to libmokoui. Created directory.
Conflict because libmokoui is not versioned, but has versioned children. Versioned directory.

That I think show a bug - because both branches have libmokoui; even though the file ids conflict we shouldn't be seeing any unversioned directories.

Changed in bzr:
status: Incomplete → Confirmed
Revision history for this message
Aaron Bentley (abentley) wrote : Re: [Bug 244115] Re: merge between two branches fails

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Robert Collins wrote:
> Its these lines here:
> Conflict adding files to libmokoui. Created directory.
> Conflict because libmokoui is not versioned, but has versioned children. Versioned directory.
>
> That I think show a bug - because both branches have libmokoui; even
> though the file ids conflict we shouldn't be seeing any unversioned
> directories.

It's behaving the way it was designed to work. I don't see that as a bug.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIaRKu0F+nu1YWqI0RAtqDAJ9ykAEvcrjj6V+PdWtwe4ZUCoHvUACfXaIJ
/LLDIRXwj+gffsqR46hU78Q=
=lbO4
-----END PGP SIGNATURE-----

Revision history for this message
Robert Collins (lifeless) wrote :

To expand on Aaron's comment:
 Whiel both trees have libmokoui before the merge, it is a cherrypick merge, which means that the mkdir() of libmokoui in trunk is not being copied across by the merge code. So the libmokoui directory is not being copied across.

One thing that I think we could tweak to improve matters, is that when this happens (the parent not being propogated), rather than moving the existing directory to NAME.moved, and creating a new NAME with only the merged files in it, we should keep the existing directory as NAME, and create the directory-with-the-missing-id as NAME.conflicts. This would stop the user having to rename them back into place.

Revision history for this message
Aaron Bentley (abentley) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Robert Collins wrote:
> To expand on Aaron's comment:
> Whiel both trees have libmokoui before the merge, it is a cherrypick merge, which means that the mkdir() of libmokoui in trunk is not being copied across by the merge code. So the libmokoui directory is not being copied across.
>
> One thing that I think we could tweak to improve matters, is that when
> this happens (the parent not being propogated), rather than moving the
> existing directory to NAME.moved, and creating a new NAME with only the
> merged files in it, we should keep the existing directory as NAME, and
> create the directory-with-the-missing-id as NAME.conflicts. This would
> stop the user having to rename them back into place.

The theory has always been that it's easier to revert a change than to
perform an action. So if only one of THIS and OTHER can have the name
"libmoku", we give it to the OTHER copy.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIaVgI0F+nu1YWqI0RAq6rAJ0ZvKyXTI6gvlWX6S+QMPzrPlbf+gCdHTLi
fYTnvnwAG/TZwptOsDtUkfQ=
=m4YU
-----END PGP SIGNATURE-----

Revision history for this message
Robert Collins (lifeless) wrote :

On Mon, 2008-06-30 at 22:02 +0000, Aaron Bentley wrote:

> > One thing that I think we could tweak to improve matters, is that when
> > this happens (the parent not being propogated), rather than moving the
> > existing directory to NAME.moved, and creating a new NAME with only the
> > merged files in it, we should keep the existing directory as NAME, and
> > create the directory-with-the-missing-id as NAME.conflicts. This would
> > stop the user having to rename them back into place.
>
> The theory has always been that it's easier to revert a change than to
> perform an action. So if only one of THIS and OTHER can have the name
> "libmoku", we give it to the OTHER copy.

In general I agree. However, the user has to take an action no matter
what here - they have two 'NAME' directories, one which we have
synthesised.

I think in the vast majority of instances of this case what people will
want (expressed as bzr commands on top of our _current_ behaviour) is
essentially:
 bzr mv NAME NAME.wrong
 bzr mv NAME.moved NAME
 bzr mv NAME.wrong/* NAME/

-Rob
--
GPG key available at: <http://www.robertcollins.net/keys.txt>.

Revision history for this message
John A Meinel (jameinel) wrote :

I agree that they want the entries in the directory to be "collapsed" together. Thinking closely about it, though, if we collapse things into the value in OTHER, it is actually better overall.

The reason is that the value then propagates. So if I do:

  cd branch1
  bzr merge ../branch2 # I now get branch2's file-id for NAME
  bzr commit -m "resolved some stuff"

  cd ../branch2
  bzr merge ../branch1 # No conflicts, because we are using the same file-ids.

However if you do the opposite:

  cd branch1
  bzr merge ../branch2 # Merge, but keep branch1's file-id for NAME
  bzr commit -m "Include branch2's changes."

  cd ../branch2
  bzr merge ../branch1 # Conflict *again*, but again resolve in favor of THIS
  bzr commit -m "bring in branch1"

  cd ../branch1
  bzr merge ../branch2 # Conflict *again* ...

I ran into this when working on "annotate". If in doubt, take "OTHER" because that "spreads" it to everyone, and eventually everyone agrees. If you always resolve in favor of THIS, then everyone always disagrees.

Revision history for this message
Robert Collins (lifeless) wrote :

On Tue, 2008-07-01 at 01:21 +0000, John A Meinel wrote:
> I agree that they want the entries in the directory to be "collapsed"
> together. Thinking closely about it, though, if we collapse things into
> the value in OTHER, it is actually better overall.
>
> The reason is that the value then propagates. So if I do:
>
> cd branch1
> bzr merge ../branch2 # I now get branch2's file-id for NAME
> bzr commit -m "resolved some stuff"
>
> cd ../branch2
> bzr merge ../branch1 # No conflicts, because we are using the same file-ids.
>
>
> However if you do the opposite:
>
> cd branch1
> bzr merge ../branch2 # Merge, but keep branch1's file-id for NAME
> bzr commit -m "Include branch2's changes."
>
> cd ../branch2
> bzr merge ../branch1 # Conflict *again*, but again resolve in favor of THIS
> bzr commit -m "bring in branch1"
>
> cd ../branch1
> bzr merge ../branch2 # Conflict *again* ...
>
> I ran into this when working on "annotate". If in doubt, take "OTHER"
> because that "spreads" it to everyone, and eventually everyone agrees.
> If you always resolve in favor of THIS, then everyone always disagrees.

Choosing OTHER is no better - simple cris-cross merges at this point will cause both sides to switch ids.

If we need want to force pseudo-joining (a bad idea today I feel, even
though I agree that the user /often/ wants to end up with one
directory), then choose something immune to criss-cross.
For instance:
create a new file id by:
new_id = ':'.join(sorted(old_ids))
(this discards both sides of the history, but in a way we could
conceptually recover from)
or
final_id = sorted(old_ids)[0]
(this takes the lexographically lowest id)

-Rob

--
GPG key available at: <http://www.robertcollins.net/keys.txt>.

Jelmer Vernooij (jelmer)
tags: added: check-for-breezy
Jelmer Vernooij (jelmer)
tags: added: merge
removed: check-for-breezy
Changed in brz:
status: New → Triaged
importance: Undecided → Low
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.