changeset 15474:95174c381525

forget: support forgetting explicit paths in subrepos Change the behavior of the forget command such that explicit paths in subrepos are handled by forgetting the file in the subrepo. This eliminates the previous behavior where if you called "hg forget" for an explicit path in a subrepo, it would state that the file is already untracked.
author David M. Carr <david@carrclan.us>
date Wed, 09 Nov 2011 19:46:51 -0500
parents d90b0b30464b
children 7c06e9c35f2f
files mercurial/commands.py mercurial/help/subrepos.txt mercurial/subrepo.py tests/test-subrepo.t
diffstat 4 files changed, 42 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Wed Nov 09 19:46:49 2011 -0500
+++ b/mercurial/commands.py	Wed Nov 09 19:46:51 2011 -0500
@@ -13,6 +13,7 @@
 import patch, help, url, encoding, templatekw, discovery
 import archival, changegroup, cmdutil, hbisect
 import sshserver, hgweb, hgweb.server, commandserver
+import match as matchmod
 import merge as mergemod
 import minirst, revset, fileset
 import dagparser, context, simplemerge
@@ -2432,23 +2433,45 @@
     if not pats:
         raise util.Abort(_('no files specified'))
 
-    m = scmutil.match(repo[None], pats, opts)
+    wctx = repo[None]
+    m = scmutil.match(wctx, pats, opts)
     s = repo.status(match=m, clean=True)
     forget = sorted(s[0] + s[1] + s[3] + s[6])
+    subforget = {}
     errs = 0
 
+    for subpath in wctx.substate:
+        sub = wctx.sub(subpath)
+        try:
+            submatch = matchmod.narrowmatcher(subpath, m)
+            for fsub in sub.walk(submatch):
+                if submatch.exact(fsub):
+                    subforget[os.path.join(subpath, fsub)] = (fsub, sub)
+        except error.LookupError:
+            ui.status(_("skipping missing subrepository: %s\n") % subpath)
+
     for f in m.files():
         if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
-            if os.path.exists(m.rel(f)):
-                ui.warn(_('not removing %s: file is already untracked\n')
-                        % m.rel(f))
-            errs = 1
+            if f not in subforget:
+                if os.path.exists(m.rel(f)):
+                    ui.warn(_('not removing %s: file is already untracked\n')
+                            % m.rel(f))
+                errs = 1
 
     for f in forget:
         if ui.verbose or not m.exact(f):
             ui.status(_('removing %s\n') % m.rel(f))
 
-    repo[None].forget(forget)
+    if ui.verbose:
+        for f in sorted(subforget.keys()):
+            ui.status(_('removing %s\n') % m.rel(f))
+
+    wctx.forget(forget)
+
+    for f in sorted(subforget.keys()):
+        fsub, sub = subforget[f]
+        sub.forget([fsub])
+
     return errs
 
 @command(
--- a/mercurial/help/subrepos.txt	Wed Nov 09 19:46:49 2011 -0500
+++ b/mercurial/help/subrepos.txt	Wed Nov 09 19:46:51 2011 -0500
@@ -95,6 +95,9 @@
     elements. Git and Subversion subrepositories are currently
     silently ignored.
 
+:forget: forget currently only handles exact file matches in subrepos.
+    Git and Subversion subrepositories are currently silently ignored.
+
 :incoming: incoming does not recurse in subrepos unless -S/--subrepos
     is specified. Git and Subversion subrepositories are currently
     silently ignored.
--- a/mercurial/subrepo.py	Wed Nov 09 19:46:49 2011 -0500
+++ b/mercurial/subrepo.py	Wed Nov 09 19:46:51 2011 -0500
@@ -360,6 +360,9 @@
         '''
         pass
 
+    def forget(self, files):
+        pass
+
 class hgsubrepo(abstractsubrepo):
     def __init__(self, ctx, path, state):
         self._path = path
@@ -553,6 +556,10 @@
         ctx = self._repo[None]
         return ctx.walk(match)
 
+    def forget(self, files):
+        ctx = self._repo[None]
+        ctx.forget(files)
+
 class svnsubrepo(abstractsubrepo):
     def __init__(self, ctx, path, state):
         self._path = path
--- a/tests/test-subrepo.t	Wed Nov 09 19:46:49 2011 -0500
+++ b/tests/test-subrepo.t	Wed Nov 09 19:46:51 2011 -0500
@@ -1006,12 +1006,12 @@
   committing subrepository s
 
 Test behavior of forget for explicit path in subrepo:
-Forgetting an explicit path in a subrepo currently gives a file untracked warn
+Forgetting an explicit path in a subrepo untracks the file
   $ echo c19 > s/f19
   $ hg add s/f19
   $ hg st -S
   A s/f19
   $ hg forget s/f19
-  not removing s/f19: file is already untracked
-  [1]
+  $ hg st -S
+  ? s/f19
   $ rm s/f19