locking: take the `wlock` for the full `hg forget` duration
authorPierre-Yves David <pierre-yves.david@octobus.net>
Tue, 13 Dec 2022 16:26:13 +0100
changeset 50006 feaa5d08bb19
parent 50005 16b78c0de506
child 50007 2aacd560cf59
locking: take the `wlock` for the full `hg forget` duration Otherwise, there is a race condition window between the time we resolve the file to forget with the matcher and the time we lock the repo and modify the dirstate. For example, the working copy might have been updated away, or purged, and the matched files would no longer be correct.
mercurial/commands.py
--- a/mercurial/commands.py	Tue Dec 13 04:22:46 2022 +0100
+++ b/mercurial/commands.py	Tue Dec 13 16:26:13 2022 +0100
@@ -2965,19 +2965,20 @@
     if not pats:
         raise error.InputError(_(b'no files specified'))
 
-    m = scmutil.match(repo[None], pats, opts)
-    dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
-    uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
-    rejected = cmdutil.forget(
-        ui,
-        repo,
-        m,
-        prefix=b"",
-        uipathfn=uipathfn,
-        explicitonly=False,
-        dryrun=dryrun,
-        interactive=interactive,
-    )[0]
+    with repo.wlock():
+        m = scmutil.match(repo[None], pats, opts)
+        dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
+        uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
+        rejected = cmdutil.forget(
+            ui,
+            repo,
+            m,
+            prefix=b"",
+            uipathfn=uipathfn,
+            explicitonly=False,
+            dryrun=dryrun,
+            interactive=interactive,
+        )[0]
     return rejected and 1 or 0