diff --git a/hgext/show.py b/hgext/show.py --- a/hgext/show.py +++ b/hgext/show.py @@ -161,9 +161,10 @@ ui.write(_('(no bookmarks set)\n')) return + revs = [repo[node].rev() for node in marks.values()] active = repo._activebookmark longestname = max(len(b) for b in marks) - # TODO consider exposing longest shortest(node). + nodelen = longestshortest(repo, revs) for bm, node in sorted(marks.items()): fm.startitem() @@ -172,7 +173,7 @@ fm.write('node', fm.hexfunc(node), fm.hexfunc(node)) fm.data(active=bm == active, longestbookmarklen=longestname, - nodelen=5) + nodelen=nodelen) @showview('stack', csettopic='stack') def showstack(ui, repo, displayer): @@ -236,6 +237,9 @@ else: newheads = set() + allrevs = set(stackrevs) | newheads | set([baserev]) + nodelen = longestshortest(repo, allrevs) + try: cmdutil.findcmd('rebase', commands.table) haverebase = True @@ -247,7 +251,7 @@ # our simplicity and the customizations required. # TODO use proper graph symbols from graphmod - shortesttmpl = formatter.maketemplater(ui, '{shortest(node, 5)}') + shortesttmpl = formatter.maketemplater(ui, '{shortest(node, %d)}' % nodelen) def shortest(ctx): return shortesttmpl.render({'ctx': ctx, 'node': ctx.hex()}) @@ -278,7 +282,7 @@ ui.write(' ') ui.write(('o ')) - displayer.show(ctx, nodelen=5) + displayer.show(ctx, nodelen=nodelen) displayer.flush(ctx) ui.write('\n') @@ -318,7 +322,7 @@ ui.write(' ') ui.write(symbol, ' ') - displayer.show(ctx, nodelen=5) + displayer.show(ctx, nodelen=nodelen) displayer.flush(ctx) ui.write('\n') @@ -335,7 +339,7 @@ ui.write(_('(stack base)'), '\n', label='stack.label') ui.write(('o ')) - displayer.show(basectx, nodelen=5) + displayer.show(basectx, nodelen=nodelen) displayer.flush(basectx) ui.write('\n') @@ -394,12 +398,13 @@ """changesets that aren't finished""" # TODO support date-based limiting when calling revset. revs = repo.revs('sort(_underway(), topo)') + nodelen = longestshortest(repo, revs) revdag = graphmod.dagwalker(repo, revs) ui.setconfig('experimental', 'graphshorten', True) cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, - props={'nodelen': 5}) + props={'nodelen': nodelen}) def extsetup(ui): # Alias `hg ` to `hg show `. @@ -420,6 +425,27 @@ ui.setconfig('alias', name, 'show %s' % view, source='show') +def longestshortest(repo, revs, minlen=5): + """Return the length of the longest shortest node to identify revisions. + + The result of this function can be used with the ``shortest()`` template + function to ensure that a value is unique and unambiguous for a given + set of nodes. + + The number of revisions in the repo is taken into account to prevent + a numeric node prefix from conflicting with an integer revision number. + If we fail to do this, a value of e.g. ``10023`` could mean either + revision 10023 or node ``10023abc...``. + """ + tmpl = formatter.maketemplater(repo.ui, '{shortest(node, %d)}' % minlen) + lens = [minlen] + for rev in revs: + ctx = repo[rev] + shortest = tmpl.render({'ctx': ctx, 'node': ctx.hex()}) + lens.append(len(shortest)) + + return max(lens) + # Adjust the docstring of the show command so it shows all registered views. # This is a bit hacky because it runs at the end of module load. When moved # into core or when another extension wants to provide a view, we'll need