Patchwork [4,of,4,mergedriver] merge: move almost all change/delete conflicts to resolve phase (BC) (API)

login
register
mail settings
Submitter Matt Harbison
Date Dec. 4, 2015, 3:19 a.m.
Message ID <op.x83ni61a9lwrgf@envy>
Download mbox | patch
Permalink /patch/11797/
State Not Applicable
Headers show

Comments

Matt Harbison - Dec. 4, 2015, 3:19 a.m.
On Mon, 30 Nov 2015 17:25:09 -0500, Siddharth Agarwal <sid0@fb.com> wrote:

> # HG changeset patch
> # User Siddharth Agarwal <sid0@fb.com>
> # Date 1448490333 28800
> #      Wed Nov 25 14:25:33 2015 -0800
> # Node ID 2d7ab840e26d1a5dfc1483c21e8bf0cbb1babafa
> # Parent  e4745330dbb979cc776cf909c4355425f145ebaa
> # Available At http://42.netv6.net/sid0-wip/hg/
> #              hg pull http://42.netv6.net/sid0-wip/hg/ -r 2d7ab840e26d
> merge: move almost all change/delete conflicts to resolve phase (BC)  
> (API)

Not sure why, but I'm seeing this on Windows:


I'd write it off because you mention not dealing with .hgsubstate  
conflicts below, but the test runs fine on Linux.  I didn't try OS X.  I  
can file a bug if it isn't an issue you are aware of/have a ready fix for.


