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