merge: let the user choose to merge, keep local or keep remote subrepo revisions

When a subrepo has changed on the local and remote revisions, prompt the user
whether it wants to merge those subrepo revisions, keep the local revision or
keep the remote revision.

Up until now mercurial would always perform a merge on a subrepo that had
changed on the local and the remote revisions. This is often inconvenient. For
example:

- You may want to perform the actual subrepo merge after you have merged the
parent subrepo files.
- Some subrepos may be considered "read only", in the sense that you are not
supposed to add new revisions to them. In those cases "merging a subrepo" means
choosing which _existing_ revision you want to use on the merged revision. This
is often the case for subrepos that contain binary dependencies (such as DLLs,
etc).

This new prompt makes mercurial better cope with those common scenarios.

Notes:

- The default behavior (which is the one that is used when ui is not
interactive) remains unchanged (i.e. merge is the default action).
- This prompt will be shown even if the ui --tool flag is set.
- I don't know of a way to test the "keep local" and "keep remote" options (i.e.
to force the test to choose those options).


# HG changeset patch
# User Angel Ezquerra <angel.ezquerra@gmail.com>
# Date 1378420708 -7200
#      Fri Sep 06 00:38:28 2013 +0200
# Node ID 2fb9cb0c7b26303ac3178b7739975e663075857d
# Parent  796d34e1b749b79834321ef1181ed8433a5515d9
merge: let the user choose to merge, keep local or keep remote subrepo revisions

When a subrepo has changed on the local and remote revisions, prompt the user
whether it wants to merge those subrepo revisions, keep the local revision or
keep the remote revision.

Up until now mercurial would always perform a merge on a subrepo that had
changed on the local and the remote revisions. This is often inconvenient. For
example:

- You may want to perform the actual subrepo merge after you have merged the
parent subrepo files.
- Some subrepos may be considered "read only", in the sense that you are not
supposed to add new revisions to them. In those cases "merging a subrepo" means
choosing which _existing_ revision you want to use on the merged revision. This
is often the case for subrepos that contain binary dependencies (such as DLLs,
etc).

This new prompt makes mercurial better cope with those common scenarios.

Notes:

- The default behavior (which is the one that is used when ui is not
interactive) remains unchanged (i.e. merge is the default action).
- This prompt will be shown even if the ui --tool flag is set.
- I don't know of a way to test the "keep local" and "keep remote" options (i.e.
to force the test to choose those options).
This commit is contained in:
Angel Ezquerra 2013-09-06 00:38:28 +02:00
parent 67877b90cc
commit 65d42d2870
5 changed files with 56 additions and 4 deletions

View File

@ -202,9 +202,24 @@ def submerge(repo, wctx, mctx, actx, overwrite):
wctx.sub(s).get(r, overwrite)
sm[s] = r
else:
debug(s, "both sides changed, merge with", r)
wctx.sub(s).merge(r)
sm[s] = l
debug(s, "both sides changed")
option = repo.ui.promptchoice(
_(' subrepository %s diverged (local revision: %s, '
'remote revision: %s)\n'
'(M)erge, keep (l)ocal or keep (r)emote?'
'$$ &Merge $$ &Local $$ &Remote')
% (s, l[1][:12], r[1][:12]), 0)
if option == 0:
wctx.sub(s).merge(r)
sm[s] = l
debug(s, "merge with", r)
elif option == 1:
sm[s] = l
debug(s, "keep local subrepo revision", l)
else:
wctx.sub(s).get(r, overwrite)
sm[s] = r
debug(s, "get remote subrepo revision", r)
elif ld == a: # remote removed, local unchanged
debug(s, "remote removed, remove")
wctx.sub(s).remove()

View File

@ -263,6 +263,8 @@ qpush
adding sub/a
$ hg qpush
applying 1.diff
subrepository sub diverged (local revision: b2fdb12cd82b, remote revision: aa037b301eba)
(M)erge, keep (l)ocal or keep (r)emote? m
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
now at: 1.diff
$ hg status -AS

