dirstate: fix a potential traceback when in `copy` and `rename`
Before this changes, calling `hg copy` or `hg rename` could trigger a traceback
about using an invalidated dirstate. This wasn't caught by the test as it needed
the blackbox extension to preload the dirstate first in a way "refresh"
invalidates it.
Changing the context creation patterns fixes it.
--- a/mercurial/commands.py Tue Mar 14 14:08:38 2023 +0000
+++ b/mercurial/commands.py Wed Mar 15 05:49:56 2023 +0100
@@ -2498,7 +2498,7 @@
"""
opts = pycompat.byteskwargs(opts)
- context = repo.dirstate.changing_files
+ context = lambda repo: repo.dirstate.changing_files(repo)
rev = opts.get(b'at_rev')
ctx = None
if rev:
@@ -6012,7 +6012,7 @@
Returns 0 on success, 1 if errors are encountered.
"""
opts = pycompat.byteskwargs(opts)
- context = repo.dirstate.changing_files
+ context = lambda repo: repo.dirstate.changing_files(repo)
rev = opts.get(b'at_rev')
ctx = None
if rev:
--- a/mercurial/dirstate.py Tue Mar 14 14:08:38 2023 +0000
+++ b/mercurial/dirstate.py Wed Mar 15 05:49:56 2023 +0100
@@ -200,6 +200,12 @@
self._cwd
def refresh(self):
+ # XXX if this happens, you likely did not enter the `changing_xxx`
+ # using `repo.dirstate`, so a later `repo.dirstate` accesss might call
+ # `refresh`.
+ if self.is_changing_any:
+ msg = "refreshing the dirstate in the middle of a change"
+ raise error.ProgrammingError(msg)
if '_branch' in vars(self):
del self._branch
if '_map' in vars(self) and self._map.may_need_refresh():
--- a/mercurial/localrepo.py Tue Mar 14 14:08:38 2023 +0000
+++ b/mercurial/localrepo.py Wed Mar 15 05:49:56 2023 +0100
@@ -2951,6 +2951,7 @@
known good state)."""
unfi = self.unfiltered()
if 'dirstate' in unfi.__dict__:
+ assert not self.dirstate.is_changing_any
del unfi.__dict__['dirstate']
def invalidate(self, clearfilecache=False):
--- a/tests/test-blackbox.t Tue Mar 14 14:08:38 2023 +0000
+++ b/tests/test-blackbox.t Wed Mar 15 05:49:56 2023 +0100
@@ -470,15 +470,16 @@
> raise RuntimeError('raise')
> EOF
- $ cat >> $HGRCPATH << EOF
+
+ $ hg init $TESTTMP/blackbox-exception-only --config blackbox.track=commandexception
+ $ cat >> $TESTTMP/blackbox-exception-only/.hg/hgrc << EOF
> [blackbox]
> track = commandexception
> [extensions]
> raise=$TESTTMP/raise.py
> EOF
+ $ cd $TESTTMP/blackbox-exception-only
- $ hg init $TESTTMP/blackbox-exception-only
- $ cd $TESTTMP/blackbox-exception-only
#if chg
(chg exits 255 because it fails to receive an exit code)
@@ -495,3 +496,25 @@
$ tail -2 .hg/blackbox.log
RuntimeError: raise
+ $ cd ..
+
+Check we did not broke `hg mv`
+------------------------------
+(we did in 6.4rc)
+
+basic setup
+
+ $ hg init blackbox-file-move
+ $ cd blackbox-file-move
+ $ echo foo > foo
+ $ hg add foo
+ $ hg commit -m 'foo'
+
+copy a file
+
+ $ hg copy foo bar
+
+move a file
+
+ $ hg mv foo goo
+