[PATCH] update: --check should fail if untracked files would be lost (issue2450)

Mark Kendrat swdev10 at live.com
Mon Jun 13 14:03:13 CDT 2011


# HG changeset patch
# User Mark Kendrat <swdev10 at live.com>
# Date 1307991775 32400
# Node ID 325b4aa6c5eac9232d91961fec5bff8d4734f565
# Parent  17c0cb1045e549d9bbbd9ba25dee18f7df4a11a3
update: --check should fail if untracked files would be lost (issue2450)

This is not a final patch. This patch is for review
to see if it is on the right track. The final patch
will move safety checks from mergemod.update to
updatecheck and mergecheck as appropriate,
leaving no safety checks in mergemod.update.

diff -r 17c0cb1045e5 -r 325b4aa6c5ea mercurial/commands.py
--- a/mercurial/commands.py	Sat Jun 11 21:24:50 2011 +0800
+++ b/mercurial/commands.py	Mon Jun 13 10:02:55 2011 -0900
@@ -427,6 +427,7 @@
     if not opts.get('merge') and op1 != node:
         try:
             ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
+            hg.updatecheck(repo, op1, False, False)
             return hg.update(repo, op1)
         finally:
             ui.setconfig('ui', 'forcemerge', '')
@@ -448,7 +449,9 @@
                   % nice(repo.changelog.tip()))
         try:
             ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
-            return hg.merge(repo, hex(repo.changelog.tip()))
+            hextip = hex(repo.changelog.tip())
+            hg.mergecheck(repo, hextip, False)
+            return hg.merge(repo, hextip)
         finally:
             ui.setconfig('ui', 'forcemerge', '')
     return 0
@@ -3530,9 +3533,11 @@
         return 0
 
     try:
+        force = opts.get('force')
+        hg.mergecheck(repo, node, force)
         # ui.forcemerge is an internal variable, do not document
         ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
-        return hg.merge(repo, node, force=opts.get('force'))
+        return hg.merge(repo, node, force)
     finally:
         ui.setconfig('ui', 'forcemerge', '')
 
@@ -3667,6 +3672,7 @@
         return
     if optupdate:
         try:
+            hg.updatecheck(repo, checkout, False, False)
             return hg.update(repo, checkout)
         except util.Abort, inst:
             ui.warn(_("not updating: %s\n" % str(inst)))
@@ -5030,9 +5036,14 @@
             raise util.Abort(_("you can't specify a revision and a date"))
         rev = cmdutil.finddate(ui, repo, date)
 
-    if clean or check:
+    if clean:
+        hg.updatecheck(repo, rev, False, True)
+        ret = hg.clean(repo, rev)
+    elif check:
+        hg.updatecheck(repo, rev, True, True)
         ret = hg.clean(repo, rev)
     else:
+        hg.updatecheck(repo, rev, False, False)
         ret = hg.update(repo, rev)
 
     if brev in repo._bookmarks:
diff -r 17c0cb1045e5 -r 325b4aa6c5ea mercurial/hg.py
--- a/mercurial/hg.py	Sat Jun 11 21:24:50 2011 +0800
+++ b/mercurial/hg.py	Mon Jun 13 10:02:55 2011 -0900
@@ -407,6 +407,9 @@
     repo.ui.status(_("%d files updated, %d files merged, "
                      "%d files removed, %d files unresolved\n") % stats)
 
+def updatecheck(repo, node, check, clean):
+    mergemod.updatecheck(repo, node, check, clean)
+
 def update(repo, node):
     """update the working directory to node, merging linear changes"""
     stats = mergemod.update(repo, node, False, False, None)
@@ -425,6 +428,9 @@
         _showstats(repo, stats)
     return stats[3] > 0
 
+def mergecheck(repo, node, force):
+    mergemod.mergecheck(repo, node, force)
+
 def merge(repo, node, force=None, remind=True):
     """Branch merge with node, resolving changes. Return true if any
     unresolved conflicts."""
diff -r 17c0cb1045e5 -r 325b4aa6c5ea mercurial/merge.py
--- a/mercurial/merge.py	Sat Jun 11 21:24:50 2011 +0800
+++ b/mercurial/merge.py	Mon Jun 13 10:02:55 2011 -0900
@@ -443,7 +443,14 @@
                 if f:
                     repo.dirstate.drop(f)
 
-def update(repo, node, branchmerge, force, partial, ancestor=None):
+def updatecheck(repo, node, check, clean):
+    update(repo, node, False, clean, None, safetychecksonly=True, check=check)
+
+def mergecheck(repo, node, force):
+    update(repo, node, True, force, False, safetychecksonly=True, check=False)
+
+def update(repo, node, branchmerge, force, partial, ancestor=None,
+        safetychecksonly=False, check=False):
     """
     Perform a merge between the working directory and the given node
 
@@ -540,8 +547,12 @@
         wc.status(unknown=True) # prime cache
         if not force:
             _checkunknown(wc, p2)
+        if check:
+            _checkunknown(wc, p2)
         if not util.checkcase(repo.path):
             _checkcollision(p2)
+        if safetychecksonly:
+            return None
         action += _forgetremoved(wc, p2, branchmerge)
         action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
 
diff -r 17c0cb1045e5 -r 325b4aa6c5ea tests/test-simple-update.t
--- a/tests/test-simple-update.t	Sat Jun 11 21:24:50 2011 +0800
+++ b/tests/test-simple-update.t	Mon Jun 13 10:02:55 2011 -0900
@@ -54,3 +54,43 @@
   $ hg upd -d foo 0
   abort: you can't specify a revision and a date
   [255]
+
+update --check should protect untracked files (issue2450)
+
+initial repo1
+  $ cd $TESTTMP
+  $ hg init repo1
+
+repo2 is a clone that adds newfile and pushes back to repo1
+  $ hg clone repo1 repo2
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd $TESTTMP/repo2
+  $ echo "finished work" > newfile
+  $ hg add newfile
+  $ hg commit -m "newfile"
+  $ hg push
+  pushing to $TESTTMP/repo1
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+
+repo1 begins work in progress in newfile
+  $ cd $TESTTMP/repo1
+  $ echo "work in progress" > newfile
+
+repo1 does an update and work in progress is protected
+  $ hg update
+  abort: untracked file in working directory differs from file in requested revision: 'newfile'
+  [255]
+
+repo1 does an update --check and work in progress is protected
+  $ hg update --check
+  abort: untracked file in working directory differs from file in requested revision: 'newfile'
+  [255]
+
+repo1 does an update --clean and work in progress is removed
+  $ hg update --clean
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved


More information about the Mercurial-devel mailing list