← Back to team overview

maria-developers team mailing list archive

Re: Bzr merge order


Following up on this, I just learned about the bzr option
append_revisions_only that can be set on a branch.

This option can be used to enforce that the main history (sequence of
primary/left-hand parents from the tip) correctly reflects the series of
pushes into the public tree.

So assume this sequence of events:

1. Joe branches lp:maria (revision 1000), and starts hacking on a patch.
2. Other developers push revisions 1001, 1002, and 1003 to lp:maria.
3. Joe finishes the patch, the review is good. He runs `bzr merge lp:maria`,
   followed by `bzr push lp:maria`.

As it is now, the resulting history of lp:maria will look like this:

1002 Joe (merge)
  1000.1.3 | Other
  1000.1.2 | developer's
  1000.1.1 | commits
1001 Joe's patch
1000 Starting point

So it is not at all clear that the other commits were at some point pushed
individually to lp:maria. And if someone goes to look at revision 1002
thinking to see one of the other developer's commits, it will be missing (or
worse refer to the wrong commit after further pushes).

But if we set the append_revisions_only option on lp:maria, instead of this
Joe will get this error:

bzr: ERROR: Server sent an unexpected error: ('error', 'Operation denied because it would change the main history, which is not permitted by the append_revisions_only setting on branch "lp-139886317008592:///~knielsen/maria/tmp-buildbot-test".')

In this case, Joe will instead have to do this:

    bzr branch lp:maria  # or bzr pull lp:maria into an existing clean clone
    bzr merge ../branch-with-patch
    bzr commit -m"merged with trunk"
    bzr push lp:maria

Then the resulting history will be this:

1004 Joe (merge)
  1000.1.1 Joe patch
1003 | Other
1002 | developer's
1001 | commits
1000 Starting point

Which is much nicer, IMHO.

So basically append_revisions_only enforces the merging style that I, Sanja,
and Monty already proposed as a good practise.

So I propose to add this option to the 5.1, 5.2, and 6.0 trees on
Launchpad. This will provide a clear record of the push history in the
repository, at the cost of enforcing the "good practise" merge style with one
extra bzr step.

Any opinions? Reasons not to do this?

If there is general agreement I will add the option (the process is somewhat
inconvenient, but I tested a procedure using sftp and that works ok).

(Incidentally, this way also makes it possible to correlate the branch history
directly with build history from Buildbot/Pushbuild, something I really missed
in the BitKeeper days).

 - Kristian.

Kristian Nielsen <knielsen@xxxxxxxxxxxxxxx> writes:

> I noticed a difference between Bitkeeper and Bzr merges.
> In Bitkeeper, merge parents are essentially unordered. The two parents of a
> merge are completely equal, and there is no way from the Bitkeeper to history
> to say whether one parent was merged into the other or vise versa. The actual
> order in which merge parents are listed is based on some deterministic
> algorithm (most recent commit date if I recall correctly).
> In particular, this means that in Bitkeeper, the result of a pull of A into B
> is exactly identical to a pull of B into A. This makes it impossible to
> establish the history of pushes into main trees from just the Bitkeeper
> history.
> In Bzr, merge parents _are_ ordered. Merging B into A gives a different result
> from merging A into B. When merging B into A (cd A; bzr merge B), A is the
> primary or left-hand parent. The resulting tree has one extra top-level merge
> revision following the tip of A, with all merged revisions of B appearing as
> sub-revisions of this.
> This means that if one merges A into B giving C1, and later merges B into A
> giving C2, then C1 and C2 are considered diverged and need another merge
> changeset to be consolidated (in Bitkeeper C1 and C2 are identical and need no
> further merge).
> What this means is that in bzr is _is_ actually possible to see the history of
> what was merged into what, at least in some sense.
> Unfortunately, it tends to be backwards with usual MySQL working style. This
> is to make a branch at some point X, make a patch, commit and get review. Then
> when pushing, the main tree has gotten additional pushes by others and is now
> at revision Y > X. So one does a bzr merge of the main tree into the local
> clone, followed by a push to the main tree. Now the local patch becomes the
> main merge parent, and all other pushes between X and Y become sub-revisions
> with their revision numbers renamed. Which eventually makes primary/secondary
> merge parent relationships more or less random.
> So since I did not take part in the transition to bzr within Sun, I just
> wanted to ask if this is something that was discussed, and if so if there were
> any conclusions?
> As I understand, the Drizzle people make sure that whenever they merge, they
> merge into a copy of their trunk, so that all past pushes are visible as the
> line of primary/left-most merge parents in the main tree. This works better
> for them, as they follow the model of a single/few merge captains merging in
> other peoples trees upon merge requests.
> My personal opinion is that while it would be nice to have the push history
> available like the Drizzle people do, the bzr support for this is not good
> enough, without a very tight control on who can push to main trees that we do
> not want. What one can do is when pushing, first swith to an up-to-date fresh
> clone of the main tree, pull from the local branch with own changes, then push
> that to the main tree. Maybe this is a good way, even though it cannot be
> enforced?

Follow ups