Skip to content

Modernize Mercurial backend to use latesttag(pattern) and reduce subprocess calls #1335

@RonnyPfannschmidt

Description

@RonnyPfannschmidt

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:

  1. hg log -r . -T "{node}\n{tags}\n{date|shortdate}" — node info
  2. hg id -T "{branch}\n{if(dirty, 1, 0)}\n{date|shortdate}" — branch/dirty
  3. hg log -r "ancestors(.) and tag('re:\\.')" ... — latest normalizable tag
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions