Differences between revisions 6 and 7
Revision 6 as of 2008-05-17 23:15:39
Size: 2881
Editor: JamesWalker
Comment: typos
Revision 7 as of 2009-01-17 19:54:48
Size: 3500
Editor: JohnMulligan
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
== Pruning dead branches == #pragma section-numbers 2
= Pruning branches =

There are three standard ways of managing branches that you no longer plan on working with. Each approach has pluses and minuses and should be selected on what best fits how you work with your repository.

[[TableOfContents]]

== No-Op Merges ==
Line 20: Line 27:
=== Using strip === == Using strip ==
Line 37: Line 44:
=== Closing branches === == Closing branches ==
Line 39: Line 46:
There was a proposal about a new "closing branches" feature for Mercurial on the mailing list.[[FootNote(http://selenic.com/pipermail/mercurial-devel/2008-March/005087.html)]] A variant was discussed to add a new flag to changesets, which – when set – indicates that a branch (or head) is to be considered "closed".[[FootNote(http://selenic.com/pipermail/mercurial-devel/2008-March/005130.html)]] This closing changeset would typically contain no modifications to tracked files. As of 2009-01-14 the mercurial main repository contains support for branch closing. This feature will be part of the next Mercurial major release. (See TimeBasedReleasePlan)
Line 41: Line 48:
Closing a branch with head H would then be done by committing a new changeset C having H as parent and setting that "closed" flag in C. Other hg commands would then respect that flag, for example {{{hg heads}}} might then return only heads which are not closed. A branch can be closed by running the following commands:
{{{
hg up -C badbranch
hg commit --close-branch -m 'close badbranch, this approach never worked'
hg up -C default # switch back to "good" branch
}}}

This creates a closing changeset which typically contains no modifications to tracked files. Closing changesets can be identified by close=1 in the changeset's extra field.

Once a branch is closed it will display the closed state in {{{hg branches}}}. A closed branch is not considered active and will not be displayed if the --active option is given to branches.
{{{
% hg branches
default 12:d52ed2ac9127
badbranch 11:cd3e11a024bf (closed)
% hg branches --active
default 12:d52ed2ac9127
}}}

In addition {{{hg heads}}} now accepts the --active option and will not display any heads that
have been marked closed if the option is specified.

Pruning branches

There are three standard ways of managing branches that you no longer plan on working with. Each approach has pluses and minuses and should be selected on what best fits how you work with your repository.

TableOfContents

1. No-Op Merges

If you've got a dead [:Branch:branch] you'd like to eliminate from the list of [:Head:heads], you can do a 'no-op merge' to remove it:

$ hg update -C tip # jump to one head
$ hg merge otherhead # merge in the other head
$ hg revert -a -r tip # undo all the changes from the merge
$ hg commit -m "eliminate other head" # create new tip identical to the old

1.1. Why this might be bad

The new merged head is based on the "eliminated" head, so it is not really eliminated. Furthermore, it is now incorporated into the main line, which actually may even be worser than simply letting that dead head alone.

Consider you have a clone of a project like Mercurial – let's say a clone of the [:CrewRepository:crew repository] – and you do make a change C1 based on some changeset P from the crew repo and propose that to the crew members for inclusion into the project.

If your change C1 is rejected or rebased on inclusion, you now have a dead branch C1 in your repo. If you merge that in your repo, you just create yet another line of development that is divergent from crew. So, in this case, merging your dead head doesn't make anything better as any new change you commit to your merged head won't be accepted for inclusion into crew anymore, since that would mean pulling-in your "eliminated" head as well. Such a new change would be said to not be "clean".

2. Using strip

Another option may be to strip your dead branch with hg strip, a command which is provided by the [:MqExtension]:

hg strip [-f] [-b] [-n] REV

strip a revision and all later revs on the same branch

options:

 -b --backup    bundle unrelated changesets
 -n --nobackup  no backups

However, note that this is a non-history-preserving transformation of your repository. If anyone else has already pulled your C1 and used that as a parent for more changes, you might get that back if you pull from that person (The "Genie is out of the Bottle" problem, see also [:EditingHistory]).

3. Closing branches

As of 2009-01-14 the mercurial main repository contains support for branch closing. This feature will be part of the next Mercurial major release. (See TimeBasedReleasePlan)

A branch can be closed by running the following commands:

hg up -C badbranch
hg commit --close-branch -m 'close badbranch, this approach never worked'
hg up -C default # switch back to "good" branch

This creates a closing changeset which typically contains no modifications to tracked files. Closing changesets can be identified by close=1 in the changeset's extra field.

Once a branch is closed it will display the closed state in hg branches. A closed branch is not considered active and will not be displayed if the --active option is given to branches.

% hg branches
default                       12:d52ed2ac9127
badbranch                 11:cd3e11a024bf (closed)
% hg branches --active
default                       12:d52ed2ac9127

In addition hg heads now accepts the --active option and will not display any heads that have been marked closed if the option is specified.


CategoryTipsAndTricks

PruningDeadBranches (last edited 2022-12-26 20:11:56 by gavenkoa)