Patchwork D8533: flags: actually merge flags in simplemerge

login
register
mail settings
Submitter phabricator
Date May 16, 2020, 8:12 p.m.
Message ID <differential-rev-PHID-DREV-afdtbwby544o3nakjok6-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/46321/
State Superseded
Headers show

Comments

phabricator - May 16, 2020, 8:12 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Since b86fc43e4b73 <https://phab.mercurial-scm.org/rHGb86fc43e4b73422ec74975f8f7dc36c74e2a9885>, the local flag were blindly taken. This resulted in bug when
  rename are involved. exec flag change are now properly merged (when merged from
  the rename side).
  
  Another bug is affecting this when merging from the side without the rename.

REPOSITORY
  rHG Mercurial

BRANCH
  stable

REVISION DETAIL
  https://phab.mercurial-scm.org/D8533

AFFECTED FILES
  mercurial/simplemerge.py
  tests/test-merge-exec.t

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-merge-exec.t b/tests/test-merge-exec.t
--- a/tests/test-merge-exec.t
+++ b/tests/test-merge-exec.t
@@ -195,7 +195,6 @@ 
   M z
     a
   $ [ -x z ] || echo "executable bit lost"
-  executable bit lost
 
 merge them (from the chmod side)
 
diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -22,7 +22,9 @@ 
 from . import (
     error,
     mdiff,
+    node as nodemod,
     pycompat,
+    util,
 )
 from .utils import stringutil
 
@@ -449,6 +451,17 @@ 
     return result
 
 
+def _bytes_to_set(b):
+    """turns a multiple bytes (usually flags) into a set of individual byte"""
+    return set(b[x : x + 1] for x in range(len(b)))
+
+
+def is_null(ctx):
+    if not util.safehasattr(ctx, "node"):
+        return False
+    return ctx.node() != nodemod.nullid
+
+
 def simplemerge(ui, localctx, basectx, otherctx, **opts):
     """Performs the simplemerge algorithm.
 
@@ -503,8 +516,20 @@ 
         else:
             mergedtext += line
 
+    # merge flags if necessary
+    flags = localctx.flags()
+    localflags = _bytes_to_set(flags)
+    otherflags = _bytes_to_set(otherctx.flags())
+    if is_null(basectx) and localflags != otherflags:
+        baseflags = _bytes_to_set(basectx.flags())
+        flags = localflags & otherflags
+        for f in localflags.symmetric_difference(otherflags):
+            if f not in baseflags:
+                flags.add(f)
+        flags = b''.join(sorted(flags))
+
     if not opts.get(b'print'):
-        localctx.write(mergedtext, localctx.flags())
+        localctx.write(mergedtext, flags)
 
     if m3.conflicts and not mode == b'union':
         return 1