views:

335

answers:

2

I'm new to Launchpad and Bazaar, and I'm trying to figure out what the best way is to submit bug fixes. I'm using some reasonably popular open-source software that's hosted on Launchpad, but it's not very stable. I've created my own branch of the project to stabilize it and apply just the bug fixes we need without adding other changes from ongoing development.

When I file bugs and then figure out how to fix them myself, I push the fix to our stable branch. How should I publish the fix back to the main project? I could create a patch file and attach it to the bug, or I could propose a merge for our stable branch.

If I fix multiple bugs, can I make a separate merge proposal for each one, or are they cumulative?

+1  A: 

Such policy (using merge proposals or patches) should be defined by core developers or maintainers of the project itself. But as general rule using separate branches for each fix is preferable way over just plain patches.

  • Because plain patches may become out-of-date when trunk branch development moving forward. When you keep the branch for the fix then you can update your fix according to recent changes in trunk.
  • Fixes in branches are simpler to analyze, because other developers can see all your intermediate steps for fixing the problem, or how your fix has evolved over the time as trunk changed.
  • Also patches attached to bug reports often tend to be missed or forgotten. While the list of all active merge proposals is prominently shown on "Branches" page of every project.
  • Merging your fix from your branch means the history (and annotations) will keep your name as path author, not the core dev who applied your patch.

Keep all fixes in one branch is not good for using it in merge proposal. But it's useful per se for testing all your fixes or using it as stable branch (e.g. for dogfooding). So I'd suggest to use separate (feature) branches for each separate fix, file for them separate merge proposals, and merge these branches into your stable branch as you doing today. This way you can get full freedom over applying additional changes to each your fix and then merge it again to your stable branch.

If you need to split your existing stable branch to several separate branches you can use the recipe from John Meinel described in his blog: http://jam-bazaar.blogspot.com/2009/10/refactoring-work-for-review-and-keep.html

bialix
Thanks, that's helpful. Could you clarify a couple of things? In John's blog, he suggests running `bzr branch --switch ../dogpile ../feature1` to create a new branch. Is that feature1 branch local to my machine or hosted at launchpad? In order to propose a branch for merging, it has to be hosted at launchpad, right?
Don Kirkby
Both dogpile and feature1 are the local branches (in local shared repository). You're working locally until you'll be ready to file merge proposal. Then you push your branch to LP: `bzr push lp:~your-name/project-name/branch-name`. Then open the branch page with command: `bzr lp-open`, and file merge proposal.
bialix
Thanks for the help. I've now posted a summary of the complete workflow I use based on your suggestions.
Don Kirkby
+4  A: 

After playing with Bazaar and Launchpad for a few days and submitting a few patches and merge proposals, I thought I'd write a summary of what I found. Launchpad and Bazaar provide some powerful tools, particularly for community-driven projects, but I don't think new users are likely to fall into the pit of success yet. There are several ways to make the process slow and frustrating, so I hope this walk through helps some people avoid a few mistakes.

Here's the work flow I've learned for working on bug fixes and submitting merge proposals back to the team for a project that's hosted on Launchpad. I'm working on a GNU/Linux workstation, but I assume the Bazaar commands would be equivalent on other platforms. In this example, I'm working on one of the projects in the OpenObject project group called OpenObject Addons. The maintainer's user name is openerp. I'll put my workspace in the ~/workspace folder.

If you want to learn more about any of the commands here, use bzr help plus the command name.

Create a shared repository

Because I'm going to be creating a branch for each feature I want to contribute back to the project, I don't want to have a separate copy of the project's entire history for each branch. To avoid that, I create a shared repository and then create each branch within that. One thing to be careful of is that your repository format has to match the official branch's format to make some of the later steps work.

Check the repository format on the official branch:

bzr info http://bazaar.launchpad.net/~openerp/openobject-addons/5.0

Get the code

Now create a workspace folder that will hold any local branches on your machine - I just name it after the project. Then create a shared repository in it using the format you found on the official branch.

cd ~
mkdir workspace
cd workspace
mkdir openobject-addons
cd openobject-addons
bzr init-repo --format=rich-root-pack .

The next step is to check out the source code from the official branch. It's usually called trunk, but you might prefer to work with a stable release branch that is just being used for bug fixes. In this example, I'm going to work on the 5.0 release branch.

cd ~/workspace/openobject-addons
bzr checkout lp:~openerp/openobject-addons/5.0/ feature-x

That step is probably the slowest in the whole process for a large project, because you're copying all the code plus all the history for the entire project onto your hard drive. Note that I name the branch after the feature I'm going to work on.

Create a branch

At this point you can experiment with building and running the code on your local workstation. You can make changes to the code, but you don't have anywhere to commit them yet, because you're probably not allowed to commit directly into the official branch. To publish your code changes you need to create a public branch. If you're new to Launchpad, you'll need to create an account and register a public key first.

Once you've set up your account, you can publish your own branch as a copy of the official branch, and start working with it. The lp-login command tells bazaar what account name to use on the launchpad site, and the whoami command tells bazaar what name to use on each revision you commit. The e-mail address you use in whoami should match one of the e-mail addresses you configured for your Launchpad account.

