Hi,

I'd like someone to check my thinking before I make a change, as I don't
want to introduce data loss or something.

First, some background.

We have a merge-package command, as a simple bzr merge doesn't cut it on
occaision.

Here's why: (apologies to anyone using screen readers or variable width
fonts)

  ---B---F
 /  /   /
/  / .-D
\ A-=
 \    `-E
  \      \
   C------G

(Time passes as you go right)

Here A is an "upstream" revision that is an import of a tarball. B and 
packaging revision based on that, and C is another packaging revision in
turn based on that. (Think B==Debian and C==Ubuntu)

Then D and E are independent packagings of two different upstream
release (say Debian jumped to 3.0, and Ubuntu took the point release
2.1). F and G are the new packaging revisions based on merging the old
ones with these new upstreams.

Now if we simply merge all F->G, we try and merge (D, F) in to (C, E,
G), which means we are merging changes from A->D with changes from A->E,
or in other words we are merging two upstream versions together.

Consider the case of a file with the version number in it. The BASE
would be "2.0", one side you change it to "2.1" and the other to "3.0",
but in reality they were sequential changes, we just can't represent
that here.

As a packager you don't care about this (generally), and you assume that
whatever in the latest is fine (you don't try and track at this point
patches in 2.1 that didn't make it in to 3.0, and even if you wanted to
this operation wouldn't just show you that)

What merge package does is first merge the two upstream revisions
together, taking the tree from whichever has the highest version number.

  ---B---F
 /  /   /
/  / .-D--.
\ A-=      H
 \    `-E-`
  \      \
   C------G

Currently it will then just merge H in to G (the target). This can
generate conflicts, which are very, very confusing to users, as it's
incredibly hard to explain why they are getting them.

  ---B---F
 /  /   /
/  / .-D--.
\ A-=      H
 \    `-E-` \
  \      \   \
   C------G---I

Once we have that merged revision we can merge F->I, which will merge
what we want.

I was thinking about this the other day and realised that uncoditionally
merging H to the target might not be the right thing to do. I think that
it should merge it in to the side that had the highest version. That
should never generate conflicts, as the revision that is being merged
has no changes against the LCA. I think it should generate an
equivalent merge though.

So, back to the graphs, if we this time consider D to be newer, but
still want to merge F->G, would it be ok if we created I on the other
side:

  ---B---F----I
 /  /   /    /
/  / .-D--. /
\ A-=      H
 \    `-E-`
  \      \
   C------G

and then merged I->G for our final revision?

I think that it should be "safe" and remove those "odd" conflicts you
get in the intermediate state, instead moving them to the final merge
when they should hopefully make sense.

Can anyone generate a scenario where this would give a worse outcode?
Can anyone in fact generate a scenario where either strategy is the
wrong thing to do?

The more I think about it the more I am confident in the change, but it
certainly doesn't seem like an obviously correct change to me.

Thanks,

James

-- 
ubuntu-distributed-devel mailing list
ubuntu-distributed-devel@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/ubuntu-distributed-devel

Reply via email to