[PATCH 3 of 4] Add option to heads to show only heads for current branch
Eric Hopper
hopper at omnifarious.org
Tue Jun 12 14:46:23 CDT 2007
# HG changeset patch
# User Eric Hopper <hopper at omnifarious.org>
# Date 1181674376 25200
# Node ID c7b1b8e2d05e26d0777c98657e558f57f3e76c34
# Parent 9b0de5e860bce0bb1f506b5c8454816a11fad085
Add option to heads to show only heads for current branch.
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1210,19 +1210,56 @@ def grep(ui, repo, pattern, *pats, **opt
found = display(fn, rev, {}, state) or found
return (not found and 1) or 0
-def heads(ui, repo, **opts):
+def heads(ui, repo, *branches, **opts):
"""show current repository heads
Show all repository head changesets.
+
+ If branch names are given this will show the heads of the
+ specified branches.
Repository "heads" are changesets that don't have children
changesets. They are where development generally takes place and
are the usual targets for update and merge operations.
+
+ Branch heads are revisions that have the branch tag, but have no
+ child revisions with that tag. They are usually where
+ development on the given branch takes place.
"""
if opts['rev']:
- heads = repo.heads(repo.lookup(opts['rev']))
+ start = repo.lookup(opts['rev'])
else:
- heads = repo.heads()
+ start = None
+ if len(branches) > 0:
+ heads = []
+ visitedset = set()
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ for branch in branches:
+ if branch == '.':
+ realbranch = repo.changectx('.').branch()
+ else:
+ realbranch = branch
+ if realbranch in visitedset:
+ continue
+ visitedset.add(realbranch)
+ if realbranch not in repo.branchtags():
+ ui.warn(_("The branch %s doesn't exist yet.\n") % (branch,))
+ continue
+ bheads = repo.branchheads(realbranch, start)
+ if len(bheads) <= 0:
+ if realbranch != branch:
+ ui.warn(_("No changes on branch %s (aka %s) are reachable "\
+ "from revision %s\n") % \
+ (branch, realbranch, opts['rev']))
+ else:
+ ui.warn(_("No changes on branch %s are reachable "\
+ "from revision %s\n") % \
+ (branch, opts['rev']))
+ heads.extend(bheads)
+ else:
+ heads = repo.heads(start)
+ if len(heads) <= 0:
+ return 1
displayer = cmdutil.show_changeset(ui, repo, opts)
for n in heads:
displayer.show(changenode=n)
@@ -2788,6 +2825,7 @@ table = {
"heads":
(heads,
[('', 'style', '', _('display using template map file')),
+ ('b', 'branch', None, _("show even inactive heads for just the current branch")),
('r', 'rev', '', _('show only heads which are descendants of rev')),
('', 'template', '', _('display with template'))],
_('hg heads [-r REV]')),
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1094,6 +1094,52 @@ class localrepository(repo.repository):
heads.sort()
return [n for (r, n) in heads]
+ def branchheads(self, branch, start=None):
+ branches = self.branchtags()
+ if branch not in branches:
+ return []
+ # The basic algorithm is this:
+ #
+ # Start from the branch tip since there are no later revisions that can
+ # possibly be in this branch, and the tip is a guaranteed head.
+ #
+ # Remember the tip's parents as the first ancestors, since these by
+ # definition are not heads.
+ #
+ # Step backwards from the brach tip through all the revisions. We are
+ # guaranteed by the rules of Mercurial that we will now be visiting the
+ # nodes in reverse topological order (children before parents).
+ #
+ # If a revision is one of the ancestors of a head then we can toss it
+ # out of the ancestors set (we've already found it and won't be
+ # visiting it again) and put its parents in the ancestors set.
+ #
+ # Otherwise, if a revision is in the branch it's another head, since it
+ # wasn't in the ancestor list of an existing head. So add it to the
+ # head list, and add its parents to the ancestor list.
+ #
+ # If it is not in the branch ignore it.
+ #
+ # Once we have a list of heads, use nodesbetween to filter out all the
+ # heads that cannot be reached from startrev. There may be a more
+ # efficient way to do this as part of the previous algorithm.
+
+ set = util.hgset
+ heads = [self.changelog.rev(branches[branch])]
+ # Don't care if ancestors contains nullrev or not.
+ ancestors = set(self.changelog.parentrevs(heads[0]))
+ for rev in xrange(heads[0] - 1, nullrev, -1):
+ if rev in ancestors:
+ ancestors.update(self.changelog.parentrevs(rev))
+ ancestors.remove(rev)
+ elif self.changectx(rev).branch() == branch:
+ heads.append(rev)
+ ancestors.update(self.changelog.parentrevs(rev))
+ heads = [self.changelog.node(rev) for rev in heads]
+ if start is not None:
+ heads = self.changelog.nodesbetween([start], heads)[2]
+ return heads
+
def branches(self, nodes):
if not nodes:
nodes = [self.changelog.tip()]
diff --git a/tests/test-bheads b/tests/test-bheads
new file mode 100755
--- /dev/null
+++ b/tests/test-bheads
@@ -0,0 +1,105 @@
+#!/bin/sh
+
+hg init a
+cd a
+echo 'root' >root
+hg add root
+hg commit -d '0 0' -u test -m "Adding root node"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+echo 'a' >a
+hg add a
+hg branch a
+hg commit -d '1 0' -u test -m "Adding a branch"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+hg update -C 0
+echo 'b' >b
+hg add b
+hg branch b
+hg commit -d '2 0' -u test -m "Adding b branch"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+echo 'bh1' >bh1
+hg add bh1
+hg commit -d '3 0' -u test -m "Adding b branch head 1"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+hg update -C 2
+echo 'bh2' >bh2
+hg add bh2
+hg commit -d '4 0' -u test -m "Adding b branch head 2"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+hg update -C 2
+echo 'bh3' >bh3
+hg add bh3
+hg commit -d '5 0' -u test -m "Adding b branch head 3"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+hg merge 4
+hg commit -d '6 0' -u test -m "Merging b branch head 2 and b branch head 3"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+echo 'c' >c
+hg add c
+hg branch c
+hg commit -d '7 0' -u test -m "Adding c branch"
+hg heads
+echo '-------'
+hg heads .
+
+echo '======='
+hg heads -r 3 .
+echo $?
+echo '-------'
+hg heads -r 2 .
+echo $?
+echo '-------'
+hg update -C 4
+echo $?
+echo '-------'
+hg heads -r 3 .
+echo $?
+echo '-------'
+hg heads -r 2 .
+echo $?
+echo '-------'
+hg heads -r 7 .
+echo $?
+
+echo '======='
+for i in 0 1 2 3 4 5 6 7; do
+ hg update -C "$i"
+ hg heads
+ echo '-------'
+ hg heads .
+ echo '-------'
+done
+
+echo '======='
+for i in a b c d; do
+ hg heads "$i"
+ echo '-------'
+done
diff --git a/tests/test-bheads.out b/tests/test-bheads.out
new file mode 100644
--- /dev/null
+++ b/tests/test-bheads.out
@@ -0,0 +1,572 @@
+changeset: 0:19709c5a4e75
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: Adding root node
+
+-------
+changeset: 0:19709c5a4e75
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: Adding root node
+
+=======
+changeset: 1:dd6b440dd85a
+branch: a
+tag: tip
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 1:dd6b440dd85a
+branch: a
+tag: tip
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+=======
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+changeset: 2:ac22033332d1
+branch: b
+tag: tip
+parent: 0:19709c5a4e75
+user: test
+date: Thu Jan 01 00:00:02 1970 +0000
+summary: Adding b branch
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 2:ac22033332d1
+branch: b
+tag: tip
+parent: 0:19709c5a4e75
+user: test
+date: Thu Jan 01 00:00:02 1970 +0000
+summary: Adding b branch
+
+=======
+changeset: 3:aee39cd168d0
+branch: b
+tag: tip
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 3:aee39cd168d0
+branch: b
+tag: tip
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+=======
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+changeset: 4:22df7444f7c1
+branch: b
+tag: tip
+parent: 2:ac22033332d1
+user: test
+date: Thu Jan 01 00:00:04 1970 +0000
+summary: Adding b branch head 2
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 4:22df7444f7c1
+branch: b
+tag: tip
+parent: 2:ac22033332d1
+user: test
+date: Thu Jan 01 00:00:04 1970 +0000
+summary: Adding b branch head 2
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+=======
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+changeset: 5:0d57af4f9583
+branch: b
+tag: tip
+parent: 2:ac22033332d1
+user: test
+date: Thu Jan 01 00:00:05 1970 +0000
+summary: Adding b branch head 3
+
+changeset: 4:22df7444f7c1
+branch: b
+parent: 2:ac22033332d1
+user: test
+date: Thu Jan 01 00:00:04 1970 +0000
+summary: Adding b branch head 2
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 5:0d57af4f9583
+branch: b
+tag: tip
+parent: 2:ac22033332d1
+user: test
+date: Thu Jan 01 00:00:05 1970 +0000
+summary: Adding b branch head 3
+
+changeset: 4:22df7444f7c1
+branch: b
+parent: 2:ac22033332d1
+user: test
+date: Thu Jan 01 00:00:04 1970 +0000
+summary: Adding b branch head 2
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+=======
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+changeset: 6:00432327d822
+branch: b
+tag: tip
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+tag: tip
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+=======
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+=======
+No changes on branch . (aka c) are reachable from revision 3
+1
+-------
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+0
+-------
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+0
+-------
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+0
+-------
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+0
+-------
+No changes on branch . (aka b) are reachable from revision 7
+1
+=======
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 0:19709c5a4e75
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: Adding root node
+
+-------
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+-------
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+-------
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+-------
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+-------
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+-------
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+-------
+=======
+changeset: 1:dd6b440dd85a
+branch: a
+user: test
+date: Thu Jan 01 00:00:01 1970 +0000
+summary: Adding a branch
+
+-------
+changeset: 6:00432327d822
+branch: b
+parent: 5:0d57af4f9583
+parent: 4:22df7444f7c1
+user: test
+date: Thu Jan 01 00:00:06 1970 +0000
+summary: Merging b branch head 2 and b branch head 3
+
+changeset: 3:aee39cd168d0
+branch: b
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: Adding b branch head 1
+
+-------
+changeset: 7:9fb091bb9835
+branch: c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:07 1970 +0000
+summary: Adding c branch
+
+-------
+The branch d doesn't exist yet.
+-------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://selenic.com/pipermail/mercurial-devel/attachments/20070612/d50468b0/attachment-0001.pgp
More information about the Mercurial-devel
mailing list