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