# HG changeset patch # User Angel Ezquerra # Date 2012-03-28 09:42:17 # Node ID 71dcce391a44407e763dda39cca0a9eed5b2a282 # Parent 9b26d541e972428a21d44837650932b2f2f5aeb0 revert: add support for reverting subrepos Reverting a subrepo is done by updating it to the revision that is selected on the parent repo .hgsubstate file. * ISSUES/TODO: - reverting added and removed subrepos is not supported yet. - reverting subrepos is only supported if the --no-backup flag is used (this limitation will be removed on another patch). - The behavior of the --all flag has been changed. It now reverts subrepos as well. Note that this may lead to data loss if the user has a dirty subrepo. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1356,8 +1356,6 @@ def revert(ui, repo, ctx, parents, *pats if path in names: return if path in repo[node].substate: - ui.warn("%s: %s\n" % (m.rel(path), - 'reverting subrepos is unsupported')) return path_ = path + '/' for f in names: @@ -1371,6 +1369,11 @@ def revert(ui, repo, ctx, parents, *pats if abs not in names: names[abs] = m.rel(abs), m.exact(abs) + targetsubs = [s for s in repo[node].substate if m(s)] + if targetsubs and not opts.get('no_backup'): + msg = _("cannot revert subrepos without --no-backup") + raise util.Abort(msg) + m = scmutil.matchfiles(repo, names) changes = repo.status(match=m)[:4] modified, added, removed, deleted = map(set, changes) @@ -1499,6 +1502,10 @@ def revert(ui, repo, ctx, parents, *pats checkout(f) normal(f) + if targetsubs: + # Revert the subrepos on the revert list + for sub in targetsubs: + ctx.sub(sub).revert(ui, ctx.substate[sub], *pats, **opts) finally: wlock.release() diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -368,6 +368,9 @@ class abstractsubrepo(object): def forget(self, ui, match, prefix): return [] + def revert(self, ui, substate, *pats, **opts): + return [] + class hgsubrepo(abstractsubrepo): def __init__(self, ctx, path, state): self._path = path @@ -573,6 +576,14 @@ class hgsubrepo(abstractsubrepo): return cmdutil.forget(ui, self._repo, match, os.path.join(prefix, self._path), True) + def revert(self, ui, substate, *pats, **opts): + # reverting a subrepo is done by updating it to the revision + # specified in the corresponding substate dictionary + ui.status(_('reverting subrepo %s\n') % substate[0]) + + # Update the repo to the revision specified in the given substate + self.get(substate, overwrite=True) + 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 @@ -42,11 +42,14 @@ Revert can't (yet) revert subrepos: $ echo b > s/a $ hg revert s - s: reverting subrepos is unsupported + abort: cannot revert subrepos without --no-backup + [255] Revert currently ignores subrepos by default $ hg revert -a + abort: cannot revert subrepos without --no-backup + [255] $ hg revert -R s -a -C reverting s/a (glob)