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