Mercurial Closing a Branch - mercurial

I have been using named branches both as feature branches and long lived branches. I just merged a bunch of feature branches into a long-lived branch, so I no longer need those feature branches muddling up the history graph (although I still want to keep the commit messages of course).
How do I do this?

Checkout the branch (hg co branchname) then hg commit --close-branch to mark the branch "closed".

Branches in mercurial are permanent, which is why they're a good choice for things that live forever like "release 1.0" and "experimental". For features you might want to consider something more transitory like bookmarks, clones, or anonymous branches. All four options are very well described here: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
As #wolvever shows you can hide it from a list, but you can't get rid of it without making your repo a different repo entirely (and thus breaking all clones).

Related

HgFlow and multiple developers

I really like the Hg Flow for Mercurial repositories. we are currently using Bitbucket, and in each product multiple developers are working. basically they can work as below:
a team might work on a single feature.
another team might work on a release/hot fix.
So do i keep the "develop" branch in BitBucket or local repositories. and how about feature branches, should i push them to the central repository and remove when required. i assume we should do so right?
Thanks
I personally neither use git flow or hg flow as tools, but I do use some of the methods for my own projects (manually).
Before going into detail, you always need to provide branches in the main/bitbucket repository when multiple people need to merge or branch from them.
This definately includes "develop" and probably also features/fixes multiple people need to work on (unless you have another repository or method to exchange branches/commits between them)
The difference between using git and mercurial/hg is relevant here, since the branching models are quite different.
See A Guide to Branching in Mercurial for details. Using hg bookmarks would be quite similar to what git does with branches, but there is no full support for the bookmark branching model on BitBucket (see this ticket).
hg flow (the tool) uses named branches. In contrast to git branches, these are not at all light-weight, but permanent and global (they can at least be closed now).
This means whenever any commit created on any (named) branch other than "default" is pushed to bitbucket (even after merging) this will create the branch in the bitbucket repository.
So you don't have any other choice than keeping all branches in the main repository.
However, You can decide when to push and when to close these.
I would advise using hg push -r to push only the branches/heads you want to push and only pushing these when they are either needed by somebody else or finished and merged.
Branches should be closed as soon they are not needed anymore. (This is probably done by hg flow automatically)
You should close branches locally whenever possible. This way they might not even appear in the bitbucket interface. Some might reach the bitbucket repository only in closed state (which hides them from the interface).
Obviously you should often push any branches multiple people need to merge from.
In my understanding of the workflow the "develop" branch is always exactly one branch per project that should be pushed frequently (after local testing).
In case you are either not using hg-flow or named branches things are a bit different.
Both, using forks/clones or bookmarks as a branching method doesn't generate permanent or necessarily global branches.
Like mentioned above, you can't use bookmarks (reliably) when you also want to use bitbucket pull requests. You have to push bookmarks separately. A normal push will only update (a head of) the branch so you might miss commits from other team members when marging later. Hg will tell you when a new head is created. In that case you might want to merge the branch with the remote bookmark into your branch before pushing.
When using forks as branches it works a bit like with bookmarks, but bitbucket has full support for that. You need to have a new fork on bitbucket for every branch.
You naturally only want to create extra forks if you need different people to work on it and you don't have other means of commit exchange for them. You will need at least a separate "develop" repository then.
I personally wouldn't use the full "flow" with hg on bitbucket.
For my projects the "develop" branch is the same as master/default, since I don't roll out releases with git (other than development builds, that wouldn't use the release branch anyways). I don't need a separate "production" branch, since tags can mostly be used for production usage.
I also don't create a separate "release-preparation" branch. There is only a point in time when I only apply bugfixes on develop and stop merging features. That obviously won't work when you need to work at the same time on features that are dependendant on features not to be released in the next release.
Always using the full "git flow" is easy because git branching is easy and light-weight.
Depending on the branching model you use and how supportive the other tools are,
using the full "hg flow" might not be "worth it".
The hg guide actually discourages use of named branches for short-lived branches.
See Feature separation through named branches.
The "easy" branching concept promoted in the guide is forking/cloning. Bookmarks would be the natural way to translate git flow if the tool/bitbucket support would be better (and bookmarks longer a core hg feature).
Disclaimer:
I prefer git when I can choose. I do use hg, but not as my personal choice.
You also might have considered most of this, but since you didn't state any of these details and accept an answer (in the comments) that is quite different to what you are asking, I wanted to elaborate a bit.
Edit:
To follow-up on the comments:
I think hg bookmarks are comparable to git branches because both are just movable pointers to commits.
The main difference is, that when you delete a branch in git, the commits are possibly lost (when not part of other branches or pointed to in a another branch before they are garbage collected). When you delete a bookmark in hg, then the commits are still part of the repository (part of the (named or default) branch) unless manually stripped.
Anonymous heads are related, but only as something the bookmarks point to. Without bookmarks pointing to them the anonymous heads are not usable as a branch to work with (for more than just a local merge) and share. When you have anonymous heads in a repository you don't know what they are supposed to be or where they came from, unless you remember or have other clues. In my eyes anonymous heads are only a workaround for late implementation of bookmarks and no good implementation of remotes/remote heads.
Named branches are rather unrelated, as the only thing they have in common with git branches is having a name. They are light-weight in comparision to cloning the whole repository (forking as branch model), but not in terms of "you can't get rid of them". They are permanent.
Most places tell you not to use named branches unless you have a very good reason or it is a long-running branch.

