Please check my thinking on bug 646979

John Arbash Meinel john at arbash-meinel.com
Tue Oct 5 15:16:36 BST 2010


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

On 10/4/2010 7:20 PM, John Arbash Meinel wrote:
> 
> ...
>> We create a new revision with D & E as parents, and the contents of the
>> later of the two (defined in terms of upstream version numbers). So, no,
>> there is no possibility of conflicts at this stage.

I've been thinking about it, and I'm pretty confident that what you are
trying to do is inherently "criss-cross". Specifically consider a
semi-ideal case:

 upstream

  A	release 2.0
  |
  B	release 2.1
  |
  C	release 3.0

with debian doing:

  A
  |\
  B d   deb 2.0-1
  | |
  C |
   \|
    e   deb 3.0-1

And ubuntu doing:

  A
  |\
  | d	deb 2.0-1
  | |
  B u   ubuntu 2.0-1ubuntu1
   \|
    v   ubuntu 2.1-1ubuntu1


These graphs are, inherently, criss-cross, because you don't have a
single point of convergence. Both 'ubuntu' and 'debian' make new changes
vs the upstream, and never does one fully supersede the other. ubuntu is
constantly pulling from debian, but debian *never* pulls back from ubuntu.

Let's draw it combined:
 A
 |\
 | d
 | |\
 B | u
 |\: |
 | \ |
 | :\|
 C | v
  \|
   e

(and that is with the 'ideal' case that C is actually a descendant of B
and not A, though if it isn't you can usually fake it:
  A
  |\
  B C
  |/
  C'
)


Anyway, in the above graph, B and d are competing as common ancestors.
If you were to strictly use d as the base, then you would get the
changes from d => e, but that would include the A=>B changes. (d does
not include B, so those changes would try to be 'replayed')

If you used B as the base, then you would be trying to merge in the 'd'
changes a second time.

Now, what matters is what is explicitly changed by each revision.
Because if "d - A" is strictly adding debian/, and not touching the
actual content, then there are likely no conflicts in a per-file sense.

That is what '--weave' should be able to handle, since it does per-file
merging.

I don't have any great answers here, if you really wanted a closed
simple merge system, then you would have something like this:

 A
 |\
 | d
 | |\
 B | u
 |\: |
 | \ |
 | :\|
 C | v
  \|/
   e

Basically, the debian package should end up based on the ubuntu package.
At which point, the common base becomes v when trying to do an e=>v merge.

Now, you could "fake" that with:

 A
 |\
 | d
 | |\
 B | u
 |\: |
 | \ |
 | :\|
 C | v
  \| |
   e |
   |/
   e'

However, doing that merge is still non-trivial, because v=>e is still a
criss-cross merge. And even worse, the graph really looks like:

 A
 |\
 | d
 | |\
 B | u
 |\: |
 | \ |
 | :\|
 C | v
  \| |
   e |
    \|
     e'

because *debian* isn't going to do their next release on top of e', they
are going to do it on top of e. The importer logic will continually
cause 'debian' and 'ubuntu' imports to diverge. ubuntu may contain all
of debian, but debian will never contain any of ubuntu.

Let me check the simpler case where everything in ubuntu comes from debian:


 A
 |\
 B d
 |\|\
 C e u
  \|\|
   f v

In this case, merging f=>v is trivial, because e is an obvious common
base. So you only get the new stuff in C and f.

However, if we can't introduce a new revision in the 'debian' line, then
it is really hard to find a single common base between the import lines.

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkyrM0QACgkQJdeBCYSNAAP4LQCeOUcBIUmb623SVxC20DCZyfW2
uOoAniVlq4UQ6BbA9/RZvjEdM5HBaX7z
=53EJ
-----END PGP SIGNATURE-----



More information about the ubuntu-distributed-devel mailing list