Patchwork [2,of,2,V2,STABLE] addremove: add back forgotten files

login
register
mail settings
Submitter Martin von Zweigbergk
Date Nov. 11, 2014, 6 p.m.
Message ID <1e90ef2c0e371ede93ac.1415728800@martinvonz.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/6682/
State Accepted
Headers show

Comments

Martin von Zweigbergk - Nov. 11, 2014, 6 p.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1415517219 28800
#      Sat Nov 08 23:13:39 2014 -0800
# Node ID 1e90ef2c0e371ede93ac15861022d5611c6d8928
# Parent  48a648e2b6d64082109c722fac4e4ea105167635
addremove: add back forgotten files

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().
Pierre-Yves David - Nov. 11, 2014, 7:27 p.m.
On 11/11/2014 06:00 PM, Martin von Zweigbergk wrote:
> # HG changeset patch
> # User Martin von Zweigbergk <martinvonz@google.com>
> # Date 1415517219 28800
> #      Sat Nov 08 23:13:39 2014 -0800
> # Node ID 1e90ef2c0e371ede93ac15861022d5611c6d8928
> # Parent  48a648e2b6d64082109c722fac4e4ea105167635
> addremove: add back forgotten files

I think this change makes sense, but they will maybe break people?

I've added a (BC) flag and pushed to the clowncopter Thanks.

Patch

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -686,9 +686,9 @@ 
     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 @@ 
                            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 @@ 
     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 @@ 
     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 @@ 
 
     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 @@ 
             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 ..