Immediate merge of a bundle vs branch -r + pull and later merge

John Arbash Meinel john at arbash-meinel.com
Tue Aug 21 17:33:22 BST 2007


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

Andrew Cowie wrote:
> Had a bit of an experiment today: thus far I've rather frantically been
> doing
> 
> (1)
>         $ cd working
>         $ bzr merge ~/Desktop/whatever.bundle
> 
> into my working directory branch, then with a whack of changes that need
> committing to merge.
> 
> My situation is that and I have typically needed to carry out a
> considerable number of changes to fix up the submissions before
> accepting them as 'mainline' worthy. Until now I have been doing this
> during the merge commit, which has been working well enough. ie
> 
> (1a)
>         [resolve conflicts *and* make changes]
>         $ bzr commit
>         $ bzr push ../mainline
> 

I would probably have a 'staging' branch, that you can pull changes into, and
then merge them into mainline as a separate step.
For Bazaar, we using a staging branch (we are forced to because we cannot
commit directly to PQM). And we find it to be a rather good workflow.
I do it with bzr.dev and jam-integration. Specifically, I have

~/dev/bzr/          #local shared repository
    bzr.dev/        # Checkout of http://bazaar-vcs.org/bzr/bzr.dev
    jam-integration # My integration branch

When we get a bundle that needs merging, I usually do:

  cd bzr.dev
  bzr update           # Get the latest bzr.dev
  cd ../jam-integration
  bzr pull ../bzr.dev  # make my integration branch the tip
  bzr merge BUNDLE

At this point, I usually have to at least edit NEWS because there was a
conflict. And I would generally do conflict resolution at that point.

If you are actually trying to clean up the submission (outside of simple
conflicts), then I would commit, and then clean up the submission.

At that point, I submit to bzr.dev, but that is equivalent to

  cd ../bzr.dev
  bzr merge ../jam-integration
  make check && bzr commit -m "(User Name) Great changes to foo"

(Note the commit doesn't happen if make check fails.)

There are times when I don't expect any conflicts so I do:

  cd jam-integration
  bzr pull --overwrite BUNDLE
  bzr pqm-submit -m "(User Name) Great changes to foo"

Though usually if I'm doing that it is actually:

  cd bzr.dev
  bzr update
  cd ../jam-integration
  bzr pull --overwrite BUNDLE
  bzr merge ../bzr.dev
  # Ok, no conflicts, revert and submit
  bzr revert
  bzr pqm-submit

Because otherwise, it isn't until pqm finishes checking that I find out I
really needed to resolve conflicts before submitting.


This sounds like a bit of overhead, and certainly it is a bit more than just
working from mainline. However:

1) You don't have to have a branch per submission. Just a single staging branch
that gets reused. It is only meant to be a temporary area.

2) If you want the very nice property that "every commit on mainline has passed
the test suite", you have to have a way to stage changes before they are
committed. You can do it as you have done by using the working tree as staging.
But as you noticed, you lose the ability to commit.

Further, if you are using a PQM or other bot to force 'make check' on mainline,
you have to have a committed staging anyway.


In your workflows, you mentioned doing either:

bzr branch mainline test
cd test
bzr pull --overwrite BUNDLE # Or maybe merge
# review, commit, merge, whatever

And then you want to know if it is better to

(a)
  cd ../mainline
  bzr merge ../test
  bzr commit

or (b)
  bzr merge ../mainline
  bzr commit
  bzr push ../mainline


And my answer is that it depends on if you want property (2) above. Many times
you (Andrew Cowie) have mentioned that you don't care about "mainline
revisions" versus "merged revisions". You would rather see flattened commits,
than indented, etc. In which case, (a) and (b) are equivalent.

However, you can't say "all commits on mainline have passed 'make check'" when
you randomly change your mainline revisions.

Let's give a picture:

  A
  |
  B
  |\
  C D
  | |
  E F
  | |
  G H
  |/
  I

versus


  A
  |
  B
  |\
  C D
  | |
  E F
  | |
  G H
   \|
    I

At a first glance, they seem equivalent, after all, it is just a merge of G and
H to produce I. (I'm trying to present that | is the primary parent, versus \
or / being a merge. Though obviously D has a primary parent of B.)

The big difference is that if I is your mainline commit, and you view its left
hand history, in the first case, you will see
  A B C E G I

In the second you will see:
  A B D F H I

If you flatten it, you would probably see:
  A B C E G D F H I
versus
  A B D F H B C E G I


Some people have a strong philosophical belief that in open source there should
be no "blessed" commits. That all trees should be treated equal, and thus bzr's
insistence on left-hand parent versus other parents is bogus.

My argument is that "blessed" is *more* important in open source, because you
have so many options that you don't know what is good and what is not. (It was
an old argument that the Internet would be the end of trademarks/brand names,
because everyone could have their own website. Instead it turned out to make
trademarks *more* important, because there is so much garbage to filter
through, you go to the names you trust. Sure you might find a great deal at
"Joe's Discount Electronics", or you might just be scammed. But you are pretty
sure that going to Target.com will send you the goods you ordered.)

People tend to use or base their kernels around Linus's tree, because it has
become the standard. Wouldn't it be nice to see how his tree evolved over time,
rather than having it jump all over the place with random committer names
because he uses the equivalent of 'merge --pull' all the time? I don't know
which patches he has reviewed and approved closely, versus what happened to be
in the history when he merged.

(Now, in the flip side, it seem like the kernel will have you rebase all the
time, so that there are no commits ever that would be "unclean". Which has a
whole different set of tradeoffs. Collaboration is more difficult outside of
the blessed trunk because the thing you just merged may get rebased, but you do
have a cleaner/easier to follow history.)


Anyway, the ultimate workflow is up to you. But I wanted to present some of the
reasons why we (the Bazaar community, or at least the primary developers) feel
that having a left hand history is not just an artifact, but a genuinely useful
thing. (Not just because 'bzr log --short' gives a really good idea of how the
trunk has changed, rather than sometimes being individual user commits, and
sometimes being mainline changes. Or having to always view 'bzr log --long' and
do all the sifting yourself.)


For Bazaar, we using a staging branch (we are forced to because we cannot
commit directly to PQM). And we find it to be a rather good workflow.

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

iD8DBQFGyxPSJdeBCYSNAAMRApWXAKDLobLpBJGv+WZB/6o+17FFYhf9/wCeLazW
kXFzmzv6hSnvnWcEPI+dPE0=
=V7Pr
-----END PGP SIGNATURE-----




More information about the bazaar mailing list