[PATCH 3 of 4] branch closing: referencing open and closed branches/heads

John Mulligan phlogistonjohn at asynchrono.us
Tue Dec 23 13:31:39 CST 2008


# HG changeset patch
# User John Mulligan <phlogistonjohn at asynchrono.us>
# Date 1230060649 18000
# Node ID 97cf9f9459b3b6e65c338a452bf94bab8b0b25ef
# Parent  8fb6d10eaebc5cf8a55f5bd7098e219d69d92ffa
branch closing: referencing open and closed branches/heads

Treat closed branches as "inactive" in the output of hg branches.
Add -a/--active option to "hg heads" which will hide heads marked closed.
When multiple branch heads exist the branch name will refer to the
tipmost open head, and if none exist, then the tipmost closed head.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -428,7 +428,7 @@
     """
     hexfunc = ui.debugflag and hex or short
     activebranches = [util.tolocal(repo[n].branch())
-                            for n in repo.heads()]
+                            for n in repo.heads(closed=False)]
     branches = util.sort([(tag in activebranches, repo.changelog.rev(node), tag)
                           for tag, node in repo.branchtags().items()])
     branches.reverse()
@@ -1252,9 +1252,10 @@
         start = repo.lookup(opts['rev'])
     else:
         start = None
+    closed = not opts.get('active')
     if not branchrevs:
         # Assume we're looking repo-wide heads if no revs were specified.
-        heads = repo.heads(start)
+        heads = repo.heads(start, closed=closed)
     else:
         heads = []
         visitedset = util.set()
@@ -1263,7 +1264,7 @@
             if branch in visitedset:
                 continue
             visitedset.add(branch)
-            bheads = repo.branchheads(branch, start)
+            bheads = repo.branchheads(branch, start, closed=closed)
             if not bheads:
                 if branch != branchrev:
                     ui.warn(_("no changes on branch %s containing %s are "
@@ -3202,6 +3203,8 @@
     "heads":
         (heads,
          [('r', 'rev', '', _('show only heads which are descendants of rev')),
+          ('a', 'active', False,
+           _('show only the active heads from open branches')),
          ] + templateopts,
          _('[-r REV] [REV]...')),
     "help": (help_, [], _('[TOPIC]')),
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -398,8 +398,21 @@
 
     def branchtags(self):
         '''return a dict where branch names map to the tipmost head of
-        the branch'''
-        return dict([ (k, v[-1]) for (k, v) in self._branchheads().items() ])
+        the branch, open heads come before closed'''
+        bt = {}
+        for bn, heads in self._branchheads().items():
+            head = None
+            for i in range(len(heads)-1, -1, -1):
+                h = heads[i]
+                if 'close' not in self.changelog.read(h)[5]:
+                    head = h
+                    break
+            # no open heads were found
+            if head is None:
+                head = heads[-1]
+            bt[bn] = head
+        return bt
+
 
     def _readbranchcache(self):
         partial = {}
@@ -1181,13 +1194,18 @@
         finally:
             del wlock
 
-    def heads(self, start=None):
+    def heads(self, start=None, closed=True):
         heads = self.changelog.heads(start)
+        def display(head):
+            if closed:
+                return True
+            extras = self.changelog.read(head)[5]
+            return ('close' not in extras)
         # sort the output in rev descending order
-        heads = [(-self.changelog.rev(h), h) for h in heads]
+        heads = [(-self.changelog.rev(h), h) for h in heads if display(h)]
         return [n for (r, n) in util.sort(heads)]
 
-    def branchheads(self, branch=None, start=None):
+    def branchheads(self, branch=None, start=None, closed=True):
         if branch is None:
             branch = self[None].branch()
         branches = self._branchheads()
@@ -1199,6 +1217,9 @@
         if start is not None:
             # filter out the heads that cannot be reached from startrev
             bheads = self.changelog.nodesbetween([start], bheads)[2]
+        if not closed:
+            bheads = [ h for h in bheads if 
+                       ('close' not in self.changelog.read(h)[5]) ]
         return bheads
 
     def branches(self, nodes):


More information about the Mercurial-devel mailing list