--- a/mercurial/merge.py Thu Apr 09 15:44:21 2020 -0400
+++ b/mercurial/merge.py Thu Apr 09 16:06:03 2020 +0530
@@ -64,6 +64,7 @@
RECORD_OVERRIDE = b't'
RECORD_UNSUPPORTED_MANDATORY = b'X'
RECORD_UNSUPPORTED_ADVISORY = b'x'
+RECORD_RESOLVED_OTHER = b'R'
MERGE_DRIVER_STATE_UNMARKED = b'u'
MERGE_DRIVER_STATE_MARKED = b'm'
@@ -74,6 +75,9 @@
MERGE_RECORD_UNRESOLVED_PATH = b'pu'
MERGE_RECORD_RESOLVED_PATH = b'pr'
MERGE_RECORD_DRIVER_RESOLVED = b'd'
+# represents that the file was automatically merged in favor
+# of other version. This info is used on commit.
+MERGE_RECORD_MERGED_OTHER = b'o'
ACTION_FORGET = b'f'
ACTION_REMOVE = b'r'
@@ -91,6 +95,8 @@
ACTION_KEEP = b'k'
ACTION_EXEC = b'e'
ACTION_CREATED_MERGE = b'cm'
+# GET the other/remote side and store this info in mergestate
+ACTION_GET_OTHER_AND_STORE = b'gs'
class mergestate(object):
@@ -227,6 +233,7 @@
RECORD_CHANGEDELETE_CONFLICT,
RECORD_PATH_CONFLICT,
RECORD_MERGE_DRIVER_MERGE,
+ RECORD_RESOLVED_OTHER,
):
bits = record.split(b'\0')
self._state[bits[0]] = bits[1:]
@@ -453,6 +460,10 @@
records.append(
(RECORD_PATH_CONFLICT, b'\0'.join([filename] + v))
)
+ elif v[0] == MERGE_RECORD_MERGED_OTHER:
+ records.append(
+ (RECORD_RESOLVED_OTHER, b'\0'.join([filename] + v))
+ )
elif v[1] == nullhex or v[6] == nullhex:
# Change/Delete or Delete/Change conflicts. These are stored in
# 'C' records. v[1] is the local file, and is nullhex when the
@@ -551,6 +562,10 @@
self._state[path] = [MERGE_RECORD_UNRESOLVED_PATH, frename, forigin]
self._dirty = True
+ def addmergedother(self, path):
+ self._state[path] = [MERGE_RECORD_MERGED_OTHER, nullhex, nullhex]
+ self._dirty = True
+
def __contains__(self, dfile):
return dfile in self._state
@@ -594,6 +609,8 @@
"""rerun merge process for file path `dfile`"""
if self[dfile] in (MERGE_RECORD_RESOLVED, MERGE_RECORD_DRIVER_RESOLVED):
return True, 0
+ if self._state[dfile][0] == MERGE_RECORD_MERGED_OTHER:
+ return True, 0
stateentry = self._state[dfile]
state, localkey, lfile, afile, anode, ofile, onode, flags = stateentry
octx = self._repo[self._other]
@@ -1209,7 +1226,7 @@
narrowed.
"""
nooptypes = {b'k'} # TODO: handle with nonconflicttypes
- nonconflicttypes = set(b'a am c cm f g r e'.split())
+ nonconflicttypes = set(b'a am c cm f g gs r e'.split())
# We mutate the items in the dict during iteration, so iterate
# over a copy.
for f, action in list(actions.items()):
@@ -1348,14 +1365,22 @@
)
else:
actions[f] = (
- ACTION_GET,
+ ACTION_GET_OTHER_AND_STORE
+ if branchmerge
+ else ACTION_GET,
(fl2, False),
b'remote is newer',
)
elif nol and n2 == a: # remote only changed 'x'
actions[f] = (ACTION_EXEC, (fl2,), b'update permissions')
elif nol and n1 == a: # local only changed 'x'
- actions[f] = (ACTION_GET, (fl1, False), b'remote is newer')
+ actions[f] = (
+ ACTION_GET_OTHER_AND_STORE
+ if branchmerge
+ else ACTION_GET,
+ (fl1, False),
+ b'remote is newer',
+ )
else: # both changed something
actions[f] = (
ACTION_MERGE,
@@ -1588,6 +1613,8 @@
for f, a in sorted(pycompat.iteritems(actions)):
m, args, msg = a
+ if m == ACTION_GET_OTHER_AND_STORE:
+ m = ACTION_GET
repo.ui.debug(b' %s: %s -> %s\n' % (f, msg, m))
if f in fbids:
d = fbids[f]
@@ -1813,6 +1840,7 @@
ACTION_KEEP,
ACTION_PATH_CONFLICT,
ACTION_PATH_CONFLICT_RESOLVE,
+ ACTION_GET_OTHER_AND_STORE,
)
}
@@ -1835,6 +1863,11 @@
updated, merged, removed = 0, 0, 0
ms = mergestate.clean(repo, wctx.p1().node(), mctx.node(), labels)
+
+ # add ACTION_GET_OTHER_AND_STORE to mergestate
+ for e in actions[ACTION_GET_OTHER_AND_STORE]:
+ ms.addmergedother(e[0])
+
moves = []
for m, l in actions.items():
l.sort()
@@ -2415,6 +2448,7 @@
ACTION_EXEC,
ACTION_REMOVE,
ACTION_PATH_CONFLICT_RESOLVE,
+ ACTION_GET_OTHER_AND_STORE,
):
msg = _(b"conflicting changes")
hint = _(b"commit or update --clean to discard changes")
@@ -2477,6 +2511,10 @@
actions[m] = []
actions[m].append((f, args, msg))
+ # ACTION_GET_OTHER_AND_STORE is a ACTION_GET + store in mergestate
+ for e in actions[ACTION_GET_OTHER_AND_STORE]:
+ actions[ACTION_GET].append(e)
+
if not util.fscasesensitive(repo.path):
# check collision between files only in p2 for clean update
if not branchmerge and (