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