changeset 16429:71dcce391a44

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.
author Angel Ezquerra <angel.ezquerra@gmail.com>
date Wed, 28 Mar 2012 11:42:17 +0200
parents 9b26d541e972
children 6883c2363f44
files mercurial/cmdutil.py mercurial/subrepo.py tests/test-subrepo.t
diffstat 3 files changed, 24 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Sat Apr 14 01:39:35 2012 -0500
+++ b/mercurial/cmdutil.py	Wed Mar 28 11:42:17 2012 +0200
@@ -1356,8 +1356,6 @@
             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 @@
             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 @@
                 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()
 
--- a/mercurial/subrepo.py	Sat Apr 14 01:39:35 2012 -0500
+++ b/mercurial/subrepo.py	Wed Mar 28 11:42:17 2012 +0200
@@ -368,6 +368,9 @@
     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 @@
         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
--- a/tests/test-subrepo.t	Sat Apr 14 01:39:35 2012 -0500
+++ b/tests/test-subrepo.t	Wed Mar 28 11:42:17 2012 +0200
@@ -42,11 +42,14 @@
 
   $ 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)