[PATCH 3 of 5] Add option to heads to show only heads for current branch
Alexis S. L. Carvalho
alexis at cecm.usp.br
Tue Jun 5 18:40:52 UTC 2007
Thus spake Eric Hopper:
> # HG changeset patch
> # User Eric Hopper <hopper at omnifarious.org>
> # Date 1181054192 25200
> # Node ID f32f2c89f227b4ce07c60882c9091f078b18a1ed
> # Parent 8b12d7cf038ff6569af620d20cb0d04cc66063bd
> 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
> @@ -1253,10 +1253,13 @@ def heads(ui, repo, **opts):
> changesets. They are where development generally takes place and
> are the usual targets for update and merge operations.
> """
> + branch = None
> + if opts['branch']:
> + branch = repo.dirstate.branch()
> if opts['rev']:
> - heads = repo.heads(repo.lookup(opts['rev']))
> + heads = repo.heads(repo.lookup(opts['rev']), branch=branch)
> else:
> - heads = repo.heads()
> + heads = repo.heads(branch=branch)
> displayer = cmdutil.show_changeset(ui, repo, opts)
> for n in heads:
> displayer.show(changenode=n)
> @@ -2822,6 +2825,7 @@ table = {
> "heads":
> (heads,
> [('', 'style', '', _('display using template map file')),
> + ('b', 'branch', None, _("show even inactive heads for just the current branch")),
The heads command in 0.9.3 (which is still the most recent version)
still has a -b/--branches option for old-style branches...
This interface also requires a "hg branch foo; hg heads -b" to see the
heads of a non-current branch, which is not exactly optimal, and which
just won't work if you can't write .hg/branch.
Maybe "hg [-b] [branch]" (-b is still a boolean option) - if you specify
branch, print heads of that branch; if you specify -b, print heads of
the current branch; if you specify both, err...
> ('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
> @@ -1079,12 +1079,40 @@ class localrepository(repo.repository):
> self.dirstate.update([dest], "a")
> self.dirstate.copy(source, dest)
>
> - def heads(self, start=None):
> + def heads(self, start=None, branch=None):
> + if branch is not None:
> + return self.bheads(branch, start)
> heads = self.changelog.heads(start)
> # sort the output in rev descending order
> heads = [(-self.changelog.rev(h), h) for h in heads]
> heads.sort()
> return [n for (r, n) in heads]
> +
> + def bheads(self, branch, start=None):
> + branches = self.branchtags()
> + if branch not in branches:
> + ui.warn(_("%s is a new branch that has no heads yet.\n") % (branch,))
This warning should be in commands.py
> + return []
> + heads = [branches[branch]]
> + p = self.changelog.parents(heads[0])
> + parents = dict.fromkeys([n for n in p if n != nullid], 0)
> + for rev in xrange(self.changelog.rev(heads[0]) - 1, -1, -1):
> + node = self.changelog.node(rev)
> + if node in parents:
> + p = self.changelog.parents(node)
> + parents.update(dict.fromkeys([n for n in p if n != nullid], 0))
> + del parents[node]
> + elif self.changectx(rev).branch() == branch:
> + heads.append(node)
> + p = self.changelog.parents(node)
> + parents.update(dict.fromkeys([n for n in p if n != nullid], 0))
Some comments outlining the algorithm (or at least the basic idea) would
be nice.
I'd say that using rev/parentrevs/nullrev would be a bit faster, but
since you're reading a good chunk of the changelog, that probably won't
be noticeable. The dict.fromkeys([...]) in the loop also look somewhat
heavy-handed.
We should probably just save all the heads in the branch cache.
> + if start is not None:
> + heads = self.changelog.nodesbetween([start], heads)[2]
> + if len(heads) < 0:
> + self.ui.warn(_("No changes on branch %s are reachable from "\
> + "revision %d\n") % \
> + (branch, self.changelog.rev(start)))
This warning should also go in commands.py (without the extra space
after "No"). You probably want to test for "not heads", since
len(heads) is probably never negative :)
Extra brownie points if you make the exit code non-zero when you print
the warnings.
Maybe the warnings should be printed only with --verbose? Or maybe
--quiet should suppress them...
> + return heads
>
> def branches(self, nodes):
> if not nodes:
>
Alexis
More information about the Mercurial-devel
mailing list