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