Patchwork [2,of,4] revert: distinct between "check" and "backup" strategy

login
register
mail settings
Submitter Pierre-Yves David
Date Sept. 20, 2014, 1:05 a.m.
Message ID <e5fd2c86f4a761efa634.1411175101@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5895/
State Superseded
Headers show

Comments

Pierre-Yves David - Sept. 20, 2014, 1:05 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1409358624 -7200
#      Sat Aug 30 02:30:24 2014 +0200
# Node ID e5fd2c86f4a761efa634c4bf3dd825165f16fadb
# Parent  c7bf7274d2184c47fa0988f054b24d1b2b3416cd
revert: distinct between "check" and "backup" strategy

"check" behave as backup did before. We check if the current file differs
from destination and we create a backup if it does. This is used for untracked
file that will be overwritten by formerly deleted file. We have to do the manual
check since no status output can provides the content comparison.

"backup" is now doing unconditional backup. This can be used for file seen as
modified compared to both the target and the working directory. In such case we
know that the file differs from target without actually comparing any content.

This new "backup" strategy will be especially useful in the case of file added
between the target and the working directory -parent- with additional modifications
in the working directory -itself-. In that case we know we need to backup it, but we
cannot run the content check as the files does not exists in target.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2621,13 +2621,14 @@  def revert(ui, repo, ctx, parents, *pats
                   }
 
 
         # should we do a backup?
         backup = 2
+        check = 1
         discard = 0
         if opts.get('no_backup'):
-            backup = 0
+            check = backup = discard
 
         disptable = (
             # dispatch table:
             #   file state
             #   action
@@ -2647,15 +2648,15 @@  def revert(ui, repo, ctx, parents, *pats
             # Added since target but file is missing in working directory
             (deladded,      actions['drop'],   discard),
             # Removed since  target, before working copy parent
             (removed,       actions['add'],      discard),
             # Same as `removed` but an unknown file exists at the same path
-            (removunk,      actions['add'],      backup),
+            (removunk,      actions['add'],      check),
             # Removed since targe, marked as such in working copy parent
             (dsremoved,     actions['undelete'], discard),
             # Same as `dsremoved` but an unknown file exists at the same path
-            (dsremovunk,    actions['undelete'], backup),
+            (dsremovunk,    actions['undelete'], check),
             ## the following sets does not result in any file changes
             # File with no modification
             (clean,         actions['noop'],     discard),
             # Existing file, not tracked anywhere
             (unknown,       actions['unknown'],  discard),
@@ -2674,16 +2675,16 @@  def revert(ui, repo, ctx, parents, *pats
             for table, (xlist, msg), dobackup in disptable:
                 if abs not in table:
                     continue
                 if xlist is not None:
                     xlist.append(abs)
-                    if (dobackup and wctx[abs].cmp(ctx[abs])):
-                        bakname = "%s.orig" % rel
-                        ui.note(_('saving current version of %s as %s\n') %
-                                (rel, bakname))
-                        if not opts.get('dry_run'):
-                            util.rename(target, bakname)
+                    if dobackup and (dobackup >= 2 or wctx[abs].cmp(ctx[abs])):
+                            bakname = "%s.orig" % rel
+                            ui.note(_('saving current version of %s as %s\n') %
+                                    (rel, bakname))
+                            if not opts.get('dry_run'):
+                                util.rename(target, bakname)
                     if ui.verbose or not exact:
                         if not isinstance(msg, basestring):
                             msg = msg(abs)
                         ui.status(msg % rel)
                 elif exact: