# HG changeset patch # User Martin von Zweigbergk # Date 2014-11-09 07:13:39 # Node ID 9f4778027bc21d512300cdef1a627b0cadfd5214 # Parent 10697f29af2b0c0907d383d432cd4e8a7b82d8b1 addremove: add back forgotten files (BC) After running "hg forget README && hg addremove", README will still be reported as removed, while "hg forget README && hg add README" adds it back so it gets reported as clean. It seems like they should behave the same. Furthermore, it seems like no files should remain untracked after 'hg addremove && hg commit' (or 'hg commit -A'). For these reasons, change the behavior of addremove so it does add forgotten files back. The problem is with scmutil._interestingfiles(), which reports the file as removed, so scmutil.addremove() does not add it. Fix by teaching _interestingfiles() to report forgotten files separately from removed files and make addremove() add forgotten files back. However, do not treat forgotten files as sources for rename detection. Note that since removed and forgotten files are treated the same before this change, forgotten files were considered sources for rename detection. Also update the other caller, marktouched(), in the same way as addremove(). diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -686,9 +686,9 @@ def addremove(repo, pats=[], opts={}, dr rejected = [] m.bad = lambda x, y: rejected.append(x) - added, unknown, deleted, removed = _interestingfiles(repo, m) + added, unknown, deleted, removed, forgotten = _interestingfiles(repo, m) - unknownset = set(unknown) + unknownset = set(unknown + forgotten) toprint = unknownset.copy() toprint.update(deleted) for abs in sorted(toprint): @@ -704,7 +704,7 @@ def addremove(repo, pats=[], opts={}, dr similarity) if not dry_run: - _markchanges(repo, unknown, deleted, renames) + _markchanges(repo, unknown + forgotten, deleted, renames) for f in rejected: if f in m.files(): @@ -718,10 +718,10 @@ def marktouched(repo, files, similarity= rejected = [] m.bad = lambda x, y: rejected.append(x) - added, unknown, deleted, removed = _interestingfiles(repo, m) + added, unknown, deleted, removed, forgotten = _interestingfiles(repo, m) if repo.ui.verbose: - unknownset = set(unknown) + unknownset = set(unknown + forgotten) toprint = unknownset.copy() toprint.update(deleted) for abs in sorted(toprint): @@ -734,7 +734,7 @@ def marktouched(repo, files, similarity= renames = _findrenames(repo, m, added + unknown, removed + deleted, similarity) - _markchanges(repo, unknown, deleted, renames) + _markchanges(repo, unknown + forgotten, deleted, renames) for f in rejected: if f in m.files(): @@ -747,7 +747,7 @@ def _interestingfiles(repo, matcher): This is different from dirstate.status because it doesn't care about whether files are modified or clean.''' - added, unknown, deleted, removed = [], [], [], [] + added, unknown, deleted, removed, forgotten = [], [], [], [], [] audit_path = pathutil.pathauditor(repo.root) ctx = repo[None] @@ -760,13 +760,15 @@ def _interestingfiles(repo, matcher): unknown.append(abs) elif dstate != 'r' and not st: deleted.append(abs) + elif dstate == 'r' and st: + forgotten.append(abs) # for finding renames - elif dstate == 'r': + elif dstate == 'r' and not st: removed.append(abs) elif dstate == 'a': added.append(abs) - return added, unknown, deleted, removed + return added, unknown, deleted, removed, forgotten def _findrenames(repo, matcher, added, removed, similarity): '''Find renames from removed files to added ones.''' diff --git a/tests/test-addremove.t b/tests/test-addremove.t --- a/tests/test-addremove.t +++ b/tests/test-addremove.t @@ -18,7 +18,11 @@ dir/bar_2 foo_2 committed changeset 1:e65414bf35c5 - $ cd ../.. + $ cd .. + $ hg forget foo + $ hg -v addremove + adding foo + $ cd .. $ hg init sim $ cd sim @@ -45,4 +49,9 @@ adding d recording removal of a as rename to b (100% similar) $ hg commit -mb + $ cp b c + $ hg forget b + $ hg addremove -s 50 + adding b + adding c $ cd ..