synacker
synacker

Reputation: 1782

How to get all closed branches via command line in mercurial?

In command line I can get all heads without closed branches via:

hg heads

Also I can get all heads with closed branches via:

hg heads --closed

But, how do I can know all closed branches via command line?

Upvotes: 6

Views: 2985

Answers (3)

Theo Chirica
Theo Chirica

Reputation: 4516

If you are interested just for the names or md5 you can use:

hg branches --closed | grep '(closed)'

Upvotes: 4

Steven Peters
Steven Peters

Reputation: 129

The hg branches --closed command shows all branches, with closed branches marked with (closed) at the end of the line:

default                     3478:154d6861fb79
regression_plugins          3415:f2e42c49b8cf
wg2                         2531:a4b3ac405ea3
qt_gui_hack                 2289:6505224a780b
github_notice              39240:8808397a6c66 (closed)
bump_9.13                  39230:e2f33b5a9364 (closed)
visual_offset_bbox         39209:6565274172c6 (closed)
remove_x11                 39207:ba78ef512346 (closed)

So you can narrow it down to only closed branches with grep: hg branches --closed | grep '(closed)$':

github_notice              39240:8808397a6c66 (closed)
bump_9.13                  39230:e2f33b5a9364 (closed)
visual_offset_bbox         39209:6565274172c6 (closed)
remove_x11                 39207:ba78ef512346 (closed)

Now, if you want only the branch names, you can use awk to strip away the changeset info:

hg branches --closed | grep '(closed)$' | awk '{ print $1; }'

github_notice
bump_9.13
visual_offset_bbox
remove_x11

Note that if your hg repository uses whitespace in branch names, then some extra care is needed. (I have no idea why they allowed this; it is not allowed in git.)

At this point, the other answers recommending hg log -r 'closed()' --template '{branch}\n' look much more elegant by comparison, but there are some edge cases in which this command is wrong. This command prints the name of any branch that has ever been closed, but mercurial allows branches to be re-opened by committing to them again. So this would incorrectly identify a re-opened branch as still closed (because it is checking all commits, not just the heads of branches).

Aha! you might say, let's use hg log -r 'closed() and head()' --template '{branch}\n' to only print branch names that have closed heads. Surely that will do the trick, and it's cleaner than piping to grep and sed/awk! But a mercurial branch can have multiple heads, and is considered open if at least one of the heads is open. This command would declare a branch closed if it has any closed heads, even if it also has an open head.

I learned this the hard way when migrating a large and complicated mercurial repository to git and trying to delete all the branches that had been closed. My script kept deleting branches that hadn't been closed, and that's when I discovered these edge cases.

Upvotes: 2

Lazy Badger
Lazy Badger

Reputation: 97282

RTM hg help revsets

hg log -r "closed()"

Samples:

>hg heads -T "{rev}:{node|short}\n"
9:caaade505e23
5:0c0ceaa4a8d2
3:3c58290b241d
1:99f7ad94a56f

>hg heads -c -T "{rev}:{node|short}\n"
10:fc7ddfb862bd
9:caaade505e23
5:0c0ceaa4a8d2
3:3c58290b241d
1:99f7ad94a56f

>hg log -r "closed()" -T "{rev}:{node|short}\n"
10:fc7ddfb862bd

Branch names for all closed heads (useful for named branches mostly)

hg log -r "closed()" -T "{branch}\n"

Upvotes: 7

Related Questions