update: better logic and messages for updates
authorMatt Mackall <mpm@selenic.com>
Mon, 24 Mar 2008 10:01:05 -0500
changeset 6375 cdc458b12f0f
parent 6374 31a01e3d99cc
child 6378 f0f830114a9b
update: better logic and messages for updates - complain about attempts to merge with ancestor - when updating, differentiate between - crossing named branches with no local changes (jump) - crossing named branches with local changes (complain) - nonlinear update on the same named branch, no changes (complain some more) - nonlinear update on the same named branch, changes (different complaining)
mercurial/commands.py
mercurial/merge.py
tests/test-issue619.out
tests/test-merge5.out
tests/test-up-local-change.out
--- a/mercurial/commands.py	Mon Mar 24 16:20:15 2008 +0100
+++ b/mercurial/commands.py	Mon Mar 24 10:01:05 2008 -0500
@@ -2764,17 +2764,17 @@
 
     Update the working directory to the specified revision, or the
     tip of the current branch if none is specified.
-    See 'hg help dates' for a list of formats valid for -d/--date.
-
-    If there are no outstanding changes in the working directory, the
-    result is the requested version.
-
-    If the requested version is a descendant of the working directory
-    and there are outstanding changes, those changes will be merged
-    into the result.
-
-    By default, update will refuse to run if there are outstanding
-    changes and the update spans branches.
+
+    If the requested revision is a descendant of the working
+    directory, any outstanding changes in the working directory will
+    be merged into the result. If it is not directly descended but is
+    on the same named branch, update aborts with a suggestion to use
+    merge or update -C instead.
+
+    If the requested revision is on a different named branch and the
+    working directory is clean, update quietly switches branches.
+
+    See 'hg help dates' for a list of formats valid for --date.
     """
     if rev and node:
         raise util.Abort(_("please specify just one revision"))
--- a/mercurial/merge.py	Mon Mar 24 16:20:15 2008 +0100
+++ b/mercurial/merge.py	Mon Mar 24 10:01:05 2008 -0500
@@ -346,7 +346,6 @@
                 else:
                     raise util.Abort(_("branch %s not found") % wc.branch())
         overwrite = force and not branchmerge
-        forcemerge = force and branchmerge
         pl = wc.parents()
         p1, p2 = pl[0], repo.changectx(node)
         pa = p1.ancestor(p2)
@@ -356,22 +355,32 @@
         ### check phase
         if not overwrite and len(pl) > 1:
             raise util.Abort(_("outstanding uncommitted merges"))
-        if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
-            if branchmerge:
-                if p1.branch() != p2.branch() and pa != p2:
+        if branchmerge:
+            if pa == p2:
+                raise util.Abort(_("can't merge with ancestor"))
+            elif pa == p1:
+                if p1.branch() != p2.branch():
                     fastforward = True
                 else:
-                    raise util.Abort(_("there is nothing to merge, just use "
-                                       "'hg update' or look at 'hg heads'"))
-        elif not (overwrite or branchmerge):
-            if wc.files() or wc.deleted():
-                raise util.Abort(_("update spans branches, use 'hg merge' "
-                                   "or 'hg update -C' to lose changes"))
-            # Allow jumping branches if there are no changes
-            overwrite = True
-        if branchmerge and not forcemerge:
-            if wc.files() or wc.deleted():
+                    raise util.Abort(_("nothing to merge (use 'hg update'"
+                                       " or check 'hg heads')"))
+            if not force and (wc.files() or wc.deleted()):
                 raise util.Abort(_("outstanding uncommitted changes"))
+        elif not overwrite:
+            if pa == p1 or pa == p2: # linear
+                pass # all good
+            elif p1.branch() == p2.branch():
+                if wc.files() or wc.deleted():
+                    raise util.Abort(_("crosses branches (use 'hg merge' or "
+                                       "'hg update -C' to discard changes)"))
+                raise util.Abort(_("crosses branches (use 'hg merge'"
+                                   "or 'hg update -C')"))
+            elif wc.files() or wc.deleted():
+                raise util.Abort(_("crosses named branches (use "
+                                   "'hg update -C' to discard changes)"))
+            else:
+                # Allow jumping branches if there are no changes
+                overwrite = True
 
         ### calculate phase
         action = []
--- a/tests/test-issue619.out	Mon Mar 24 16:20:15 2008 +0100
+++ b/tests/test-issue619.out	Mon Mar 24 10:01:05 2008 -0500
@@ -6,5 +6,5 @@
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
 bogus fast-forward should fail
-abort: there is nothing to merge, just use 'hg update' or look at 'hg heads'
+abort: can't merge with ancestor
 done
--- a/tests/test-merge5.out	Mon Mar 24 16:20:15 2008 +0100
+++ b/tests/test-merge5.out	Mon Mar 24 10:01:05 2008 -0500
@@ -2,6 +2,6 @@
 removing b
 created new head
 % should abort
-abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
+abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
 % should succeed
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+abort: crosses branches (use 'hg merge'or 'hg update -C')
--- a/tests/test-up-local-change.out	Mon Mar 24 16:20:15 2008 +0100
+++ b/tests/test-up-local-change.out	Mon Mar 24 10:01:05 2008 -0500
@@ -103,7 +103,7 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     2
 
-abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
+abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
 failed
 abort: outstanding uncommitted changes
 failed