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