Mercurial Path Configuration Using $HOME Fails in Production
0 reputation · 23 May 2022, 17:37 UTC
0 reputation · 23 May 2022, 17:37 UTC
Configure a repository to use paths.default = $HOME/repo so that local developers can pull and push without hard‑coding absolute paths.
On a production server the $HOME variable may be unset or point to a different directory. Mercurial then treats the variable as a literal string, resulting in an empty or invalid path and causing hg pull or hg push to fail.
There is no built‑in graceful fallback for missing environment variables in path definitions. A clear error message or a configurable default is currently lacking.
1. Is there a syntax or extension that allows specifying a fallback path when $HOME is missing?
2. Will upcoming Mercurial releases address this by providing clearer error handling or a default resolution mechanism?
3. How can CI pipelines reliably set or emulate $HOME to avoid silent failures across environments?
35275 reputation · 23 May 2022, 22:06 UTC
Mercurial expands environment variables in paths sections using os.path.expandvars. If $HOME is unset or points to an unexpected directory, the expansion yields an empty or wrong string, and hg pull / hg push fail with “repository not found” or “invalid path”. Mercurial has no built‑in syntax for a fallback value, nor a graceful error message for a missing variable.
HOME unless explicitly set.HOME to /root when the user is not defined.path expansion failed: $HOME is not defined when the variable is missing.The failure is almost always caused by the Mercurial process running under a user whose HOME environment variable is either empty or points to a directory that does not contain the expected repository. This can happen when:
Environment=HOME=….root in a container where $HOME defaults to /root.HOME when Mercurial starts.# Run as the service user
sudo -u mercurial_user sh -c 'echo $HOME'
HOME is empty or wrong, set it explicitly.Environment=HOME=/opt/mercurial/repo to the unit file, then systemctl daemon-reload and restart.HOME=/opt/mercurial/repo in the job script before invoking hg.hg-wrapper.sh:
#!/usr/bin/env bash
# Resolve $HOME or fallback
export HOME=${HOME:-/opt/mercurial/repo}
exec hg "$@"
Replace direct hg calls with ./hg-wrapper.sh or point the service’s ExecStart to this script.
~/.hgrc or mercurial.ini explaining the dependency on $HOME and the steps taken to guarantee it.
Mercurial’s configuration language does not support conditional expressions or default values like ${HOME:-/default/path}. Therefore, the only reliable approaches are to ensure HOME is set correctly in the environment or to wrap hg with a small script that supplies a fallback.
There is no official roadmap item for adding environment‑variable fallbacks or improved error messages for missing variables. Users are advised to monitor the Mercurial project page for any future enhancements.
HOME in the job configuration (e.g., export HOME=/opt/mercurial/repo).hg --config paths.default=$HOME/repo to override the config per run if needed.echo "HOME=$HOME" to the log for debugging.
To refine the recommendation, could you confirm the value (or lack thereof) of HOME when Mercurial runs in the production environment? This will determine whether the issue is purely environmental or if a deeper configuration problem exists.
Use comments to ask for clarification. Post a solution as an answer.
6,130 reputation · 23 May 2022, 23:38 UTC
One clarification worth adding: if the goal is to avoid hard-coding absolute paths, $HOME is the wrong tool here. Mercurial expands ~ in paths.default via os.path.expanduser, which resolves the home directory from the passwd entry even when HOME is unset, so paths.default = ~/repo is more robust than $HOME/repo for this use case.
Also note the distinction between hg showconfig paths.default (shows the raw value) and the path Mercurial actually uses at runtime. Running hg paths as the service user is the quickest way to confirm what was resolved.
For CI, a safer pattern is to have the pipeline write the absolute path into .hg/hgrc at job setup rather than relying on $HOME being correct—hg pull failing with "no such repository" is the strict behavior; there is no fallback syntax in current releases (verify against your Mercurial version, as this could change).