[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