# HG changeset patch # User Arun Kulshreshtha # Date 1660158110 14400 # Node ID 3681a47611b8a8f0a34908dd3e8bf15c7ddf0b6c # Parent 2edb41ed6c4990b52d0154af05d565b6870fb5b2 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.) diff -r 2edb41ed6c49 -r 3681a47611b8 mercurial/dispatch.py --- 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 diff -r 2edb41ed6c49 -r 3681a47611b8 tests/test-chg.t --- 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+)