changeset 44790:84614212ae39 stable

flags: actually merge flags in simplemerge Since b86fc43e4b73, 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. Differential Revision: https://phab.mercurial-scm.org/D8533
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sat, 16 May 2020 20:38:19 +0200
parents 783f059509e4
children 4234c9af515d
files mercurial/simplemerge.py tests/test-merge-exec.t
diffstat 2 files changed, 26 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/simplemerge.py	Sat May 16 20:38:07 2020 +0200
+++ b/mercurial/simplemerge.py	Sat May 16 20:38:19 2020 +0200
@@ -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
--- a/tests/test-merge-exec.t	Sat May 16 20:38:07 2020 +0200
+++ b/tests/test-merge-exec.t	Sat May 16 20:38:19 2020 +0200
@@ -195,7 +195,6 @@
   M z
     a
   $ [ -x z ] || echo "executable bit lost"
-  executable bit lost
 
 merge them (from the chmod side)