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