dispatch: change cwd when loading local config
Previously, the `_getlocal` function would not correctly load the repo config
when given a relative `rpath` and an alternate cwd via the `wd` parameter.
Normally when `--cwd` is specified, hg changes to the given directory before
attempting to load the local config (and therefore does not specify a `wd`).
The only time the function is called with `wd` set is when hg is running as a
command server (e.g., with chg), in which case each forked worker process will
attempt to configure itself via `_getlocal` before responding to the client.
When given a relative repo path, the worker fails to load the repo config,
detects a config mismatch with the client, and enters a redirect/respawn loop.
To fix this, we can simply change to the desired working directory during
config loading. (Note that simply concatenating `wd` and `rpath` won't work
in all cases. The repo path could be something more complicated than a simple
relative path, such as a `union:` repo.)
--- a/mercurial/dispatch.py Mon Aug 08 17:27:49 2022 +0200
+++ b/mercurial/dispatch.py Wed Aug 10 15:01:50 2022 -0400
@@ -952,14 +952,22 @@
Takes paths in [cwd]/.hg/hgrc into account."
"""
+ try:
+ cwd = encoding.getcwd()
+ except OSError as e:
+ raise error.Abort(
+ _(b"error getting current working directory: %s")
+ % encoding.strtolocal(e.strerror)
+ )
+
+ # If using an alternate wd, temporarily switch to it so that relative
+ # paths are resolved correctly during config loading.
+ oldcwd = None
if wd is None:
- try:
- wd = encoding.getcwd()
- except OSError as e:
- raise error.Abort(
- _(b"error getting current working directory: %s")
- % encoding.strtolocal(e.strerror)
- )
+ wd = cwd
+ else:
+ oldcwd = cwd
+ os.chdir(wd)
path = cmdutil.findrepo(wd) or b""
if not path:
@@ -979,6 +987,9 @@
lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
+ if oldcwd:
+ os.chdir(oldcwd)
+
return path, lui
--- a/tests/test-chg.t Mon Aug 08 17:27:49 2022 +0200
+++ b/tests/test-chg.t Wed Aug 10 15:01:50 2022 -0400
@@ -432,6 +432,20 @@
YYYY/MM/DD HH:MM:SS (PID)> log -R cached
YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
+Test that -R is interpreted relative to --cwd.
+
+ $ hg init repo1
+ $ mkdir -p a/b
+ $ hg init a/b/repo2
+ $ printf "[alias]\ntest=repo1\n" >> repo1/.hg/hgrc
+ $ printf "[alias]\ntest=repo2\n" >> a/b/repo2/.hg/hgrc
+ $ cd a
+ $ chg --cwd .. -R repo1 show alias.test
+ repo1
+ $ chg --cwd . -R b/repo2 show alias.test
+ repo2
+ $ cd ..
+
Test that chg works (sets to the user's actual LC_CTYPE) even when python
"coerces" the locale (py3.7+)