# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 1601469441 -19800 # Node ID e8078af6af3004f7abe94bc6e832bd688df11432 # Parent 29c1d24018239392e1d1c9be519384a716432eb8 merge: if CHANGED_DELETED and KEEP_NEW are actions, choose CHANGED_DELETED ACTION_KEEP_NEW and ACTION_CHANGED_DELETED are conflicting actions as one says that file is new while other says that file was present earlier and has changed-delete conflicts. Let's do changed-delete which will lead to conflicts and make user choose the right way. diff -r 29c1d2401823 -r e8078af6af30 mercurial/merge.py --- a/mercurial/merge.py Wed Sep 30 17:51:40 2020 +0530 +++ b/mercurial/merge.py Wed Sep 30 18:07:21 2020 +0530 @@ -1215,6 +1215,21 @@ repo.ui.note(_(b" %s: picking 'keep absent' action\n") % f) mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_ABSENT][0]) continue + # ACTION_KEEP_NEW and ACTION_CHANGED_DELETED are conflicting actions + # as one say that file is new while other says that file was present + # earlier too and has a change delete conflict + # Let's fall back to conflicting ACTION_CHANGED_DELETED and let user + # do the right thing + if ( + mergestatemod.ACTION_CHANGED_DELETED in bids + and mergestatemod.ACTION_KEEP_NEW in bids + and len(bids) == 2 + ): + repo.ui.note(_(b" %s: picking 'changed/deleted' action\n") % f) + mresult.addfile( + f, *bids[mergestatemod.ACTION_CHANGED_DELETED][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) diff -r 29c1d2401823 -r e8078af6af30 tests/test-merge-criss-cross.t --- a/tests/test-merge-criss-cross.t Wed Sep 30 17:51:40 2020 +0530 +++ b/tests/test-merge-criss-cross.t Wed Sep 30 18:07:21 2020 +0530 @@ -855,30 +855,61 @@ no merge state found (merging a deletion with keeping → conflict) -BROKEN: this should result in conflict $ hg update --clean 'desc("merge-keeping-the-file-from-deleted")' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved +#if newfilenode + $ hg merge 'desc("merge-deleting-the-file-from-deleted")' + file 'the-file' was deleted in other [merge rev] but was modified in local [working copy]. + You can use (c)hanged version, (d)elete, or leave (u)nresolved. + What do you want to do? u + 0 files updated, 0 files merged, 0 files removed, 1 files unresolved + use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon + [1] +#else $ hg merge 'desc("merge-deleting-the-file-from-deleted")' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) +#endif $ ls -1 other-file the-file + +#if newfilenode $ hg debugmergestate local (working copy): 38a4c3e7cac8c294ecb0a7a85a05464e9836ca78 (newfilenode !) local (working copy): e9b7081317232edce73f7ad5ae0b7807ff5c326a (old !) other (merge rev): adfd88e5d7d3d3e22bdd26512991ee64d59c1d8f + file: the-file (state "u") + local path: the-file (hash 6d2e02da5a9fe0691363dc6b573845fa271eaa35, flags "") + ancestor path: the-file (node 59e363a07dc876278f0e41756236f30213b6b460) + other path: the-file (node 0000000000000000000000000000000000000000) + extra: ancestorlinknode = 9b610631ab29024c5f44af7d2c19658ef8f8f071 + extra: merge-removal-candidate = yes +#else + $ hg debugmergestate + local (working copy): e9b7081317232edce73f7ad5ae0b7807ff5c326a + other (merge rev): adfd88e5d7d3d3e22bdd26512991ee64d59c1d8f extra: the-file (merge-removal-candidate = yes) +#endif (merging a deletion with keeping → conflict) -BROKEN: this should result in conflict $ hg update --clean 'desc("merge-keeping-the-file-from-deleted")' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved +#if newfilenode + $ hg merge 'desc("merge-deleting-the-file-from-updated")' + file 'the-file' was deleted in other [merge rev] but was modified in local [working copy]. + You can use (c)hanged version, (d)elete, or leave (u)nresolved. + What do you want to do? u + 0 files updated, 0 files merged, 0 files removed, 1 files unresolved + use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon + [1] +#else $ hg merge 'desc("merge-deleting-the-file-from-updated")' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) +#endif $ ls -1 other-file the-file @@ -886,7 +917,12 @@ $ hg debugmergestate local (working copy): 38a4c3e7cac8c294ecb0a7a85a05464e9836ca78 other (merge rev): a4e0e44229dc130be2915b92c957c093f8c7ee3e - extra: the-file (merge-removal-candidate = yes) + file: the-file (state "u") + local path: the-file (hash 6d2e02da5a9fe0691363dc6b573845fa271eaa35, flags "") + ancestor path: the-file (node 59e363a07dc876278f0e41756236f30213b6b460) + other path: the-file (node 0000000000000000000000000000000000000000) + extra: ancestorlinknode = 9b610631ab29024c5f44af7d2c19658ef8f8f071 + extra: merge-removal-candidate = yes #else $ hg debugmergestate local (working copy): e9b7081317232edce73f7ad5ae0b7807ff5c326a