Mercurial Hgflow: Adding a new feature to a release branch? - mercurial

From what I've read adding new features to a release is discouraged.
Now suppose the boss really wants that new feature in the current release, how would you handle this?
I can think of two options, which I believe are not supported by hgflow:
option 1:
branch from dev at the branching point of release/x.x
finish feature
merge to release/x.x
close feature branch
option2:
branch from latest point in release/x.x
release/x.x/featName
finish feature
merge to release/x.x
close feature branch
How would you deal with this scenario?

The newer versions of hgflow (0.9.4 is the latest) by yujiewu support Option2. The syntax is something like the following:
# In release/x.x branch
hg flow release/x.x start boss_wants_new_feature
# Now you create a branch called release/x.x/boss_wants_new_feature.
(a bunch of commits to implement the feature)
# In release/x.x/boss_wants_new_feature branch
hg flow release/x.x finish

If I understood correctly, the only difference is that option 1 uses the version from the moment of release and option 2 takes code added after the version was released. If that's the case, it totally dependeds on whenether you want this new code to be included when you release the new feature or not. If you are unsure, take option 1.

Related

Mercurial: Feature branch workflow?

Suppose I'm working on a new feature.
While working on my new feature, I get enough basic functionality so that I want to release it while continuing to work on the full feature. When the new feature is fully complete, I want to merge that back to the main release, replacing the basic feature.
What is the Mercurial workflow to do this?
The way I would approach this would be to create a feature branch. Mercurial branches can be merged into each other multiple times. So you could merge at milestone 1 (basic / minimal features) and again later (full / complete features) from the feature branch into your main branch.
Branches can be either named or unnamed / anonymous; the workflow will work the same either way. Whether you choose to create a named branch is essentially a personal / team preference; be aware that named branches persist forever in the repository history so typically they are used for long-running projects.
Anonymous branches are so common some people don't even realize that's what they are using. Effectively a branch is created anytime you commit work. Each developer will implicitly be working on their own branch (at least until their new work is pushed and synchronized.) So you could simply work locally on the new feature and only push it to share with others when its ready. Work more, push again later.
Personally I use this approach often because it is very flexible and simple. I often like to keep multiple local repository clones, each dedicated to a single task. These can be easily created, used, and removed at will. If your repository is large then I recommend using hg share instead of hg clone to create the 2nd through nth local repositories, as it will save time & space.
If you prefer to do so you can also use the Mercurial bookmark feature to "label" an anonymous branch, this could be preferable to creating a permanent named branch since bookmarks can be removed later.

in Mercurial prevent to up to a older version (tag or branch)

Is there any way to prevent to move back to an older version?
I mean, I want to always do hg up to forward and never to back.
Make use of the hooks which mercurial offers and implement a hook to the update command which compares the desired version with the currently checked-out version. Fail the hook, when the desired version is older than the currently checked-out one. See the docs for the available hooks and some examples.
That said, it might be an undesirable constraint on usage of a VCS. If it is about deployment on a production syste, that's more sane; yet then you do not need to copy the whole repository with its history, but just the current version to the deployment target.
For my purpose of deployment, I only check whether the build is set to be a release build (tag, or manually selected in jenkins) or if it is HEAD of a branch. In those cases I trigger the deployment to production after the build passed regression tests: https://github.com/OpenTTD/nml/blob/master/.devzone/build/jenkins_postbuild.sh

Can I checkout & commit to several Mercurial hg branches at once?

I've forked a project from the internet, and I want to write some new features. I want to write several orthogonal features at the same time, (eg. debug helpers, new feature X, new feature Y), and have the code for all of them in my current directory, but when I commit, I want to be able to say "these files go to branch 'debug'", "those files go to branch 'feature X'", etc. Where these are branches in the 'hg branches' sense.
The reason for this is the project upstream may not want to merge my debug helpers or hacked bug fixes, but I certainly want to use them whilst developing my features.
Effectively, I just want to apply the changes in those files to the branch, but keep several branches checked out & merged to my current working directory.
Is this possible? Perhaps there's some hg extension to do this?
Thanks!
Look at mercurial queues (MQ) for things like debug helpers or local hacks. Very useful for patches that you only want locally and may want to apply to any revision/branch.
Doing the same thing with branches becomes tedious IMHO as you have to be very careful to do the changes for debug and features on different branches, and then merge them in to a local, throwaway branch in order to run anything. You can end up with lots of changesets on the feature branch that leave the tree in a broken state because you can only test after you commit.
I don't fully understand why you'd you would want to do things that way. If your features are orthogonal, you can work on them independently until they are ready to be merged. That is exactly what branches are for after all!
But to answer your question: you could commit on a branch and then, as a matter of workflow, always up to default and merge it in. That would keep the default branch as the sum of the other features. You would need to update to the feature branch before you commit, though and that could get tedious.
The other option for post-facto determining which branch you want to commit to is to use the rebase extension. In this case, you'd commit your changes and then do hg rebase -d targetBranch.
I don't recommend using history revisions as part of your standard workflow, though. That smells to me.

How do I update a branch to be the state of a tag on a different branch in Mercurial?

