# HG changeset patch # User David M. Carr # Date 2011-11-10 00:46:51 # Node ID 95174c381525bb3f0953c003b363745456b9174d # Parent d90b0b30464b60c4456c5f08ef3690482d32f4b1 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. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -13,6 +13,7 @@ import hg, scmutil, util, revlog, extens 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 @@ def forget(ui, repo, *pats, **opts): 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( diff --git a/mercurial/help/subrepos.txt b/mercurial/help/subrepos.txt --- a/mercurial/help/subrepos.txt +++ b/mercurial/help/subrepos.txt @@ -95,6 +95,9 @@ Interaction with Mercurial Commands 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. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -360,6 +360,9 @@ class abstractsubrepo(object): ''' pass + def forget(self, files): + pass + class hgsubrepo(abstractsubrepo): def __init__(self, ctx, path, state): self._path = path @@ -553,6 +556,10 @@ class hgsubrepo(abstractsubrepo): 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 diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -1006,12 +1006,12 @@ Adding with a pattern with -S also adds 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