diff mercurial/merge.py @ 18985:a59e575c6ff8

update: allow dirty update to foreground (successors) Update to "foreground" are no longer seen as cross branch update. "Foreground" are descendants or successors (or successors of descendants (or descendant of successors (etc))). This allows to update with uncommited changes that get automatically merged. This changeset is a small step forward. We want to allow dirty update to "background" (precursors) and takes obsolescence in account when finding the default update destination. But those requires deeper changes and will comes in later changesets.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Tue, 16 Apr 2013 15:33:18 +0200
parents ed676ed67a5c
children 5cc71484ee9c
line wrap: on
line diff
--- a/mercurial/merge.py	Tue Apr 16 15:16:33 2013 +0200
+++ b/mercurial/merge.py	Tue Apr 16 15:33:18 2013 +0200
@@ -7,6 +7,7 @@
 
 from node import nullid, nullrev, hex, bin
 from i18n import _
+from mercurial import obsolete
 import error, util, filemerge, copies, subrepo, worker, dicthelpers
 import errno, os, shutil
 
@@ -697,17 +698,26 @@
                                        "subrepository '%s'") % s)
 
         elif not overwrite:
-            if pa == p1 or pa == p2: # linear
-                pass # all good
-            elif wc.dirty(missing=True):
-                raise util.Abort(_("crosses branches (merge branches or use"
-                                   " --clean to discard changes)"))
-            elif onode is None:
-                raise util.Abort(_("crosses branches (merge branches or update"
-                                   " --check to force update)"))
-            else:
-                # Allow jumping branches if clean and specific rev given
-                pa = p1
+            if pa not in (p1, p2):  # nolinear
+                dirty = wc.dirty(missing=True)
+                if dirty or onode is None:
+                    # Branching is a bit strange to ensure we do the minimal
+                    # amount of call to obsolete.background.
+                    foreground = obsolete.foreground(repo, [p1.node()])
+                    # note: the <node> variable contains a random identifier
+                    if repo[node].node() in foreground:
+                        pa = p1  # allow updating to successors
+                    elif dirty:
+                        msg = _("crosses branches (merge branches or use"
+                                " --clean to discard changes)")
+                        raise util.Abort(msg)
+                    else:  # node is none
+                        msg = _("crosses branches (merge branches or update"
+                                " --check to force update)")
+                        raise util.Abort(msg)
+                else:
+                    # Allow jumping branches if clean and specific rev given
+                    pa = p1
 
         ### calculate phase
         actions = calculateupdates(repo, wc, p2, pa,