diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -552,6 +552,7 @@ class mergeresult(object): NO_OP_ACTIONS = ( mergestatemod.ACTION_KEEP, mergestatemod.ACTION_KEEP_ABSENT, + mergestatemod.ACTION_KEEP_NEW, ) def __init__(self): @@ -921,7 +922,7 @@ def manifestmerge( else: # file not in ancestor, not in remote mresult.addfile( f, - mergestatemod.ACTION_KEEP, + mergestatemod.ACTION_KEEP_NEW, None, b'ancestor missing, remote missing', ) @@ -1191,6 +1192,11 @@ def calculateupdates( repo.ui.note(_(b" %s: picking 'keep absent' action\n") % f) mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_ABSENT][0]) continue + # If keep new is an option, let's just do that + if mergestatemod.ACTION_KEEP_NEW in bids: + repo.ui.note(_(b" %s: picking 'keep new' action\n") % f) + mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_NEW][0]) + continue # If there are gets and they all agree [how could they not?], do it. if mergestatemod.ACTION_GET in bids: ga0 = bids[mergestatemod.ACTION_GET][0] @@ -1496,16 +1502,10 @@ def applyupdates( progress.increment(item=f) # keep (noop, just log it) - for f, args, msg in mresult.getactions( - (mergestatemod.ACTION_KEEP,), sort=True - ): - repo.ui.debug(b" %s: %s -> k\n" % (f, msg)) - # no progress - for f, args, msg in mresult.getactions( - (mergestatemod.ACTION_KEEP_ABSENT,), sort=True - ): - repo.ui.debug(b" %s: %s -> ka\n" % (f, msg)) - # no progress + for a in mergeresult.NO_OP_ACTIONS: + for f, args, msg in mresult.getactions((a,), sort=True): + repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a)) + # no progress # directory rename, move local for f, args, msg in mresult.getactions( diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py --- a/mercurial/mergestate.py +++ b/mercurial/mergestate.py @@ -117,6 +117,9 @@ ACTION_KEEP = b'k' # keep it absent (absent means file not present, it can be a result # of file deletion, rename etc.) ACTION_KEEP_ABSENT = b'ka' +# the file is absent on the ancestor and remote side of the merge +# hence this file is new and we should keep it +ACTION_KEEP_NEW = b'kn' ACTION_EXEC = b'e' ACTION_CREATED_MERGE = b'cm' @@ -767,6 +770,10 @@ def recordupdates(repo, actions, branchm for f, args, msg in actions.get(ACTION_KEEP_ABSENT, []): pass + # keep new + for f, args, msg in actions.get(ACTION_KEEP_NEW, []): + pass + # get for f, args, msg in actions.get(ACTION_GET, []): if branchmerge: diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t --- a/tests/test-merge-criss-cross.t +++ b/tests/test-merge-criss-cross.t @@ -431,8 +431,8 @@ Verify that the old context ancestor wor resolving manifests branchmerge: True, force: False, partial: False ancestor: 11b5b303e36c, local: c0ef19750a22+, remote: 6ca01f7342b9 - d1/a: ancestor missing, remote missing -> k - d1/b: ancestor missing, remote missing -> k + d1/a: ancestor missing, remote missing -> kn + d1/b: ancestor missing, remote missing -> kn d2/b: remote created -> g calculating bids for ancestor 154e6000f54e @@ -452,13 +452,13 @@ Verify that the old context ancestor wor auction for merging merge bids (2 ancestors) list of bids for d1/a: - ancestor missing, remote missing -> k + ancestor missing, remote missing -> kn other deleted -> r - d1/a: picking 'keep' action + d1/a: picking 'keep new' action list of bids for d1/b: - ancestor missing, remote missing -> k + ancestor missing, remote missing -> kn other deleted -> r - d1/b: picking 'keep' action + d1/b: picking 'keep new' action list of bids for d2/b: remote created -> g remote created -> g @@ -467,8 +467,8 @@ Verify that the old context ancestor wor d2/b: remote created -> g getting d2/b - d1/a: ancestor missing, remote missing -> k - d1/b: ancestor missing, remote missing -> k + d1/a: ancestor missing, remote missing -> kn + d1/b: ancestor missing, remote missing -> kn 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)