##// END OF EJS Templates
unshelve: add interactive mode...
Navaneeth Suresh -
r42835:5162753c default
parent child Browse files
Show More
@@ -266,7 +266,7 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
269 if not opts.get('interactive-unshelve'):
270 270 checkunfinished(repo, commit=True)
271 271 wctx = repo[None]
272 272 merge = len(wctx.parents()) > 1
@@ -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] SHELVED]'),
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)
724 if not interactive:
725 ispartialunshelve = False
723 726 newnode = repo.commit(text=shelvectx.description(),
724 727 extra=shelvectx.extra(),
725 728 user=shelvectx.user(),
726 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
752 if not ispartialunshelve:
746 753 if not phases.supportinternal(repo):
747 754 repair.strip(ui, repo, state.nodestoremove, backup=False,
748 755 topic='shelve')
749 _restoreactivebookmark(repo, state.activebookmark)
750 756 shelvedstate.clear(repo)
751 757 unshelvecleanup(ui, repo, state.name, opts)
758 _restoreactivebookmark(repo, state.activebookmark)
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)
864 if not interactive:
865 ispartialunshelve = False
831 866 newnode = repo.commit(text=shelvectx.description(),
832 867 extra=shelvectx.extra(),
833 868 user=shelvectx.user(),
834 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,14 +983,14 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, tr, oldtiprev,
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)
993 if not ispartialunshelve:
952 994 _forgetunknownfiles(repo, shelvectx, addedbefore)
953 995
954 996 shelvedstate.clear(repo)
@@ -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