add: add back forgotten files even when not matching exactly (BC)
I accidentally did 'hg forget .' and tried to undo the operation with
'hg add .'. I expected the files to be reported as either modified or
clean, but they were still reported as removed. It turns out that
forgotten files are only added back if they are listed explicitly, as
shown by the following two invocations. This makes it hard to recover
from the mistake of forgetting a lot of files.
$ hg forget README && hg add README && hg status -A README
C README
$ hg forget README && hg add . && hg status -A README
R README
The problem lies in cmdutil.add(). That method checks that the file
isn't already tracked before adding it, but it does so by checking the
dirstate, which does have an entry for forgotten files (state 'r'). We
should instead be checking whether the file exists in the
workingctx. The workingctx is also what we later call add() on, and
that method takes care of transforming the add() into a normallookup()
on the dirstate.
Since we're changing repo.dirstate into wctx, let's also change
repo.walk into wctx.walk for consistency (repo.walk calls wctx.walk,
so we're simply inlining the call).
--- a/mercurial/cmdutil.py Tue Nov 11 10:16:54 2014 -0800
+++ b/mercurial/cmdutil.py Mon Nov 10 14:51:18 2014 -0800
@@ -1982,9 +1982,9 @@
abort, warn = scmutil.checkportabilityalert(ui)
if abort or warn:
cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
- for f in repo.walk(match):
+ for f in wctx.walk(match):
exact = match.exact(f)
- if exact or not explicitonly and f not in repo.dirstate:
+ if exact or not explicitonly and f not in wctx:
if cca:
cca(f)
names.append(f)
--- a/tests/test-add.t Tue Nov 11 10:16:54 2014 -0800
+++ b/tests/test-add.t Mon Nov 10 14:51:18 2014 -0800
@@ -126,6 +126,19 @@
M a
? a.orig
+Forgotten file can be added back (as either clean or modified)
+
+ $ hg forget b
+ $ hg add b
+ $ hg st -A b
+ C b
+ $ hg forget b
+ $ echo modified > b
+ $ hg add b
+ $ hg st -A b
+ M b
+ $ hg revert -qC b
+
$ hg add c && echo "unexpected addition of missing file"
c: * (glob)
[1]