[PATCH 2 of 3 RFC] revert: add support for reverting subrepos without --no-backup and/or --all

Angel Ezquerra angel.ezquerra at gmail.com
Thu Mar 22 17:34:38 CDT 2012


# HG changeset patch
# User Angel Ezquerra <angel.ezquerra at gmail.com>
# Date 1332366307 -3600
# Node ID 4f3b203e770e8a738d84eb9e006e124718ee4cf5
# Parent  e45677da232ff46f043603fd232a07897f5fb6f2
revert: add support for reverting subrepos without --no-backup and/or --all

When a subrepo is reverted but --no-backup is not set, call revert on the
subrepo that is being reverted prior to updating it to the revision specified
in the parent repo's .hgsubstate file.

The --all flag is passed down to the subrepo when it is being reverted. If the
--all flag is not set, all files that are modified on the subrepo will be
reverted.

* NOTES / ISSUES:

- The revert function is shadowed by an existing revert variable. I used
"import commands" and "commands.revert" to access it, but perhaps there is a
better way (e.g. renaming the revert variable).

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4839,12 +4839,8 @@
             if abs not in names:
                 names[abs] = m.rel(abs), m.exact(abs)
 
+        # get the list of subrepos that must be reverted
         targetsubs = [s for s in repo[node].substate if m(s)]
-        if targetsubs and not opts.get('no_backup'):
-            msg = _("cannot revert subrepos unless the no-backup flag is set")
-            hint = _("there are subrepos on the revert list, "
-                     "use --no-backup to revert them")
-            raise util.Abort(msg, hint=hint)
 
         m = scmutil.matchfiles(repo, names)
         changes = repo.status(match=m)[:4]
@@ -4976,10 +4972,27 @@
 
             if targetsubs:
                 # Revert the subrepos on the revert list
-                # reverting a subrepo is done by updating it to the revision
-                # specified in the corresponding substate dictionary
+                # reverting a subrepo is a 2 step process:
+                # 1. if the no_backup is not set, revert all modified files inside the subrepo
+                # 2. update the subrepo to the revision specified in the corresponding substate dictionary
+
+                # the revert function name is shadowed
+                import commands
+                revert = commands.revert
                 for sname in targetsubs:
                     ui.status(_('reverting subrepo %s\n') % sname)
+                    if not opts.get('no_backup'):
+                        # Revert all files on the subrepo, creating backups
+                        # Note that this will not recursively revert subrepos
+                        # We could do it if there was a set:subrepos() predicate
+                        revert_opts = opts.copy()
+                        revert_opts['date'] = None
+                        revert_opts['rev'] = ctx.substate[sname][1]
+                        if revert_opts['all']:
+                            revert(ui, ctx.sub(sname)._repo, **revert_opts)
+                        else:
+                            revert(ui, ctx.sub(sname)._repo, 'set:modified()', **revert_opts)
+                    # Update the repo to the revision specified in the parent repo revision
                     ctx.sub(sname).get(ctx.substate[sname], overwrite=True)
     finally:
         wlock.release()


More information about the Mercurial-devel mailing list