cd ~/workspace/openobject-addons/feature-x
bzr lp-login donkirkby
bzr whoami "Don Kirkby <[email protected]>"
bzr branch --stacked --switch lp:~openerp/openobject-addons/5.0/ lp:~donkirkby/openobject-addons/feature-x

You switch to the new branch so that commits will be recorded in your local history and in your public branch. You might want to learn about the difference between a checkout and a branch. Making this a stacked branch means that it's very fast to create because it only contains the history that's not in the official branch. This blog post makes it sound like branches of public projects should default to stacked, but that hasn't worked for me. Notice that I named the branch after some feature I want to add. As bialix suggested, I create a separate branch for each feature that I will eventually propose merging back into the official branch.

Commit and make a merge proposal

Now that you have a branch, you can make code changes and commit them.

cd ~/workspace/openobject-addons/feature-x
bzr commit -m "Fixed bug lp:12345 by fleaking the woverbinate() function."

You can commit from anywhere within the branch structure, and it commits the entire branch by default. Run bzr help commit for details. You might also find bzr status and bzr diff useful.

Once you're happy with the changes and you've committed everything to your feature branch, you can go to the Launchpad web site and create a merge proposal. Here's a handy shortcut that you can run to launch the branch's web page:

cd ~/workspace/openobject-addons/feature-x
bzr lp-open

Once you create the merge proposal, Launchpad will generate a diff for it. It's well worth reviewing that diff. Sometimes I've selected the wrong branch as a target, and I only noticed because the diff had way more changes than I expected. There's also a bzr send command for merge proposals, but I haven't used it.

There's an e-mail interface for shepherding your proposal through the process, or you can just use the web site.

It's also useful to attach the branch to the bug so that other people can use it like a patch on their own systems.

Ongoing changes

If you work on several features and the maintainer isn't very speedy at reviewing your proposals, it's probably worth setting up your own mainline branch. This branch collects all your features together and it holds the code that you would run on your servers. It's also useful if the official branch isn't very stable and you want to stabilize a branch for your production environment. Then you can decide when to upgrade to the latest, and when to take specific patches for bugs that are hurting your users.

The first step is to create another branch that is stacked on the official branch:

cd ~/workspace/openobject-addons
bzr checkout lp:~openerp/openobject-addons/5.0/ main
cd main
bzr branch --stacked --switch lp:~openerp/openobject-addons/5.0/ lp:~donkirkby/openobject-addons/main

Now there are two sources of changes you'll need to merge from. First, merging from a feature or bug fix branch:

cd ~/workspace/openobject-addons/main
bzr merge lp:~donkirkby/openobject-addons/feature-x/
bzr commit -m "Merged feature x"

Of course, if you still have a local copy of the feature branch, it will be faster to do a local merge:

cd ~/workspace/openobject-addons/main
bzr merge ../feature-x
bzr commit -m "Merged feature x"

Second, you'll occassionally want to merge the latest and greatest from the official branch:

cd ~/workspace/openobject-addons/main
bzr merge --remember lp:~openerp/openobject-addons/5.0/
bzr commit -m "Merged from 5.0 branch"

After using --remember when you merge from the official branch, you can just use bzr merge on its own to merge from the official branch. If the project uses tags to mark release points, you can view a list of tags and merge from a tag.

cd ~/workspace/openobject-addons/main
bzr tags -d lp:~openerp/openobject-addons/5.0/
bzr merge -r tag:5.0.7rc2
Don Kirkby
This is good summary. But why you decided to use `bzr branch --stacked` instead of just `bzr push`?
bialix
@bialix, when I used `bzr push`, it took forever. I assume it was copying the complete repository to my new public branch. `bzr branch --stacked` only takes a few seconds because it's copying some metadata and nothing else. Does that sound right to you?
Don Kirkby
push stacked by default onto branch-development focus, but it seems for you it selects wrong branch. That said: yes, your approach in this case is correct.
bialix
Just checked it. Yes, by default push will stack on `lp:openobject-addons` but you want to stack on `lp:openobject-addons/5.0`. Fortunately there is `--stacked-on` option in push, so you can use `bzr push --stacked-on lp:openobject-addons/5.0 lp:~donkirkby/openobject-addons/feature-x`. Also you can use `lp:`-style URLs, they're shorter.
bialix
@bialix, I'm going to stick with the branch command, because it seems more intuitive to me. (Maybe I'm still suffering from Subversion bias.) As for the `lp:` protocol, I started using `bzr+ssh:` after I got some errors with `lp:`, but now it seems to work fine. Maybe I hadn't called `lp-login` or something. Anyway, I converted the walkthrough to use the shorter URL's.
Don Kirkby
@Don, `branch` is fine. I think you need to accept your own answer, because it looks like very good and concise instruction.
bialix
I found a gotcha when merging feature branches. If they were branched from the official branch after you last updated your stable branch, then they may bring along extra changes when you merge them into your stable branch. The simplest fix is to merge from the official branch before you merge from the feature branch. I'll experiment with the ancestor: revision axis and then update the post.
Don Kirkby