Context
During the audit and fix for #310 (PR #1334), we identified several opportunities to modernize the Mercurial backend. The current code uses patterns from ~2015-era Mercurial scripting and manually reimplements features that have been built into Mercurial templates for years.
Minimum supported Mercurial version should be documented as 5.2 (August 2019). All current LTS distros ship 5.6+.
Follow-up tasks
1. Replace get_latest_normalizable_tag() with latesttag(pattern)
The method at _hg.py:193 manually reimplements what {latesttag(r're:\.')} + {latesttagdistance} already provide (available since Mercurial ~4.6, May 2018). This would:
- Replace the manual
ancestors(.) and tag('re:\\.') revset with a single template expression
- Reduce the number of
hg log subprocess calls from 3-4 to 2
- Remove ~15 lines of manual tag discovery code
Caveat: latesttagdistance uses "longest path" semantics which may differ slightly from the current "count revisions in revset" approach. Needs careful testing.
2. Consolidate _get_node_info + distance resolution into fewer hg calls
Currently get_meta() makes up to 4 separate hg subprocess calls:
hg log -r . -T "{node}\n{tags}\n{date|shortdate}" — node info
hg id -T "{branch}\n{if(dirty, 1, 0)}\n{date|shortdate}" — branch/dirty
hg log -r "ancestors(.) and tag('re:\\.')" ... — latest normalizable tag
hg log -r "(tag::.) -T "." — distance count
With latesttag(pattern), calls 1+3+4 could potentially be merged into a single hg log call with a richer template.
3. Audit hg-git path for similar improvements
GitWorkdirHgClient.default_describe() in _hg_git.py uses similar tag discovery patterns with tag(r're:v?[0-9].*') revset. It's less impacted (already has version-regex filtering) but could benefit from the same latesttag(pattern) approach.
4. Document minimum Mercurial version
Add a note to the docs that Mercurial 5.2+ is required. No runtime version check is needed — the template features have been stable for 7+ years.
Audit reference
Full audit was performed covering:
- All
run_hg() and hg_log() invocations across _hg.py, _hg_git.py, _file_finders/_hg.py
- All template keywords used:
{node}, {tags}, {branch}, {dirty}, {bookmarks}, {date|shortdate}, {shortdate(date)}
- Mercurial version history for feature availability
- Current LTS distro Mercurial package versions
Context
During the audit and fix for #310 (PR #1334), we identified several opportunities to modernize the Mercurial backend. The current code uses patterns from ~2015-era Mercurial scripting and manually reimplements features that have been built into Mercurial templates for years.
Minimum supported Mercurial version should be documented as 5.2 (August 2019). All current LTS distros ship 5.6+.
Follow-up tasks
1. Replace
get_latest_normalizable_tag()withlatesttag(pattern)The method at
_hg.py:193manually reimplements what{latesttag(r're:\.')}+{latesttagdistance}already provide (available since Mercurial ~4.6, May 2018). This would:ancestors(.) and tag('re:\\.')revset with a single template expressionhg logsubprocess calls from 3-4 to 2Caveat:
latesttagdistanceuses "longest path" semantics which may differ slightly from the current "count revisions in revset" approach. Needs careful testing.2. Consolidate
_get_node_info+ distance resolution into fewer hg callsCurrently
get_meta()makes up to 4 separatehgsubprocess calls:hg log -r . -T "{node}\n{tags}\n{date|shortdate}"— node infohg id -T "{branch}\n{if(dirty, 1, 0)}\n{date|shortdate}"— branch/dirtyhg log -r "ancestors(.) and tag('re:\\.')" ...— latest normalizable taghg log -r "(tag::.) -T "."— distance countWith
latesttag(pattern), calls 1+3+4 could potentially be merged into a singlehg logcall with a richer template.3. Audit hg-git path for similar improvements
GitWorkdirHgClient.default_describe()in_hg_git.pyuses similar tag discovery patterns withtag(r're:v?[0-9].*')revset. It's less impacted (already has version-regex filtering) but could benefit from the samelatesttag(pattern)approach.4. Document minimum Mercurial version
Add a note to the docs that Mercurial 5.2+ is required. No runtime version check is needed — the template features have been stable for 7+ years.
Audit reference
Full audit was performed covering:
run_hg()andhg_log()invocations across_hg.py,_hg_git.py,_file_finders/_hg.py{node},{tags},{branch},{dirty},{bookmarks},{date|shortdate},{shortdate(date)}