# HG changeset patch # User John Mulligan # Date 2009-01-15 02:47:38 # Node ID 6a24fb994701945190be5687d2feda811a748c6c # Parent cce37dab7ad6e7f80fe9b44e827e2b3334faeadc branch closing: referencing open and closed branches/heads Treat fully closed branches similarly to "inactive" in the output of 'hg branches'. They will be suffixed with "(closed)" where inactive branches are marked with "(inactive)". If the -a/--active option is given both inactive and closed branches will not be shown. Partially closed branches (multiple heads, at least one not closed) will display the next (tipmost) open head. Add -a/--active option to "hg heads" which will hide closed heads iff the option is specified. In other hg commands, 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 @@ -431,7 +431,7 @@ def branches(ui, repo, active=False): """ 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() @@ -441,9 +441,15 @@ def branches(ui, repo, active=False): if ui.quiet: ui.write("%s\n" % tag) else: + hn = repo.lookup(node) + if isactive: + notice = '' + elif hn not in repo.branchheads(tag, closed=False): + notice = ' (closed)' + else: + notice = ' (inactive)' rev = str(node).rjust(31 - util.locallen(tag)) - isinactive = ((not isactive) and " (inactive)") or '' - data = tag, rev, hexfunc(repo.lookup(node)), isinactive + data = tag, rev, hexfunc(hn), notice ui.write("%s %s:%s%s\n" % data) def bundle(ui, repo, fname, dest=None, **opts): @@ -1266,9 +1272,10 @@ def heads(ui, repo, *branchrevs, **opts) 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() @@ -1277,7 +1284,7 @@ def heads(ui, repo, *branchrevs, **opts) 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 " @@ -3215,6 +3222,8 @@ table = { "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 @@ class localrepository(repo.repository): 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().iteritems()]) + the branch, open heads come before closed''' + bt = {} + for bn, heads in self._branchheads().iteritems(): + 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 = {} @@ -1180,13 +1193,18 @@ class localrepository(repo.repository): 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() @@ -1198,6 +1216,9 @@ class localrepository(repo.repository): 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):