diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -933,12 +933,41 @@ f, mergestatemod.ACTION_REMOVE, None, b'other deleted', ) else: # file not in ancestor, not in remote - mresult.addfile( - f, - mergestatemod.ACTION_KEEP, - None, - b'ancestor missing, remote missing', - ) + rename_found = False + for source, dest in branch_copies1.dirmove.items(): + if f.startswith(dest): + # this directory in which this file is created + # is moved from somewhere else + # we should check if the source file exists on + # remote side + sf = source + f[len(dest) :] + if sf in m2: + rename_found = True + if m2[sf] == ma[sf]: + mresult.addfile( + f, + mergestatemod.ACTION_KEEP, + None, + b'file is rename dest and rename source' + b' did not change', + ) + else: + mresult.addfile( + f, + mergestatemod.ACTION_MERGE, + (f, sf, sf, False, pa.node()), + b'local directory rename - respect move ' + b'from %s' % sf, + ) + break + + if not rename_found: + mresult.addfile( + f, + mergestatemod.ACTION_KEEP, + None, + b'ancestor missing, remote missing', + ) elif n2: # file exists only on remote side if f in copied1: @@ -1010,12 +1039,16 @@ df = branch_copies1.dirmove[d] + f[len(d) :] break if df is not None and df in m1: + # this file is not present in local however its a source + # of rename for another file. keep this file not + # present in local. Action for rename dest is written + # while processing it mresult.addfile( - df, - mergestatemod.ACTION_MERGE, - (df, f, f, False, pa.node()), - b'local directory rename - respect move ' - b'from %s' % f, + f, + mergestatemod.ACTION_KEEP_ABSENT, + None, + b'remote directory is rename source - respect move ' + b'to %s' % df, ) elif acceptremote: mresult.addfile(