> We have finally laid all the groundwork to make this happen.
>
> The only change/delete conflicts that haven't been moved are .hgsubstate
> conflicts. Those are trickier to deal with and well outside the scope of  
> this
> series.
>
> We add comprehensive testing not just for the initial selections but  
> also for
> re-resolves and all possible dirstate transitions caused by merge tools.  
> That
> testing managed to shake out several bugs in the way we were handling  
> dirstate
> transitions.
>
> The other test changes are because we now treat change/delete conflicts  
> as
> proper merges, and increment the 'merged' counter rather than the  
> 'updated'
> counter. I believe this is the right approach here.
>
> For third-party extensions, if they're interacting with filemerge code  
> they
> might have to deal with an absentfilectx rather than a regular filectx.
>
> Still to come:
> - add a 'leave unresolved' option to merges
> - change the default for non-interactive change/delete conflicts to be  
> 'leave
>   unresolved'
> - add debug output to go alongside debug outputs for binary and symlink  
> file
>   merges
>
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -997,8 +997,11 @@ def applyupdates(repo, actions, wctx, mc
>      for m, l in actions.items():
>          l.sort()
> -    # prescan for merges
> -    for f, args, msg in actions['m']:
> +    # 'cd' and 'dc' actions are treated like other merge conflicts
> +    mergeactions = sorted(actions['cd'])
> +    mergeactions.extend(sorted(actions['dc']))
> +    mergeactions.extend(actions['m'])
> +    for f, args, msg in mergeactions:
>          f1, f2, fa, move, anc = args
>          if f == '.hgsubstate': # merged internally
>              continue
> @@ -1111,7 +1114,6 @@ def applyupdates(repo, actions, wctx, mc
>          util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
>          updated += 1
> -    mergeactions = actions['m']
>      # the ordering is important here -- ms.mergedriver will raise if  
> the merge
>      # driver has changed, and we want to be able to bypass it when  
> overwrite is
>      # True
> @@ -1419,8 +1421,12 @@ def update(repo, node, branchmerge, forc
>              else:
>                  _checkcollision(repo, wc.manifest(), actions)
> -        # Prompt and create actions. TODO: Move this towards resolve  
> phase.
> +        # Prompt and create actions. Most of this is in the resolve  
> phase
> +        # already, but we can't handle .hgsubstate in filemerge or
> +        # subrepo.submerge yet so we have to keep prompting for it.
>          for f, args, msg in sorted(actions['cd']):
> +            if f != '.hgsubstate':
> +                continue
>              if repo.ui.promptchoice(
>                  _("local changed %s which remote deleted\n"
>                    "use (c)hanged version or (d)elete?"
> @@ -1432,6 +1438,8 @@ def update(repo, node, branchmerge, forc
>                  actions['a'].append((f, None, "prompt keep"))
>         for f, args, msg in sorted(actions['dc']):
> +            if f != '.hgsubstate':
> +                continue
>              f1, f2, fa, move, anc = args
>              flags = p2[f2].flags()
>              if repo.ui.promptchoice(
> diff --git a/tests/test-merge-changedelete.t  
> b/tests/test-merge-changedelete.t
> --- a/tests/test-merge-changedelete.t
> +++ b/tests/test-merge-changedelete.t
> @@ -1,4 +1,4 @@
> -Test for
> +Tests for change/delete conflicts, including:
>  b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
>   (issue897)
> @@ -25,7 +25,8 @@ Make sure HGMERGE doesn't interfere with
>    >     done
>    > }
> -  $ hg init
> +  $ hg init repo
> +  $ cd repo
>   $ echo 1 > file1
>    $ echo 2 > file2
> @@ -59,7 +60,7 @@ Non-interactive merge:
>    use (c)hanged version or leave (d)eleted? c
>    merging file3
>    warning: conflicts while merging file3! (edit, then use 'hg resolve  
> --mark')
> -  1 files updated, 0 files merged, 0 files removed, 1 files unresolved
> +  0 files updated, 2 files merged, 0 files removed, 1 files unresolved
>    use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
>    [1]
> @@ -69,11 +70,21 @@ Non-interactive merge:
>    M file3
>    C file1
>    --- resolve --list ---
> +  R file1
> +  R file2
>    U file3
>    --- debugmergestate ---
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
>    file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -108,7 +119,7 @@ Interactive merge:
>    use (c)hanged version or leave (d)eleted? d
>    merging file3
>    warning: conflicts while merging file3! (edit, then use 'hg resolve  
> --mark')
> -  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
> +  0 files updated, 2 files merged, 0 files removed, 1 files unresolved
>    use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
>    [1]
> @@ -118,11 +129,21 @@ Interactive merge:
>    M file3
>    C file1
>    --- resolve --list ---
> +  R file1
> +  R file2
>    U file3
>    --- debugmergestate ---
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
>    file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -167,7 +188,7 @@ Interactive merge with bad input:
>    use (c)hanged version or leave (d)eleted? c
>    merging file3
>    warning: conflicts while merging file3! (edit, then use 'hg resolve  
> --mark')
> -  1 files updated, 0 files merged, 1 files removed, 1 files unresolved
> +  0 files updated, 1 files merged, 1 files removed, 1 files unresolved
>    use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
>    [1]
> @@ -177,11 +198,21 @@ Interactive merge with bad input:
>    M file3
>    R file1
>    --- resolve --list ---
> +  R file1
> +  R file2
>    U file3
>    --- debugmergestate ---
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
>    file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -210,17 +241,83 @@ Interactive merge with not enough input:
>    local changed file1 which remote deleted
>    use (c)hanged version or (d)elete? d
>    remote changed file2 which local deleted
> -  use (c)hanged version or leave (d)eleted? abort: response expected
> -  [255]
> +  use (c)hanged version or leave (d)eleted?
> +  merging file3
> +  warning: conflicts while merging file3! (edit, then use 'hg resolve  
> --mark')
> +  0 files updated, 0 files merged, 1 files removed, 2 files unresolved
> +  use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
> +  [1]
>   $ status
>    --- status ---
> +  M file2
> +  M file3
> +  R file1
> +  --- resolve --list ---
> +  R file1
> +  U file2
> +  U file3
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "u", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
> +  *** file1 does not exist
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2,  
> changed file3
> +  changed2
> +  =======
> +  changed1
> +  >>>>>>> other: 10f9a0a634e8  - test: removed file1, changed file2,  
> changed file3
> +
> +Choose local versions of files
> +
> +  $ hg co -C
> +  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +
> +  $ hg merge --tool :local
> +  0 files updated, 3 files merged, 0 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ status 2>&1 | tee $TESTTMP/local.status
> +  --- status ---
>    file2: * (glob)
> +  M file3
>    C file1
> -  C file3
>    --- resolve --list ---
> +  R file1
> +  R file2
> +  R file3
>    --- debugmergestate ---
> -  no merge state found
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "r", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
>    --- file1 ---
>    1
>    changed
> @@ -229,6 +326,350 @@ Interactive merge with not enough input:
>    3
>    changed2
> +Choose other versions of files
> +
> +  $ hg co -C
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +
> +  $ hg merge --tool :other
> +  0 files updated, 2 files merged, 1 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ status 2>&1 | tee $TESTTMP/other.status
> +  --- status ---
> +  M file2
> +  M file3
> +  R file1
> +  --- resolve --list ---
> +  R file1
> +  R file2
> +  R file3
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "r", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
> +  *** file1 does not exist
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed1
> +
> +Fail
> +
> +  $ hg co -C
> +  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +
> +  $ hg merge --tool :fail
> +  0 files updated, 0 files merged, 0 files removed, 3 files unresolved
> +  use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
> +  [1]
> +  $ status 2>&1 | tee $TESTTMP/fail.status
> +  --- status ---
> +  M file2
> +  M file3
> +  C file1
> +  --- resolve --list ---
> +  U file1
> +  U file2
> +  U file3
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "u", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "u", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed2
> +
> +Force prompts with no input (should be similar to :fail)
> +
> +  $ hg co -C
> +  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +
> +  $ hg merge --config ui.interactive=True --tool :prompt
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  no tool found to merge file3
> +  keep (l)ocal or take (o)ther?
> +  0 files updated, 0 files merged, 0 files removed, 3 files unresolved
> +  use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
> +  [1]
> +  $ status 2>&1 | tee $TESTTMP/prompt.status
> +  --- status ---
> +  M file2
> +  M file3
> +  C file1
> +  --- resolve --list ---
> +  U file1
> +  U file2
> +  U file3
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "u", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "u", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed2
> +  $ diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
> +
> +
> +Force prompts
> +
> +  $ hg co -C
> +  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +
> +  $ hg merge --tool :prompt
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete? c
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  no tool found to merge file3
> +  keep (l)ocal or take (o)ther? l
> +  0 files updated, 3 files merged, 0 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ status
> +  --- status ---
> +  M file2
> +  M file3
> +  C file1
> +  --- resolve --list ---
> +  R file1
> +  R file2
> +  R file3
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "r", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed2
> +
> +Choose to merge all files
> +
> +  $ hg co -C
> +  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +
> +  $ hg merge --tool :merge3
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete? c
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging file3
> +  warning: conflicts while merging file3! (edit, then use 'hg resolve  
> --mark')
> +  0 files updated, 2 files merged, 0 files removed, 1 files unresolved
> +  use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
> +  [1]
> +  $ status
> +  --- status ---
> +  M file2
> +  M file3
> +  C file1
> +  --- resolve --list ---
> +  R file1
> +  R file2
> +  U file3
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  file: file3 (record type "F", state "u", hash  
> d5b0a58bc47161b1b8a831084b366f757c4f0b11)
> +    local path: file3 (flags "")
> +    ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> +    other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2,  
> changed file3
> +  changed2
> +  ||||||| base
> +  =======
> +  changed1
> +  >>>>>>> other: 10f9a0a634e8  - test: removed file1, changed file2,  
> changed file3
> +
> +Exercise transitions between local, other, fail and prompt, and make  
> sure the
> +dirstate stays consistent. (Compare with each other and to the above
> +invocations.)
> +
> +  $ testtransitions() {
> +  >     # this traversal order covers every transition
> +  >     tools="local other prompt local fail other local prompt other  
> fail prompt fail local"
> +  >     lasttool="merge3"
> +  >     for tool in $tools; do
> +  >         echo "=== :$lasttool -> :$tool ==="
> +  >         ref="$TESTTMP/$tool.status"
> +  >         hg resolve --unmark --all
> +  >         hg resolve --tool ":$tool" --all --config  
> ui.interactive=True
> +  >         status > "$TESTTMP/compare.status" 2>&1
> +  >         echo '--- diff of status ---'
> +  >         if diff -U8 "$TESTTMP/$tool.status"  
> "$TESTTMP/compare.status"; then
> +  >             echo '(status identical)'
> +  >         fi
> +  >         lasttool="$tool"
> +  >         echo
> +  >     done
> +  > }
> +
> +  $ testtransitions
> +  === :merge3 -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :local -> :other ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :other -> :prompt ===
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  no tool found to merge file3
> +  keep (l)ocal or take (o)ther?
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :prompt -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :local -> :fail ===
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :fail -> :other ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :other -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :local -> :prompt ===
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  no tool found to merge file3
> +  keep (l)ocal or take (o)ther?
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :prompt -> :other ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :other -> :fail ===
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :fail -> :prompt ===
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  no tool found to merge file3
> +  keep (l)ocal or take (o)ther?
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :prompt -> :fail ===
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :fail -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +
> +
>  Non-interactive linear update
>   $ hg co -C 0
> @@ -240,15 +681,27 @@ Non-interactive linear update
>    use (c)hanged version or (d)elete? c
>    remote changed file2 which local deleted
>    use (c)hanged version or leave (d)eleted? c
> -  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  1 files updated, 2 files merged, 0 files removed, 0 files unresolved
>    $ status
>    --- status ---
>    A file1
>    C file2
>    C file3
>    --- resolve --list ---
> +  R file1
> +  R file2
>    --- debugmergestate ---
> -  no merge state found
> +  * version 2 records
> +  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
>    --- file1 ---
>    1
>    changed
> @@ -258,3 +711,277 @@ Non-interactive linear update
>    --- file3 ---
>    3
>    changed1
> +
> +Choose local versions of files
> +
> +  $ hg co -C 0
> +  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ echo changed >> file1
> +  $ hg rm file2
> +  $ hg update 1 --tool :local
> +  1 files updated, 2 files merged, 0 files removed, 0 files unresolved
> +  $ status 2>&1 | tee $TESTTMP/local.status
> +  --- status ---
> +  file2: * (glob)
> +  A file1
> +  C file3
> +  --- resolve --list ---
> +  R file1
> +  R file2
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  --- file1 ---
> +  1
> +  changed
> +  *** file2 does not exist
> +  --- file3 ---
> +  3
> +  changed1
> +
> +Choose other versions of files
> +
> +  $ hg co -C 0
> +  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ echo changed >> file1
> +  $ hg rm file2
> +  $ hg update 1 --tool :other
> +  1 files updated, 1 files merged, 1 files removed, 0 files unresolved
> +  $ status 2>&1 | tee $TESTTMP/other.status
> +  --- status ---
> +  file1: * (glob)
> +  C file2
> +  C file3
> +  --- resolve --list ---
> +  R file1
> +  R file2
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  *** file1 does not exist
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed1
> +
> +Fail
> +
> +  $ hg co -C 0
> +  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ echo changed >> file1
> +  $ hg rm file2
> +  $ hg update 1 --tool :fail
> +  1 files updated, 0 files merged, 0 files removed, 2 files unresolved
> +  use 'hg resolve' to retry unresolved file merges
> +  [1]
> +  $ status 2>&1 | tee $TESTTMP/fail.status
> +  --- status ---
> +  A file1
> +  C file2
> +  C file3
> +  --- resolve --list ---
> +  U file1
> +  U file2
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "u", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "u", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed1
> +
> +Force prompts with no input
> +
> +  $ hg co -C 0
> +  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ echo changed >> file1
> +  $ hg rm file2
> +  $ hg update 1 --config ui.interactive=True --tool :prompt
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  1 files updated, 0 files merged, 0 files removed, 2 files unresolved
> +  use 'hg resolve' to retry unresolved file merges
> +  [1]
> +  $ status 2>&1 | tee $TESTTMP/prompt.status
> +  --- status ---
> +  A file1
> +  C file2
> +  C file3
> +  --- resolve --list ---
> +  U file1
> +  U file2
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "u", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "u", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed1
> +  $ diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
> +
> +Choose to merge all files
> +
> +  $ hg co -C 0
> +  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ echo changed >> file1
> +  $ hg rm file2
> +  $ hg update 1 --tool :merge3
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete? c
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  1 files updated, 2 files merged, 0 files removed, 0 files unresolved
> +  $ status
> +  --- status ---
> +  A file1
> +  C file2
> +  C file3
> +  --- resolve --list ---
> +  R file1
> +  R file2
> +  --- debugmergestate ---
> +  * version 2 records
> +  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
> +  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file: file1 (record type "C", state "r", hash  
> 60b27f004e454aca81b0480209cce5081ec52390)
> +    local path: file1 (flags "")
> +    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
> +    other path: file1 (node null)
> +  file: file2 (record type "C", state "r", hash null)
> +    local path: file2 (flags "")
> +    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> +    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
> +  --- file1 ---
> +  1
> +  changed
> +  --- file2 ---
> +  2
> +  changed
> +  --- file3 ---
> +  3
> +  changed1
> +
> +Test transitions between different merge tools
> +
> +  $ testtransitions
> +  === :merge3 -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :local -> :other ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :other -> :prompt ===
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :prompt -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :local -> :fail ===
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :fail -> :other ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :other -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :local -> :prompt ===
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :prompt -> :other ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :other -> :fail ===
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :fail -> :prompt ===
> +  local changed file1 which remote deleted
> +  use (c)hanged version or (d)elete?
> +  remote changed file2 which local deleted
> +  use (c)hanged version or leave (d)eleted?
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :prompt -> :fail ===
> +  --- diff of status ---
> +  (status identical)
> +
> +  === :fail -> :local ===
> +  (no more unresolved files)
> +  --- diff of status ---
> +  (status identical)
> +
> diff --git a/tests/test-merge-force.t b/tests/test-merge-force.t
> --- a/tests/test-merge-force.t
> +++ b/tests/test-merge-force.t
> @@ -5,7 +5,8 @@ file that was modified in the remote cha
>  local changeset, and then modified in the working copy to match the
>  remote content, then finally forgotten.
> -  $ hg init
> +  $ hg init repo
> +  $ cd repo
> Create base changeset
> @@ -214,7 +215,7 @@ Merge with remote
>    warning: conflicts while merging  
> missing_content2_content3_content4-tracked! (edit, then use 'hg resolve  
> --mark')
>    warning: conflicts while merging  
> missing_content2_missing_content4-tracked! (edit, then use 'hg resolve  
> --mark')
>    warning: conflicts while merging  
> missing_content2_missing_content4-untracked! (edit, then use 'hg resolve  
> --mark')
> -  39 files updated, 3 files merged, 8 files removed, 10 files unresolved
> +  18 files updated, 28 files merged, 8 files removed, 10 files  
> unresolved
>    use 'hg resolve' to retry unresolved file merges or 'hg update -C .'  
> to abandon
>    [1]
> @@ -226,14 +227,39 @@ Interestingly, one untracked file got me
>  odd 'if force and branchmerge and different' case in manifestmerge().
>   $ hg resolve -l
> +  R content1_content2_content1_content1-untracked
> +  R content1_content2_content1_content2-untracked
>    U content1_content2_content1_content4-tracked
> +  R content1_content2_content1_content4-untracked
> +  R content1_content2_content1_missing-tracked
> +  R content1_content2_content1_missing-untracked
>    R content1_content2_content2_content1-tracked
> +  R content1_content2_content2_content1-untracked
> +  R content1_content2_content2_content2-untracked
>    U content1_content2_content2_content4-tracked
> +  R content1_content2_content2_content4-untracked
> +  R content1_content2_content2_missing-tracked
> +  R content1_content2_content2_missing-untracked
>    R content1_content2_content3_content1-tracked
> +  R content1_content2_content3_content1-untracked
> +  R content1_content2_content3_content2-untracked
>    U content1_content2_content3_content3-tracked
> +  R content1_content2_content3_content3-untracked
>    U content1_content2_content3_content4-tracked
> +  R content1_content2_content3_content4-untracked
> +  R content1_content2_content3_missing-tracked
> +  R content1_content2_content3_missing-untracked
>    R content1_content2_missing_content1-tracked
> +  R content1_content2_missing_content1-untracked
> +  R content1_content2_missing_content2-untracked
>    U content1_content2_missing_content4-tracked
> +  R content1_content2_missing_content4-untracked
> +  R content1_content2_missing_missing-tracked
> +  R content1_content2_missing_missing-untracked
> +  R content1_missing_content1_content4-tracked
> +  R content1_missing_content3_content3-tracked
> +  R content1_missing_content3_content4-tracked
> +  R content1_missing_missing_content4-tracked
>    U missing_content2_content2_content4-tracked
>    U missing_content2_content3_content3-tracked
>    U missing_content2_content3_content4-tracked
> @@ -260,17 +286,20 @@ almost as strange.
>  missing_missing_content3_missing-tracked becomes removed ('R'), even  
> though
>  the remote side did not touch the file
> -  $ for f in `python $TESTDIR/generate-working-copy-states.py filelist  
> 3`
> -  > do
> -  >   echo
> -  >   hg status -A $f
> -  >   if test -f $f
> -  >   then
> -  >     cat $f
> -  >   else
> -  >     echo '<missing>'
> -  >   fi
> -  > done
> +  $ checkstatus() {
> +  >   for f in `python $TESTDIR/generate-working-copy-states.py  
> filelist 3`
> +  >   do
> +  >     echo
> +  >     hg status -A $f
> +  >     if test -f $f
> +  >     then
> +  >       cat $f
> +  >     else
> +  >       echo '<missing>'
> +  >     fi
> +  >   done
> +  > }
> +  $ checkstatus 2>&1 | tee $TESTTMP/status1
>   C content1_content1_content1_content1-tracked
>    content1
> @@ -667,3 +696,87 @@ the remote side did not touch the file
>    content4
>    missing_content2_missing_content4-untracked.orig:
>    content4
> +
> +Re-resolve and check status
> +
> +  $ hg resolve --unmark --all
> +  $ hg resolve --all --tool :local
> +  (no more unresolved files)
> +  $ hg resolve --unmark --all
> +  $ hg resolve --all --tool internal:merge3
> +  remote changed content1_content2_content1_content1-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content1_content2-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_content1_content4-tracked
> +  remote changed content1_content2_content1_content4-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content1_missing-tracked which local  
> deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content1_missing-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_content2_content1-tracked
> +  remote changed content1_content2_content2_content1-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content2_content2-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_content2_content4-tracked
> +  remote changed content1_content2_content2_content4-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content2_missing-tracked which local  
> deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content2_missing-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_content3_content1-tracked
> +  remote changed content1_content2_content3_content1-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content3_content2-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_content3_content3-tracked
> +  remote changed content1_content2_content3_content3-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_content3_content4-tracked
> +  remote changed content1_content2_content3_content4-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content3_missing-tracked which local  
> deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_content3_missing-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_missing_content1-tracked
> +  remote changed content1_content2_missing_content1-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_missing_content2-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  merging content1_content2_missing_content4-tracked
> +  remote changed content1_content2_missing_content4-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_missing_missing-tracked which local  
> deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  remote changed content1_content2_missing_missing-untracked which  
> local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +  local changed content1_missing_content1_content4-tracked which remote  
> deleted
> +  use (c)hanged version or (d)elete? c
> +  local changed content1_missing_content3_content3-tracked which remote  
> deleted
> +  use (c)hanged version or (d)elete? c
> +  local changed content1_missing_content3_content4-tracked which remote  
> deleted
> +  use (c)hanged version or (d)elete? c
> +  local changed content1_missing_missing_content4-tracked which remote  
> deleted
> +  use (c)hanged version or (d)elete? c
> +  merging missing_content2_content2_content4-tracked
> +  merging missing_content2_content3_content3-tracked
> +  merging missing_content2_content3_content4-tracked
> +  merging missing_content2_missing_content4-tracked
> +  merging missing_content2_missing_content4-untracked
> +  warning: conflicts while merging  
> content1_content2_content1_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> content1_content2_content2_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> content1_content2_content3_content3-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> content1_content2_content3_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> content1_content2_missing_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> missing_content2_content2_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> missing_content2_content3_content3-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> missing_content2_content3_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> missing_content2_missing_content4-tracked! (edit, then use 'hg resolve  
> --mark')
> +  warning: conflicts while merging  
> missing_content2_missing_content4-untracked! (edit, then use 'hg resolve  
> --mark')
> +  [1]
> +  $ checkstatus > $TESTTMP/status2 2>&1
> +  $ diff -U8 $TESTTMP/status1 $TESTTMP/status2
> diff --git a/tests/test-merge-remove.t b/tests/test-merge-remove.t
> --- a/tests/test-merge-remove.t
> +++ b/tests/test-merge-remove.t
> @@ -105,7 +105,7 @@ Those who use force will lose
>    remote changed bar which local deleted
>    use (c)hanged version or leave (d)eleted? c
>    merging foo1 and foo to foo1
> -  1 files updated, 1 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 2 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
>    $ cat bar
>    bleh
> diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t
> --- a/tests/test-rename-merge2.t
> +++ b/tests/test-rename-merge2.t
> @@ -679,12 +679,12 @@ m "um a c" "um x c" "      " "10 do merg
>    resolving manifests
>     branchmerge: True, force: False, partial: False
>     ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
> +   preserving b for resolve of b
> +   preserving rev for resolve of rev
> +   a: prompt deleted/changed -> m (premerge)
> +  picked tool ':prompt' for a (binary False symlink False)
>    remote changed a which local deleted
>    use (c)hanged version or leave (d)eleted? c
> -   preserving b for resolve of b
> -   preserving rev for resolve of rev
> -   a: prompt recreating -> g
> -  getting a
>     b: both created -> m (premerge)
>    picked tool 'python ../merge' for b (binary False symlink False)
>    merging b
> @@ -703,7 +703,7 @@ m "um a c" "um x c" "      " "10 do merg
>    my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
>    launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
>    merge tool returned: 0
> -  1 files updated, 2 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 3 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
>    --------------
>    M a
> @@ -721,11 +721,13 @@ m "um a c" "um x c" "      " "10 do merg
>    resolving manifests
>     branchmerge: True, force: False, partial: False
>     ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
> +   preserving a for resolve of a
> +   preserving b for resolve of b
> +   preserving rev for resolve of rev
> +   a: prompt changed/deleted -> m (premerge)
> +  picked tool ':prompt' for a (binary False symlink False)
>    local changed a which remote deleted
>    use (c)hanged version or (d)elete? c
> -   preserving b for resolve of b
> -   preserving rev for resolve of rev
> -   a: prompt keep -> am
>     b: both created -> m (premerge)
>    picked tool 'python ../merge' for b (binary False symlink False)
>    merging b
> @@ -744,7 +746,7 @@ m "um a c" "um x c" "      " "10 do merg
>    my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
>    launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
>    merge tool returned: 0
> -  0 files updated, 2 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 3 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
>    --------------
>    M b
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel
Pierre-Yves David - Dec. 4, 2015, 3:48 a.m.
On 12/03/2015 07:19 PM, Matt Harbison wrote:
> On Mon, 30 Nov 2015 17:25:09 -0500, Siddharth Agarwal <sid0@fb.com> wrote:
>
>> # HG changeset patch
>> # User Siddharth Agarwal <sid0@fb.com>
>> # Date 1448490333 28800
>> #      Wed Nov 25 14:25:33 2015 -0800
>> # Node ID 2d7ab840e26d1a5dfc1483c21e8bf0cbb1babafa
>> # Parent  e4745330dbb979cc776cf909c4355425f145ebaa
>> # Available At http://42.netv6.net/sid0-wip/hg/
>> #              hg pull http://42.netv6.net/sid0-wip/hg/ -r 2d7ab840e26d
>> merge: move almost all change/delete conflicts to resolve phase (BC)
>> (API)
>
> Not sure why, but I'm seeing this on Windows:
>
> --- c:/Users/Matt/Projects/hg/tests/test-subrepo-missing.t
> +++ c:/Users/Matt/Projects/hg/tests/test-subrepo-missing.t.err
> @@ -64,8 +64,12 @@
>     $ hg up 0
>     remote changed .hgsubstate which local deleted
>     use (c)hanged version or leave (d)eleted? c
> +   subrepository subrepo diverged (local revision: , remote revision:
> 07f494440405)
> +  (M)erge, keep (l)ocal or keep (r)emote? m
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>     1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>     $ hg st
> +  M .hgsubstate
>     $ ls subrepo
>     a
>
> I'd write it off because you mention not dealing with .hgsubstate
> conflicts below, but the test runs fine on Linux.  I didn't try OS X.  I
> can file a bug if it isn't an issue you are aware of/have a ready fix for.

Please do file a bug.

Patch

--- c:/Users/Matt/Projects/hg/tests/test-subrepo-missing.t
+++ c:/Users/Matt/Projects/hg/tests/test-subrepo-missing.t.err
@@ -64,8 +64,12 @@ 
    $ hg up 0
    remote changed .hgsubstate which local deleted
    use (c)hanged version or leave (d)eleted? c
+   subrepository subrepo diverged (local revision: , remote revision:  
07f494440405)
+  (M)erge, keep (l)ocal or keep (r)emote? m
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
    $ hg st
+  M .hgsubstate
    $ ls subrepo
    a