Changesets and multiple ancestors

John A Meinel john at arbash-meinel.com
Tue Jun 28 19:33:52 BST 2005


Aaron Bentley wrote:

> John A Meinel wrote:
>
> >Aaron Bentley wrote:
>
>
> >A changeset has to be against some other version. Yes if you send me a
> >G->K changeset, I cannot apply that to I, but if you send me a I->K
> >changeset I can.
>
>
> Sure, but as long as you can produce the other revision, it doesn't
> matter what it is-- the changeset is merely a representation of K.

Well a changeset is inherently a X->Y entity. You have to select a base
to get the changes from it.

>
> >But you are right, since the 'official' base between K and I is G you
> >could generate a G->K changeset, which should be theoretically applyable
> >to any I tree (since I has G as an ancestor),
>
>
> It's not applyable to an I tree.  You can only merge it into an I tree.
>
> >but I could not apply it
> >on *my* tree, since I don't have the snapshot for G.
>
>
> We may just be using different terminology, though.

Well, K is only mergeable to I, you can never just apply it directly.
(You can only apply it to the base that was selected).

>
> >So I would say, "Yes, branch->branch merging will always be preferred",
> >but changeset merging can still get 90% of the job done.
>
>
> It's not very satisfying to me.
>
> I'd like changesets to be seamless, but it seems like if you always use
> changesets, you'll eventually get screwed.  Of course, sometimes
> 'perfect' is the enemy of 'good', and sometimes 90% isn't even half as
> good as 100%.
>
> It seems we end up with two classes of ancestors: the ones in the branch
> revision history, which are expected to be present, and those listed in
> the revisions, which may or may not be present.

I'm arguing to make changesets complete enough such that you will always
have an entry in the revision-store for every possible ancestor. Just
that you wouldn't necessarily have an entry in the inventory-store or
text-store.
This would still allow future merges to be able to detect *what* the
correct base would be. Because it can tell who has what revisions in
their history. (You don't just point back to H without realizing you
also have G).

The idea is that a changeset would say something like "if revision not
in base -> include meta info into the changeset"

My changeset plugin needs updating anyway, since it doesn't handle
multiple parents yet. Also, a changeset implicitly h

>
> That will make things ugly in the branch and pull code, since missing
> revisions are currently treated as fatal errors, and must now be
> tolerated some of the time, but not all of the time.

Doing a "try: copy_the_inventory except: if rev_id not in
revision_history(): continue" isn't terrible.
Meaning you try and copy everything, but if the copy fails and the
revision id is not in the revision-history, it isn't fatal.

>
> Aaron

I'm trying to think of where you can screw yourself over. Going back to:

Me-  A - B - C - D - E - I - L
         |             /    /
You-     + - F - G - H     /
                 |        /
Other-           + - J - K


If H was merged into I so that it just has a reference to G (no inventory).
If I try to directly merge K, I'm still okay, because K would need G in
order to be branched from it.
Say when K branches, they don't realize that H or I have been done. They
then generate a G-K changeset, and submit it to You, and you ask me to
merge it, since I have already merged you, and I cannot.
But if H->I hadn't happened you have:

Me-  A - B - C - D - E
         |
You-     + - F - G - H
                 |
Other-           + - J - K

And I can only merge K if I go back to B as the base.

I think you are just dealing with the basic issues of roll-up changesets.

Think about Arch. If 'me' tried to merge K+I to get L, it would fail. At
least with tla, I'm not positive about baz. Because in the tree 'me' I
have no way of re-creating tree G. I'm pretty sure that is correct, but
you are more knowledgeable about how merges are recorded (especially in
baz). It might be that if I have access to the 'You' repository, I can
set that as base, and do the right thing. (but I need access to You).

In bzr, you at least have the nice property that if the local stores are
greedy, and pull in ancestry when they can, then you already have a copy
of what you need for G.

But it also means that merging operations actually have to merge H by
applying F then G then H. With the current storage of compressed texts,
you can just copy the entries.
But if your tree uses texts, and my tree uses revfiles, I have to
recompute what it means to be F and G and H before I can merge from you.
I think if both trees are revfile based, then if I have your base, I can
just merge the deltas directly. Since an entry in a revfile can have an
arbitrary base.
Because of the extra work, I can actually see merges not being as
greedy, in which case a merge is identical to a changeset application.
In which case you always have to have 1 of the merged trees containing
base in their revision-history. (more like arch.)
For example, this situation:

Me-  A - B - C - D - E - F
         |     /        /
You-     + - G - H     /
         |         \  /
Other-   + - I - J - K

Technically F should try to use G as the base when merging K. If you
always store all of your ancestors, I think this should be possible. I'm
pretty sure this is a case that Arch cannot automate with merge (it does
replay changeset and manual fixup just fine).

John
=:->
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 253 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20050628/ccdd5d6a/attachment.pgp 


More information about the bazaar mailing list