Patchwork [1,of,4,V2] merge: branch code into {n1 and n2, n1, n2} top-level cases

login
register
mail settings
Submitter Martin von Zweigbergk
Date Dec. 4, 2014, 5:15 a.m.
Message ID <a83394de0a4f71f25766.1417670149@martinvonz.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/6993/
State Accepted
Commit 922b10c870c5d2dccd01b6dd40c9e78ea7b93bfa
Headers show

Comments

Martin von Zweigbergk - Dec. 4, 2014, 5:15 a.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1416780550 28800
#      Sun Nov 23 14:09:10 2014 -0800
# Node ID a83394de0a4f71f25766f9797948b92a49e9f175
# Parent  c237499a7fba65c88a2da721a22b66df4f39cf4e
merge: branch code into {n1 and n2, n1, n2} top-level cases

There are three high-level cases that are of interest in
manifestmerge(): 1) The file exists on both sides, 2) The file exists
only on the local side, and 3) The file exists only on the remote
side. Let's make this clearer in the code.

The 'if f in copied' case will be broken up into the two applicable
branches in the next patch.

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -414,7 +414,7 @@ 
     for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
         if partial and not partial(f):
             continue
-        if n1 and n2:
+        if n1 and n2: # file exists on both local and remote side
             if f not in ma:
                 fa = copy.get(f, None)
                 if fa is not None:
@@ -443,72 +443,76 @@ 
                                    "versions differ"))
         elif f in copied: # files we'll deal with on m2 side
             pass
-        elif n1 and f in movewithdir: # directory rename, move local
-            f2 = movewithdir[f]
-            actions['dm'].append((f2, (f, fl1),
-                            "remote directory rename - move from " + f))
-        elif n1 and f in copy:
-            f2 = copy[f]
-            actions['m'].append((f, (f, f2, f2, False, pa.node()),
-                            "local copied/moved from " + f2))
-        elif n1 and f in ma: # clean, a different, no remote
-            if n1 != ma[f]:
-                if acceptremote:
-                    actions['r'].append((f, None, "remote delete"))
+        elif n1: # file exists only on local side
+            if f in movewithdir: # directory rename, move local
+                f2 = movewithdir[f]
+                actions['dm'].append((f2, (f, fl1),
+                                "remote directory rename - move from " + f))
+            elif f in copy:
+                f2 = copy[f]
+                actions['m'].append((f, (f, f2, f2, False, pa.node()),
+                                "local copied/moved from " + f2))
+            elif f in ma: # clean, a different, no remote
+                if n1 != ma[f]:
+                    if acceptremote:
+                        actions['r'].append((f, None, "remote delete"))
+                    else:
+                        actions['cd'].append((f, None,
+                                              "prompt changed/deleted"))
+                elif n1[20:] == 'a':
+                    # This extra 'a' is added by working copy manifest to mark
+                    # the file as locally added. We should forget it instead of
+                    # deleting it.
+                    actions['f'].append((f, None, "remote deleted"))
                 else:
-                    actions['cd'].append((f, None, "prompt changed/deleted"))
-            elif n1[20:] == 'a':
-                # This extra 'a' is added by working copy manifest to mark the
-                # file as locally added. We should forget it instead of
-                # deleting it.
-                actions['f'].append((f, None, "remote deleted"))
-            else:
-                actions['r'].append((f, None, "other deleted"))
-        elif n2 and f in movewithdir:
-            f2 = movewithdir[f]
-            actions['dg'].append((f2, (f, fl2),
-                            "local directory rename - get from " + f))
-        elif n2 and f in copy:
-            f2 = copy[f]
-            if f2 in m2:
-                actions['m'].append((f, (f2, f, f2, False, pa.node()),
-                                "remote copied from " + f2))
-            else:
-                actions['m'].append((f, (f2, f, f2, True, pa.node()),
-                                "remote moved from " + f2))
-        elif n2 and f not in ma:
-            # local unknown, remote created: the logic is described by the
-            # following table:
-            #
-            # force  branchmerge  different  |  action
-            #   n         *           n      |    get
-            #   n         *           y      |   abort
-            #   y         n           *      |    get
-            #   y         y           n      |    get
-            #   y         y           y      |   merge
-            #
-            # Checking whether the files are different is expensive, so we
-            # don't do that when we can avoid it.
-            if force and not branchmerge:
-                actions['g'].append((f, (fl2,), "remote created"))
-            else:
+                    actions['r'].append((f, None, "other deleted"))
+        elif n2: # file exists only on remote side
+            if f in movewithdir:
+                f2 = movewithdir[f]
+                actions['dg'].append((f2, (f, fl2),
+                                "local directory rename - get from " + f))
+            elif f in copy:
+                f2 = copy[f]
+                if f2 in m2:
+                    actions['m'].append((f, (f2, f, f2, False, pa.node()),
+                                    "remote copied from " + f2))
+                else:
+                    actions['m'].append((f, (f2, f, f2, True, pa.node()),
+                                    "remote moved from " + f2))
+            elif f not in ma:
+                # local unknown, remote created: the logic is described by the
+                # following table:
+                #
+                # force  branchmerge  different  |  action
+                #   n         *           n      |    get
+                #   n         *           y      |   abort
+                #   y         n           *      |    get
+                #   y         y           n      |    get
+                #   y         y           y      |   merge
+                #
+                # Checking whether the files are different is expensive, so we
+                # don't do that when we can avoid it.
+                if force and not branchmerge:
+                    actions['g'].append((f, (fl2,), "remote created"))
+                else:
+                    different = _checkunknownfile(repo, wctx, p2, f)
+                    if force and branchmerge and different:
+                        actions['m'].append((f, (f, f, None, False, pa.node()),
+                                        "remote differs from untracked local"))
+                    elif not force and different:
+                        aborts.append((f, 'ud'))
+                    else:
+                        actions['g'].append((f, (fl2,), "remote created"))
+            elif n2 != ma[f]:
                 different = _checkunknownfile(repo, wctx, p2, f)
-                if force and branchmerge and different:
-                    actions['m'].append((f, (f, f, None, False, pa.node()),
-                                    "remote differs from untracked local"))
-                elif not force and different:
+                if not force and different:
                     aborts.append((f, 'ud'))
                 else:
-                    actions['g'].append((f, (fl2,), "remote created"))
-        elif n2 and n2 != ma[f]:
-            different = _checkunknownfile(repo, wctx, p2, f)
-            if not force and different:
-                aborts.append((f, 'ud'))
-            else:
-                if acceptremote:
-                    actions['g'].append((f, (fl2,), "remote recreating"))
-                else:
-                    actions['dc'].append((f, (fl2,), "prompt deleted/changed"))
+                    if acceptremote:
+                        actions['g'].append((f, (fl2,), "remote recreating"))
+                    else:
+                        actions['dc'].append((f, (fl2,),
+                                              "prompt deleted/changed"))
 
     for f, m in sorted(aborts):
         if m == 'ud':