How to develop in multiple branches with hgflow - mercurial

I'm evaluating hgflow. The model meets most of my version control needs except that I can't figure out how to support multiple releases.
Assuming I have released v1.0 a while ago, have just released v2.0 and I have been using hgflow since the beginning. A customer who is still on v1.0 requests for a feature to be implemented. Because of the stability of v1.0, he doesn't want to upgrade to v2.0 or v3.0.
Using the generalized streams concept:
hg flow develop start 1.x (create develop/1.x)
hg flow develop/1.x:release start 1.0 (create release/1.0 from develop/1.x)
hg flow develop/1.x:release finish (close release/1.0 and create v1.0 on master)
repeat for 2.x & 2.0, so v2.0 tag is created on master after v1.0 tag
request to enhance 1.x is received
hg flow develop/1.x
work on enhancement
hg flow develop/1.x:release start 1.1 (create release/1.1 from develop/1.x)
hg flow develop/1.x:release finish <--- v1.1 tag is created after v2.0 tag on master
If I follow the hgflow model, I may end up with a v1.1 tag created after the v2.0 tag in the master stream. Worse still, the changes in v1.1 may overwrite the various enhancements I have made between v1.0 to v2.0.
My question is: can anyone suggest a solution to my problem? Any suggestion is appreciated. Thanks.

The workflow that you want to use for this situation has something to do with the support stream:
hg flow master # Update the workspace dir to the master branch.
hg flow support start 1.x -r v1.0 # Create a support/1.x branch from v1.0 snapshot.
hg flow support/1.x start feature1 # Create a support/1.x/feature1 branch.
... # Commits to implement feature1
hg flow support/1.x finish # Finish feature1. Changes in support/1.x/feature1 will be merged into the support/1.x branch.
hg tag v1.1 # Create support releases in the support/1.x branch.
All your changes to support the 1.x release are in the support/1.x branch, which by concept will normally not merge to other streams.

Related

How to show content of unapplied Mercurial queue patch?

From the hg command line interface, is there a way to show the content of an unapplied Mercurial queue patch without having to apply it or having to find the patch file manually in the corresponding queue patch folder from the .hgdirectory?
No, not quite. Unapplied patches from an mq are exactly not part of the repository itself, thus not accessible by the normal mercurial commands.
The (experimental) evolve extension is meant to become the successor of the mq extension. Making use of mercurial's phases, it allows to alter patches and easily evolve (similar to rebase) changesets which are children of the changed changeset. There all changesets, whatever phase, are accessible by all the usual mercurial commands.

Mercurial bookmark to label failed TeamCity builds

Setup is
a "central" hg repo and devs pulling from it.
TeamCity CI server is triggered by pushes to the central repo.
4 configs are built nightly and tag the repo.
We want to visualize the information
"this changeset resulted in a Failed CI build in TeamCity"
directly inside the DAG of TortoiseHG.
This way, devs are able to determine which changeset is "a good starting point", without having to look it up on the TeamCity server.
We are looking into Mercurial Bookmarks: setting them in a last build step when the CI build succeeded.
Advantages:
they stand out in TortoiseHG
adding or removing them doesn't increase the history
Disadvantages:
pulling them over is not guaranteed
they can be modified at will
they are meant to move
Tags are less of an option: we are already tagging 4 times during nightly builds,
so those new tags would add to the clutter.
Also, we have no idea if tagging (a growing .hgtags file) will scale well with the extra tags.

Mercurial workflow help - how to make a tag of a tag and get it to central repo?