Using Mercurial local clones for branched development?

I'm an ex SVN user trying to work out the best way to do branched development in hg. My project is fairly new currently has no branches. A friend of mine suggested that making a local clone of the repos. then working in that was better than using a named branch.
So if I use this model, would the workflow be:
[say original project has been cloned to be in c:\projects\sk\tracker]
hg clone https:[url of repos] tracker_featurex [to be issued from c:\projects\sk]
change to subdir tracker_featurex
checkin and push as per normal
[optional, how do I pull changes from the main repos. into this one?]
[final step, how do I get changes from this clone back into the main trunk?]
I need help on whether this workflow is correct and what the exact commands would be for the two steps in the [] braces.
Thanks a great deal to anyone who can help,
Fred
I would recommend you take a look at Steve Losh's post on branching in Mercurial: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
He goes over various types of branches (clones, bookmarks, named branches, anonymous branches) as well as the commands you would run for each. There are pros and cons to all of them. Local clones are ok if you are the only developer but they are not as useful in a workflow where more than one developer needs to work on a branch. The claim that clones are universally better than named branches is a myth. You should find a branching model that fits your workflow.
Update:
If you do want to do local clones you can move you changes using hg push from the new workspace (Assuming you have a Projects folder and a repo named test):
Projects> hg clone test test-new-feature
Projects> cd test-new-feature
Projects/test-new-feature> <do some work>
Projects/test-new-feature> hg commit -m "Work is done."
Projects/test> <Might need a pull/merge here>
Projects/test-new-feature> hg push
If there are changes in the test repo you need to pull/merge them before pushing.
You can also hg pull from the original workspace:
Projects> hg clone test test-new-feature
Projects> cd test-new-feature
Projects/test-new-feature> <do some work>
Projects/test-new-feature> hg commit -m "Work is done."
Projects/test-new-feature> cd ../test
Projects/test> hg pull ../test-new-feature
This might create multiple heads in the test repo and you would need to merge/commit.
Projects/test> hg merge
Projects/test> hg commit -m "Merged in new-feature."
Either are good options. I might recommend pulling rather than pushing. The main difference to me is the location of the merge step. I think pulling from the feature repo makes the history a little more readable.
I am fledgling to Hg, so take what I say with a word of caution :-)
I love having named branches, but use them very judiciously! There are downsides to the approach I use below, but it works well for my current environment which is a small shop. I don't mind preserving history forever and I'm not concerned with reducing the number of commits (but Mq/record/etc can address this latter bit).
This is how I use branches in the code I work on:
Default branch.
This is built on the build server.
This should only have one head.
This should always compile.
This should always be the "best effort" at completing bugs/features.
"Workbench" branch.
This can have multiple heads.
Anonymous branches are encouraged. Shared bookmarks used to "name" active anonymous branches.
The state should be almost always compilable, but it is not a requirement.
Represents "work in progress".
Okay, so this is what my process might look like this: (I've excluded pull/push/merge-theirs steps).
I get a bug report in.
I switch to "workbench" tip (or whatever revision is appropriate).
I fix the bug, possibly committing several times. (I really should learn to use queues or record, etc.)
(If I am interrupted in the above process, e.g. have to work on a different bug, or am otherwise side-tracked I will create a new head above where #2, or as appropriate. I may give the current anonymous branch tip a name with a bookmark, or I may not.)
Once complete, I merge the relevant branch/changes into "default" and hopefully the build server still loves me :-)
I think the best thing to do is forget about how branches in SVN worked. They are not liked named branches at all and anyone who says otherwise is latching onto the fact they both have "names" and not much more. Every branch in Hg is part of a "named branch" (that is, has a name associated with it, be it "default" or "workbench" or otherwise). But it doesn't matter, except for organization: a branch is a branch and it doesn't matter if it's referring to the "tip" of an anonymous branch or the tip of the only head (really an anonymous branch itself) in a named branch.
Try a few things, use what works best :)
making a local clone of the repos. then working in that was better than using a named branch.
Overly dramatic and ambitious statement in common. When you clone-per-feature, you have only one branch (named branch) per repo, but nothing more (practically, briefly speaking).
When feature is finished, you have to "push to parent"|"pull from clone" in order to return changes back. At this stage, if some work was done in parent repo after clone, anonymous branch will appear (+1 head) and merge is a must (same as for work in named brach in one repo), but, it named brach can tells something fast later (you use good names, isn't it?), anonymous branch tells almost nothing without additional tricks (bookmarks, f.e). Part of my repo below as example of work in clone with intermediate pulls and must-merges after pulls/ (sorry, russian commit-messages) and even I can't recall now, why I had repo cloned for editorials - maybe I just play with Clones-Workflow

Close an unmerged wasteful branch in mercurial

I decide to start an experiment in a branch
[default] $ hg branch experiment
[experiment] $ [... some commits ...]
Aargh! does not work! I want to throw it away.
[experiment] $ hg commit -m "did not work; closing ..." --close-branch
[experiment] $ hg update default
To get the real tip back -
[default] $ [... some commits ...]
[default] $ hg push
Is this a correct workflow to destroy an experimental branch?
You've got two fine answers on how to undo your branch, but the bigger point is don't use named branches for temporary concepts. Named branches are for long lived entities like 'development' and 'stable'. For features, expiriments, etc. you want either clones, bookmarks, or anonymous branches. All three are contrasted with named branches in this excellent article by Steve Losh:
http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
You can see similar advice from the Mercurial project here:
https://www.mercurial-scm.org/wiki/StandardBranching
The Mercurial wiki covers all the options for Pruning Dead Branches. Briefly, these options include:
Closing the branch (as done in your original post)
Create a new clone that does not include the dead branch
Use a no-op merge
Use the strip command that is bundled with the mq extension
Closing a branch will leave it in the repository, and the closed branch will be pushed with other changesets next time you do a push.
If you don't want this to happen, and your branch is local, just strip it.
On the other hand, if you have already pushed the experimental branch, stripping it won't help, so you can either close it or do a dummy merge (or both).
In my opinion, you should just close the branch and forget about it.
In the long run, there's no harm in a "dead" branch being present in the repository. Any given branch is almost certainly tiny in comparison to the contents of your repository and any additional "noise" created by the additional changesets is going to fade into the past relatively quickly.
However, by not worrying about cleaning up the branch, you achieve two things:
You don't have to deal with any of the potential issues associated with altering history in a DVCS.
(More importantly) You have a permanent record of your attempt.
That second point is key -- you can actually make use of what you learned if the branch is still around: any fellow developers can learn from it; you can go back and try again if you learn something else; you can prevent trying the same thing again by seeing this branch in history.
A lot of developers have a hard time with keeping history that isn't "pristine" in their DVCS, especially when they recently came from a centralized VCS.* Over time, I've come to realize that there's nothing bad or wrong about that "other" history and in fact it can turn out to be remarkably useful if kept around.
*I'm not necessarily implying that you fall into either of these camps, just making an observation.

What is the purpose of closing a branch

I was wondering, what is the purpose of closing a branch. As for issue-1 branch, I had already close. But
I still can see issue1-1 in my revision graph
I still can switch to branch issue1-1, and continue to commit.
So, what is the whole point of closing a branch?
See: https://www.mercurial-scm.org/wiki/PruningDeadBranches
It is informational so that hg branches will show that these branches are closed. And hg heads --active will not display any heads that are marked closed.
In a long run, number of branches can be considerable and can add to informational noise. This is a good way to prune some of those noise.
This is exactly why named branches probably aren't the right choice for per-feature and per-issue branches -- you can hide them but you can't eliminate them. Consider reserving named branches for long-lived concepts like 'stable', 'experimental', etc. For per-issue and per-feature branching either anonymous branches, clone branches, or bookmarks are better solutions. They're all described wonderfully here:
A Guide to Branching In Mercurial.

Can I branch in Mercurial without cloning the repository?

Recently, I've started experimenting with Mercurial, due to the fact that it always attracted it because of its simplicity and "just works" principle. Or at least, that's how others always described it.
They also usually described it as "practically the same as git with just a few minor changes you won't notice" - only for me to discover it isn't quite so.
I'm having problem with Hg branches. Pardon me if this is an overly simple question, but in git one has a working directory and a repo (.git). In the repo one has revisions, and branches, and can jump from one to another.
I'm having trouble finding a similar model in Hg. As far as I can see, for Hg to have a "branch" one needs to clone a repo to another directory? Is there a way Hg could work just like git does - i.e. one working dir., and one repo, in which you can do things as regard to branching and revs?
Mercurial supports a very rich set of ways to branch. See http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
In brief, you can create a named branch by running
hg branch NewBranch
and switch to that branch using
hg up NewBranch
or switch back to trunk using
hg up default
In Mercurial, if you go to any particular revision, you can always edit your working copy and commit, thereby making another "head." Merging works on head revisions by default. You can use hg head to see what heads are in your repository. This seems to be the most "idiomatic" way I have found branching to work in Mercurial.
Take a look at section about branches in my answer to "Git and Mercurial - Compare and Contrast" here on StackOverflow.
The information about various options available for branching in Mercurial (anonymous heads, not-propagated (I think yet still) bookmarks, and global (world-wide) commit labels aka named branches) was taken from http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/, and expanded using feedback on #mercurial IRC channel on FreeNode.