##// END OF EJS Templates
shelve: make --keep option survive user intervention (issue5431)...
Kostia Balytskyi -
r30522:7b3136bc default
parent child Browse files
Show More
@@ -1,966 +1,973
1 1 # shelve.py - save/restore working directory state
2 2 #
3 3 # Copyright 2013 Facebook, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """save and restore changes to the working directory
9 9
10 10 The "hg shelve" command saves changes made to the working directory
11 11 and reverts those changes, resetting the working directory to a clean
12 12 state.
13 13
14 14 Later on, the "hg unshelve" command restores the changes saved by "hg
15 15 shelve". Changes can be restored even after updating to a different
16 16 parent, in which case Mercurial's merge machinery will resolve any
17 17 conflicts if necessary.
18 18
19 19 You can have more than one shelved change outstanding at a time; each
20 20 shelved change has a distinct name. For details, see the help for "hg
21 21 shelve".
22 22 """
23 23 from __future__ import absolute_import
24 24
25 25 import collections
26 26 import errno
27 27 import itertools
28 28
29 29 from mercurial.i18n import _
30 30 from mercurial import (
31 31 bundle2,
32 32 bundlerepo,
33 33 changegroup,
34 34 cmdutil,
35 35 commands,
36 36 error,
37 37 exchange,
38 38 hg,
39 39 lock as lockmod,
40 40 mdiff,
41 41 merge,
42 42 node as nodemod,
43 43 patch,
44 44 phases,
45 45 repair,
46 46 scmutil,
47 47 templatefilters,
48 48 util,
49 49 )
50 50
51 51 from . import (
52 52 rebase,
53 53 )
54 54
55 55 cmdtable = {}
56 56 command = cmdutil.command(cmdtable)
57 57 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
58 58 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
59 59 # be specifying the version(s) of Mercurial they are tested with, or
60 60 # leave the attribute unspecified.
61 61 testedwith = 'ships-with-hg-core'
62 62
63 63 backupdir = 'shelve-backup'
64 64 shelvedir = 'shelved'
65 65 shelvefileextensions = ['hg', 'patch']
66 66
67 67 # we never need the user, so we use a
68 68 # generic user for all shelve operations
69 69 shelveuser = 'shelve@localhost'
70 70
71 71 class shelvedfile(object):
72 72 """Helper for the file storing a single shelve
73 73
74 74 Handles common functions on shelve files (.hg/.patch) using
75 75 the vfs layer"""
76 76 def __init__(self, repo, name, filetype=None):
77 77 self.repo = repo
78 78 self.name = name
79 79 self.vfs = scmutil.vfs(repo.join(shelvedir))
80 80 self.backupvfs = scmutil.vfs(repo.join(backupdir))
81 81 self.ui = self.repo.ui
82 82 if filetype:
83 83 self.fname = name + '.' + filetype
84 84 else:
85 85 self.fname = name
86 86
87 87 def exists(self):
88 88 return self.vfs.exists(self.fname)
89 89
90 90 def filename(self):
91 91 return self.vfs.join(self.fname)
92 92
93 93 def backupfilename(self):
94 94 def gennames(base):
95 95 yield base
96 96 base, ext = base.rsplit('.', 1)
97 97 for i in itertools.count(1):
98 98 yield '%s-%d.%s' % (base, i, ext)
99 99
100 100 name = self.backupvfs.join(self.fname)
101 101 for n in gennames(name):
102 102 if not self.backupvfs.exists(n):
103 103 return n
104 104
105 105 def movetobackup(self):
106 106 if not self.backupvfs.isdir():
107 107 self.backupvfs.makedir()
108 108 util.rename(self.filename(), self.backupfilename())
109 109
110 110 def stat(self):
111 111 return self.vfs.stat(self.fname)
112 112
113 113 def opener(self, mode='rb'):
114 114 try:
115 115 return self.vfs(self.fname, mode)
116 116 except IOError as err:
117 117 if err.errno != errno.ENOENT:
118 118 raise
119 119 raise error.Abort(_("shelved change '%s' not found") % self.name)
120 120
121 121 def applybundle(self):
122 122 fp = self.opener()
123 123 try:
124 124 gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs)
125 125 if not isinstance(gen, bundle2.unbundle20):
126 126 gen.apply(self.repo, 'unshelve',
127 127 'bundle:' + self.vfs.join(self.fname),
128 128 targetphase=phases.secret)
129 129 if isinstance(gen, bundle2.unbundle20):
130 130 bundle2.applybundle(self.repo, gen,
131 131 self.repo.currenttransaction(),
132 132 source='unshelve',
133 133 url='bundle:' + self.vfs.join(self.fname))
134 134 finally:
135 135 fp.close()
136 136
137 137 def bundlerepo(self):
138 138 return bundlerepo.bundlerepository(self.repo.baseui, self.repo.root,
139 139 self.vfs.join(self.fname))
140 140 def writebundle(self, bases, node):
141 141 cgversion = changegroup.safeversion(self.repo)
142 142 if cgversion == '01':
143 143 btype = 'HG10BZ'
144 144 compression = None
145 145 else:
146 146 btype = 'HG20'
147 147 compression = 'BZ'
148 148
149 149 cg = changegroup.changegroupsubset(self.repo, bases, [node], 'shelve',
150 150 version=cgversion)
151 151 bundle2.writebundle(self.ui, cg, self.fname, btype, self.vfs,
152 152 compression=compression)
153 153
154 154 class shelvedstate(object):
155 155 """Handle persistence during unshelving operations.
156 156
157 157 Handles saving and restoring a shelved state. Ensures that different
158 158 versions of a shelved state are possible and handles them appropriately.
159 159 """
160 160 _version = 1
161 161 _filename = 'shelvedstate'
162 _keep = 'keep'
163 _nokeep = 'nokeep'
162 164
163 165 @classmethod
164 166 def load(cls, repo):
165 167 fp = repo.vfs(cls._filename)
166 168 try:
167 169 version = int(fp.readline().strip())
168 170
169 171 if version != cls._version:
170 172 raise error.Abort(_('this version of shelve is incompatible '
171 173 'with the version used in this repo'))
172 174 name = fp.readline().strip()
173 175 wctx = nodemod.bin(fp.readline().strip())
174 176 pendingctx = nodemod.bin(fp.readline().strip())
175 177 parents = [nodemod.bin(h) for h in fp.readline().split()]
176 178 stripnodes = [nodemod.bin(h) for h in fp.readline().split()]
177 179 branchtorestore = fp.readline().strip()
180 keep = fp.readline().strip() == cls._keep
178 181 except (ValueError, TypeError) as err:
179 182 raise error.CorruptedState(str(err))
180 183 finally:
181 184 fp.close()
182 185
183 186 try:
184 187 obj = cls()
185 188 obj.name = name
186 189 obj.wctx = repo[wctx]
187 190 obj.pendingctx = repo[pendingctx]
188 191 obj.parents = parents
189 192 obj.stripnodes = stripnodes
190 193 obj.branchtorestore = branchtorestore
194 obj.keep = keep
191 195 except error.RepoLookupError as err:
192 196 raise error.CorruptedState(str(err))
193 197
194 198 return obj
195 199
196 200 @classmethod
197 201 def save(cls, repo, name, originalwctx, pendingctx, stripnodes,
198 branchtorestore):
202 branchtorestore, keep=False):
199 203 fp = repo.vfs(cls._filename, 'wb')
200 204 fp.write('%i\n' % cls._version)
201 205 fp.write('%s\n' % name)
202 206 fp.write('%s\n' % nodemod.hex(originalwctx.node()))
203 207 fp.write('%s\n' % nodemod.hex(pendingctx.node()))
204 208 fp.write('%s\n' %
205 209 ' '.join([nodemod.hex(p) for p in repo.dirstate.parents()]))
206 210 fp.write('%s\n' %
207 211 ' '.join([nodemod.hex(n) for n in stripnodes]))
208 212 fp.write('%s\n' % branchtorestore)
213 fp.write('%s\n' % (cls._keep if keep else cls._nokeep))
209 214 fp.close()
210 215
211 216 @classmethod
212 217 def clear(cls, repo):
213 218 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
214 219
215 220 def cleanupoldbackups(repo):
216 221 vfs = scmutil.vfs(repo.join(backupdir))
217 222 maxbackups = repo.ui.configint('shelve', 'maxbackups', 10)
218 223 hgfiles = [f for f in vfs.listdir() if f.endswith('.hg')]
219 224 hgfiles = sorted([(vfs.stat(f).st_mtime, f) for f in hgfiles])
220 225 if 0 < maxbackups and maxbackups < len(hgfiles):
221 226 bordermtime = hgfiles[-maxbackups][0]
222 227 else:
223 228 bordermtime = None
224 229 for mtime, f in hgfiles[:len(hgfiles) - maxbackups]:
225 230 if mtime == bordermtime:
226 231 # keep it, because timestamp can't decide exact order of backups
227 232 continue
228 233 base = f[:-3]
229 234 for ext in shelvefileextensions:
230 235 try:
231 236 vfs.unlink(base + '.' + ext)
232 237 except OSError as err:
233 238 if err.errno != errno.ENOENT:
234 239 raise
235 240
236 241 def _aborttransaction(repo):
237 242 '''Abort current transaction for shelve/unshelve, but keep dirstate
238 243 '''
239 244 tr = repo.currenttransaction()
240 245 repo.dirstate.savebackup(tr, suffix='.shelve')
241 246 tr.abort()
242 247 repo.dirstate.restorebackup(None, suffix='.shelve')
243 248
244 249 def createcmd(ui, repo, pats, opts):
245 250 """subcommand that creates a new shelve"""
246 251 with repo.wlock():
247 252 cmdutil.checkunfinished(repo)
248 253 return _docreatecmd(ui, repo, pats, opts)
249 254
250 255 def getshelvename(repo, parent, opts):
251 256 """Decide on the name this shelve is going to have"""
252 257 def gennames():
253 258 yield label
254 259 for i in xrange(1, 100):
255 260 yield '%s-%02d' % (label, i)
256 261 name = opts.get('name')
257 262 label = repo._activebookmark or parent.branch() or 'default'
258 263 # slashes aren't allowed in filenames, therefore we rename it
259 264 label = label.replace('/', '_')
260 265
261 266 if name:
262 267 if shelvedfile(repo, name, 'hg').exists():
263 268 e = _("a shelved change named '%s' already exists") % name
264 269 raise error.Abort(e)
265 270 else:
266 271 for n in gennames():
267 272 if not shelvedfile(repo, n, 'hg').exists():
268 273 name = n
269 274 break
270 275 else:
271 276 raise error.Abort(_("too many shelved changes named '%s'") % label)
272 277
273 278 # ensure we are not creating a subdirectory or a hidden file
274 279 if '/' in name or '\\' in name:
275 280 raise error.Abort(_('shelved change names may not contain slashes'))
276 281 if name.startswith('.'):
277 282 raise error.Abort(_("shelved change names may not start with '.'"))
278 283 return name
279 284
280 285 def mutableancestors(ctx):
281 286 """return all mutable ancestors for ctx (included)
282 287
283 288 Much faster than the revset ancestors(ctx) & draft()"""
284 289 seen = set([nodemod.nullrev])
285 290 visit = collections.deque()
286 291 visit.append(ctx)
287 292 while visit:
288 293 ctx = visit.popleft()
289 294 yield ctx.node()
290 295 for parent in ctx.parents():
291 296 rev = parent.rev()
292 297 if rev not in seen:
293 298 seen.add(rev)
294 299 if parent.mutable():
295 300 visit.append(parent)
296 301
297 302 def getcommitfunc(extra, interactive, editor=False):
298 303 def commitfunc(ui, repo, message, match, opts):
299 304 hasmq = util.safehasattr(repo, 'mq')
300 305 if hasmq:
301 306 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
302 307 backup = repo.ui.backupconfig('phases', 'new-commit')
303 308 try:
304 309 repo.ui.setconfig('phases', 'new-commit', phases.secret)
305 310 editor_ = False
306 311 if editor:
307 312 editor_ = cmdutil.getcommiteditor(editform='shelve.shelve',
308 313 **opts)
309 314 return repo.commit(message, shelveuser, opts.get('date'), match,
310 315 editor=editor_, extra=extra)
311 316 finally:
312 317 repo.ui.restoreconfig(backup)
313 318 if hasmq:
314 319 repo.mq.checkapplied = saved
315 320
316 321 def interactivecommitfunc(ui, repo, *pats, **opts):
317 322 match = scmutil.match(repo['.'], pats, {})
318 323 message = opts['message']
319 324 return commitfunc(ui, repo, message, match, opts)
320 325
321 326 return interactivecommitfunc if interactive else commitfunc
322 327
323 328 def _nothingtoshelvemessaging(ui, repo, pats, opts):
324 329 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
325 330 if stat.deleted:
326 331 ui.status(_("nothing changed (%d missing files, see "
327 332 "'hg status')\n") % len(stat.deleted))
328 333 else:
329 334 ui.status(_("nothing changed\n"))
330 335
331 336 def _shelvecreatedcommit(repo, node, name):
332 337 bases = list(mutableancestors(repo[node]))
333 338 shelvedfile(repo, name, 'hg').writebundle(bases, node)
334 339 cmdutil.export(repo, [node],
335 340 fp=shelvedfile(repo, name, 'patch').opener('wb'),
336 341 opts=mdiff.diffopts(git=True))
337 342
338 343 def _includeunknownfiles(repo, pats, opts, extra):
339 344 s = repo.status(match=scmutil.match(repo[None], pats, opts),
340 345 unknown=True)
341 346 if s.unknown:
342 347 extra['shelve_unknown'] = '\0'.join(s.unknown)
343 348 repo[None].add(s.unknown)
344 349
345 350 def _finishshelve(repo):
346 351 _aborttransaction(repo)
347 352
348 353 def _docreatecmd(ui, repo, pats, opts):
349 354 wctx = repo[None]
350 355 parents = wctx.parents()
351 356 if len(parents) > 1:
352 357 raise error.Abort(_('cannot shelve while merging'))
353 358 parent = parents[0]
354 359 origbranch = wctx.branch()
355 360
356 361 if parent.node() != nodemod.nullid:
357 362 desc = "changes to: %s" % parent.description().split('\n', 1)[0]
358 363 else:
359 364 desc = '(changes in empty repository)'
360 365
361 366 if not opts.get('message'):
362 367 opts['message'] = desc
363 368
364 369 lock = tr = None
365 370 try:
366 371 lock = repo.lock()
367 372
368 373 # use an uncommitted transaction to generate the bundle to avoid
369 374 # pull races. ensure we don't print the abort message to stderr.
370 375 tr = repo.transaction('commit', report=lambda x: None)
371 376
372 377 interactive = opts.get('interactive', False)
373 378 includeunknown = (opts.get('unknown', False) and
374 379 not opts.get('addremove', False))
375 380
376 381 name = getshelvename(repo, parent, opts)
377 382 extra = {}
378 383 if includeunknown:
379 384 _includeunknownfiles(repo, pats, opts, extra)
380 385
381 386 if _iswctxonnewbranch(repo) and not _isbareshelve(pats, opts):
382 387 # In non-bare shelve we don't store newly created branch
383 388 # at bundled commit
384 389 repo.dirstate.setbranch(repo['.'].branch())
385 390
386 391 commitfunc = getcommitfunc(extra, interactive, editor=True)
387 392 if not interactive:
388 393 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
389 394 else:
390 395 node = cmdutil.dorecord(ui, repo, commitfunc, None,
391 396 False, cmdutil.recordfilter, *pats, **opts)
392 397 if not node:
393 398 _nothingtoshelvemessaging(ui, repo, pats, opts)
394 399 return 1
395 400
396 401 _shelvecreatedcommit(repo, node, name)
397 402
398 403 if ui.formatted():
399 404 desc = util.ellipsis(desc, ui.termwidth())
400 405 ui.status(_('shelved as %s\n') % name)
401 406 hg.update(repo, parent.node())
402 407 if origbranch != repo['.'].branch() and not _isbareshelve(pats, opts):
403 408 repo.dirstate.setbranch(origbranch)
404 409
405 410 _finishshelve(repo)
406 411 finally:
407 412 lockmod.release(tr, lock)
408 413
409 414 def _isbareshelve(pats, opts):
410 415 return (not pats
411 416 and not opts.get('interactive', False)
412 417 and not opts.get('include', False)
413 418 and not opts.get('exclude', False))
414 419
415 420 def _iswctxonnewbranch(repo):
416 421 return repo[None].branch() != repo['.'].branch()
417 422
418 423 def cleanupcmd(ui, repo):
419 424 """subcommand that deletes all shelves"""
420 425
421 426 with repo.wlock():
422 427 for (name, _type) in repo.vfs.readdir(shelvedir):
423 428 suffix = name.rsplit('.', 1)[-1]
424 429 if suffix in shelvefileextensions:
425 430 shelvedfile(repo, name).movetobackup()
426 431 cleanupoldbackups(repo)
427 432
428 433 def deletecmd(ui, repo, pats):
429 434 """subcommand that deletes a specific shelve"""
430 435 if not pats:
431 436 raise error.Abort(_('no shelved changes specified!'))
432 437 with repo.wlock():
433 438 try:
434 439 for name in pats:
435 440 for suffix in shelvefileextensions:
436 441 shfile = shelvedfile(repo, name, suffix)
437 442 # patch file is necessary, as it should
438 443 # be present for any kind of shelve,
439 444 # but the .hg file is optional as in future we
440 445 # will add obsolete shelve with does not create a
441 446 # bundle
442 447 if shfile.exists() or suffix == 'patch':
443 448 shfile.movetobackup()
444 449 cleanupoldbackups(repo)
445 450 except OSError as err:
446 451 if err.errno != errno.ENOENT:
447 452 raise
448 453 raise error.Abort(_("shelved change '%s' not found") % name)
449 454
450 455 def listshelves(repo):
451 456 """return all shelves in repo as list of (time, filename)"""
452 457 try:
453 458 names = repo.vfs.readdir(shelvedir)
454 459 except OSError as err:
455 460 if err.errno != errno.ENOENT:
456 461 raise
457 462 return []
458 463 info = []
459 464 for (name, _type) in names:
460 465 pfx, sfx = name.rsplit('.', 1)
461 466 if not pfx or sfx != 'patch':
462 467 continue
463 468 st = shelvedfile(repo, name).stat()
464 469 info.append((st.st_mtime, shelvedfile(repo, pfx).filename()))
465 470 return sorted(info, reverse=True)
466 471
467 472 def listcmd(ui, repo, pats, opts):
468 473 """subcommand that displays the list of shelves"""
469 474 pats = set(pats)
470 475 width = 80
471 476 if not ui.plain():
472 477 width = ui.termwidth()
473 478 namelabel = 'shelve.newest'
474 479 for mtime, name in listshelves(repo):
475 480 sname = util.split(name)[1]
476 481 if pats and sname not in pats:
477 482 continue
478 483 ui.write(sname, label=namelabel)
479 484 namelabel = 'shelve.name'
480 485 if ui.quiet:
481 486 ui.write('\n')
482 487 continue
483 488 ui.write(' ' * (16 - len(sname)))
484 489 used = 16
485 490 age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True)
486 491 ui.write(age, label='shelve.age')
487 492 ui.write(' ' * (12 - len(age)))
488 493 used += 12
489 494 with open(name + '.patch', 'rb') as fp:
490 495 while True:
491 496 line = fp.readline()
492 497 if not line:
493 498 break
494 499 if not line.startswith('#'):
495 500 desc = line.rstrip()
496 501 if ui.formatted():
497 502 desc = util.ellipsis(desc, width - used)
498 503 ui.write(desc)
499 504 break
500 505 ui.write('\n')
501 506 if not (opts['patch'] or opts['stat']):
502 507 continue
503 508 difflines = fp.readlines()
504 509 if opts['patch']:
505 510 for chunk, label in patch.difflabel(iter, difflines):
506 511 ui.write(chunk, label=label)
507 512 if opts['stat']:
508 513 for chunk, label in patch.diffstatui(difflines, width=width):
509 514 ui.write(chunk, label=label)
510 515
511 516 def singlepatchcmds(ui, repo, pats, opts, subcommand):
512 517 """subcommand that displays a single shelf"""
513 518 if len(pats) != 1:
514 519 raise error.Abort(_("--%s expects a single shelf") % subcommand)
515 520 shelfname = pats[0]
516 521
517 522 if not shelvedfile(repo, shelfname, 'patch').exists():
518 523 raise error.Abort(_("cannot find shelf %s") % shelfname)
519 524
520 525 listcmd(ui, repo, pats, opts)
521 526
522 527 def checkparents(repo, state):
523 528 """check parent while resuming an unshelve"""
524 529 if state.parents != repo.dirstate.parents():
525 530 raise error.Abort(_('working directory parents do not match unshelve '
526 531 'state'))
527 532
528 533 def pathtofiles(repo, files):
529 534 cwd = repo.getcwd()
530 535 return [repo.pathto(f, cwd) for f in files]
531 536
532 537 def unshelveabort(ui, repo, state, opts):
533 538 """subcommand that abort an in-progress unshelve"""
534 539 with repo.lock():
535 540 try:
536 541 checkparents(repo, state)
537 542
538 543 util.rename(repo.join('unshelverebasestate'),
539 544 repo.join('rebasestate'))
540 545 try:
541 546 rebase.rebase(ui, repo, **{
542 547 'abort' : True
543 548 })
544 549 except Exception:
545 550 util.rename(repo.join('rebasestate'),
546 551 repo.join('unshelverebasestate'))
547 552 raise
548 553
549 554 mergefiles(ui, repo, state.wctx, state.pendingctx)
550 555 repair.strip(ui, repo, state.stripnodes, backup=False,
551 556 topic='shelve')
552 557 finally:
553 558 shelvedstate.clear(repo)
554 559 ui.warn(_("unshelve of '%s' aborted\n") % state.name)
555 560
556 561 def mergefiles(ui, repo, wctx, shelvectx):
557 562 """updates to wctx and merges the changes from shelvectx into the
558 563 dirstate."""
559 564 oldquiet = ui.quiet
560 565 try:
561 566 ui.quiet = True
562 567 hg.update(repo, wctx.node())
563 568 files = []
564 569 files.extend(shelvectx.files())
565 570 files.extend(shelvectx.parents()[0].files())
566 571
567 572 # revert will overwrite unknown files, so move them out of the way
568 573 for file in repo.status(unknown=True).unknown:
569 574 if file in files:
570 575 util.rename(file, scmutil.origpath(ui, repo, file))
571 576 ui.pushbuffer(True)
572 577 cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
573 578 *pathtofiles(repo, files),
574 579 **{'no_backup': True})
575 580 ui.popbuffer()
576 581 finally:
577 582 ui.quiet = oldquiet
578 583
579 584 def restorebranch(ui, repo, branchtorestore):
580 585 if branchtorestore and branchtorestore != repo.dirstate.branch():
581 586 repo.dirstate.setbranch(branchtorestore)
582 587 ui.status(_('marked working directory as branch %s\n')
583 588 % branchtorestore)
584 589
585 590 def unshelvecleanup(ui, repo, name, opts):
586 591 """remove related files after an unshelve"""
587 592 if not opts.get('keep'):
588 593 for filetype in shelvefileextensions:
589 594 shfile = shelvedfile(repo, name, filetype)
590 595 if shfile.exists():
591 596 shfile.movetobackup()
592 597 cleanupoldbackups(repo)
593 598
594 599 def unshelvecontinue(ui, repo, state, opts):
595 600 """subcommand to continue an in-progress unshelve"""
596 601 # We're finishing off a merge. First parent is our original
597 602 # parent, second is the temporary "fake" commit we're unshelving.
598 603 with repo.lock():
599 604 checkparents(repo, state)
600 605 ms = merge.mergestate.read(repo)
601 606 if [f for f in ms if ms[f] == 'u']:
602 607 raise error.Abort(
603 608 _("unresolved conflicts, can't continue"),
604 609 hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
605 610
606 611 util.rename(repo.join('unshelverebasestate'),
607 612 repo.join('rebasestate'))
608 613 try:
609 614 rebase.rebase(ui, repo, **{
610 615 'continue' : True
611 616 })
612 617 except Exception:
613 618 util.rename(repo.join('rebasestate'),
614 619 repo.join('unshelverebasestate'))
615 620 raise
616 621
617 622 shelvectx = repo['tip']
618 623 if not shelvectx in state.pendingctx.children():
619 624 # rebase was a no-op, so it produced no child commit
620 625 shelvectx = state.pendingctx
621 626 else:
622 627 # only strip the shelvectx if the rebase produced it
623 628 state.stripnodes.append(shelvectx.node())
624 629
625 630 mergefiles(ui, repo, state.wctx, shelvectx)
626 631 restorebranch(ui, repo, state.branchtorestore)
627 632
628 633 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
629 634 shelvedstate.clear(repo)
630 635 unshelvecleanup(ui, repo, state.name, opts)
631 636 ui.status(_("unshelve of '%s' complete\n") % state.name)
632 637
633 638 def _commitworkingcopychanges(ui, repo, opts, tmpwctx):
634 639 """Temporarily commit working copy changes before moving unshelve commit"""
635 640 # Store pending changes in a commit and remember added in case a shelve
636 641 # contains unknown files that are part of the pending change
637 642 s = repo.status()
638 643 addedbefore = frozenset(s.added)
639 644 if not (s.modified or s.added or s.removed or s.deleted):
640 645 return tmpwctx, addedbefore
641 646 ui.status(_("temporarily committing pending changes "
642 647 "(restore with 'hg unshelve --abort')\n"))
643 648 commitfunc = getcommitfunc(extra=None, interactive=False,
644 649 editor=False)
645 650 tempopts = {}
646 651 tempopts['message'] = "pending changes temporary commit"
647 652 tempopts['date'] = opts.get('date')
648 653 ui.quiet = True
649 654 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
650 655 tmpwctx = repo[node]
651 656 return tmpwctx, addedbefore
652 657
653 658 def _unshelverestorecommit(ui, repo, basename, oldquiet):
654 659 """Recreate commit in the repository during the unshelve"""
655 660 ui.quiet = True
656 661 shelvedfile(repo, basename, 'hg').applybundle()
657 662 shelvectx = repo['tip']
658 663 ui.quiet = oldquiet
659 664 return repo, shelvectx
660 665
661 666 def _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev, basename, pctx,
662 667 tmpwctx, shelvectx, branchtorestore):
663 668 """Rebase restored commit from its original location to a destination"""
664 669 # If the shelve is not immediately on top of the commit
665 670 # we'll be merging with, rebase it to be on top.
666 671 if tmpwctx.node() == shelvectx.parents()[0].node():
667 672 return shelvectx
668 673
669 674 ui.status(_('rebasing shelved changes\n'))
670 675 try:
671 676 rebase.rebase(ui, repo, **{
672 677 'rev': [shelvectx.rev()],
673 678 'dest': str(tmpwctx.rev()),
674 679 'keep': True,
675 680 'tool': opts.get('tool', ''),
676 681 })
677 682 except error.InterventionRequired:
678 683 tr.close()
679 684
680 685 stripnodes = [repo.changelog.node(rev)
681 686 for rev in xrange(oldtiprev, len(repo))]
682 687 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes,
683 branchtorestore)
688 branchtorestore, opts.get('keep'))
684 689
685 690 util.rename(repo.join('rebasestate'),
686 691 repo.join('unshelverebasestate'))
687 692 raise error.InterventionRequired(
688 693 _("unresolved conflicts (see 'hg resolve', then "
689 694 "'hg unshelve --continue')"))
690 695
691 696 # refresh ctx after rebase completes
692 697 shelvectx = repo['tip']
693 698
694 699 if not shelvectx in tmpwctx.children():
695 700 # rebase was a no-op, so it produced no child commit
696 701 shelvectx = tmpwctx
697 702 return shelvectx
698 703
699 704 def _forgetunknownfiles(repo, shelvectx, addedbefore):
700 705 # Forget any files that were unknown before the shelve, unknown before
701 706 # unshelve started, but are now added.
702 707 shelveunknown = shelvectx.extra().get('shelve_unknown')
703 708 if not shelveunknown:
704 709 return
705 710 shelveunknown = frozenset(shelveunknown.split('\0'))
706 711 addedafter = frozenset(repo.status().added)
707 712 toforget = (addedafter & shelveunknown) - addedbefore
708 713 repo[None].forget(toforget)
709 714
710 715 def _finishunshelve(repo, oldtiprev, tr):
711 716 # The transaction aborting will strip all the commits for us,
712 717 # but it doesn't update the inmemory structures, so addchangegroup
713 718 # hooks still fire and try to operate on the missing commits.
714 719 # Clean up manually to prevent this.
715 720 repo.unfiltered().changelog.strip(oldtiprev, tr)
716 721 _aborttransaction(repo)
717 722
718 723 @command('unshelve',
719 724 [('a', 'abort', None,
720 725 _('abort an incomplete unshelve operation')),
721 726 ('c', 'continue', None,
722 727 _('continue an incomplete unshelve operation')),
723 728 ('k', 'keep', None,
724 729 _('keep shelve after unshelving')),
725 730 ('t', 'tool', '', _('specify merge tool')),
726 731 ('', 'date', '',
727 732 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
728 733 _('hg unshelve [SHELVED]'))
729 734 def unshelve(ui, repo, *shelved, **opts):
730 735 """restore a shelved change to the working directory
731 736
732 737 This command accepts an optional name of a shelved change to
733 738 restore. If none is given, the most recent shelved change is used.
734 739
735 740 If a shelved change is applied successfully, the bundle that
736 741 contains the shelved changes is moved to a backup location
737 742 (.hg/shelve-backup).
738 743
739 744 Since you can restore a shelved change on top of an arbitrary
740 745 commit, it is possible that unshelving will result in a conflict
741 746 between your changes and the commits you are unshelving onto. If
742 747 this occurs, you must resolve the conflict, then use
743 748 ``--continue`` to complete the unshelve operation. (The bundle
744 749 will not be moved until you successfully complete the unshelve.)
745 750
746 751 (Alternatively, you can use ``--abort`` to abandon an unshelve
747 752 that causes a conflict. This reverts the unshelved changes, and
748 753 leaves the bundle in place.)
749 754
750 755 If bare shelved change(when no files are specified, without interactive,
751 756 include and exclude option) was done on newly created branch it would
752 757 restore branch information to the working directory.
753 758
754 759 After a successful unshelve, the shelved changes are stored in a
755 760 backup directory. Only the N most recent backups are kept. N
756 761 defaults to 10 but can be overridden using the ``shelve.maxbackups``
757 762 configuration option.
758 763
759 764 .. container:: verbose
760 765
761 766 Timestamp in seconds is used to decide order of backups. More
762 767 than ``maxbackups`` backups are kept, if same timestamp
763 768 prevents from deciding exact order of them, for safety.
764 769 """
765 770 with repo.wlock():
766 771 return _dounshelve(ui, repo, *shelved, **opts)
767 772
768 773 def _dounshelve(ui, repo, *shelved, **opts):
769 774 abortf = opts.get('abort')
770 775 continuef = opts.get('continue')
771 776 if not abortf and not continuef:
772 777 cmdutil.checkunfinished(repo)
773 778
774 779 if abortf or continuef:
775 780 if abortf and continuef:
776 781 raise error.Abort(_('cannot use both abort and continue'))
777 782 if shelved:
778 783 raise error.Abort(_('cannot combine abort/continue with '
779 784 'naming a shelved change'))
780 785 if abortf and opts.get('tool', False):
781 786 ui.warn(_('tool option will be ignored\n'))
782 787
783 788 try:
784 789 state = shelvedstate.load(repo)
790 if opts.get('keep') is None:
791 opts['keep'] = state.keep
785 792 except IOError as err:
786 793 if err.errno != errno.ENOENT:
787 794 raise
788 795 cmdutil.wrongtooltocontinue(repo, _('unshelve'))
789 796 except error.CorruptedState as err:
790 797 ui.debug(str(err) + '\n')
791 798 if continuef:
792 799 msg = _('corrupted shelved state file')
793 800 hint = _('please run hg unshelve --abort to abort unshelve '
794 801 'operation')
795 802 raise error.Abort(msg, hint=hint)
796 803 elif abortf:
797 804 msg = _('could not read shelved state file, your working copy '
798 805 'may be in an unexpected state\nplease update to some '
799 806 'commit\n')
800 807 ui.warn(msg)
801 808 shelvedstate.clear(repo)
802 809 return
803 810
804 811 if abortf:
805 812 return unshelveabort(ui, repo, state, opts)
806 813 elif continuef:
807 814 return unshelvecontinue(ui, repo, state, opts)
808 815 elif len(shelved) > 1:
809 816 raise error.Abort(_('can only unshelve one change at a time'))
810 817 elif not shelved:
811 818 shelved = listshelves(repo)
812 819 if not shelved:
813 820 raise error.Abort(_('no shelved changes to apply!'))
814 821 basename = util.split(shelved[0][1])[1]
815 822 ui.status(_("unshelving change '%s'\n") % basename)
816 823 else:
817 824 basename = shelved[0]
818 825
819 826 if not shelvedfile(repo, basename, 'patch').exists():
820 827 raise error.Abort(_("shelved change '%s' not found") % basename)
821 828
822 829 oldquiet = ui.quiet
823 830 lock = tr = None
824 831 forcemerge = ui.backupconfig('ui', 'forcemerge')
825 832 try:
826 833 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'unshelve')
827 834 lock = repo.lock()
828 835
829 836 tr = repo.transaction('unshelve', report=lambda x: None)
830 837 oldtiprev = len(repo)
831 838
832 839 pctx = repo['.']
833 840 tmpwctx = pctx
834 841 # The goal is to have a commit structure like so:
835 842 # ...-> pctx -> tmpwctx -> shelvectx
836 843 # where tmpwctx is an optional commit with the user's pending changes
837 844 # and shelvectx is the unshelved changes. Then we merge it all down
838 845 # to the original pctx.
839 846
840 847 tmpwctx, addedbefore = _commitworkingcopychanges(ui, repo, opts,
841 848 tmpwctx)
842 849
843 850 repo, shelvectx = _unshelverestorecommit(ui, repo, basename, oldquiet)
844 851
845 852 branchtorestore = ''
846 853 if shelvectx.branch() != shelvectx.p1().branch():
847 854 branchtorestore = shelvectx.branch()
848 855
849 856 shelvectx = _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev,
850 857 basename, pctx, tmpwctx, shelvectx,
851 858 branchtorestore)
852 859 mergefiles(ui, repo, pctx, shelvectx)
853 860 restorebranch(ui, repo, branchtorestore)
854 861 _forgetunknownfiles(repo, shelvectx, addedbefore)
855 862
856 863 shelvedstate.clear(repo)
857 864 _finishunshelve(repo, oldtiprev, tr)
858 865 unshelvecleanup(ui, repo, basename, opts)
859 866 finally:
860 867 ui.quiet = oldquiet
861 868 if tr:
862 869 tr.release()
863 870 lockmod.release(lock)
864 871 ui.restoreconfig(forcemerge)
865 872
866 873 @command('shelve',
867 874 [('A', 'addremove', None,
868 875 _('mark new/missing files as added/removed before shelving')),
869 876 ('u', 'unknown', None,
870 877 _('store unknown files in the shelve')),
871 878 ('', 'cleanup', None,
872 879 _('delete all shelved changes')),
873 880 ('', 'date', '',
874 881 _('shelve with the specified commit date'), _('DATE')),
875 882 ('d', 'delete', None,
876 883 _('delete the named shelved change(s)')),
877 884 ('e', 'edit', False,
878 885 _('invoke editor on commit messages')),
879 886 ('l', 'list', None,
880 887 _('list current shelves')),
881 888 ('m', 'message', '',
882 889 _('use text as shelve message'), _('TEXT')),
883 890 ('n', 'name', '',
884 891 _('use the given name for the shelved commit'), _('NAME')),
885 892 ('p', 'patch', None,
886 893 _('show patch')),
887 894 ('i', 'interactive', None,
888 895 _('interactive mode, only works while creating a shelve')),
889 896 ('', 'stat', None,
890 897 _('output diffstat-style summary of changes'))] + commands.walkopts,
891 898 _('hg shelve [OPTION]... [FILE]...'))
892 899 def shelvecmd(ui, repo, *pats, **opts):
893 900 '''save and set aside changes from the working directory
894 901
895 902 Shelving takes files that "hg status" reports as not clean, saves
896 903 the modifications to a bundle (a shelved change), and reverts the
897 904 files so that their state in the working directory becomes clean.
898 905
899 906 To restore these changes to the working directory, using "hg
900 907 unshelve"; this will work even if you switch to a different
901 908 commit.
902 909
903 910 When no files are specified, "hg shelve" saves all not-clean
904 911 files. If specific files or directories are named, only changes to
905 912 those files are shelved.
906 913
907 914 In bare shelve(when no files are specified, without interactive,
908 915 include and exclude option), shelving remembers information if the
909 916 working directory was on newly created branch, in other words working
910 917 directory was on different branch than its first parent. In this
911 918 situation unshelving restores branch information to the working directory.
912 919
913 920 Each shelved change has a name that makes it easier to find later.
914 921 The name of a shelved change defaults to being based on the active
915 922 bookmark, or if there is no active bookmark, the current named
916 923 branch. To specify a different name, use ``--name``.
917 924
918 925 To see a list of existing shelved changes, use the ``--list``
919 926 option. For each shelved change, this will print its name, age,
920 927 and description; use ``--patch`` or ``--stat`` for more details.
921 928
922 929 To delete specific shelved changes, use ``--delete``. To delete
923 930 all shelved changes, use ``--cleanup``.
924 931 '''
925 932 allowables = [
926 933 ('addremove', set(['create'])), # 'create' is pseudo action
927 934 ('unknown', set(['create'])),
928 935 ('cleanup', set(['cleanup'])),
929 936 # ('date', set(['create'])), # ignored for passing '--date "0 0"' in tests
930 937 ('delete', set(['delete'])),
931 938 ('edit', set(['create'])),
932 939 ('list', set(['list'])),
933 940 ('message', set(['create'])),
934 941 ('name', set(['create'])),
935 942 ('patch', set(['patch', 'list'])),
936 943 ('stat', set(['stat', 'list'])),
937 944 ]
938 945 def checkopt(opt):
939 946 if opts.get(opt):
940 947 for i, allowable in allowables:
941 948 if opts[i] and opt not in allowable:
942 949 raise error.Abort(_("options '--%s' and '--%s' may not be "
943 950 "used together") % (opt, i))
944 951 return True
945 952 if checkopt('cleanup'):
946 953 if pats:
947 954 raise error.Abort(_("cannot specify names when using '--cleanup'"))
948 955 return cleanupcmd(ui, repo)
949 956 elif checkopt('delete'):
950 957 return deletecmd(ui, repo, pats)
951 958 elif checkopt('list'):
952 959 return listcmd(ui, repo, pats, opts)
953 960 elif checkopt('patch'):
954 961 return singlepatchcmds(ui, repo, pats, opts, subcommand='patch')
955 962 elif checkopt('stat'):
956 963 return singlepatchcmds(ui, repo, pats, opts, subcommand='stat')
957 964 else:
958 965 return createcmd(ui, repo, pats, opts)
959 966
960 967 def extsetup(ui):
961 968 cmdutil.unfinishedstates.append(
962 969 [shelvedstate._filename, False, False,
963 970 _('unshelve already in progress'),
964 971 _("use 'hg unshelve --continue' or 'hg unshelve --abort'")])
965 972 cmdutil.afterresolvedstates.append(
966 973 [shelvedstate._filename, _('hg unshelve --continue')])
@@ -1,1624 +1,1652
1 1 $ cat <<EOF >> $HGRCPATH
2 2 > [extensions]
3 3 > mq =
4 4 > shelve =
5 5 > [defaults]
6 6 > diff = --nodates --git
7 7 > qnew = --date '0 0'
8 8 > [shelve]
9 9 > maxbackups = 2
10 10 > EOF
11 11
12 12 $ hg init repo
13 13 $ cd repo
14 14 $ mkdir a b
15 15 $ echo a > a/a
16 16 $ echo b > b/b
17 17 $ echo c > c
18 18 $ echo d > d
19 19 $ echo x > x
20 20 $ hg addremove -q
21 21
22 22 shelve has a help message
23 23 $ hg shelve -h
24 24 hg shelve [OPTION]... [FILE]...
25 25
26 26 save and set aside changes from the working directory
27 27
28 28 Shelving takes files that "hg status" reports as not clean, saves the
29 29 modifications to a bundle (a shelved change), and reverts the files so
30 30 that their state in the working directory becomes clean.
31 31
32 32 To restore these changes to the working directory, using "hg unshelve";
33 33 this will work even if you switch to a different commit.
34 34
35 35 When no files are specified, "hg shelve" saves all not-clean files. If
36 36 specific files or directories are named, only changes to those files are
37 37 shelved.
38 38
39 39 In bare shelve(when no files are specified, without interactive, include
40 40 and exclude option), shelving remembers information if the working
41 41 directory was on newly created branch, in other words working directory
42 42 was on different branch than its first parent. In this situation
43 43 unshelving restores branch information to the working directory.
44 44
45 45 Each shelved change has a name that makes it easier to find later. The
46 46 name of a shelved change defaults to being based on the active bookmark,
47 47 or if there is no active bookmark, the current named branch. To specify a
48 48 different name, use "--name".
49 49
50 50 To see a list of existing shelved changes, use the "--list" option. For
51 51 each shelved change, this will print its name, age, and description; use "
52 52 --patch" or "--stat" for more details.
53 53
54 54 To delete specific shelved changes, use "--delete". To delete all shelved
55 55 changes, use "--cleanup".
56 56
57 57 (use 'hg help -e shelve' to show help for the shelve extension)
58 58
59 59 options ([+] can be repeated):
60 60
61 61 -A --addremove mark new/missing files as added/removed before
62 62 shelving
63 63 -u --unknown store unknown files in the shelve
64 64 --cleanup delete all shelved changes
65 65 --date DATE shelve with the specified commit date
66 66 -d --delete delete the named shelved change(s)
67 67 -e --edit invoke editor on commit messages
68 68 -l --list list current shelves
69 69 -m --message TEXT use text as shelve message
70 70 -n --name NAME use the given name for the shelved commit
71 71 -p --patch show patch
72 72 -i --interactive interactive mode, only works while creating a shelve
73 73 --stat output diffstat-style summary of changes
74 74 -I --include PATTERN [+] include names matching the given patterns
75 75 -X --exclude PATTERN [+] exclude names matching the given patterns
76 76 --mq operate on patch repository
77 77
78 78 (some details hidden, use --verbose to show complete help)
79 79
80 80 shelving in an empty repo should be possible
81 81 (this tests also that editor is not invoked, if '--edit' is not
82 82 specified)
83 83
84 84 $ HGEDITOR=cat hg shelve
85 85 shelved as default
86 86 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
87 87
88 88 $ hg unshelve
89 89 unshelving change 'default'
90 90
91 91 $ hg commit -q -m 'initial commit'
92 92
93 93 $ hg shelve
94 94 nothing changed
95 95 [1]
96 96
97 97 make sure shelve files were backed up
98 98
99 99 $ ls .hg/shelve-backup
100 100 default.hg
101 101 default.patch
102 102
103 103 create an mq patch - shelving should work fine with a patch applied
104 104
105 105 $ echo n > n
106 106 $ hg add n
107 107 $ hg commit n -m second
108 108 $ hg qnew second.patch
109 109
110 110 shelve a change that we will delete later
111 111
112 112 $ echo a >> a/a
113 113 $ hg shelve
114 114 shelved as default
115 115 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 116
117 117 set up some more complex changes to shelve
118 118
119 119 $ echo a >> a/a
120 120 $ hg mv b b.rename
121 121 moving b/b to b.rename/b (glob)
122 122 $ hg cp c c.copy
123 123 $ hg status -C
124 124 M a/a
125 125 A b.rename/b
126 126 b/b
127 127 A c.copy
128 128 c
129 129 R b/b
130 130
131 131 prevent some foot-shooting
132 132
133 133 $ hg shelve -n foo/bar
134 134 abort: shelved change names may not contain slashes
135 135 [255]
136 136 $ hg shelve -n .baz
137 137 abort: shelved change names may not start with '.'
138 138 [255]
139 139
140 140 the common case - no options or filenames
141 141
142 142 $ hg shelve
143 143 shelved as default-01
144 144 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
145 145 $ hg status -C
146 146
147 147 ensure that our shelved changes exist
148 148
149 149 $ hg shelve -l
150 150 default-01 (*)* changes to: [mq]: second.patch (glob)
151 151 default (*)* changes to: [mq]: second.patch (glob)
152 152
153 153 $ hg shelve -l -p default
154 154 default (*)* changes to: [mq]: second.patch (glob)
155 155
156 156 diff --git a/a/a b/a/a
157 157 --- a/a/a
158 158 +++ b/a/a
159 159 @@ -1,1 +1,2 @@
160 160 a
161 161 +a
162 162
163 163 $ hg shelve --list --addremove
164 164 abort: options '--list' and '--addremove' may not be used together
165 165 [255]
166 166
167 167 delete our older shelved change
168 168
169 169 $ hg shelve -d default
170 170 $ hg qfinish -a -q
171 171
172 172 ensure shelve backups aren't overwritten
173 173
174 174 $ ls .hg/shelve-backup/
175 175 default-1.hg
176 176 default-1.patch
177 177 default.hg
178 178 default.patch
179 179
180 180 local edits should not prevent a shelved change from applying
181 181
182 182 $ printf "z\na\n" > a/a
183 183 $ hg unshelve --keep
184 184 unshelving change 'default-01'
185 185 temporarily committing pending changes (restore with 'hg unshelve --abort')
186 186 rebasing shelved changes
187 187 rebasing 4:32c69314e062 "changes to: [mq]: second.patch" (tip)
188 188 merging a/a
189 189
190 190 $ hg revert --all -q
191 191 $ rm a/a.orig b.rename/b c.copy
192 192
193 193 apply it and make sure our state is as expected
194 194
195 195 (this also tests that same timestamp prevents backups from being
196 196 removed, even though there are more than 'maxbackups' backups)
197 197
198 198 $ f -t .hg/shelve-backup/default.hg
199 199 .hg/shelve-backup/default.hg: file
200 200 $ touch -t 200001010000 .hg/shelve-backup/default.hg
201 201 $ f -t .hg/shelve-backup/default-1.hg
202 202 .hg/shelve-backup/default-1.hg: file
203 203 $ touch -t 200001010000 .hg/shelve-backup/default-1.hg
204 204
205 205 $ hg unshelve
206 206 unshelving change 'default-01'
207 207 $ hg status -C
208 208 M a/a
209 209 A b.rename/b
210 210 b/b
211 211 A c.copy
212 212 c
213 213 R b/b
214 214 $ hg shelve -l
215 215
216 216 (both of default.hg and default-1.hg should be still kept, because it
217 217 is difficult to decide actual order of them from same timestamp)
218 218
219 219 $ ls .hg/shelve-backup/
220 220 default-01.hg
221 221 default-01.patch
222 222 default-1.hg
223 223 default-1.patch
224 224 default.hg
225 225 default.patch
226 226
227 227 $ hg unshelve
228 228 abort: no shelved changes to apply!
229 229 [255]
230 230 $ hg unshelve foo
231 231 abort: shelved change 'foo' not found
232 232 [255]
233 233
234 234 named shelves, specific filenames, and "commit messages" should all work
235 235 (this tests also that editor is invoked, if '--edit' is specified)
236 236
237 237 $ hg status -C
238 238 M a/a
239 239 A b.rename/b
240 240 b/b
241 241 A c.copy
242 242 c
243 243 R b/b
244 244 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
245 245 wat
246 246
247 247
248 248 HG: Enter commit message. Lines beginning with 'HG:' are removed.
249 249 HG: Leave message empty to abort commit.
250 250 HG: --
251 251 HG: user: shelve@localhost
252 252 HG: branch 'default'
253 253 HG: changed a/a
254 254
255 255 expect "a" to no longer be present, but status otherwise unchanged
256 256
257 257 $ hg status -C
258 258 A b.rename/b
259 259 b/b
260 260 A c.copy
261 261 c
262 262 R b/b
263 263 $ hg shelve -l --stat
264 264 wibble (*) wat (glob)
265 265 a/a | 1 +
266 266 1 files changed, 1 insertions(+), 0 deletions(-)
267 267
268 268 and now "a/a" should reappear
269 269
270 270 $ cd a
271 271 $ hg unshelve -q wibble
272 272 $ cd ..
273 273 $ hg status -C
274 274 M a/a
275 275 A b.rename/b
276 276 b/b
277 277 A c.copy
278 278 c
279 279 R b/b
280 280
281 281 ensure old shelve backups are being deleted automatically
282 282
283 283 $ ls .hg/shelve-backup/
284 284 default-01.hg
285 285 default-01.patch
286 286 wibble.hg
287 287 wibble.patch
288 288
289 289 cause unshelving to result in a merge with 'a' conflicting
290 290
291 291 $ hg shelve -q
292 292 $ echo c>>a/a
293 293 $ hg commit -m second
294 294 $ hg tip --template '{files}\n'
295 295 a/a
296 296
297 297 add an unrelated change that should be preserved
298 298
299 299 $ mkdir foo
300 300 $ echo foo > foo/foo
301 301 $ hg add foo/foo
302 302
303 303 force a conflicted merge to occur
304 304
305 305 $ hg unshelve
306 306 unshelving change 'default'
307 307 temporarily committing pending changes (restore with 'hg unshelve --abort')
308 308 rebasing shelved changes
309 309 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
310 310 merging a/a
311 311 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
312 312 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
313 313 [1]
314 314
315 315 ensure that we have a merge with unresolved conflicts
316 316
317 317 $ hg heads -q --template '{rev}\n'
318 318 5
319 319 4
320 320 $ hg parents -q --template '{rev}\n'
321 321 4
322 322 5
323 323 $ hg status
324 324 M a/a
325 325 M b.rename/b
326 326 M c.copy
327 327 R b/b
328 328 ? a/a.orig
329 329 $ hg diff
330 330 diff --git a/a/a b/a/a
331 331 --- a/a/a
332 332 +++ b/a/a
333 333 @@ -1,2 +1,6 @@
334 334 a
335 335 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
336 336 c
337 337 +=======
338 338 +a
339 339 +>>>>>>> source: 32c69314e062 - shelve: changes to: [mq]: second.patch
340 340 diff --git a/b/b b/b.rename/b
341 341 rename from b/b
342 342 rename to b.rename/b
343 343 diff --git a/c b/c.copy
344 344 copy from c
345 345 copy to c.copy
346 346 $ hg resolve -l
347 347 U a/a
348 348
349 349 $ hg shelve
350 350 abort: unshelve already in progress
351 351 (use 'hg unshelve --continue' or 'hg unshelve --abort')
352 352 [255]
353 353
354 354 abort the unshelve and be happy
355 355
356 356 $ hg status
357 357 M a/a
358 358 M b.rename/b
359 359 M c.copy
360 360 R b/b
361 361 ? a/a.orig
362 362 $ hg unshelve -a
363 363 rebase aborted
364 364 unshelve of 'default' aborted
365 365 $ hg heads -q
366 366 3:2e69b451d1ea
367 367 $ hg parents
368 368 changeset: 3:2e69b451d1ea
369 369 tag: tip
370 370 user: test
371 371 date: Thu Jan 01 00:00:00 1970 +0000
372 372 summary: second
373 373
374 374 $ hg resolve -l
375 375 $ hg status
376 376 A foo/foo
377 377 ? a/a.orig
378 378
379 379 try to continue with no unshelve underway
380 380
381 381 $ hg unshelve -c
382 382 abort: no unshelve in progress
383 383 [255]
384 384 $ hg status
385 385 A foo/foo
386 386 ? a/a.orig
387 387
388 388 redo the unshelve to get a conflict
389 389
390 390 $ hg unshelve -q
391 391 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
392 392 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
393 393 [1]
394 394
395 395 attempt to continue
396 396
397 397 $ hg unshelve -c
398 398 abort: unresolved conflicts, can't continue
399 399 (see 'hg resolve', then 'hg unshelve --continue')
400 400 [255]
401 401
402 402 $ hg revert -r . a/a
403 403 $ hg resolve -m a/a
404 404 (no more unresolved files)
405 405 continue: hg unshelve --continue
406 406
407 407 $ hg commit -m 'commit while unshelve in progress'
408 408 abort: unshelve already in progress
409 409 (use 'hg unshelve --continue' or 'hg unshelve --abort')
410 410 [255]
411 411
412 412 $ hg graft --continue
413 413 abort: no graft in progress
414 414 (continue: hg unshelve --continue)
415 415 [255]
416 416 $ hg unshelve -c
417 417 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
418 418 unshelve of 'default' complete
419 419
420 420 ensure the repo is as we hope
421 421
422 422 $ hg parents
423 423 changeset: 3:2e69b451d1ea
424 424 tag: tip
425 425 user: test
426 426 date: Thu Jan 01 00:00:00 1970 +0000
427 427 summary: second
428 428
429 429 $ hg heads -q
430 430 3:2e69b451d1ea
431 431
432 432 $ hg status -C
433 433 A b.rename/b
434 434 b/b
435 435 A c.copy
436 436 c
437 437 A foo/foo
438 438 R b/b
439 439 ? a/a.orig
440 440
441 441 there should be no shelves left
442 442
443 443 $ hg shelve -l
444 444
445 445 #if execbit
446 446
447 447 ensure that metadata-only changes are shelved
448 448
449 449 $ chmod +x a/a
450 450 $ hg shelve -q -n execbit a/a
451 451 $ hg status a/a
452 452 $ hg unshelve -q execbit
453 453 $ hg status a/a
454 454 M a/a
455 455 $ hg revert a/a
456 456
457 457 #endif
458 458
459 459 #if symlink
460 460
461 461 $ rm a/a
462 462 $ ln -s foo a/a
463 463 $ hg shelve -q -n symlink a/a
464 464 $ hg status a/a
465 465 $ hg unshelve -q symlink
466 466 $ hg status a/a
467 467 M a/a
468 468 $ hg revert a/a
469 469
470 470 #endif
471 471
472 472 set up another conflict between a commit and a shelved change
473 473
474 474 $ hg revert -q -C -a
475 475 $ rm a/a.orig b.rename/b c.copy
476 476 $ echo a >> a/a
477 477 $ hg shelve -q
478 478 $ echo x >> a/a
479 479 $ hg ci -m 'create conflict'
480 480 $ hg add foo/foo
481 481
482 482 if we resolve a conflict while unshelving, the unshelve should succeed
483 483
484 484 $ hg unshelve --tool :merge-other --keep
485 485 unshelving change 'default'
486 486 temporarily committing pending changes (restore with 'hg unshelve --abort')
487 487 rebasing shelved changes
488 488 rebasing 6:2f694dd83a13 "changes to: second" (tip)
489 489 merging a/a
490 490 $ hg parents -q
491 491 4:33f7f61e6c5e
492 492 $ hg shelve -l
493 493 default (*)* changes to: second (glob)
494 494 $ hg status
495 495 M a/a
496 496 A foo/foo
497 497 $ cat a/a
498 498 a
499 499 c
500 500 a
501 501 $ cat > a/a << EOF
502 502 > a
503 503 > c
504 504 > x
505 505 > EOF
506 506
507 507 $ HGMERGE=true hg unshelve
508 508 unshelving change 'default'
509 509 temporarily committing pending changes (restore with 'hg unshelve --abort')
510 510 rebasing shelved changes
511 511 rebasing 6:2f694dd83a13 "changes to: second" (tip)
512 512 merging a/a
513 513 note: rebase of 6:2f694dd83a13 created no changes to commit
514 514 $ hg parents -q
515 515 4:33f7f61e6c5e
516 516 $ hg shelve -l
517 517 $ hg status
518 518 A foo/foo
519 519 $ cat a/a
520 520 a
521 521 c
522 522 x
523 523
524 524 test keep and cleanup
525 525
526 526 $ hg shelve
527 527 shelved as default
528 528 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
529 529 $ hg shelve --list
530 530 default (*)* changes to: create conflict (glob)
531 531 $ hg unshelve -k
532 532 unshelving change 'default'
533 533 $ hg shelve --list
534 534 default (*)* changes to: create conflict (glob)
535 535 $ hg shelve --cleanup
536 536 $ hg shelve --list
537 537
538 538 $ hg shelve --cleanup --delete
539 539 abort: options '--cleanup' and '--delete' may not be used together
540 540 [255]
541 541 $ hg shelve --cleanup --patch
542 542 abort: options '--cleanup' and '--patch' may not be used together
543 543 [255]
544 544 $ hg shelve --cleanup --message MESSAGE
545 545 abort: options '--cleanup' and '--message' may not be used together
546 546 [255]
547 547
548 548 test bookmarks
549 549
550 550 $ hg bookmark test
551 551 $ hg bookmark
552 552 * test 4:33f7f61e6c5e
553 553 $ hg shelve
554 554 shelved as test
555 555 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
556 556 $ hg bookmark
557 557 * test 4:33f7f61e6c5e
558 558 $ hg unshelve
559 559 unshelving change 'test'
560 560 $ hg bookmark
561 561 * test 4:33f7f61e6c5e
562 562
563 563 shelve should still work even if mq is disabled
564 564
565 565 $ hg --config extensions.mq=! shelve
566 566 shelved as test
567 567 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
568 568 $ hg --config extensions.mq=! shelve --list
569 569 test (*)* changes to: create conflict (glob)
570 570 $ hg bookmark
571 571 * test 4:33f7f61e6c5e
572 572 $ hg --config extensions.mq=! unshelve
573 573 unshelving change 'test'
574 574 $ hg bookmark
575 575 * test 4:33f7f61e6c5e
576 576
577 577 shelve should leave dirstate clean (issue4055)
578 578
579 579 $ cd ..
580 580 $ hg init shelverebase
581 581 $ cd shelverebase
582 582 $ printf 'x\ny\n' > x
583 583 $ echo z > z
584 584 $ hg commit -Aqm xy
585 585 $ echo z >> x
586 586 $ hg commit -Aqm z
587 587 $ hg up 0
588 588 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
589 589 $ printf 'a\nx\ny\nz\n' > x
590 590 $ hg commit -Aqm xyz
591 591 $ echo c >> z
592 592 $ hg shelve
593 593 shelved as default
594 594 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
595 595 $ hg rebase -d 1 --config extensions.rebase=
596 596 rebasing 2:323bfa07f744 "xyz" (tip)
597 597 merging x
598 598 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
599 599 $ hg unshelve
600 600 unshelving change 'default'
601 601 rebasing shelved changes
602 602 rebasing 4:82a0d7d6ba61 "changes to: xyz" (tip)
603 603 $ hg status
604 604 M z
605 605
606 606 $ cd ..
607 607
608 608 shelve should only unshelve pending changes (issue4068)
609 609
610 610 $ hg init onlypendingchanges
611 611 $ cd onlypendingchanges
612 612 $ touch a
613 613 $ hg ci -Aqm a
614 614 $ touch b
615 615 $ hg ci -Aqm b
616 616 $ hg up -q 0
617 617 $ touch c
618 618 $ hg ci -Aqm c
619 619
620 620 $ touch d
621 621 $ hg add d
622 622 $ hg shelve
623 623 shelved as default
624 624 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
625 625 $ hg up -q 1
626 626 $ hg unshelve
627 627 unshelving change 'default'
628 628 rebasing shelved changes
629 629 rebasing 3:958bcbd1776e "changes to: c" (tip)
630 630 $ hg status
631 631 A d
632 632
633 633 unshelve should work on an ancestor of the original commit
634 634
635 635 $ hg shelve
636 636 shelved as default
637 637 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
638 638 $ hg up 0
639 639 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
640 640 $ hg unshelve
641 641 unshelving change 'default'
642 642 rebasing shelved changes
643 643 rebasing 3:013284d9655e "changes to: b" (tip)
644 644 $ hg status
645 645 A d
646 646
647 647 test bug 4073 we need to enable obsolete markers for it
648 648
649 649 $ cat >> $HGRCPATH << EOF
650 650 > [experimental]
651 651 > evolution=createmarkers
652 652 > EOF
653 653 $ hg shelve
654 654 shelved as default
655 655 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
656 656 $ hg debugobsolete `hg --debug id -i -r 1`
657 657 $ hg unshelve
658 658 unshelving change 'default'
659 659
660 660 unshelve should leave unknown files alone (issue4113)
661 661
662 662 $ echo e > e
663 663 $ hg shelve
664 664 shelved as default
665 665 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
666 666 $ hg status
667 667 ? e
668 668 $ hg unshelve
669 669 unshelving change 'default'
670 670 $ hg status
671 671 A d
672 672 ? e
673 673 $ cat e
674 674 e
675 675
676 676 unshelve should keep a copy of unknown files
677 677
678 678 $ hg add e
679 679 $ hg shelve
680 680 shelved as default
681 681 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
682 682 $ echo z > e
683 683 $ hg unshelve
684 684 unshelving change 'default'
685 685 $ cat e
686 686 e
687 687 $ cat e.orig
688 688 z
689 689
690 690
691 691 unshelve and conflicts with tracked and untracked files
692 692
693 693 preparing:
694 694
695 695 $ rm *.orig
696 696 $ hg ci -qm 'commit stuff'
697 697 $ hg phase -p null:
698 698
699 699 no other changes - no merge:
700 700
701 701 $ echo f > f
702 702 $ hg add f
703 703 $ hg shelve
704 704 shelved as default
705 705 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
706 706 $ echo g > f
707 707 $ hg unshelve
708 708 unshelving change 'default'
709 709 $ hg st
710 710 A f
711 711 ? f.orig
712 712 $ cat f
713 713 f
714 714 $ cat f.orig
715 715 g
716 716
717 717 other uncommitted changes - merge:
718 718
719 719 $ hg st
720 720 A f
721 721 ? f.orig
722 722 $ hg shelve
723 723 shelved as default
724 724 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
725 725 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
726 726 o 4 changes to: commit stuff shelve@localhost
727 727 |
728 728 ~
729 729 $ hg log -G --template '{rev} {desc|firstline} {author}'
730 730 @ 3 commit stuff test
731 731 |
732 732 | o 2 c test
733 733 |/
734 734 o 0 a test
735 735
736 736 $ mv f.orig f
737 737 $ echo 1 > a
738 738 $ hg unshelve --date '1073741824 0'
739 739 unshelving change 'default'
740 740 temporarily committing pending changes (restore with 'hg unshelve --abort')
741 741 rebasing shelved changes
742 742 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
743 743 merging f
744 744 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
745 745 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
746 746 [1]
747 747 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
748 748 @ 5 changes to: commit stuff shelve@localhost 1970-01-01 00:00 +0000
749 749 |
750 750 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
751 751 |/
752 752 o 3 commit stuff test 1970-01-01 00:00 +0000
753 753 |
754 754 | o 2 c test 1970-01-01 00:00 +0000
755 755 |/
756 756 o 0 a test 1970-01-01 00:00 +0000
757 757
758 758 $ hg st
759 759 M f
760 760 ? f.orig
761 761 $ cat f
762 762 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
763 763 g
764 764 =======
765 765 f
766 766 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
767 767 $ cat f.orig
768 768 g
769 769 $ hg unshelve --abort -t false
770 770 tool option will be ignored
771 771 rebase aborted
772 772 unshelve of 'default' aborted
773 773 $ hg st
774 774 M a
775 775 ? f.orig
776 776 $ cat f.orig
777 777 g
778 778 $ hg unshelve
779 779 unshelving change 'default'
780 780 temporarily committing pending changes (restore with 'hg unshelve --abort')
781 781 rebasing shelved changes
782 782 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
783 783 $ hg st
784 784 M a
785 785 A f
786 786 ? f.orig
787 787
788 788 other committed changes - merge:
789 789
790 790 $ hg shelve f
791 791 shelved as default
792 792 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
793 793 $ hg ci a -m 'intermediate other change'
794 794 $ mv f.orig f
795 795 $ hg unshelve
796 796 unshelving change 'default'
797 797 rebasing shelved changes
798 798 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
799 799 merging f
800 800 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
801 801 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
802 802 [1]
803 803 $ hg st
804 804 M f
805 805 ? f.orig
806 806 $ cat f
807 807 <<<<<<< dest: * - test: intermediate other change (glob)
808 808 g
809 809 =======
810 810 f
811 811 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
812 812 $ cat f.orig
813 813 g
814 814 $ hg unshelve --abort
815 815 rebase aborted
816 816 unshelve of 'default' aborted
817 817 $ hg st
818 818 ? f.orig
819 819 $ cat f.orig
820 820 g
821 821 $ hg shelve --delete default
822 822
823 823 Recreate some conflict again
824 824
825 825 $ cd ../repo
826 826 $ hg up -C -r 3
827 827 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
828 828 (leaving bookmark test)
829 829 $ echo y >> a/a
830 830 $ hg shelve
831 831 shelved as default
832 832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
833 833 $ hg up test
834 834 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
835 835 (activating bookmark test)
836 836 $ hg bookmark
837 837 * test 4:33f7f61e6c5e
838 838 $ hg unshelve
839 839 unshelving change 'default'
840 840 rebasing shelved changes
841 841 rebasing 5:e42a7da90865 "changes to: second" (tip)
842 842 merging a/a
843 843 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
844 844 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
845 845 [1]
846 846 $ hg bookmark
847 847 test 4:33f7f61e6c5e
848 848
849 849 Test that resolving all conflicts in one direction (so that the rebase
850 850 is a no-op), works (issue4398)
851 851
852 852 $ hg revert -a -r .
853 853 reverting a/a (glob)
854 854 $ hg resolve -m a/a
855 855 (no more unresolved files)
856 856 continue: hg unshelve --continue
857 857 $ hg unshelve -c
858 858 rebasing 5:e42a7da90865 "changes to: second" (tip)
859 859 note: rebase of 5:e42a7da90865 created no changes to commit
860 860 unshelve of 'default' complete
861 861 $ hg bookmark
862 862 * test 4:33f7f61e6c5e
863 863 $ hg diff
864 864 $ hg status
865 865 ? a/a.orig
866 866 ? foo/foo
867 867 $ hg summary
868 868 parent: 4:33f7f61e6c5e tip
869 869 create conflict
870 870 branch: default
871 871 bookmarks: *test
872 872 commit: 2 unknown (clean)
873 873 update: (current)
874 874 phases: 5 draft
875 875
876 876 $ hg shelve --delete --stat
877 877 abort: options '--delete' and '--stat' may not be used together
878 878 [255]
879 879 $ hg shelve --delete --name NAME
880 880 abort: options '--delete' and '--name' may not be used together
881 881 [255]
882 882
883 883 Test interactive shelve
884 884 $ cat <<EOF >> $HGRCPATH
885 885 > [ui]
886 886 > interactive = true
887 887 > EOF
888 888 $ echo 'a' >> a/b
889 889 $ cat a/a >> a/b
890 890 $ echo 'x' >> a/b
891 891 $ mv a/b a/a
892 892 $ echo 'a' >> foo/foo
893 893 $ hg st
894 894 M a/a
895 895 ? a/a.orig
896 896 ? foo/foo
897 897 $ cat a/a
898 898 a
899 899 a
900 900 c
901 901 x
902 902 x
903 903 $ cat foo/foo
904 904 foo
905 905 a
906 906 $ hg shelve --interactive --config ui.interactive=false
907 907 abort: running non-interactively
908 908 [255]
909 909 $ hg shelve --interactive << EOF
910 910 > y
911 911 > y
912 912 > n
913 913 > EOF
914 914 diff --git a/a/a b/a/a
915 915 2 hunks, 2 lines changed
916 916 examine changes to 'a/a'? [Ynesfdaq?] y
917 917
918 918 @@ -1,3 +1,4 @@
919 919 +a
920 920 a
921 921 c
922 922 x
923 923 record change 1/2 to 'a/a'? [Ynesfdaq?] y
924 924
925 925 @@ -1,3 +2,4 @@
926 926 a
927 927 c
928 928 x
929 929 +x
930 930 record change 2/2 to 'a/a'? [Ynesfdaq?] n
931 931
932 932 shelved as test
933 933 merging a/a
934 934 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
935 935 $ cat a/a
936 936 a
937 937 c
938 938 x
939 939 x
940 940 $ cat foo/foo
941 941 foo
942 942 a
943 943 $ hg st
944 944 M a/a
945 945 ? foo/foo
946 946 $ hg bookmark
947 947 * test 4:33f7f61e6c5e
948 948 $ hg unshelve
949 949 unshelving change 'test'
950 950 temporarily committing pending changes (restore with 'hg unshelve --abort')
951 951 rebasing shelved changes
952 952 rebasing 6:96a1354f65f6 "changes to: create conflict" (tip)
953 953 merging a/a
954 954 $ hg bookmark
955 955 * test 4:33f7f61e6c5e
956 956 $ cat a/a
957 957 a
958 958 a
959 959 c
960 960 x
961 961 x
962 962
963 963 shelve --patch and shelve --stat should work with a single valid shelfname
964 964
965 965 $ hg up --clean .
966 966 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
967 967 (leaving bookmark test)
968 968 $ hg shelve --list
969 969 $ echo 'patch a' > shelf-patch-a
970 970 $ hg add shelf-patch-a
971 971 $ hg shelve
972 972 shelved as default
973 973 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
974 974 $ echo 'patch b' > shelf-patch-b
975 975 $ hg add shelf-patch-b
976 976 $ hg shelve
977 977 shelved as default-01
978 978 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
979 979 $ hg shelve --patch default default-01
980 980 abort: --patch expects a single shelf
981 981 [255]
982 982 $ hg shelve --stat default default-01
983 983 abort: --stat expects a single shelf
984 984 [255]
985 985 $ hg shelve --patch default
986 986 default (*)* changes to: create conflict (glob)
987 987
988 988 diff --git a/shelf-patch-a b/shelf-patch-a
989 989 new file mode 100644
990 990 --- /dev/null
991 991 +++ b/shelf-patch-a
992 992 @@ -0,0 +1,1 @@
993 993 +patch a
994 994 $ hg shelve --stat default
995 995 default (*)* changes to: create conflict (glob)
996 996 shelf-patch-a | 1 +
997 997 1 files changed, 1 insertions(+), 0 deletions(-)
998 998 $ hg shelve --patch nonexistentshelf
999 999 abort: cannot find shelf nonexistentshelf
1000 1000 [255]
1001 1001 $ hg shelve --stat nonexistentshelf
1002 1002 abort: cannot find shelf nonexistentshelf
1003 1003 [255]
1004 1004
1005 1005 $ cd ..
1006 1006
1007 1007 Shelve from general delta repo uses bundle2 on disk
1008 1008 --------------------------------------------------
1009 1009
1010 1010 no general delta
1011 1011
1012 1012 $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
1013 1013 requesting all changes
1014 1014 adding changesets
1015 1015 adding manifests
1016 1016 adding file changes
1017 1017 added 5 changesets with 8 changes to 6 files
1018 1018 updating to branch default
1019 1019 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1020 1020 $ cd bundle1
1021 1021 $ echo babar > jungle
1022 1022 $ hg add jungle
1023 1023 $ hg shelve
1024 1024 shelved as default
1025 1025 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1026 1026 $ hg debugbundle .hg/shelved/*.hg
1027 1027 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1028 1028 $ cd ..
1029 1029
1030 1030 with general delta
1031 1031
1032 1032 $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
1033 1033 requesting all changes
1034 1034 adding changesets
1035 1035 adding manifests
1036 1036 adding file changes
1037 1037 added 5 changesets with 8 changes to 6 files
1038 1038 updating to branch default
1039 1039 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1040 1040 $ cd bundle2
1041 1041 $ echo babar > jungle
1042 1042 $ hg add jungle
1043 1043 $ hg shelve
1044 1044 shelved as default
1045 1045 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1046 1046 $ hg debugbundle .hg/shelved/*.hg
1047 1047 Stream params: sortdict([('Compression', 'BZ')])
1048 1048 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
1049 1049 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1050 1050 $ cd ..
1051 1051
1052 1052 Test visibility of in-memory changes inside transaction to external hook
1053 1053 ------------------------------------------------------------------------
1054 1054
1055 1055 $ cd repo
1056 1056
1057 1057 $ echo xxxx >> x
1058 1058 $ hg commit -m "#5: changes to invoke rebase"
1059 1059
1060 1060 $ cat > $TESTTMP/checkvisibility.sh <<EOF
1061 1061 > echo "==== \$1:"
1062 1062 > hg parents --template "VISIBLE {rev}:{node|short}\n"
1063 1063 > # test that pending changes are hidden
1064 1064 > unset HG_PENDING
1065 1065 > hg parents --template "ACTUAL {rev}:{node|short}\n"
1066 1066 > echo "===="
1067 1067 > EOF
1068 1068
1069 1069 $ cat >> .hg/hgrc <<EOF
1070 1070 > [defaults]
1071 1071 > # to fix hash id of temporary revisions
1072 1072 > unshelve = --date '0 0'
1073 1073 > EOF
1074 1074
1075 1075 "hg unshelve" at REV5 implies steps below:
1076 1076
1077 1077 (1) commit changes in the working directory (REV6)
1078 1078 (2) unbundle shelved revision (REV7)
1079 1079 (3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
1080 1080 (4) rebase: commit merged revision (REV8)
1081 1081 (5) rebase: update to REV6 (REV8 => REV6)
1082 1082 (6) update to REV5 (REV6 => REV5)
1083 1083 (7) abort transaction
1084 1084
1085 1085 == test visibility to external preupdate hook
1086 1086
1087 1087 $ cat >> .hg/hgrc <<EOF
1088 1088 > [hooks]
1089 1089 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
1090 1090 > EOF
1091 1091
1092 1092 $ echo nnnn >> n
1093 1093
1094 1094 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1095 1095 ==== before-unshelving:
1096 1096 VISIBLE 5:703117a2acfb
1097 1097 ACTUAL 5:703117a2acfb
1098 1098 ====
1099 1099
1100 1100 $ hg unshelve --keep default
1101 1101 temporarily committing pending changes (restore with 'hg unshelve --abort')
1102 1102 rebasing shelved changes
1103 1103 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1104 1104 ==== preupdate:
1105 1105 VISIBLE 6:66b86db80ee4
1106 1106 ACTUAL 5:703117a2acfb
1107 1107 ====
1108 1108 ==== preupdate:
1109 1109 VISIBLE 8:a0e04704317e
1110 1110 ACTUAL 5:703117a2acfb
1111 1111 ====
1112 1112 ==== preupdate:
1113 1113 VISIBLE 6:66b86db80ee4
1114 1114 ACTUAL 5:703117a2acfb
1115 1115 ====
1116 1116
1117 1117 $ cat >> .hg/hgrc <<EOF
1118 1118 > [hooks]
1119 1119 > preupdate.visibility =
1120 1120 > EOF
1121 1121
1122 1122 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1123 1123 ==== after-unshelving:
1124 1124 VISIBLE 5:703117a2acfb
1125 1125 ACTUAL 5:703117a2acfb
1126 1126 ====
1127 1127
1128 1128 == test visibility to external update hook
1129 1129
1130 1130 $ hg update -q -C 5
1131 1131
1132 1132 $ cat >> .hg/hgrc <<EOF
1133 1133 > [hooks]
1134 1134 > update.visibility = sh $TESTTMP/checkvisibility.sh update
1135 1135 > EOF
1136 1136
1137 1137 $ echo nnnn >> n
1138 1138
1139 1139 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1140 1140 ==== before-unshelving:
1141 1141 VISIBLE 5:703117a2acfb
1142 1142 ACTUAL 5:703117a2acfb
1143 1143 ====
1144 1144
1145 1145 $ hg unshelve --keep default
1146 1146 temporarily committing pending changes (restore with 'hg unshelve --abort')
1147 1147 rebasing shelved changes
1148 1148 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1149 1149 ==== update:
1150 1150 VISIBLE 6:66b86db80ee4
1151 1151 VISIBLE 7:206bf5d4f922
1152 1152 ACTUAL 5:703117a2acfb
1153 1153 ====
1154 1154 ==== update:
1155 1155 VISIBLE 6:66b86db80ee4
1156 1156 ACTUAL 5:703117a2acfb
1157 1157 ====
1158 1158 ==== update:
1159 1159 VISIBLE 5:703117a2acfb
1160 1160 ACTUAL 5:703117a2acfb
1161 1161 ====
1162 1162
1163 1163 $ cat >> .hg/hgrc <<EOF
1164 1164 > [hooks]
1165 1165 > update.visibility =
1166 1166 > EOF
1167 1167
1168 1168 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1169 1169 ==== after-unshelving:
1170 1170 VISIBLE 5:703117a2acfb
1171 1171 ACTUAL 5:703117a2acfb
1172 1172 ====
1173 1173
1174 1174 $ cd ..
1175 1175
1176 1176 test .orig files go where the user wants them to
1177 1177 ---------------------------------------------------------------
1178 1178 $ hg init salvage
1179 1179 $ cd salvage
1180 1180 $ echo 'content' > root
1181 1181 $ hg commit -A -m 'root' -q
1182 1182 $ echo '' > root
1183 1183 $ hg shelve -q
1184 1184 $ echo 'contADDent' > root
1185 1185 $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
1186 1186 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1187 1187 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1188 1188 [1]
1189 1189 $ ls .hg/origbackups
1190 1190 root.orig
1191 1191 $ rm -rf .hg/origbackups
1192 1192
1193 1193 test Abort unshelve always gets user out of the unshelved state
1194 1194 ---------------------------------------------------------------
1195 1195 Wreak havoc on the unshelve process
1196 1196 $ rm .hg/unshelverebasestate
1197 1197 $ hg unshelve --abort
1198 1198 unshelve of 'default' aborted
1199 1199 abort: (No such file or directory|The system cannot find the file specified) (re)
1200 1200 [255]
1201 1201 Can the user leave the current state?
1202 1202 $ hg up -C .
1203 1203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1204 1204
1205 1205 Try again but with a corrupted shelve state file
1206 1206 $ hg strip -r 2 -r 1 -q
1207 1207 $ hg up -r 0 -q
1208 1208 $ echo '' > root
1209 1209 $ hg shelve -q
1210 1210 $ echo 'contADDent' > root
1211 1211 $ hg unshelve -q
1212 1212 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1213 1213 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1214 1214 [1]
1215 1215 $ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
1216 1216 $ mv ../corrupt-shelvedstate .hg/histedit-state
1217 1217 $ hg unshelve --abort 2>&1 | grep 'rebase aborted'
1218 1218 rebase aborted
1219 1219 $ hg up -C .
1220 1220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1221 1221
1222 1222 $ cd ..
1223 1223
1224 1224 Keep active bookmark while (un)shelving even on shared repo (issue4940)
1225 1225 -----------------------------------------------------------------------
1226 1226
1227 1227 $ cat <<EOF >> $HGRCPATH
1228 1228 > [extensions]
1229 1229 > share =
1230 1230 > EOF
1231 1231
1232 1232 $ hg bookmarks -R repo
1233 1233 test 4:33f7f61e6c5e
1234 1234 $ hg share -B repo share
1235 1235 updating working directory
1236 1236 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1237 1237 $ cd share
1238 1238
1239 1239 $ hg bookmarks
1240 1240 test 4:33f7f61e6c5e
1241 1241 $ hg bookmarks foo
1242 1242 $ hg bookmarks
1243 1243 * foo 5:703117a2acfb
1244 1244 test 4:33f7f61e6c5e
1245 1245 $ echo x >> x
1246 1246 $ hg shelve
1247 1247 shelved as foo
1248 1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1249 1249 $ hg bookmarks
1250 1250 * foo 5:703117a2acfb
1251 1251 test 4:33f7f61e6c5e
1252 1252
1253 1253 $ hg unshelve
1254 1254 unshelving change 'foo'
1255 1255 $ hg bookmarks
1256 1256 * foo 5:703117a2acfb
1257 1257 test 4:33f7f61e6c5e
1258 1258
1259 1259 $ cd ..
1260 1260
1261 1261 Shelve and unshelve unknown files. For the purposes of unshelve, a shelved
1262 1262 unknown file is the same as a shelved added file, except that it will be in
1263 1263 unknown state after unshelve if and only if it was either absent or unknown
1264 1264 before the unshelve operation.
1265 1265
1266 1266 $ hg init unknowns
1267 1267 $ cd unknowns
1268 1268
1269 1269 The simplest case is if I simply have an unknown file that I shelve and unshelve
1270 1270
1271 1271 $ echo unknown > unknown
1272 1272 $ hg status
1273 1273 ? unknown
1274 1274 $ hg shelve --unknown
1275 1275 shelved as default
1276 1276 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1277 1277 $ hg status
1278 1278 $ hg unshelve
1279 1279 unshelving change 'default'
1280 1280 $ hg status
1281 1281 ? unknown
1282 1282 $ rm unknown
1283 1283
1284 1284 If I shelve, add the file, and unshelve, does it stay added?
1285 1285
1286 1286 $ echo unknown > unknown
1287 1287 $ hg shelve -u
1288 1288 shelved as default
1289 1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1290 1290 $ hg status
1291 1291 $ touch unknown
1292 1292 $ hg add unknown
1293 1293 $ hg status
1294 1294 A unknown
1295 1295 $ hg unshelve
1296 1296 unshelving change 'default'
1297 1297 temporarily committing pending changes (restore with 'hg unshelve --abort')
1298 1298 rebasing shelved changes
1299 1299 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1300 1300 merging unknown
1301 1301 $ hg status
1302 1302 A unknown
1303 1303 $ hg forget unknown
1304 1304 $ rm unknown
1305 1305
1306 1306 And if I shelve, commit, then unshelve, does it become modified?
1307 1307
1308 1308 $ echo unknown > unknown
1309 1309 $ hg shelve -u
1310 1310 shelved as default
1311 1311 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1312 1312 $ hg status
1313 1313 $ touch unknown
1314 1314 $ hg add unknown
1315 1315 $ hg commit -qm "Add unknown"
1316 1316 $ hg status
1317 1317 $ hg unshelve
1318 1318 unshelving change 'default'
1319 1319 rebasing shelved changes
1320 1320 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1321 1321 merging unknown
1322 1322 $ hg status
1323 1323 M unknown
1324 1324 $ hg remove --force unknown
1325 1325 $ hg commit -qm "Remove unknown"
1326 1326
1327 1327 $ cd ..
1328 1328
1329 1329 We expects that non-bare shelve keeps newly created branch in
1330 1330 working directory.
1331 1331
1332 1332 $ hg init shelve-preserve-new-branch
1333 1333 $ cd shelve-preserve-new-branch
1334 1334 $ echo "a" >> a
1335 1335 $ hg add a
1336 1336 $ echo "b" >> b
1337 1337 $ hg add b
1338 1338 $ hg commit -m "ab"
1339 1339 $ echo "aa" >> a
1340 1340 $ echo "bb" >> b
1341 1341 $ hg branch new-branch
1342 1342 marked working directory as branch new-branch
1343 1343 (branches are permanent and global, did you want a bookmark?)
1344 1344 $ hg status
1345 1345 M a
1346 1346 M b
1347 1347 $ hg branch
1348 1348 new-branch
1349 1349 $ hg shelve a
1350 1350 shelved as default
1351 1351 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1352 1352 $ hg branch
1353 1353 new-branch
1354 1354 $ hg status
1355 1355 M b
1356 1356 $ touch "c" >> c
1357 1357 $ hg add c
1358 1358 $ hg status
1359 1359 M b
1360 1360 A c
1361 1361 $ hg shelve --exclude c
1362 1362 shelved as default-01
1363 1363 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1364 1364 $ hg branch
1365 1365 new-branch
1366 1366 $ hg status
1367 1367 A c
1368 1368 $ hg shelve --include c
1369 1369 shelved as default-02
1370 1370 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1371 1371 $ hg branch
1372 1372 new-branch
1373 1373 $ hg status
1374 1374 $ echo "d" >> d
1375 1375 $ hg add d
1376 1376 $ hg status
1377 1377 A d
1378 1378
1379 1379 We expect that bare-shelve will not keep branch in current working directory.
1380 1380
1381 1381 $ hg shelve
1382 1382 shelved as default-03
1383 1383 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1384 1384 $ hg branch
1385 1385 default
1386 1386
1387 1387 When i shelve commit on newly created branch i expect
1388 1388 that after unshelve newly created branch will be preserved.
1389 1389
1390 1390 $ hg init shelve_on_new_branch_simple
1391 1391 $ cd shelve_on_new_branch_simple
1392 1392 $ echo "aaa" >> a
1393 1393 $ hg commit -A -m "a"
1394 1394 adding a
1395 1395 $ hg branch
1396 1396 default
1397 1397 $ hg branch test
1398 1398 marked working directory as branch test
1399 1399 (branches are permanent and global, did you want a bookmark?)
1400 1400 $ echo "bbb" >> a
1401 1401 $ hg status
1402 1402 M a
1403 1403 $ hg shelve
1404 1404 shelved as default
1405 1405 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1406 1406 $ hg branch
1407 1407 default
1408 1408 $ echo "bbb" >> b
1409 1409 $ hg status
1410 1410 ? b
1411 1411 $ hg unshelve
1412 1412 unshelving change 'default'
1413 1413 marked working directory as branch test
1414 1414 $ hg status
1415 1415 M a
1416 1416 ? b
1417 1417 $ hg branch
1418 1418 test
1419 1419
1420 1420 When i shelve commit on newly created branch, make
1421 1421 some changes, unshelve it and running into merge
1422 1422 conflicts i expect that after fixing them and
1423 1423 running unshelve --continue newly created branch
1424 1424 will be preserved.
1425 1425
1426 1426 $ hg init shelve_on_new_branch_conflict
1427 1427 $ cd shelve_on_new_branch_conflict
1428 1428 $ echo "aaa" >> a
1429 1429 $ hg commit -A -m "a"
1430 1430 adding a
1431 1431 $ hg branch
1432 1432 default
1433 1433 $ hg branch test
1434 1434 marked working directory as branch test
1435 1435 (branches are permanent and global, did you want a bookmark?)
1436 1436 $ echo "bbb" >> a
1437 1437 $ hg status
1438 1438 M a
1439 1439 $ hg shelve
1440 1440 shelved as default
1441 1441 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1442 1442 $ hg branch
1443 1443 default
1444 1444 $ echo "ccc" >> a
1445 1445 $ hg status
1446 1446 M a
1447 1447 $ hg unshelve
1448 1448 unshelving change 'default'
1449 1449 temporarily committing pending changes (restore with 'hg unshelve --abort')
1450 1450 rebasing shelved changes
1451 1451 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1452 1452 merging a
1453 1453 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1454 1454 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1455 1455 [1]
1456 1456 $ echo "aaabbbccc" > a
1457 1457 $ rm a.orig
1458 1458 $ hg resolve --mark a
1459 1459 (no more unresolved files)
1460 1460 continue: hg unshelve --continue
1461 1461 $ hg unshelve --continue
1462 1462 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1463 1463 marked working directory as branch test
1464 1464 unshelve of 'default' complete
1465 1465 $ cat a
1466 1466 aaabbbccc
1467 1467 $ hg status
1468 1468 M a
1469 1469 $ hg branch
1470 1470 test
1471 1471 $ hg commit -m "test-commit"
1472 1472
1473 1473 When i shelve on test branch, update to default branch
1474 1474 and unshelve i expect that it will not preserve previous
1475 1475 test branch.
1476 1476
1477 1477 $ echo "xxx" > b
1478 1478 $ hg add b
1479 1479 $ hg shelve
1480 1480 shelved as test
1481 1481 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1482 1482 $ hg update -r default
1483 1483 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1484 1484 $ hg unshelve
1485 1485 unshelving change 'test'
1486 1486 rebasing shelved changes
1487 1487 rebasing 2:357525f34729 "changes to: test-commit" (tip)
1488 1488 $ hg status
1489 1489 A b
1490 1490 $ hg branch
1491 1491 default
1492 1492
1493 1493 When i unshelve resulting in merge conflicts and makes saved
1494 1494 file shelvedstate looks like in previous versions in
1495 1495 mercurial(without restore branch information in 7th line) i
1496 1496 expect that after resolving conflicts and successfully
1497 1497 running 'shelve --continue' the branch information won't be
1498 1498 restored and branch will be unchanged.
1499 1499
1500 1500 shelve on new branch, conflict with previous shelvedstate
1501 1501
1502 1502 $ hg init conflict
1503 1503 $ cd conflict
1504 1504 $ echo "aaa" >> a
1505 1505 $ hg commit -A -m "a"
1506 1506 adding a
1507 1507 $ hg branch
1508 1508 default
1509 1509 $ hg branch test
1510 1510 marked working directory as branch test
1511 1511 (branches are permanent and global, did you want a bookmark?)
1512 1512 $ echo "bbb" >> a
1513 1513 $ hg status
1514 1514 M a
1515 1515 $ hg shelve
1516 1516 shelved as default
1517 1517 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1518 1518 $ hg branch
1519 1519 default
1520 1520 $ echo "ccc" >> a
1521 1521 $ hg status
1522 1522 M a
1523 1523 $ hg unshelve
1524 1524 unshelving change 'default'
1525 1525 temporarily committing pending changes (restore with 'hg unshelve --abort')
1526 1526 rebasing shelved changes
1527 1527 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1528 1528 merging a
1529 1529 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1530 1530 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1531 1531 [1]
1532 1532
1533 1533 Removing restore branch information from shelvedstate file(making it looks like
1534 1534 in previous versions) and running unshelve --continue
1535 1535
1536 1536 $ head -n 6 < .hg/shelvedstate > .hg/shelvedstate_oldformat
1537 1537 $ rm .hg/shelvedstate
1538 1538 $ mv .hg/shelvedstate_oldformat .hg/shelvedstate
1539 1539
1540 1540 $ echo "aaabbbccc" > a
1541 1541 $ rm a.orig
1542 1542 $ hg resolve --mark a
1543 1543 (no more unresolved files)
1544 1544 continue: hg unshelve --continue
1545 1545 $ hg unshelve --continue
1546 1546 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1547 1547 unshelve of 'default' complete
1548 1548 $ cat a
1549 1549 aaabbbccc
1550 1550 $ hg status
1551 1551 M a
1552 1552 $ hg branch
1553 1553 default
1554 1554
1555 1555 On non bare shelve the branch information shouldn't be restored
1556 1556
1557 1557 $ hg init bare_shelve_on_new_branch
1558 1558 $ cd bare_shelve_on_new_branch
1559 1559 $ echo "aaa" >> a
1560 1560 $ hg commit -A -m "a"
1561 1561 adding a
1562 1562 $ hg branch
1563 1563 default
1564 1564 $ hg branch test
1565 1565 marked working directory as branch test
1566 1566 (branches are permanent and global, did you want a bookmark?)
1567 1567 $ echo "bbb" >> a
1568 1568 $ hg status
1569 1569 M a
1570 1570 $ hg shelve a
1571 1571 shelved as default
1572 1572 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1573 1573 $ hg branch
1574 1574 test
1575 1575 $ hg branch default
1576 1576 marked working directory as branch default
1577 1577 (branches are permanent and global, did you want a bookmark?)
1578 1578 $ echo "bbb" >> b
1579 1579 $ hg status
1580 1580 ? b
1581 1581 $ hg unshelve
1582 1582 unshelving change 'default'
1583 1583 $ hg status
1584 1584 M a
1585 1585 ? b
1586 1586 $ hg branch
1587 1587 default
1588 1588 $ cd ..
1589 1589
1590 1590 Prepare unshelve with a corrupted shelvedstate
1591 1591 $ hg init r1 && cd r1
1592 1592 $ echo text1 > file && hg add file
1593 1593 $ hg shelve
1594 1594 shelved as default
1595 1595 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1596 1596 $ echo text2 > file && hg ci -Am text1
1597 1597 adding file
1598 1598 $ hg unshelve
1599 1599 unshelving change 'default'
1600 1600 rebasing shelved changes
1601 1601 rebasing 1:396ea74229f9 "(changes in empty repository)" (tip)
1602 1602 merging file
1603 1603 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1604 1604 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1605 1605 [1]
1606 1606 $ echo somethingsomething > .hg/shelvedstate
1607 1607
1608 1608 Unshelve --continue fails with appropriate message if shelvedstate is corrupted
1609 1609 $ hg unshelve --continue
1610 1610 abort: corrupted shelved state file
1611 1611 (please run hg unshelve --abort to abort unshelve operation)
1612 1612 [255]
1613 1613
1614 1614 Unshelve --abort works with a corrupted shelvedstate
1615 1615 $ hg unshelve --abort
1616 1616 could not read shelved state file, your working copy may be in an unexpected state
1617 1617 please update to some commit
1618 1618
1619 1619 Unshelve --abort fails with appropriate message if there's no unshelve in
1620 1620 progress
1621 1621 $ hg unshelve --abort
1622 1622 abort: no unshelve in progress
1623 1623 [255]
1624 1624 $ cd ..
1625
1626 Unshelve respects --keep even if user intervention is needed
1627 $ hg init unshelvekeep
1628 $ echo 1 > file && hg ci -Am 1
1629 adding file
1630 $ echo 2 >> file
1631 $ hg shelve
1632 shelved as default
1633 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1634 $ echo 3 >> file && hg ci -Am 13
1635 $ hg shelve --list
1636 default (1s ago) changes to: 1
1637 $ hg unshelve --keep
1638 unshelving change 'default'
1639 rebasing shelved changes
1640 rebasing 3:1d24e58054c8 "changes to: 1" (tip)
1641 merging file
1642 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1643 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1644 [1]
1645 $ hg resolve --mark file
1646 (no more unresolved files)
1647 continue: hg unshelve --continue
1648 $ hg unshelve --continue
1649 rebasing 3:1d24e58054c8 "changes to: 1" (tip)
1650 unshelve of 'default' complete
1651 $ hg shelve --list
1652 default (1s ago) changes to: 1
General Comments 0
You need to be logged in to leave comments. Login now