I have a repository with a master and a develop branch.
I want to create a third named branch, say it's called bugfixes.
I want to be able to update to bugfixes and then have the tip of bugfixes be the same as a previous tag on master. (Say that tag is called Release5.1).
I've tried updating to the branch, and then updating to the tag, but that switches the branch back to master (where the tag is). I've also tried merging
hg merge -r Release5.1
but that only brought in the changes and didn't cause the branch to "go back in time".
How do I get that tag to the the tip of the named branch?
I'm asking this question because my CruiseControl.net guy tells me that we can only do builds off of the tips of branches and not off of specific revisions. (Maybe that is another question....)
First some basics:
Merges are directional:
When you merge bugfixes into master, then master gets the changesets that were committed on the bugfixes branch.
When you merge master into bugfixes, then the reverse happens.
If you want two branches to mirror each other, then you must do the merge in both directions.
I would argue that you don't need the bugfixes branch at all. Instead, I would set a policy that says:
master should always be in a state that may be released
Bug fixes are committed to master
All releases are tags on master
New features are committed to develop
When it is time to release, develop is merged into master
After every release, master is merged into develop to insure that new features are based on the latest release.
This would result in something like this:
If you must have a bugfixes branch, then I set a policy like this:
master should always be in a state that may be released
All releases are tags on master
Bug fixes are committed to bugfixes
New features are committed to develop
When it is time to for a bug fix release:
Merge bugfixes into master
Tag master
Merge master into bugfixes to make them match
Merge master into develop to make sure new features are based on the latest release.
When it is time for a major release:
Merge bugfixes into master
Merge develop into master
Tag master
Merge master into bugfixes to make them match
Merge master into develop to make sure new features are based on the latest
This will result in something that looks like this:
To fix a bug in an old revision, you should:
hg update <TAG>
hg branch Release1.x
<fix the bug>
hg commit -m "Bug fix to older version"
hg tag Release1.2
...if the bug is present in master, then you should also:
hg update master
hg merge Release1.x
hg commit -m "merged bug fix in Release1.x to master"
This would result in something like this:
NOTE 1: At this point, master has commits which should never be part of a Release1.x release. Due to this, you should never merge master into Release1.x.
NOTE 2: If you must support multiple releases of a product in the field, it is common to have a named branch for each major release. These long-running named branches are then used only for bug fixes. If you are very careful, you can merge bug fixes from one release branch to another, but in my experience it is more common to use hg transplant to copy the changes between branches.
I would suggest that you keep the bugfixes branch essentially a mirror of the master branch except for when you are fixing a bug, and once the bug is fixed, merge bugfix back into master to again sync them up.
If you need to maintain multiple old versions of master, you will probably need to have a bugfix named branch for each old version you need to maintain.
Ideally, you wouldn't need a named branch dedicated to bug fixes. Much of Mercurial's power comes from how easy it is to branch from a previous revision (un-named branch). I am not too familiar with CruiseControl.net, but if you can build off of unnamed branches, then all you would have to do is:
Update to the tag you want to base the fix on
Make the changes
Commit (this will make an unnamed branch)
Build / test the tip of the new, unnamed branch
Tag the new version
Merge as needed to make sure all code lines get the bug fix
Due to how Mercurial's internal hash structure works, unwinding changes off of the "stack" (or inserting new changesets into the stack, depending on how you look at it) is a really, really hard thing to do and is likely to break any repositories that were clones of the one you are working on.

How do I fix a bug in a previous release version via mercurial?

We are using mercurial in a single repository. We have a master branch and a develop branch (as well as feature branches, but they aren't germane to the issue at hand).
We tag the master branch with releases (5.1.0.102, etc). We do our development on develop.
But now we want to fix a bug in a previous version. There are a lot of questions here on SO about this issue, but none of them seem to explain what I want to do.
What I want to do is this:
Update to the point where we released (say 6.1.1)
Fix a number of bugs in that release
Label that resulting code state as (6.1.2)
Do a build of this new 6.1.2 codebase.
Migrate those fixes into the develop branch
Do this in such a way that I can go back to 6.1.2 and fix bugs there if need be.
I can't seem to do this via updating. I tried to update to the 6.1.1, create a branch, and go from there, but that brings in the tip of the master branch, including all subsequent changes.
Is there a standard way of doing this? Did I explain that correctly so you guys get what I need to do? It seems like this is a pretty common thing to do.
You don't need to explicitly create a branch. The way I would do it is this:
Update to the point where you released (6.1.1 in the master branch).
Make changes and commit them.
Tag the latest commit in master as 6.1.2.
Pull those changes into the develop branch.
Continue working.
If you need to make more changes, then simply repeat the above but using the 6.1.2 tag in the master branch.
You really shouldn't need to create a named branch unless you truly want to have a full-out branch. What you probably want to do is:
update to 6.1.1
make the edits
commit (will create a new un-named branch)
tag that new revision as 6.1.2.
You can then merge that edit into your develop branch
As long as you are updating to a revision earlier than the tip on the Master branch, the commit will make a new branch off of it.
This will leave the version tagged so you can easily get back to it.