##// END OF EJS Templates
shelve: move patch extension to a string constant...
Kostia Balytskyi -
r30554:1775975d default
parent child Browse files
Show More
@@ -1,973 +1,976
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 # universal extension is present in all types of shelves
67 patchextension = 'patch'
66 68
67 69 # we never need the user, so we use a
68 70 # generic user for all shelve operations
69 71 shelveuser = 'shelve@localhost'
70 72
71 73 class shelvedfile(object):
72 74 """Helper for the file storing a single shelve
73 75
74 76 Handles common functions on shelve files (.hg/.patch) using
75 77 the vfs layer"""
76 78 def __init__(self, repo, name, filetype=None):
77 79 self.repo = repo
78 80 self.name = name
79 81 self.vfs = scmutil.vfs(repo.join(shelvedir))
80 82 self.backupvfs = scmutil.vfs(repo.join(backupdir))
81 83 self.ui = self.repo.ui
82 84 if filetype:
83 85 self.fname = name + '.' + filetype
84 86 else:
85 87 self.fname = name
86 88
87 89 def exists(self):
88 90 return self.vfs.exists(self.fname)
89 91
90 92 def filename(self):
91 93 return self.vfs.join(self.fname)
92 94
93 95 def backupfilename(self):
94 96 def gennames(base):
95 97 yield base
96 98 base, ext = base.rsplit('.', 1)
97 99 for i in itertools.count(1):
98 100 yield '%s-%d.%s' % (base, i, ext)
99 101
100 102 name = self.backupvfs.join(self.fname)
101 103 for n in gennames(name):
102 104 if not self.backupvfs.exists(n):
103 105 return n
104 106
105 107 def movetobackup(self):
106 108 if not self.backupvfs.isdir():
107 109 self.backupvfs.makedir()
108 110 util.rename(self.filename(), self.backupfilename())
109 111
110 112 def stat(self):
111 113 return self.vfs.stat(self.fname)
112 114
113 115 def opener(self, mode='rb'):
114 116 try:
115 117 return self.vfs(self.fname, mode)
116 118 except IOError as err:
117 119 if err.errno != errno.ENOENT:
118 120 raise
119 121 raise error.Abort(_("shelved change '%s' not found") % self.name)
120 122
121 123 def applybundle(self):
122 124 fp = self.opener()
123 125 try:
124 126 gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs)
125 127 if not isinstance(gen, bundle2.unbundle20):
126 128 gen.apply(self.repo, 'unshelve',
127 129 'bundle:' + self.vfs.join(self.fname),
128 130 targetphase=phases.secret)
129 131 if isinstance(gen, bundle2.unbundle20):
130 132 bundle2.applybundle(self.repo, gen,
131 133 self.repo.currenttransaction(),
132 134 source='unshelve',
133 135 url='bundle:' + self.vfs.join(self.fname))
134 136 finally:
135 137 fp.close()
136 138
137 139 def bundlerepo(self):
138 140 return bundlerepo.bundlerepository(self.repo.baseui, self.repo.root,
139 141 self.vfs.join(self.fname))
140 142 def writebundle(self, bases, node):
141 143 cgversion = changegroup.safeversion(self.repo)
142 144 if cgversion == '01':
143 145 btype = 'HG10BZ'
144 146 compression = None
145 147 else:
146 148 btype = 'HG20'
147 149 compression = 'BZ'
148 150
149 151 cg = changegroup.changegroupsubset(self.repo, bases, [node], 'shelve',
150 152 version=cgversion)
151 153 bundle2.writebundle(self.ui, cg, self.fname, btype, self.vfs,
152 154 compression=compression)
153 155
154 156 class shelvedstate(object):
155 157 """Handle persistence during unshelving operations.
156 158
157 159 Handles saving and restoring a shelved state. Ensures that different
158 160 versions of a shelved state are possible and handles them appropriately.
159 161 """
160 162 _version = 1
161 163 _filename = 'shelvedstate'
162 164 _keep = 'keep'
163 165 _nokeep = 'nokeep'
164 166
165 167 @classmethod
166 168 def load(cls, repo):
167 169 fp = repo.vfs(cls._filename)
168 170 try:
169 171 version = int(fp.readline().strip())
170 172
171 173 if version != cls._version:
172 174 raise error.Abort(_('this version of shelve is incompatible '
173 175 'with the version used in this repo'))
174 176 name = fp.readline().strip()
175 177 wctx = nodemod.bin(fp.readline().strip())
176 178 pendingctx = nodemod.bin(fp.readline().strip())
177 179 parents = [nodemod.bin(h) for h in fp.readline().split()]
178 180 stripnodes = [nodemod.bin(h) for h in fp.readline().split()]
179 181 branchtorestore = fp.readline().strip()
180 182 keep = fp.readline().strip() == cls._keep
181 183 except (ValueError, TypeError) as err:
182 184 raise error.CorruptedState(str(err))
183 185 finally:
184 186 fp.close()
185 187
186 188 try:
187 189 obj = cls()
188 190 obj.name = name
189 191 obj.wctx = repo[wctx]
190 192 obj.pendingctx = repo[pendingctx]
191 193 obj.parents = parents
192 194 obj.stripnodes = stripnodes
193 195 obj.branchtorestore = branchtorestore
194 196 obj.keep = keep
195 197 except error.RepoLookupError as err:
196 198 raise error.CorruptedState(str(err))
197 199
198 200 return obj
199 201
200 202 @classmethod
201 203 def save(cls, repo, name, originalwctx, pendingctx, stripnodes,
202 204 branchtorestore, keep=False):
203 205 fp = repo.vfs(cls._filename, 'wb')
204 206 fp.write('%i\n' % cls._version)
205 207 fp.write('%s\n' % name)
206 208 fp.write('%s\n' % nodemod.hex(originalwctx.node()))
207 209 fp.write('%s\n' % nodemod.hex(pendingctx.node()))
208 210 fp.write('%s\n' %
209 211 ' '.join([nodemod.hex(p) for p in repo.dirstate.parents()]))
210 212 fp.write('%s\n' %
211 213 ' '.join([nodemod.hex(n) for n in stripnodes]))
212 214 fp.write('%s\n' % branchtorestore)
213 215 fp.write('%s\n' % (cls._keep if keep else cls._nokeep))
214 216 fp.close()
215 217
216 218 @classmethod
217 219 def clear(cls, repo):
218 220 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
219 221
220 222 def cleanupoldbackups(repo):
221 223 vfs = scmutil.vfs(repo.join(backupdir))
222 224 maxbackups = repo.ui.configint('shelve', 'maxbackups', 10)
223 hgfiles = [f for f in vfs.listdir() if f.endswith('.hg')]
225 hgfiles = [f for f in vfs.listdir()
226 if f.endswith('.' + patchextension)]
224 227 hgfiles = sorted([(vfs.stat(f).st_mtime, f) for f in hgfiles])
225 228 if 0 < maxbackups and maxbackups < len(hgfiles):
226 229 bordermtime = hgfiles[-maxbackups][0]
227 230 else:
228 231 bordermtime = None
229 232 for mtime, f in hgfiles[:len(hgfiles) - maxbackups]:
230 233 if mtime == bordermtime:
231 234 # keep it, because timestamp can't decide exact order of backups
232 235 continue
233 base = f[:-3]
236 base = f[:-(1 + len(patchextension))]
234 237 for ext in shelvefileextensions:
235 238 try:
236 239 vfs.unlink(base + '.' + ext)
237 240 except OSError as err:
238 241 if err.errno != errno.ENOENT:
239 242 raise
240 243
241 244 def _aborttransaction(repo):
242 245 '''Abort current transaction for shelve/unshelve, but keep dirstate
243 246 '''
244 247 tr = repo.currenttransaction()
245 248 repo.dirstate.savebackup(tr, suffix='.shelve')
246 249 tr.abort()
247 250 repo.dirstate.restorebackup(None, suffix='.shelve')
248 251
249 252 def createcmd(ui, repo, pats, opts):
250 253 """subcommand that creates a new shelve"""
251 254 with repo.wlock():
252 255 cmdutil.checkunfinished(repo)
253 256 return _docreatecmd(ui, repo, pats, opts)
254 257
255 258 def getshelvename(repo, parent, opts):
256 259 """Decide on the name this shelve is going to have"""
257 260 def gennames():
258 261 yield label
259 262 for i in xrange(1, 100):
260 263 yield '%s-%02d' % (label, i)
261 264 name = opts.get('name')
262 265 label = repo._activebookmark or parent.branch() or 'default'
263 266 # slashes aren't allowed in filenames, therefore we rename it
264 267 label = label.replace('/', '_')
265 268
266 269 if name:
267 if shelvedfile(repo, name, 'hg').exists():
270 if shelvedfile(repo, name, patchextension).exists():
268 271 e = _("a shelved change named '%s' already exists") % name
269 272 raise error.Abort(e)
270 273 else:
271 274 for n in gennames():
272 if not shelvedfile(repo, n, 'hg').exists():
275 if not shelvedfile(repo, n, patchextension).exists():
273 276 name = n
274 277 break
275 278 else:
276 279 raise error.Abort(_("too many shelved changes named '%s'") % label)
277 280
278 281 # ensure we are not creating a subdirectory or a hidden file
279 282 if '/' in name or '\\' in name:
280 283 raise error.Abort(_('shelved change names may not contain slashes'))
281 284 if name.startswith('.'):
282 285 raise error.Abort(_("shelved change names may not start with '.'"))
283 286 return name
284 287
285 288 def mutableancestors(ctx):
286 289 """return all mutable ancestors for ctx (included)
287 290
288 291 Much faster than the revset ancestors(ctx) & draft()"""
289 292 seen = set([nodemod.nullrev])
290 293 visit = collections.deque()
291 294 visit.append(ctx)
292 295 while visit:
293 296 ctx = visit.popleft()
294 297 yield ctx.node()
295 298 for parent in ctx.parents():
296 299 rev = parent.rev()
297 300 if rev not in seen:
298 301 seen.add(rev)
299 302 if parent.mutable():
300 303 visit.append(parent)
301 304
302 305 def getcommitfunc(extra, interactive, editor=False):
303 306 def commitfunc(ui, repo, message, match, opts):
304 307 hasmq = util.safehasattr(repo, 'mq')
305 308 if hasmq:
306 309 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
307 310 backup = repo.ui.backupconfig('phases', 'new-commit')
308 311 try:
309 312 repo.ui.setconfig('phases', 'new-commit', phases.secret)
310 313 editor_ = False
311 314 if editor:
312 315 editor_ = cmdutil.getcommiteditor(editform='shelve.shelve',
313 316 **opts)
314 317 return repo.commit(message, shelveuser, opts.get('date'), match,
315 318 editor=editor_, extra=extra)
316 319 finally:
317 320 repo.ui.restoreconfig(backup)
318 321 if hasmq:
319 322 repo.mq.checkapplied = saved
320 323
321 324 def interactivecommitfunc(ui, repo, *pats, **opts):
322 325 match = scmutil.match(repo['.'], pats, {})
323 326 message = opts['message']
324 327 return commitfunc(ui, repo, message, match, opts)
325 328
326 329 return interactivecommitfunc if interactive else commitfunc
327 330
328 331 def _nothingtoshelvemessaging(ui, repo, pats, opts):
329 332 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
330 333 if stat.deleted:
331 334 ui.status(_("nothing changed (%d missing files, see "
332 335 "'hg status')\n") % len(stat.deleted))
333 336 else:
334 337 ui.status(_("nothing changed\n"))
335 338
336 339 def _shelvecreatedcommit(repo, node, name):
337 340 bases = list(mutableancestors(repo[node]))
338 341 shelvedfile(repo, name, 'hg').writebundle(bases, node)
339 342 cmdutil.export(repo, [node],
340 fp=shelvedfile(repo, name, 'patch').opener('wb'),
343 fp=shelvedfile(repo, name, patchextension).opener('wb'),
341 344 opts=mdiff.diffopts(git=True))
342 345
343 346 def _includeunknownfiles(repo, pats, opts, extra):
344 347 s = repo.status(match=scmutil.match(repo[None], pats, opts),
345 348 unknown=True)
346 349 if s.unknown:
347 350 extra['shelve_unknown'] = '\0'.join(s.unknown)
348 351 repo[None].add(s.unknown)
349 352
350 353 def _finishshelve(repo):
351 354 _aborttransaction(repo)
352 355
353 356 def _docreatecmd(ui, repo, pats, opts):
354 357 wctx = repo[None]
355 358 parents = wctx.parents()
356 359 if len(parents) > 1:
357 360 raise error.Abort(_('cannot shelve while merging'))
358 361 parent = parents[0]
359 362 origbranch = wctx.branch()
360 363
361 364 if parent.node() != nodemod.nullid:
362 365 desc = "changes to: %s" % parent.description().split('\n', 1)[0]
363 366 else:
364 367 desc = '(changes in empty repository)'
365 368
366 369 if not opts.get('message'):
367 370 opts['message'] = desc
368 371
369 372 lock = tr = None
370 373 try:
371 374 lock = repo.lock()
372 375
373 376 # use an uncommitted transaction to generate the bundle to avoid
374 377 # pull races. ensure we don't print the abort message to stderr.
375 378 tr = repo.transaction('commit', report=lambda x: None)
376 379
377 380 interactive = opts.get('interactive', False)
378 381 includeunknown = (opts.get('unknown', False) and
379 382 not opts.get('addremove', False))
380 383
381 384 name = getshelvename(repo, parent, opts)
382 385 extra = {}
383 386 if includeunknown:
384 387 _includeunknownfiles(repo, pats, opts, extra)
385 388
386 389 if _iswctxonnewbranch(repo) and not _isbareshelve(pats, opts):
387 390 # In non-bare shelve we don't store newly created branch
388 391 # at bundled commit
389 392 repo.dirstate.setbranch(repo['.'].branch())
390 393
391 394 commitfunc = getcommitfunc(extra, interactive, editor=True)
392 395 if not interactive:
393 396 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
394 397 else:
395 398 node = cmdutil.dorecord(ui, repo, commitfunc, None,
396 399 False, cmdutil.recordfilter, *pats, **opts)
397 400 if not node:
398 401 _nothingtoshelvemessaging(ui, repo, pats, opts)
399 402 return 1
400 403
401 404 _shelvecreatedcommit(repo, node, name)
402 405
403 406 if ui.formatted():
404 407 desc = util.ellipsis(desc, ui.termwidth())
405 408 ui.status(_('shelved as %s\n') % name)
406 409 hg.update(repo, parent.node())
407 410 if origbranch != repo['.'].branch() and not _isbareshelve(pats, opts):
408 411 repo.dirstate.setbranch(origbranch)
409 412
410 413 _finishshelve(repo)
411 414 finally:
412 415 lockmod.release(tr, lock)
413 416
414 417 def _isbareshelve(pats, opts):
415 418 return (not pats
416 419 and not opts.get('interactive', False)
417 420 and not opts.get('include', False)
418 421 and not opts.get('exclude', False))
419 422
420 423 def _iswctxonnewbranch(repo):
421 424 return repo[None].branch() != repo['.'].branch()
422 425
423 426 def cleanupcmd(ui, repo):
424 427 """subcommand that deletes all shelves"""
425 428
426 429 with repo.wlock():
427 430 for (name, _type) in repo.vfs.readdir(shelvedir):
428 431 suffix = name.rsplit('.', 1)[-1]
429 432 if suffix in shelvefileextensions:
430 433 shelvedfile(repo, name).movetobackup()
431 434 cleanupoldbackups(repo)
432 435
433 436 def deletecmd(ui, repo, pats):
434 437 """subcommand that deletes a specific shelve"""
435 438 if not pats:
436 439 raise error.Abort(_('no shelved changes specified!'))
437 440 with repo.wlock():
438 441 try:
439 442 for name in pats:
440 443 for suffix in shelvefileextensions:
441 444 shfile = shelvedfile(repo, name, suffix)
442 445 # patch file is necessary, as it should
443 446 # be present for any kind of shelve,
444 447 # but the .hg file is optional as in future we
445 448 # will add obsolete shelve with does not create a
446 449 # bundle
447 if shfile.exists() or suffix == 'patch':
450 if shfile.exists() or suffix == patchextension:
448 451 shfile.movetobackup()
449 452 cleanupoldbackups(repo)
450 453 except OSError as err:
451 454 if err.errno != errno.ENOENT:
452 455 raise
453 456 raise error.Abort(_("shelved change '%s' not found") % name)
454 457
455 458 def listshelves(repo):
456 459 """return all shelves in repo as list of (time, filename)"""
457 460 try:
458 461 names = repo.vfs.readdir(shelvedir)
459 462 except OSError as err:
460 463 if err.errno != errno.ENOENT:
461 464 raise
462 465 return []
463 466 info = []
464 467 for (name, _type) in names:
465 468 pfx, sfx = name.rsplit('.', 1)
466 if not pfx or sfx != 'patch':
469 if not pfx or sfx != patchextension:
467 470 continue
468 471 st = shelvedfile(repo, name).stat()
469 472 info.append((st.st_mtime, shelvedfile(repo, pfx).filename()))
470 473 return sorted(info, reverse=True)
471 474
472 475 def listcmd(ui, repo, pats, opts):
473 476 """subcommand that displays the list of shelves"""
474 477 pats = set(pats)
475 478 width = 80
476 479 if not ui.plain():
477 480 width = ui.termwidth()
478 481 namelabel = 'shelve.newest'
479 482 for mtime, name in listshelves(repo):
480 483 sname = util.split(name)[1]
481 484 if pats and sname not in pats:
482 485 continue
483 486 ui.write(sname, label=namelabel)
484 487 namelabel = 'shelve.name'
485 488 if ui.quiet:
486 489 ui.write('\n')
487 490 continue
488 491 ui.write(' ' * (16 - len(sname)))
489 492 used = 16
490 493 age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True)
491 494 ui.write(age, label='shelve.age')
492 495 ui.write(' ' * (12 - len(age)))
493 496 used += 12
494 with open(name + '.patch', 'rb') as fp:
497 with open(name + '.' + patchextension, 'rb') as fp:
495 498 while True:
496 499 line = fp.readline()
497 500 if not line:
498 501 break
499 502 if not line.startswith('#'):
500 503 desc = line.rstrip()
501 504 if ui.formatted():
502 505 desc = util.ellipsis(desc, width - used)
503 506 ui.write(desc)
504 507 break
505 508 ui.write('\n')
506 509 if not (opts['patch'] or opts['stat']):
507 510 continue
508 511 difflines = fp.readlines()
509 512 if opts['patch']:
510 513 for chunk, label in patch.difflabel(iter, difflines):
511 514 ui.write(chunk, label=label)
512 515 if opts['stat']:
513 516 for chunk, label in patch.diffstatui(difflines, width=width):
514 517 ui.write(chunk, label=label)
515 518
516 519 def singlepatchcmds(ui, repo, pats, opts, subcommand):
517 520 """subcommand that displays a single shelf"""
518 521 if len(pats) != 1:
519 522 raise error.Abort(_("--%s expects a single shelf") % subcommand)
520 523 shelfname = pats[0]
521 524
522 if not shelvedfile(repo, shelfname, 'patch').exists():
525 if not shelvedfile(repo, shelfname, patchextension).exists():
523 526 raise error.Abort(_("cannot find shelf %s") % shelfname)
524 527
525 528 listcmd(ui, repo, pats, opts)
526 529
527 530 def checkparents(repo, state):
528 531 """check parent while resuming an unshelve"""
529 532 if state.parents != repo.dirstate.parents():
530 533 raise error.Abort(_('working directory parents do not match unshelve '
531 534 'state'))
532 535
533 536 def pathtofiles(repo, files):
534 537 cwd = repo.getcwd()
535 538 return [repo.pathto(f, cwd) for f in files]
536 539
537 540 def unshelveabort(ui, repo, state, opts):
538 541 """subcommand that abort an in-progress unshelve"""
539 542 with repo.lock():
540 543 try:
541 544 checkparents(repo, state)
542 545
543 546 util.rename(repo.join('unshelverebasestate'),
544 547 repo.join('rebasestate'))
545 548 try:
546 549 rebase.rebase(ui, repo, **{
547 550 'abort' : True
548 551 })
549 552 except Exception:
550 553 util.rename(repo.join('rebasestate'),
551 554 repo.join('unshelverebasestate'))
552 555 raise
553 556
554 557 mergefiles(ui, repo, state.wctx, state.pendingctx)
555 558 repair.strip(ui, repo, state.stripnodes, backup=False,
556 559 topic='shelve')
557 560 finally:
558 561 shelvedstate.clear(repo)
559 562 ui.warn(_("unshelve of '%s' aborted\n") % state.name)
560 563
561 564 def mergefiles(ui, repo, wctx, shelvectx):
562 565 """updates to wctx and merges the changes from shelvectx into the
563 566 dirstate."""
564 567 oldquiet = ui.quiet
565 568 try:
566 569 ui.quiet = True
567 570 hg.update(repo, wctx.node())
568 571 files = []
569 572 files.extend(shelvectx.files())
570 573 files.extend(shelvectx.parents()[0].files())
571 574
572 575 # revert will overwrite unknown files, so move them out of the way
573 576 for file in repo.status(unknown=True).unknown:
574 577 if file in files:
575 578 util.rename(file, scmutil.origpath(ui, repo, file))
576 579 ui.pushbuffer(True)
577 580 cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
578 581 *pathtofiles(repo, files),
579 582 **{'no_backup': True})
580 583 ui.popbuffer()
581 584 finally:
582 585 ui.quiet = oldquiet
583 586
584 587 def restorebranch(ui, repo, branchtorestore):
585 588 if branchtorestore and branchtorestore != repo.dirstate.branch():
586 589 repo.dirstate.setbranch(branchtorestore)
587 590 ui.status(_('marked working directory as branch %s\n')
588 591 % branchtorestore)
589 592
590 593 def unshelvecleanup(ui, repo, name, opts):
591 594 """remove related files after an unshelve"""
592 595 if not opts.get('keep'):
593 596 for filetype in shelvefileextensions:
594 597 shfile = shelvedfile(repo, name, filetype)
595 598 if shfile.exists():
596 599 shfile.movetobackup()
597 600 cleanupoldbackups(repo)
598 601
599 602 def unshelvecontinue(ui, repo, state, opts):
600 603 """subcommand to continue an in-progress unshelve"""
601 604 # We're finishing off a merge. First parent is our original
602 605 # parent, second is the temporary "fake" commit we're unshelving.
603 606 with repo.lock():
604 607 checkparents(repo, state)
605 608 ms = merge.mergestate.read(repo)
606 609 if [f for f in ms if ms[f] == 'u']:
607 610 raise error.Abort(
608 611 _("unresolved conflicts, can't continue"),
609 612 hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
610 613
611 614 util.rename(repo.join('unshelverebasestate'),
612 615 repo.join('rebasestate'))
613 616 try:
614 617 rebase.rebase(ui, repo, **{
615 618 'continue' : True
616 619 })
617 620 except Exception:
618 621 util.rename(repo.join('rebasestate'),
619 622 repo.join('unshelverebasestate'))
620 623 raise
621 624
622 625 shelvectx = repo['tip']
623 626 if not shelvectx in state.pendingctx.children():
624 627 # rebase was a no-op, so it produced no child commit
625 628 shelvectx = state.pendingctx
626 629 else:
627 630 # only strip the shelvectx if the rebase produced it
628 631 state.stripnodes.append(shelvectx.node())
629 632
630 633 mergefiles(ui, repo, state.wctx, shelvectx)
631 634 restorebranch(ui, repo, state.branchtorestore)
632 635
633 636 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
634 637 shelvedstate.clear(repo)
635 638 unshelvecleanup(ui, repo, state.name, opts)
636 639 ui.status(_("unshelve of '%s' complete\n") % state.name)
637 640
638 641 def _commitworkingcopychanges(ui, repo, opts, tmpwctx):
639 642 """Temporarily commit working copy changes before moving unshelve commit"""
640 643 # Store pending changes in a commit and remember added in case a shelve
641 644 # contains unknown files that are part of the pending change
642 645 s = repo.status()
643 646 addedbefore = frozenset(s.added)
644 647 if not (s.modified or s.added or s.removed or s.deleted):
645 648 return tmpwctx, addedbefore
646 649 ui.status(_("temporarily committing pending changes "
647 650 "(restore with 'hg unshelve --abort')\n"))
648 651 commitfunc = getcommitfunc(extra=None, interactive=False,
649 652 editor=False)
650 653 tempopts = {}
651 654 tempopts['message'] = "pending changes temporary commit"
652 655 tempopts['date'] = opts.get('date')
653 656 ui.quiet = True
654 657 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
655 658 tmpwctx = repo[node]
656 659 return tmpwctx, addedbefore
657 660
658 661 def _unshelverestorecommit(ui, repo, basename, oldquiet):
659 662 """Recreate commit in the repository during the unshelve"""
660 663 ui.quiet = True
661 664 shelvedfile(repo, basename, 'hg').applybundle()
662 665 shelvectx = repo['tip']
663 666 ui.quiet = oldquiet
664 667 return repo, shelvectx
665 668
666 669 def _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev, basename, pctx,
667 670 tmpwctx, shelvectx, branchtorestore):
668 671 """Rebase restored commit from its original location to a destination"""
669 672 # If the shelve is not immediately on top of the commit
670 673 # we'll be merging with, rebase it to be on top.
671 674 if tmpwctx.node() == shelvectx.parents()[0].node():
672 675 return shelvectx
673 676
674 677 ui.status(_('rebasing shelved changes\n'))
675 678 try:
676 679 rebase.rebase(ui, repo, **{
677 680 'rev': [shelvectx.rev()],
678 681 'dest': str(tmpwctx.rev()),
679 682 'keep': True,
680 683 'tool': opts.get('tool', ''),
681 684 })
682 685 except error.InterventionRequired:
683 686 tr.close()
684 687
685 688 stripnodes = [repo.changelog.node(rev)
686 689 for rev in xrange(oldtiprev, len(repo))]
687 690 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes,
688 691 branchtorestore, opts.get('keep'))
689 692
690 693 util.rename(repo.join('rebasestate'),
691 694 repo.join('unshelverebasestate'))
692 695 raise error.InterventionRequired(
693 696 _("unresolved conflicts (see 'hg resolve', then "
694 697 "'hg unshelve --continue')"))
695 698
696 699 # refresh ctx after rebase completes
697 700 shelvectx = repo['tip']
698 701
699 702 if not shelvectx in tmpwctx.children():
700 703 # rebase was a no-op, so it produced no child commit
701 704 shelvectx = tmpwctx
702 705 return shelvectx
703 706
704 707 def _forgetunknownfiles(repo, shelvectx, addedbefore):
705 708 # Forget any files that were unknown before the shelve, unknown before
706 709 # unshelve started, but are now added.
707 710 shelveunknown = shelvectx.extra().get('shelve_unknown')
708 711 if not shelveunknown:
709 712 return
710 713 shelveunknown = frozenset(shelveunknown.split('\0'))
711 714 addedafter = frozenset(repo.status().added)
712 715 toforget = (addedafter & shelveunknown) - addedbefore
713 716 repo[None].forget(toforget)
714 717
715 718 def _finishunshelve(repo, oldtiprev, tr):
716 719 # The transaction aborting will strip all the commits for us,
717 720 # but it doesn't update the inmemory structures, so addchangegroup
718 721 # hooks still fire and try to operate on the missing commits.
719 722 # Clean up manually to prevent this.
720 723 repo.unfiltered().changelog.strip(oldtiprev, tr)
721 724 _aborttransaction(repo)
722 725
723 726 @command('unshelve',
724 727 [('a', 'abort', None,
725 728 _('abort an incomplete unshelve operation')),
726 729 ('c', 'continue', None,
727 730 _('continue an incomplete unshelve operation')),
728 731 ('k', 'keep', None,
729 732 _('keep shelve after unshelving')),
730 733 ('t', 'tool', '', _('specify merge tool')),
731 734 ('', 'date', '',
732 735 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
733 736 _('hg unshelve [SHELVED]'))
734 737 def unshelve(ui, repo, *shelved, **opts):
735 738 """restore a shelved change to the working directory
736 739
737 740 This command accepts an optional name of a shelved change to
738 741 restore. If none is given, the most recent shelved change is used.
739 742
740 743 If a shelved change is applied successfully, the bundle that
741 744 contains the shelved changes is moved to a backup location
742 745 (.hg/shelve-backup).
743 746
744 747 Since you can restore a shelved change on top of an arbitrary
745 748 commit, it is possible that unshelving will result in a conflict
746 749 between your changes and the commits you are unshelving onto. If
747 750 this occurs, you must resolve the conflict, then use
748 751 ``--continue`` to complete the unshelve operation. (The bundle
749 752 will not be moved until you successfully complete the unshelve.)
750 753
751 754 (Alternatively, you can use ``--abort`` to abandon an unshelve
752 755 that causes a conflict. This reverts the unshelved changes, and
753 756 leaves the bundle in place.)
754 757
755 758 If bare shelved change(when no files are specified, without interactive,
756 759 include and exclude option) was done on newly created branch it would
757 760 restore branch information to the working directory.
758 761
759 762 After a successful unshelve, the shelved changes are stored in a
760 763 backup directory. Only the N most recent backups are kept. N
761 764 defaults to 10 but can be overridden using the ``shelve.maxbackups``
762 765 configuration option.
763 766
764 767 .. container:: verbose
765 768
766 769 Timestamp in seconds is used to decide order of backups. More
767 770 than ``maxbackups`` backups are kept, if same timestamp
768 771 prevents from deciding exact order of them, for safety.
769 772 """
770 773 with repo.wlock():
771 774 return _dounshelve(ui, repo, *shelved, **opts)
772 775
773 776 def _dounshelve(ui, repo, *shelved, **opts):
774 777 abortf = opts.get('abort')
775 778 continuef = opts.get('continue')
776 779 if not abortf and not continuef:
777 780 cmdutil.checkunfinished(repo)
778 781
779 782 if abortf or continuef:
780 783 if abortf and continuef:
781 784 raise error.Abort(_('cannot use both abort and continue'))
782 785 if shelved:
783 786 raise error.Abort(_('cannot combine abort/continue with '
784 787 'naming a shelved change'))
785 788 if abortf and opts.get('tool', False):
786 789 ui.warn(_('tool option will be ignored\n'))
787 790
788 791 try:
789 792 state = shelvedstate.load(repo)
790 793 if opts.get('keep') is None:
791 794 opts['keep'] = state.keep
792 795 except IOError as err:
793 796 if err.errno != errno.ENOENT:
794 797 raise
795 798 cmdutil.wrongtooltocontinue(repo, _('unshelve'))
796 799 except error.CorruptedState as err:
797 800 ui.debug(str(err) + '\n')
798 801 if continuef:
799 802 msg = _('corrupted shelved state file')
800 803 hint = _('please run hg unshelve --abort to abort unshelve '
801 804 'operation')
802 805 raise error.Abort(msg, hint=hint)
803 806 elif abortf:
804 807 msg = _('could not read shelved state file, your working copy '
805 808 'may be in an unexpected state\nplease update to some '
806 809 'commit\n')
807 810 ui.warn(msg)
808 811 shelvedstate.clear(repo)
809 812 return
810 813
811 814 if abortf:
812 815 return unshelveabort(ui, repo, state, opts)
813 816 elif continuef:
814 817 return unshelvecontinue(ui, repo, state, opts)
815 818 elif len(shelved) > 1:
816 819 raise error.Abort(_('can only unshelve one change at a time'))
817 820 elif not shelved:
818 821 shelved = listshelves(repo)
819 822 if not shelved:
820 823 raise error.Abort(_('no shelved changes to apply!'))
821 824 basename = util.split(shelved[0][1])[1]
822 825 ui.status(_("unshelving change '%s'\n") % basename)
823 826 else:
824 827 basename = shelved[0]
825 828
826 if not shelvedfile(repo, basename, 'patch').exists():
829 if not shelvedfile(repo, basename, patchextension).exists():
827 830 raise error.Abort(_("shelved change '%s' not found") % basename)
828 831
829 832 oldquiet = ui.quiet
830 833 lock = tr = None
831 834 forcemerge = ui.backupconfig('ui', 'forcemerge')
832 835 try:
833 836 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'unshelve')
834 837 lock = repo.lock()
835 838
836 839 tr = repo.transaction('unshelve', report=lambda x: None)
837 840 oldtiprev = len(repo)
838 841
839 842 pctx = repo['.']
840 843 tmpwctx = pctx
841 844 # The goal is to have a commit structure like so:
842 845 # ...-> pctx -> tmpwctx -> shelvectx
843 846 # where tmpwctx is an optional commit with the user's pending changes
844 847 # and shelvectx is the unshelved changes. Then we merge it all down
845 848 # to the original pctx.
846 849
847 850 tmpwctx, addedbefore = _commitworkingcopychanges(ui, repo, opts,
848 851 tmpwctx)
849 852
850 853 repo, shelvectx = _unshelverestorecommit(ui, repo, basename, oldquiet)
851 854
852 855 branchtorestore = ''
853 856 if shelvectx.branch() != shelvectx.p1().branch():
854 857 branchtorestore = shelvectx.branch()
855 858
856 859 shelvectx = _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev,
857 860 basename, pctx, tmpwctx, shelvectx,
858 861 branchtorestore)
859 862 mergefiles(ui, repo, pctx, shelvectx)
860 863 restorebranch(ui, repo, branchtorestore)
861 864 _forgetunknownfiles(repo, shelvectx, addedbefore)
862 865
863 866 shelvedstate.clear(repo)
864 867 _finishunshelve(repo, oldtiprev, tr)
865 868 unshelvecleanup(ui, repo, basename, opts)
866 869 finally:
867 870 ui.quiet = oldquiet
868 871 if tr:
869 872 tr.release()
870 873 lockmod.release(lock)
871 874 ui.restoreconfig(forcemerge)
872 875
873 876 @command('shelve',
874 877 [('A', 'addremove', None,
875 878 _('mark new/missing files as added/removed before shelving')),
876 879 ('u', 'unknown', None,
877 880 _('store unknown files in the shelve')),
878 881 ('', 'cleanup', None,
879 882 _('delete all shelved changes')),
880 883 ('', 'date', '',
881 884 _('shelve with the specified commit date'), _('DATE')),
882 885 ('d', 'delete', None,
883 886 _('delete the named shelved change(s)')),
884 887 ('e', 'edit', False,
885 888 _('invoke editor on commit messages')),
886 889 ('l', 'list', None,
887 890 _('list current shelves')),
888 891 ('m', 'message', '',
889 892 _('use text as shelve message'), _('TEXT')),
890 893 ('n', 'name', '',
891 894 _('use the given name for the shelved commit'), _('NAME')),
892 895 ('p', 'patch', None,
893 896 _('show patch')),
894 897 ('i', 'interactive', None,
895 898 _('interactive mode, only works while creating a shelve')),
896 899 ('', 'stat', None,
897 900 _('output diffstat-style summary of changes'))] + commands.walkopts,
898 901 _('hg shelve [OPTION]... [FILE]...'))
899 902 def shelvecmd(ui, repo, *pats, **opts):
900 903 '''save and set aside changes from the working directory
901 904
902 905 Shelving takes files that "hg status" reports as not clean, saves
903 906 the modifications to a bundle (a shelved change), and reverts the
904 907 files so that their state in the working directory becomes clean.
905 908
906 909 To restore these changes to the working directory, using "hg
907 910 unshelve"; this will work even if you switch to a different
908 911 commit.
909 912
910 913 When no files are specified, "hg shelve" saves all not-clean
911 914 files. If specific files or directories are named, only changes to
912 915 those files are shelved.
913 916
914 917 In bare shelve (when no files are specified, without interactive,
915 918 include and exclude option), shelving remembers information if the
916 919 working directory was on newly created branch, in other words working
917 920 directory was on different branch than its first parent. In this
918 921 situation unshelving restores branch information to the working directory.
919 922
920 923 Each shelved change has a name that makes it easier to find later.
921 924 The name of a shelved change defaults to being based on the active
922 925 bookmark, or if there is no active bookmark, the current named
923 926 branch. To specify a different name, use ``--name``.
924 927
925 928 To see a list of existing shelved changes, use the ``--list``
926 929 option. For each shelved change, this will print its name, age,
927 930 and description; use ``--patch`` or ``--stat`` for more details.
928 931
929 932 To delete specific shelved changes, use ``--delete``. To delete
930 933 all shelved changes, use ``--cleanup``.
931 934 '''
932 935 allowables = [
933 936 ('addremove', set(['create'])), # 'create' is pseudo action
934 937 ('unknown', set(['create'])),
935 938 ('cleanup', set(['cleanup'])),
936 939 # ('date', set(['create'])), # ignored for passing '--date "0 0"' in tests
937 940 ('delete', set(['delete'])),
938 941 ('edit', set(['create'])),
939 942 ('list', set(['list'])),
940 943 ('message', set(['create'])),
941 944 ('name', set(['create'])),
942 945 ('patch', set(['patch', 'list'])),
943 946 ('stat', set(['stat', 'list'])),
944 947 ]
945 948 def checkopt(opt):
946 949 if opts.get(opt):
947 950 for i, allowable in allowables:
948 951 if opts[i] and opt not in allowable:
949 952 raise error.Abort(_("options '--%s' and '--%s' may not be "
950 953 "used together") % (opt, i))
951 954 return True
952 955 if checkopt('cleanup'):
953 956 if pats:
954 957 raise error.Abort(_("cannot specify names when using '--cleanup'"))
955 958 return cleanupcmd(ui, repo)
956 959 elif checkopt('delete'):
957 960 return deletecmd(ui, repo, pats)
958 961 elif checkopt('list'):
959 962 return listcmd(ui, repo, pats, opts)
960 963 elif checkopt('patch'):
961 964 return singlepatchcmds(ui, repo, pats, opts, subcommand='patch')
962 965 elif checkopt('stat'):
963 966 return singlepatchcmds(ui, repo, pats, opts, subcommand='stat')
964 967 else:
965 968 return createcmd(ui, repo, pats, opts)
966 969
967 970 def extsetup(ui):
968 971 cmdutil.unfinishedstates.append(
969 972 [shelvedstate._filename, False, False,
970 973 _('unshelve already in progress'),
971 974 _("use 'hg unshelve --continue' or 'hg unshelve --abort'")])
972 975 cmdutil.afterresolvedstates.append(
973 976 [shelvedstate._filename, _('hg unshelve --continue')])
@@ -1,1657 +1,1657
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 $ f -t .hg/shelve-backup/default.hg
199 .hg/shelve-backup/default.hg: file
200 $ touch -t 200001010000 .hg/shelve-backup/default.hg
201 $ f -t .hg/shelve-backup/default-1.hg
202 .hg/shelve-backup/default-1.hg: file
203 $ touch -t 200001010000 .hg/shelve-backup/default-1.hg
198 $ f -t .hg/shelve-backup/default.patch
199 .hg/shelve-backup/default.patch: file
200 $ touch -t 200001010000 .hg/shelve-backup/default.patch
201 $ f -t .hg/shelve-backup/default-1.patch
202 .hg/shelve-backup/default-1.patch: file
203 $ touch -t 200001010000 .hg/shelve-backup/default-1.patch
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 $ cd ..
1387 1387
1388 1388 When i shelve commit on newly created branch i expect
1389 1389 that after unshelve newly created branch will be preserved.
1390 1390
1391 1391 $ hg init shelve_on_new_branch_simple
1392 1392 $ cd shelve_on_new_branch_simple
1393 1393 $ echo "aaa" >> a
1394 1394 $ hg commit -A -m "a"
1395 1395 adding a
1396 1396 $ hg branch
1397 1397 default
1398 1398 $ hg branch test
1399 1399 marked working directory as branch test
1400 1400 (branches are permanent and global, did you want a bookmark?)
1401 1401 $ echo "bbb" >> a
1402 1402 $ hg status
1403 1403 M a
1404 1404 $ hg shelve
1405 1405 shelved as default
1406 1406 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1407 1407 $ hg branch
1408 1408 default
1409 1409 $ echo "bbb" >> b
1410 1410 $ hg status
1411 1411 ? b
1412 1412 $ hg unshelve
1413 1413 unshelving change 'default'
1414 1414 marked working directory as branch test
1415 1415 $ hg status
1416 1416 M a
1417 1417 ? b
1418 1418 $ hg branch
1419 1419 test
1420 1420 $ cd ..
1421 1421
1422 1422 When i shelve commit on newly created branch, make
1423 1423 some changes, unshelve it and running into merge
1424 1424 conflicts i expect that after fixing them and
1425 1425 running unshelve --continue newly created branch
1426 1426 will be preserved.
1427 1427
1428 1428 $ hg init shelve_on_new_branch_conflict
1429 1429 $ cd shelve_on_new_branch_conflict
1430 1430 $ echo "aaa" >> a
1431 1431 $ hg commit -A -m "a"
1432 1432 adding a
1433 1433 $ hg branch
1434 1434 default
1435 1435 $ hg branch test
1436 1436 marked working directory as branch test
1437 1437 (branches are permanent and global, did you want a bookmark?)
1438 1438 $ echo "bbb" >> a
1439 1439 $ hg status
1440 1440 M a
1441 1441 $ hg shelve
1442 1442 shelved as default
1443 1443 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1444 1444 $ hg branch
1445 1445 default
1446 1446 $ echo "ccc" >> a
1447 1447 $ hg status
1448 1448 M a
1449 1449 $ hg unshelve
1450 1450 unshelving change 'default'
1451 1451 temporarily committing pending changes (restore with 'hg unshelve --abort')
1452 1452 rebasing shelved changes
1453 1453 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1454 1454 merging a
1455 1455 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1456 1456 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1457 1457 [1]
1458 1458 $ echo "aaabbbccc" > a
1459 1459 $ rm a.orig
1460 1460 $ hg resolve --mark a
1461 1461 (no more unresolved files)
1462 1462 continue: hg unshelve --continue
1463 1463 $ hg unshelve --continue
1464 1464 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1465 1465 marked working directory as branch test
1466 1466 unshelve of 'default' complete
1467 1467 $ cat a
1468 1468 aaabbbccc
1469 1469 $ hg status
1470 1470 M a
1471 1471 $ hg branch
1472 1472 test
1473 1473 $ hg commit -m "test-commit"
1474 1474
1475 1475 When i shelve on test branch, update to default branch
1476 1476 and unshelve i expect that it will not preserve previous
1477 1477 test branch.
1478 1478
1479 1479 $ echo "xxx" > b
1480 1480 $ hg add b
1481 1481 $ hg shelve
1482 1482 shelved as test
1483 1483 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1484 1484 $ hg update -r default
1485 1485 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1486 1486 $ hg unshelve
1487 1487 unshelving change 'test'
1488 1488 rebasing shelved changes
1489 1489 rebasing 2:357525f34729 "changes to: test-commit" (tip)
1490 1490 $ hg status
1491 1491 A b
1492 1492 $ hg branch
1493 1493 default
1494 1494 $ cd ..
1495 1495
1496 1496 When i unshelve resulting in merge conflicts and makes saved
1497 1497 file shelvedstate looks like in previous versions in
1498 1498 mercurial(without restore branch information in 7th line) i
1499 1499 expect that after resolving conflicts and successfully
1500 1500 running 'shelve --continue' the branch information won't be
1501 1501 restored and branch will be unchanged.
1502 1502
1503 1503 shelve on new branch, conflict with previous shelvedstate
1504 1504
1505 1505 $ hg init conflict
1506 1506 $ cd conflict
1507 1507 $ echo "aaa" >> a
1508 1508 $ hg commit -A -m "a"
1509 1509 adding a
1510 1510 $ hg branch
1511 1511 default
1512 1512 $ hg branch test
1513 1513 marked working directory as branch test
1514 1514 (branches are permanent and global, did you want a bookmark?)
1515 1515 $ echo "bbb" >> a
1516 1516 $ hg status
1517 1517 M a
1518 1518 $ hg shelve
1519 1519 shelved as default
1520 1520 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1521 1521 $ hg branch
1522 1522 default
1523 1523 $ echo "ccc" >> a
1524 1524 $ hg status
1525 1525 M a
1526 1526 $ hg unshelve
1527 1527 unshelving change 'default'
1528 1528 temporarily committing pending changes (restore with 'hg unshelve --abort')
1529 1529 rebasing shelved changes
1530 1530 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1531 1531 merging a
1532 1532 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1533 1533 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1534 1534 [1]
1535 1535
1536 1536 Removing restore branch information from shelvedstate file(making it looks like
1537 1537 in previous versions) and running unshelve --continue
1538 1538
1539 1539 $ head -n 6 < .hg/shelvedstate > .hg/shelvedstate_oldformat
1540 1540 $ rm .hg/shelvedstate
1541 1541 $ mv .hg/shelvedstate_oldformat .hg/shelvedstate
1542 1542
1543 1543 $ echo "aaabbbccc" > a
1544 1544 $ rm a.orig
1545 1545 $ hg resolve --mark a
1546 1546 (no more unresolved files)
1547 1547 continue: hg unshelve --continue
1548 1548 $ hg unshelve --continue
1549 1549 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1550 1550 unshelve of 'default' complete
1551 1551 $ cat a
1552 1552 aaabbbccc
1553 1553 $ hg status
1554 1554 M a
1555 1555 $ hg branch
1556 1556 default
1557 1557 $ cd ..
1558 1558
1559 1559 On non bare shelve the branch information shouldn't be restored
1560 1560
1561 1561 $ hg init bare_shelve_on_new_branch
1562 1562 $ cd bare_shelve_on_new_branch
1563 1563 $ echo "aaa" >> a
1564 1564 $ hg commit -A -m "a"
1565 1565 adding a
1566 1566 $ hg branch
1567 1567 default
1568 1568 $ hg branch test
1569 1569 marked working directory as branch test
1570 1570 (branches are permanent and global, did you want a bookmark?)
1571 1571 $ echo "bbb" >> a
1572 1572 $ hg status
1573 1573 M a
1574 1574 $ hg shelve a
1575 1575 shelved as default
1576 1576 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1577 1577 $ hg branch
1578 1578 test
1579 1579 $ hg branch default
1580 1580 marked working directory as branch default
1581 1581 (branches are permanent and global, did you want a bookmark?)
1582 1582 $ echo "bbb" >> b
1583 1583 $ hg status
1584 1584 ? b
1585 1585 $ hg unshelve
1586 1586 unshelving change 'default'
1587 1587 $ hg status
1588 1588 M a
1589 1589 ? b
1590 1590 $ hg branch
1591 1591 default
1592 1592 $ cd ..
1593 1593
1594 1594 Prepare unshelve with a corrupted shelvedstate
1595 1595 $ hg init r1 && cd r1
1596 1596 $ echo text1 > file && hg add file
1597 1597 $ hg shelve
1598 1598 shelved as default
1599 1599 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1600 1600 $ echo text2 > file && hg ci -Am text1
1601 1601 adding file
1602 1602 $ hg unshelve
1603 1603 unshelving change 'default'
1604 1604 rebasing shelved changes
1605 1605 rebasing 1:396ea74229f9 "(changes in empty repository)" (tip)
1606 1606 merging file
1607 1607 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1608 1608 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1609 1609 [1]
1610 1610 $ echo somethingsomething > .hg/shelvedstate
1611 1611
1612 1612 Unshelve --continue fails with appropriate message if shelvedstate is corrupted
1613 1613 $ hg unshelve --continue
1614 1614 abort: corrupted shelved state file
1615 1615 (please run hg unshelve --abort to abort unshelve operation)
1616 1616 [255]
1617 1617
1618 1618 Unshelve --abort works with a corrupted shelvedstate
1619 1619 $ hg unshelve --abort
1620 1620 could not read shelved state file, your working copy may be in an unexpected state
1621 1621 please update to some commit
1622 1622
1623 1623 Unshelve --abort fails with appropriate message if there's no unshelve in
1624 1624 progress
1625 1625 $ hg unshelve --abort
1626 1626 abort: no unshelve in progress
1627 1627 [255]
1628 1628 $ cd ..
1629 1629
1630 1630 Unshelve respects --keep even if user intervention is needed
1631 1631 $ hg init unshelvekeep && cd unshelvekeep
1632 1632 $ echo 1 > file && hg ci -Am 1
1633 1633 adding file
1634 1634 $ echo 2 >> file
1635 1635 $ hg shelve
1636 1636 shelved as default
1637 1637 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1638 1638 $ echo 3 >> file && hg ci -Am 13
1639 1639 $ hg shelve --list
1640 1640 default (1s ago) changes to: 1
1641 1641 $ hg unshelve --keep
1642 1642 unshelving change 'default'
1643 1643 rebasing shelved changes
1644 1644 rebasing 2:3fbe6fbb0bef "changes to: 1" (tip)
1645 1645 merging file
1646 1646 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1647 1647 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1648 1648 [1]
1649 1649 $ hg resolve --mark file
1650 1650 (no more unresolved files)
1651 1651 continue: hg unshelve --continue
1652 1652 $ hg unshelve --continue
1653 1653 rebasing 2:3fbe6fbb0bef "changes to: 1" (tip)
1654 1654 unshelve of 'default' complete
1655 1655 $ hg shelve --list
1656 1656 default (*s ago) changes to: 1 (glob)
1657 1657 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now