Mercurial and Agile

Mads Kiilerich mads at kiilerich.com
Wed Jul 1 19:28:45 CDT 2009


Bret Naylor wrote, On 07/02/2009 01:21 AM:
> Short Question:  Why is it so hard to cherry pick individual 
> changesets and only move those across repositories?

Short answer: Because it _is_ hard.

Changes are always made in a context, and a two changes will thus always 
either be ordered or have no ordering and be "in parallel". 
Cherrypicking means taking and applying changes out of context and 
order. Changesets which are fine one context might be wrong in another, 
so moving changesets around is dangerous.

Darcs claims they can handle cherrypicking - and sometimes they can. 
Perforce can do it reasonable well too. Much can be done with simple 
diff and patch, possibly wrapped somehow. But core Mercurial doesn't try 
to support it and doesn't claim to. (Mq and transplant and other 
extensions integrates the simple approach with Mercurial and might be a 
usable solution for you.)

> Longer Version:  We have a fairly large repository with a few thousand 
> source files.  We are trying to switch our development methodology to 
> a more Agile approach where we release a new version of our software 
> each month.

I agree that release-often is an important part of what often is called 
agile. But it is not just releasing once a month. It is more about 
keeping the main repository in a state where a release can be made at 
any time. If "something" is ready for release then it can go in the main 
repo. If something isn't ready then it can't go to the main repo. There 
is thus no such thing as cherry-picking changes ready for release.

However: "agile" is just a word which we might use differently. And 
there is definitely other usecases for cherry-picking - especially when 
bug-fixes must be applied on several maintenance/release branches.

> We would like each item that developers work on to pass from 
> development, to testing, and then to release.  To do this we have 
> setup repositories that the development groups work in.  We then have 
> a QA repository where all items that are ready for QA can be pushed to 
> and tested by our QA group.  Finally, we have a release repository for 
> items that have been signed off by the QA group.
>
> In order for this to work, we need to be able to keep changesets that 
> aren't ready for QA out of the QA repository and we need to keep 
> changesets that are not ready for Release out of the release repository.
>
> The problem is, we can't choose a changeset from one of the group 
> repositories and push it into QA by itself.  it always has to have all 
> of its parents.  Some of the parents may not be ready for QA and so 
> this causes a problem for us.

Unfortunately changesets can't be handled the way you want to. They 
might - and will - have intended and unintended dependencies, both 
explicit and implicit.

Mercurial requires all the parents to be "included" because that is the 
only way to ensure that no dependencies have been forgotten.

> To get around this for now, we are creating a new branch for each new 
> enhancement or bug fix and only merging the branch back into the 
> shared head once an item is ready for QA.  However, the problem 
> repeats itself for the QA to Release scenario.  There may be 
> changesets that are fully tested and accepted and ready to be pushed 
> to the Release repository but once again, we can't just push that 
> changeset over, we have to push all parent changesets over which will 
> invariable contain changesets that have not yet passed QA.

If some developers are working on a project which passes QA but depends 
on or is intertwined with another which isn't ready yet, _then_ you have 
a problem.

So you will need processes that supports what you want to do. No tool 
can fix a process problem, but if you have the right process then 
Mercurial can help you.

I think the "workaround" you describe is a fine solution. If you want to 
be able to separate changes later on, then you have to keep them 
separated from the beginning and all the way to the point where you make 
the final integration and merge them. In Mercurial you can do that by 
having separate repositories or branches.

/Mads


More information about the Mercurial mailing list