I'm new with HG, I'm looking for some advice on how to handle this scenario.
We have a central repo hosted at Kiln. The three guys on my team code away and eventually are ready with our code which we tag and release as Version1. We then happily start working on our next major version. While working on it, there's the need to fix a critical bug in Version1 so James clones his repo using hg clone -r Version1 http://centralrepo where he makes his change and tags it as Version1.1.
Now, how does Version1.1 get back to the central repo? Using hg push causes an abort because there are two remote heads. Without it being in the central repo, Doug can never come along and make a fix to Version1.1 if it ever becomes necessary.
How can I modify my process so that all my tags are always stored on the central repo and easily pulled into the dev branch?
UPDATE/EDIT
With the suggestion from Joel, I made the following tweaks:
On the Kiln website, I create my main active dev repo. Once I have the code in there, I create a new branch from it.
I clone my ActiveDev branch: hg clone http://activeDev code-activeDev
I clone my Stable branch: ht clone http://stable code-stable
I setup a tag on my stable branch: hg tag V1.0 and then push it to the stable branch and to the active dev branch. When going to activeDev I use the -f command. Now both branches are identical.
I do an hg pull and start on a new feature in ActiveDev. Then push that feature back to central:
hg com
hg push
Stable gets a bug fix, then pushed to it's own repo using the same two commands. Now when I try to push that fix to the activeDev branch, I'm again given the 'you are making two heads, use -f' message. However, if I force it, the new feature I pushed earlier in activeDev is blown away by the fixes I did in stable.
Did I do something wrong? Am I missing a step somewhere?
Basically, you need to merge the fix so that there is only 1 head again. There is a way of managing 2 branches that makes doing bugfixes on released versions (in parallel with development) easier:
The process I use is to create a named branch called Stable in addition to the default branch. I work on new features and whatnot on the default branch. Whenever I do an actual release of code, I merge that over to the Stable branch and only tag things like v1.0, v1.1, etc. on that branch.
Then I can continue development on the default branch, but when a bug comes up that is relevant to a previous version I can put that fix on the Stable branch and recompile. When ready, I merge fixes from the Stable branch over to default to make sure that Stable is always just a subset of default.
If you start using this, the first time you push that named branch to central you will have to use hg push --force, but only once.

Using Mercurial with Branches - publishing to FTPonly accessible WebServers

We are a small team of developers working with a Web Application which is published using a Web Server that is only accessible throught FTP.
Our workflow is the following one:
A developer is working out some requested feature locally
When its done, commits it and Pushes to a 'central' repository
Few times a day, one of developers publishes the files that have been changed to a testing WebSite, to let key users see how does features have been implemented.
Once in a week, we deploy to our production site
As our Webserver doesnt support SSH, we can't push changesets and update on the server, so we created a custom script which Transfers the changed files throught FTP.
Each time we use that script a new tag is created, so we know -using hg diff- the diference between tags (a release for us).
It was all fine until now, that we introduced branches in our workflow, to let a developer work on a radical changes in the code, and keep contributing in daily small changes which are published to production.
The problem is that hg diff doesnt support Branches (or seems that its still in development)
So, which would be the best way to do it ? some options we have been thinking about are:
Mounting FTP as a Volume localy (using MacFuse or similar) and use mercurial push/update But would be so sloooow.
Play around with Bundles and see if they can help us but seems quite complicated
Example
$ hg tag qa-001 /* init to see diferences QA Site */
$ hg tag prod-001 /* init to see diferences Production Site */
$ hg ci -m "working on a stable feature"
$ hg tag qa-002
$ hg ci -m "change on the stable feature"
$ hg tag qa-003
$ hg tag prod-002
$ hg ci -m "another change on stable"
$ hg pull ../CentralRepo /*Where there is another Branch with unstable files*/
With last operation, a new head is created , so now there are two heads (stable, and unstable branch)
$hg diff -r qa-003 -r tip
The Result of hg diff is showing up the Unstable Files without doing the merge
Many Thanks for your comments
In your example, you are creating tags, not (named) branches. Tags won't help you to create separate lines of development: they are just stand-alone identifiers assigned with particular revisions.
Creating branches
To start using branches, you probably want to review some tutorials, such as:
Chapter 8. Managing releases and branchy development (from Bryan O'Sullivan's book)
A Guide to Branching in Mercurial (Steve Losh)
Based on your description, you probably want to create prod and qa branches based on your current default branch, as well as any feature / topic branches you might want for radical changes.
Once you have these branches in place, it's very easy to compare them, merge between them, see what changes are pending from one to the other, and so on as your workflow demands.
Bundles
Play around with Bundles and see if they can help us but seems quite complicated
If you only have FTP access, then bundles probably won't help you. You could upload a bundle to the server via FTP, but you would need to be able to run hg on the server to unpack the bundle into a repository.

Submit bug fixes on launchpad through patches or merge proposals?

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?
Update: It looks like the OpenERP project's official documentation now has guidelines for making merge proposals. I'll also leave my version here because it has some different details.
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 <donkirkby#example.com>"
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
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