View File

@ -155,6 +155,8 @@ user a pulls, merges, commits
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg merge 2>/dev/null
subrepository s diverged (local revision: 796959400868, remote revision: aa84837ccfbd)
(M)erge, keep (l)ocal or keep (r)emote? m
pulling subrepo s from $TESTTMP/gitroot
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@ -462,6 +464,8 @@ Sticky subrepositorys, file changes
da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
$ cd ..
$ hg update 4
subrepository s diverged (local revision: da5f5b1d8ffc, remote revision: aa84837ccfbd)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ
use (l)ocal source (da5f5b1) or (r)emote source (aa84837)?
l
@ -487,6 +491,8 @@ Sticky subrepository, revision updates
HEAD is now at aa84837... f
$ cd ..
$ hg update 1
subrepository s diverged (local revision: 32a343883b74, remote revision: da5f5b1d8ffc)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ (in checked out version)
use (l)ocal source (32a3438) or (r)emote source (da5f5b1)?
l
@ -508,6 +514,8 @@ Sticky subrepository, file changes and revision updates
$ hg id -n
1+
$ hg update 7
subrepository s diverged (local revision: 32a343883b74, remote revision: 32a343883b74)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ
use (l)ocal source (32a3438) or (r)emote source (32a3438)?
l

View File

@ -319,6 +319,8 @@ Sticky subrepositorys, file changes
2M
$ cd ..
$ hg update tip
subrepository s diverged (local revision: 2, remote revision: 3)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ
use (l)ocal source (2) or (r)emote source (3)?
l
@ -349,6 +351,8 @@ Sticky subrepository, revision updates
$ svn update -qr 1
$ cd ..
$ hg update 1
subrepository s diverged (local revision: 3, remote revision: 2)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ (in checked out version)
use (l)ocal source (1) or (r)emote source (2)?
l
@ -371,6 +375,8 @@ Sticky subrepository, file changes and revision updates
$ hg id -n
1+
$ hg update tip
subrepository s diverged (local revision: 3, remote revision: 3)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ
use (l)ocal source (1) or (r)emote source (3)?
l
@ -404,6 +410,8 @@ Test subrepo already at intended revision:
$ svn update -qr 2
$ cd ..
$ hg update 1
subrepository s diverged (local revision: 3, remote revision: 2)
(M)erge, keep (l)ocal or keep (r)emote? m
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg id -n
1+

View File

@ -236,7 +236,9 @@ merge tests
.hgsubstate: versions differ -> m
updating: .hgsubstate 1/1 files (100.00%)
subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
subrepo t: both sides changed
subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
(M)erge, keep (l)ocal or keep (r)emote? m
merging subrepo t
searching for copies back to rev 2
resolving manifests
@ -252,6 +254,7 @@ merge tests
merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@ -620,6 +623,8 @@ shouldn't need merging
$ hg up 5
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 4 # try to merge default into br again
subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
(M)erge, keep (l)ocal or keep (r)emote? m
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ cd ..
@ -922,9 +927,13 @@ Sticky subrepositorys, file changes
$ hg -R t id
e95bcfa18a35+
$ hg update tip
subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ
use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
l
subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for t differ
use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
l
@ -953,6 +962,10 @@ Sticky subrepository, revision updates
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd ..
$ hg update 10
subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for t differ (in checked out version)
use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
l
@ -976,9 +989,13 @@ Sticky subrepository, file changes and revision updates
$ hg -R t id
7af322bc1198+
$ hg update tip
subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for s differ
use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
l
subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
(M)erge, keep (l)ocal or keep (r)emote? m
subrepository sources for t differ
use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
l
@ -1006,6 +1023,8 @@ Test subrepo already at intended revision:
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd ..
$ hg update 11
subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
(M)erge, keep (l)ocal or keep (r)emote? m
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg id -n