Show More
@@ -266,8 +266,8 b' def dorecord(ui, repo, commitfunc, cmdsu' | |||
|
266 | 266 | In the end we'll record interesting changes, and everything else |
|
267 | 267 | will be left in place, so the user can continue working. |
|
268 | 268 | """ |
|
269 | ||
|
270 | checkunfinished(repo, commit=True) | |
|
269 | if not opts.get('interactive-unshelve'): | |
|
270 | checkunfinished(repo, commit=True) | |
|
271 | 271 | wctx = repo[None] |
|
272 | 272 | merge = len(wctx.parents()) > 1 |
|
273 | 273 | if merge: |
@@ -6168,6 +6168,8 b' def unbundle(ui, repo, fname1, *fnames, ' | |||
|
6168 | 6168 | _('abort an incomplete unshelve operation')), |
|
6169 | 6169 | ('c', 'continue', None, |
|
6170 | 6170 | _('continue an incomplete unshelve operation')), |
|
6171 | ('i', 'interactive', None, | |
|
6172 | _('use interactive mode')), | |
|
6171 | 6173 | ('k', 'keep', None, |
|
6172 | 6174 | _('keep shelve after unshelving')), |
|
6173 | 6175 | ('n', 'name', '', |
@@ -6175,7 +6177,7 b' def unbundle(ui, repo, fname1, *fnames, ' | |||
|
6175 | 6177 | ('t', 'tool', '', _('specify merge tool')), |
|
6176 | 6178 | ('', 'date', '', |
|
6177 | 6179 | _('set date for temporary commits (DEPRECATED)'), _('DATE'))], |
|
6178 |
_('hg unshelve [[-n |
|
|
6180 | _('hg unshelve [OPTION]... [FILE]... [-n SHELVED]'), | |
|
6179 | 6181 | helpcategory=command.CATEGORY_WORKING_DIRECTORY) |
|
6180 | 6182 | def unshelve(ui, repo, *shelved, **opts): |
|
6181 | 6183 | """restore a shelved change to the working directory |
@@ -694,10 +694,11 b' def unshelvecleanup(ui, repo, name, opts' | |||
|
694 | 694 | if shfile.exists(): |
|
695 | 695 | shfile.movetobackup() |
|
696 | 696 | cleanupoldbackups(repo) |
|
697 | def unshelvecontinue(ui, repo, state, opts): | |
|
697 | def unshelvecontinue(ui, repo, state, opts, basename=None): | |
|
698 | 698 | """subcommand to continue an in-progress unshelve""" |
|
699 | 699 | # We're finishing off a merge. First parent is our original |
|
700 | 700 | # parent, second is the temporary "fake" commit we're unshelving. |
|
701 | interactive = opts.get('interactive') | |
|
701 | 702 | with repo.lock(): |
|
702 | 703 | checkparents(repo, state) |
|
703 | 704 | ms = merge.mergestate.read(repo) |
@@ -720,10 +721,15 b' def unshelvecontinue(ui, repo, state, op' | |||
|
720 | 721 | with repo.ui.configoverride(overrides, 'unshelve'): |
|
721 | 722 | with repo.dirstate.parentchange(): |
|
722 | 723 | repo.setparents(state.parents[0], nodemod.nullid) |
|
723 | newnode = repo.commit(text=shelvectx.description(), | |
|
724 | extra=shelvectx.extra(), | |
|
725 | user=shelvectx.user(), | |
|
726 |
|
|
|
724 | if not interactive: | |
|
725 | ispartialunshelve = False | |
|
726 | newnode = repo.commit(text=shelvectx.description(), | |
|
727 | extra=shelvectx.extra(), | |
|
728 | user=shelvectx.user(), | |
|
729 | date=shelvectx.date()) | |
|
730 | else: | |
|
731 | newnode, ispartialunshelve = _dounshelveinteractive(ui, | |
|
732 | repo, shelvectx, basename, opts) | |
|
727 | 733 | |
|
728 | 734 | if newnode is None: |
|
729 | 735 | # If it ended up being a no-op commit, then the normal |
@@ -743,12 +749,13 b' def unshelvecontinue(ui, repo, state, op' | |||
|
743 | 749 | mergefiles(ui, repo, state.wctx, shelvectx) |
|
744 | 750 | restorebranch(ui, repo, state.branchtorestore) |
|
745 | 751 | |
|
746 |
if not |
|
|
747 | repair.strip(ui, repo, state.nodestoremove, backup=False, | |
|
748 | topic='shelve') | |
|
752 | if not ispartialunshelve: | |
|
753 | if not phases.supportinternal(repo): | |
|
754 | repair.strip(ui, repo, state.nodestoremove, backup=False, | |
|
755 | topic='shelve') | |
|
756 | shelvedstate.clear(repo) | |
|
757 | unshelvecleanup(ui, repo, state.name, opts) | |
|
749 | 758 | _restoreactivebookmark(repo, state.activebookmark) |
|
750 | shelvedstate.clear(repo) | |
|
751 | unshelvecleanup(ui, repo, state.name, opts) | |
|
752 | 759 | ui.status(_("unshelve of '%s' complete\n") % state.name) |
|
753 | 760 | |
|
754 | 761 | def hgcontinueunshelve(ui, repo): |
@@ -797,14 +804,40 b' def _unshelverestorecommit(ui, repo, tr,' | |||
|
797 | 804 | |
|
798 | 805 | return repo, shelvectx |
|
799 | 806 | |
|
807 | def _dounshelveinteractive(ui, repo, shelvectx, basename, opts): | |
|
808 | """The user might want to unshelve certain changes only from the stored | |
|
809 | shelve. So, we would create two commits. One with requested changes to | |
|
810 | unshelve at that time and the latter is shelved for future. | |
|
811 | """ | |
|
812 | opts['message'] = shelvectx.description() | |
|
813 | opts['interactive-unshelve'] = True | |
|
814 | pats = [] | |
|
815 | commitfunc = getcommitfunc(shelvectx.extra(), interactive=True, | |
|
816 | editor=True) | |
|
817 | newnode = cmdutil.dorecord(ui, repo, commitfunc, None, False, | |
|
818 | cmdutil.recordfilter, *pats, | |
|
819 | **pycompat.strkwargs(opts)) | |
|
820 | snode = repo.commit(text=shelvectx.description(), | |
|
821 | extra=shelvectx.extra(), | |
|
822 | user=shelvectx.user(), | |
|
823 | date=shelvectx.date()) | |
|
824 | m = scmutil.matchfiles(repo, repo[snode].files()) | |
|
825 | if snode: | |
|
826 | _shelvecreatedcommit(repo, snode, basename, m) | |
|
827 | ||
|
828 | return newnode, bool(snode) | |
|
829 | ||
|
800 | 830 | def _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev, basename, pctx, |
|
801 | 831 | tmpwctx, shelvectx, branchtorestore, |
|
802 | 832 | activebookmark): |
|
803 | 833 | """Rebase restored commit from its original location to a destination""" |
|
804 | 834 | # If the shelve is not immediately on top of the commit |
|
805 | 835 | # we'll be merging with, rebase it to be on top. |
|
806 | if tmpwctx.node() == shelvectx.p1().node(): | |
|
807 | return shelvectx | |
|
836 | interactive = opts.get('interactive') | |
|
837 | if tmpwctx.node() == shelvectx.p1().node() and not interactive: | |
|
838 | # We won't skip on interactive mode because, the user might want to | |
|
839 | # unshelve certain changes only. | |
|
840 | return shelvectx, False | |
|
808 | 841 | |
|
809 | 842 | overrides = { |
|
810 | 843 | ('ui', 'forcemerge'): opts.get('tool', ''), |
@@ -828,10 +861,15 b' def _rebaserestoredcommit(ui, repo, opts' | |||
|
828 | 861 | |
|
829 | 862 | with repo.dirstate.parentchange(): |
|
830 | 863 | repo.setparents(tmpwctx.node(), nodemod.nullid) |
|
831 | newnode = repo.commit(text=shelvectx.description(), | |
|
832 | extra=shelvectx.extra(), | |
|
833 | user=shelvectx.user(), | |
|
834 |
|
|
|
864 | if not interactive: | |
|
865 | ispartialunshelve = False | |
|
866 | newnode = repo.commit(text=shelvectx.description(), | |
|
867 | extra=shelvectx.extra(), | |
|
868 | user=shelvectx.user(), | |
|
869 | date=shelvectx.date()) | |
|
870 | else: | |
|
871 | newnode, ispartialunshelve = _dounshelveinteractive(ui, repo, | |
|
872 | shelvectx, basename, opts) | |
|
835 | 873 | |
|
836 | 874 | if newnode is None: |
|
837 | 875 | # If it ended up being a no-op commit, then the normal |
@@ -846,7 +884,7 b' def _rebaserestoredcommit(ui, repo, opts' | |||
|
846 | 884 | shelvectx = repo[newnode] |
|
847 | 885 | hg.updaterepo(repo, tmpwctx.node(), False) |
|
848 | 886 | |
|
849 | return shelvectx | |
|
887 | return shelvectx, ispartialunshelve | |
|
850 | 888 | |
|
851 | 889 | def _forgetunknownfiles(repo, shelvectx, addedbefore): |
|
852 | 890 | # Forget any files that were unknown before the shelve, unknown before |
@@ -883,13 +921,14 b' def dounshelve(ui, repo, *shelved, **opt' | |||
|
883 | 921 | opts = pycompat.byteskwargs(opts) |
|
884 | 922 | abortf = opts.get('abort') |
|
885 | 923 | continuef = opts.get('continue') |
|
924 | interactive = opts.get('interactive') | |
|
886 | 925 | if not abortf and not continuef: |
|
887 | 926 | cmdutil.checkunfinished(repo) |
|
888 | 927 | shelved = list(shelved) |
|
889 | 928 | if opts.get("name"): |
|
890 | 929 | shelved.append(opts["name"]) |
|
891 | 930 | |
|
892 | if abortf or continuef: | |
|
931 | if abortf or continuef and not interactive: | |
|
893 | 932 | if abortf and continuef: |
|
894 | 933 | raise error.Abort(_('cannot use both abort and continue')) |
|
895 | 934 | if shelved: |
@@ -911,8 +950,11 b' def dounshelve(ui, repo, *shelved, **opt' | |||
|
911 | 950 | raise error.Abort(_('no shelved changes to apply!')) |
|
912 | 951 | basename = util.split(shelved[0][1])[1] |
|
913 | 952 | ui.status(_("unshelving change '%s'\n") % basename) |
|
914 | else: | |
|
953 | elif shelved: | |
|
915 | 954 | basename = shelved[0] |
|
955 | if continuef and interactive: | |
|
956 | state = _loadshelvedstate(ui, repo, opts) | |
|
957 | return unshelvecontinue(ui, repo, state, opts, basename) | |
|
916 | 958 | |
|
917 | 959 | if not shelvedfile(repo, basename, patchextension).exists(): |
|
918 | 960 | raise error.Abort(_("shelved change '%s' not found") % basename) |
@@ -941,19 +983,19 b' def dounshelve(ui, repo, *shelved, **opt' | |||
|
941 | 983 | if shelvectx.branch() != shelvectx.p1().branch(): |
|
942 | 984 | branchtorestore = shelvectx.branch() |
|
943 | 985 | |
|
944 |
shelvectx = _rebaserestoredcommit(ui, repo, opts, |
|
|
945 | basename, pctx, tmpwctx, | |
|
946 | shelvectx, branchtorestore, | |
|
947 | activebookmark) | |
|
986 | shelvectx, ispartialunshelve = _rebaserestoredcommit(ui, repo, opts, | |
|
987 | tr, oldtiprev, basename, pctx, tmpwctx, shelvectx, | |
|
988 | branchtorestore, activebookmark) | |
|
948 | 989 | overrides = {('ui', 'forcemerge'): opts.get('tool', '')} |
|
949 | 990 | with ui.configoverride(overrides, 'unshelve'): |
|
950 | 991 | mergefiles(ui, repo, pctx, shelvectx) |
|
951 | 992 | restorebranch(ui, repo, branchtorestore) |
|
952 | _forgetunknownfiles(repo, shelvectx, addedbefore) | |
|
993 | if not ispartialunshelve: | |
|
994 | _forgetunknownfiles(repo, shelvectx, addedbefore) | |
|
953 | 995 | |
|
954 | shelvedstate.clear(repo) | |
|
955 | _finishunshelve(repo, oldtiprev, tr, activebookmark) | |
|
956 | unshelvecleanup(ui, repo, basename, opts) | |
|
996 | shelvedstate.clear(repo) | |
|
997 | _finishunshelve(repo, oldtiprev, tr, activebookmark) | |
|
998 | unshelvecleanup(ui, repo, basename, opts) | |
|
957 | 999 | finally: |
|
958 | 1000 | if tr: |
|
959 | 1001 | tr.release() |
@@ -354,7 +354,7 b' Show all commands + options' | |||
|
354 | 354 | tags: template |
|
355 | 355 | tip: patch, git, style, template |
|
356 | 356 | unbundle: update |
|
357 | unshelve: abort, continue, keep, name, tool, date | |
|
357 | unshelve: abort, continue, interactive, keep, name, tool, date | |
|
358 | 358 | update: clean, check, merge, date, rev, tool |
|
359 | 359 | verify: full |
|
360 | 360 | version: template |
@@ -1158,3 +1158,228 b' Abort unshelve while merging (issue5123)' | |||
|
1158 | 1158 | [255] |
|
1159 | 1159 | |
|
1160 | 1160 | $ cd .. |
|
1161 | ||
|
1162 | -- test for interactive mode on unshelve | |
|
1163 | ||
|
1164 | $ hg init a | |
|
1165 | $ cd a | |
|
1166 | $ echo > b | |
|
1167 | $ hg ci -Am b | |
|
1168 | adding b | |
|
1169 | $ echo > c | |
|
1170 | $ echo > d | |
|
1171 | $ hg add . | |
|
1172 | adding c | |
|
1173 | adding d | |
|
1174 | $ hg shelve | |
|
1175 | shelved as default | |
|
1176 | 0 files updated, 0 files merged, 2 files removed, 0 files unresolved | |
|
1177 | $ echo > e | |
|
1178 | $ hg add e | |
|
1179 | $ hg ci -m e | |
|
1180 | $ hg shelve --patch | |
|
1181 | default (1s ago) changes to: b | |
|
1182 | ||
|
1183 | diff --git a/c b/c | |
|
1184 | new file mode 100644 | |
|
1185 | --- /dev/null | |
|
1186 | +++ b/c | |
|
1187 | @@ -0,0 +1,1 @@ | |
|
1188 | + | |
|
1189 | diff --git a/d b/d | |
|
1190 | new file mode 100644 | |
|
1191 | --- /dev/null | |
|
1192 | +++ b/d | |
|
1193 | @@ -0,0 +1,1 @@ | |
|
1194 | + | |
|
1195 | $ hg unshelve -i <<EOF | |
|
1196 | > y | |
|
1197 | > y | |
|
1198 | > y | |
|
1199 | > n | |
|
1200 | > EOF | |
|
1201 | unshelving change 'default' | |
|
1202 | rebasing shelved changes | |
|
1203 | diff --git a/c b/c | |
|
1204 | new file mode 100644 | |
|
1205 | examine changes to 'c'? | |
|
1206 | (enter ? for help) [Ynesfdaq?] y | |
|
1207 | ||
|
1208 | @@ -0,0 +1,1 @@ | |
|
1209 | + | |
|
1210 | record change 1/2 to 'c'? | |
|
1211 | (enter ? for help) [Ynesfdaq?] y | |
|
1212 | ||
|
1213 | diff --git a/d b/d | |
|
1214 | new file mode 100644 | |
|
1215 | examine changes to 'd'? | |
|
1216 | (enter ? for help) [Ynesfdaq?] y | |
|
1217 | ||
|
1218 | @@ -0,0 +1,1 @@ | |
|
1219 | + | |
|
1220 | record change 2/2 to 'd'? | |
|
1221 | (enter ? for help) [Ynesfdaq?] n | |
|
1222 | ||
|
1223 | $ ls | |
|
1224 | b | |
|
1225 | c | |
|
1226 | e | |
|
1227 | -- shelve should not contain `c` now | |
|
1228 | $ hg shelve --patch | |
|
1229 | default (1s ago) changes to: b | |
|
1230 | ||
|
1231 | diff --git a/d b/d | |
|
1232 | new file mode 100644 | |
|
1233 | --- /dev/null | |
|
1234 | +++ b/d | |
|
1235 | @@ -0,0 +1,1 @@ | |
|
1236 | + | |
|
1237 | $ hg unshelve -i <<EOF | |
|
1238 | > y | |
|
1239 | > y | |
|
1240 | > EOF | |
|
1241 | unshelving change 'default' | |
|
1242 | rebasing shelved changes | |
|
1243 | diff --git a/d b/d | |
|
1244 | new file mode 100644 | |
|
1245 | examine changes to 'd'? | |
|
1246 | (enter ? for help) [Ynesfdaq?] y | |
|
1247 | ||
|
1248 | @@ -0,0 +1,1 @@ | |
|
1249 | + | |
|
1250 | record this change to 'd'? | |
|
1251 | (enter ? for help) [Ynesfdaq?] y | |
|
1252 | ||
|
1253 | $ ls | |
|
1254 | b | |
|
1255 | c | |
|
1256 | d | |
|
1257 | e | |
|
1258 | $ hg shelve --list | |
|
1259 | ||
|
1260 | -- now, unshelve selected changes from a file | |
|
1261 | ||
|
1262 | $ echo B > foo | |
|
1263 | $ hg add foo | |
|
1264 | $ hg ci -m 'add B to foo' | |
|
1265 | $ cat > foo <<EOF | |
|
1266 | > A | |
|
1267 | > B | |
|
1268 | > C | |
|
1269 | > EOF | |
|
1270 | $ hg shelve | |
|
1271 | shelved as default | |
|
1272 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
1273 | $ cat foo | |
|
1274 | B | |
|
1275 | $ hg unshelve -i <<EOF | |
|
1276 | > y | |
|
1277 | > y | |
|
1278 | > n | |
|
1279 | > EOF | |
|
1280 | unshelving change 'default' | |
|
1281 | rebasing shelved changes | |
|
1282 | diff --git a/foo b/foo | |
|
1283 | 2 hunks, 2 lines changed | |
|
1284 | examine changes to 'foo'? | |
|
1285 | (enter ? for help) [Ynesfdaq?] y | |
|
1286 | ||
|
1287 | @@ -1,1 +1,2 @@ | |
|
1288 | +A | |
|
1289 | B | |
|
1290 | record change 1/2 to 'foo'? | |
|
1291 | (enter ? for help) [Ynesfdaq?] y | |
|
1292 | ||
|
1293 | @@ -1,1 +2,2 @@ | |
|
1294 | B | |
|
1295 | +C | |
|
1296 | record change 2/2 to 'foo'? | |
|
1297 | (enter ? for help) [Ynesfdaq?] n | |
|
1298 | ||
|
1299 | $ cat foo | |
|
1300 | A | |
|
1301 | B | |
|
1302 | $ hg shelve --patch | |
|
1303 | default (1s ago) changes to: add B to foo | |
|
1304 | ||
|
1305 | diff --git a/foo b/foo | |
|
1306 | --- a/foo | |
|
1307 | +++ b/foo | |
|
1308 | @@ -1,2 +1,3 @@ | |
|
1309 | A | |
|
1310 | B | |
|
1311 | +C | |
|
1312 | ||
|
1313 | -- unshelve interactive on conflicts | |
|
1314 | ||
|
1315 | $ echo A >> bar1 | |
|
1316 | $ echo A >> bar2 | |
|
1317 | $ hg add bar1 bar2 | |
|
1318 | $ hg ci -m 'add A to bars' | |
|
1319 | $ echo B >> bar1 | |
|
1320 | $ echo B >> bar2 | |
|
1321 | $ hg shelve | |
|
1322 | shelved as default-01 | |
|
1323 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
1324 | $ echo C >> bar1 | |
|
1325 | $ echo C >> bar2 | |
|
1326 | $ hg ci -m 'add C to bars' | |
|
1327 | $ hg unshelve -i | |
|
1328 | unshelving change 'default-01' | |
|
1329 | rebasing shelved changes | |
|
1330 | merging bar1 | |
|
1331 | merging bar2 | |
|
1332 | warning: conflicts while merging bar1! (edit, then use 'hg resolve --mark') | |
|
1333 | warning: conflicts while merging bar2! (edit, then use 'hg resolve --mark') | |
|
1334 | unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue') | |
|
1335 | [1] | |
|
1336 | ||
|
1337 | $ cat > bar1 <<EOF | |
|
1338 | > A | |
|
1339 | > B | |
|
1340 | > C | |
|
1341 | > EOF | |
|
1342 | $ cat > bar2 <<EOF | |
|
1343 | > A | |
|
1344 | > B | |
|
1345 | > C | |
|
1346 | > EOF | |
|
1347 | $ hg resolve -m bar1 bar2 | |
|
1348 | (no more unresolved files) | |
|
1349 | continue: hg unshelve --continue | |
|
1350 | $ cat bar1 | |
|
1351 | A | |
|
1352 | B | |
|
1353 | C | |
|
1354 | $ hg unshelve --continue -i <<EOF | |
|
1355 | > y | |
|
1356 | > y | |
|
1357 | > y | |
|
1358 | > y | |
|
1359 | > EOF | |
|
1360 | unshelving change 'default-01' | |
|
1361 | diff --git a/bar1 b/bar1 | |
|
1362 | 1 hunks, 1 lines changed | |
|
1363 | examine changes to 'bar1'? | |
|
1364 | (enter ? for help) [Ynesfdaq?] y | |
|
1365 | ||
|
1366 | @@ -1,2 +1,3 @@ | |
|
1367 | A | |
|
1368 | +B | |
|
1369 | C | |
|
1370 | record change 1/2 to 'bar1'? | |
|
1371 | (enter ? for help) [Ynesfdaq?] y | |
|
1372 | ||
|
1373 | diff --git a/bar2 b/bar2 | |
|
1374 | 1 hunks, 1 lines changed | |
|
1375 | examine changes to 'bar2'? | |
|
1376 | (enter ? for help) [Ynesfdaq?] y | |
|
1377 | ||
|
1378 | @@ -1,2 +1,3 @@ | |
|
1379 | A | |
|
1380 | +B | |
|
1381 | C | |
|
1382 | record change 2/2 to 'bar2'? | |
|
1383 | (enter ? for help) [Ynesfdaq?] y | |
|
1384 | ||
|
1385 | unshelve of 'default-01' complete |
General Comments 0
You need to be logged in to leave comments.
Login now