##// END OF EJS Templates
shelve: lowercase flag description...
timeless -
r27921:158bdc89 3.7-rc stable
parent child Browse files
Show More
@@ -1,859 +1,859 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
23
24 import collections
24 import collections
25 import itertools
25 import itertools
26 from mercurial.i18n import _
26 from mercurial.i18n import _
27 from mercurial.node import nullid, nullrev, bin, hex
27 from mercurial.node import nullid, nullrev, bin, hex
28 from mercurial import changegroup, cmdutil, scmutil, phases, commands
28 from mercurial import changegroup, cmdutil, scmutil, phases, commands
29 from mercurial import error, hg, mdiff, merge, patch, repair, util
29 from mercurial import error, hg, mdiff, merge, patch, repair, util
30 from mercurial import templatefilters, exchange, bundlerepo, bundle2
30 from mercurial import templatefilters, exchange, bundlerepo, bundle2
31 from mercurial import lock as lockmod
31 from mercurial import lock as lockmod
32 from hgext import rebase
32 from hgext import rebase
33 import errno
33 import errno
34
34
35 cmdtable = {}
35 cmdtable = {}
36 command = cmdutil.command(cmdtable)
36 command = cmdutil.command(cmdtable)
37 # Note for extension authors: ONLY specify testedwith = 'internal' for
37 # Note for extension authors: ONLY specify testedwith = 'internal' for
38 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
38 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
39 # be specifying the version(s) of Mercurial they are tested with, or
39 # be specifying the version(s) of Mercurial they are tested with, or
40 # leave the attribute unspecified.
40 # leave the attribute unspecified.
41 testedwith = 'internal'
41 testedwith = 'internal'
42
42
43 backupdir = 'shelve-backup'
43 backupdir = 'shelve-backup'
44
44
45 class shelvedfile(object):
45 class shelvedfile(object):
46 """Helper for the file storing a single shelve
46 """Helper for the file storing a single shelve
47
47
48 Handles common functions on shelve files (.hg/.patch) using
48 Handles common functions on shelve files (.hg/.patch) using
49 the vfs layer"""
49 the vfs layer"""
50 def __init__(self, repo, name, filetype=None):
50 def __init__(self, repo, name, filetype=None):
51 self.repo = repo
51 self.repo = repo
52 self.name = name
52 self.name = name
53 self.vfs = scmutil.vfs(repo.join('shelved'))
53 self.vfs = scmutil.vfs(repo.join('shelved'))
54 self.backupvfs = scmutil.vfs(repo.join(backupdir))
54 self.backupvfs = scmutil.vfs(repo.join(backupdir))
55 self.ui = self.repo.ui
55 self.ui = self.repo.ui
56 if filetype:
56 if filetype:
57 self.fname = name + '.' + filetype
57 self.fname = name + '.' + filetype
58 else:
58 else:
59 self.fname = name
59 self.fname = name
60
60
61 def exists(self):
61 def exists(self):
62 return self.vfs.exists(self.fname)
62 return self.vfs.exists(self.fname)
63
63
64 def filename(self):
64 def filename(self):
65 return self.vfs.join(self.fname)
65 return self.vfs.join(self.fname)
66
66
67 def backupfilename(self):
67 def backupfilename(self):
68 def gennames(base):
68 def gennames(base):
69 yield base
69 yield base
70 base, ext = base.rsplit('.', 1)
70 base, ext = base.rsplit('.', 1)
71 for i in itertools.count(1):
71 for i in itertools.count(1):
72 yield '%s-%d.%s' % (base, i, ext)
72 yield '%s-%d.%s' % (base, i, ext)
73
73
74 name = self.backupvfs.join(self.fname)
74 name = self.backupvfs.join(self.fname)
75 for n in gennames(name):
75 for n in gennames(name):
76 if not self.backupvfs.exists(n):
76 if not self.backupvfs.exists(n):
77 return n
77 return n
78
78
79 def movetobackup(self):
79 def movetobackup(self):
80 if not self.backupvfs.isdir():
80 if not self.backupvfs.isdir():
81 self.backupvfs.makedir()
81 self.backupvfs.makedir()
82 util.rename(self.filename(), self.backupfilename())
82 util.rename(self.filename(), self.backupfilename())
83
83
84 def stat(self):
84 def stat(self):
85 return self.vfs.stat(self.fname)
85 return self.vfs.stat(self.fname)
86
86
87 def opener(self, mode='rb'):
87 def opener(self, mode='rb'):
88 try:
88 try:
89 return self.vfs(self.fname, mode)
89 return self.vfs(self.fname, mode)
90 except IOError as err:
90 except IOError as err:
91 if err.errno != errno.ENOENT:
91 if err.errno != errno.ENOENT:
92 raise
92 raise
93 raise error.Abort(_("shelved change '%s' not found") % self.name)
93 raise error.Abort(_("shelved change '%s' not found") % self.name)
94
94
95 def applybundle(self):
95 def applybundle(self):
96 fp = self.opener()
96 fp = self.opener()
97 try:
97 try:
98 gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs)
98 gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs)
99 if not isinstance(gen, bundle2.unbundle20):
99 if not isinstance(gen, bundle2.unbundle20):
100 gen.apply(self.repo, 'unshelve',
100 gen.apply(self.repo, 'unshelve',
101 'bundle:' + self.vfs.join(self.fname),
101 'bundle:' + self.vfs.join(self.fname),
102 targetphase=phases.secret)
102 targetphase=phases.secret)
103 if isinstance(gen, bundle2.unbundle20):
103 if isinstance(gen, bundle2.unbundle20):
104 bundle2.applybundle(self.repo, gen,
104 bundle2.applybundle(self.repo, gen,
105 self.repo.currenttransaction(),
105 self.repo.currenttransaction(),
106 source='unshelve',
106 source='unshelve',
107 url='bundle:' + self.vfs.join(self.fname))
107 url='bundle:' + self.vfs.join(self.fname))
108 finally:
108 finally:
109 fp.close()
109 fp.close()
110
110
111 def bundlerepo(self):
111 def bundlerepo(self):
112 return bundlerepo.bundlerepository(self.repo.baseui, self.repo.root,
112 return bundlerepo.bundlerepository(self.repo.baseui, self.repo.root,
113 self.vfs.join(self.fname))
113 self.vfs.join(self.fname))
114 def writebundle(self, bases, node):
114 def writebundle(self, bases, node):
115 btype = 'HG10BZ'
115 btype = 'HG10BZ'
116 cgversion = '01'
116 cgversion = '01'
117 compression = None
117 compression = None
118 if 'generaldelta' in self.repo.requirements:
118 if 'generaldelta' in self.repo.requirements:
119 btype = 'HG20'
119 btype = 'HG20'
120 cgversion = '02'
120 cgversion = '02'
121 compression = 'BZ'
121 compression = 'BZ'
122
122
123 cg = changegroup.changegroupsubset(self.repo, bases, [node], 'shelve',
123 cg = changegroup.changegroupsubset(self.repo, bases, [node], 'shelve',
124 version=cgversion)
124 version=cgversion)
125 changegroup.writebundle(self.ui, cg, self.fname, btype, self.vfs,
125 changegroup.writebundle(self.ui, cg, self.fname, btype, self.vfs,
126 compression=compression)
126 compression=compression)
127
127
128 class shelvedstate(object):
128 class shelvedstate(object):
129 """Handle persistence during unshelving operations.
129 """Handle persistence during unshelving operations.
130
130
131 Handles saving and restoring a shelved state. Ensures that different
131 Handles saving and restoring a shelved state. Ensures that different
132 versions of a shelved state are possible and handles them appropriately.
132 versions of a shelved state are possible and handles them appropriately.
133 """
133 """
134 _version = 1
134 _version = 1
135 _filename = 'shelvedstate'
135 _filename = 'shelvedstate'
136
136
137 @classmethod
137 @classmethod
138 def load(cls, repo):
138 def load(cls, repo):
139 fp = repo.vfs(cls._filename)
139 fp = repo.vfs(cls._filename)
140 try:
140 try:
141 version = int(fp.readline().strip())
141 version = int(fp.readline().strip())
142
142
143 if version != cls._version:
143 if version != cls._version:
144 raise error.Abort(_('this version of shelve is incompatible '
144 raise error.Abort(_('this version of shelve is incompatible '
145 'with the version used in this repo'))
145 'with the version used in this repo'))
146 name = fp.readline().strip()
146 name = fp.readline().strip()
147 wctx = fp.readline().strip()
147 wctx = fp.readline().strip()
148 pendingctx = fp.readline().strip()
148 pendingctx = fp.readline().strip()
149 parents = [bin(h) for h in fp.readline().split()]
149 parents = [bin(h) for h in fp.readline().split()]
150 stripnodes = [bin(h) for h in fp.readline().split()]
150 stripnodes = [bin(h) for h in fp.readline().split()]
151 finally:
151 finally:
152 fp.close()
152 fp.close()
153
153
154 obj = cls()
154 obj = cls()
155 obj.name = name
155 obj.name = name
156 obj.wctx = repo[bin(wctx)]
156 obj.wctx = repo[bin(wctx)]
157 obj.pendingctx = repo[bin(pendingctx)]
157 obj.pendingctx = repo[bin(pendingctx)]
158 obj.parents = parents
158 obj.parents = parents
159 obj.stripnodes = stripnodes
159 obj.stripnodes = stripnodes
160
160
161 return obj
161 return obj
162
162
163 @classmethod
163 @classmethod
164 def save(cls, repo, name, originalwctx, pendingctx, stripnodes):
164 def save(cls, repo, name, originalwctx, pendingctx, stripnodes):
165 fp = repo.vfs(cls._filename, 'wb')
165 fp = repo.vfs(cls._filename, 'wb')
166 fp.write('%i\n' % cls._version)
166 fp.write('%i\n' % cls._version)
167 fp.write('%s\n' % name)
167 fp.write('%s\n' % name)
168 fp.write('%s\n' % hex(originalwctx.node()))
168 fp.write('%s\n' % hex(originalwctx.node()))
169 fp.write('%s\n' % hex(pendingctx.node()))
169 fp.write('%s\n' % hex(pendingctx.node()))
170 fp.write('%s\n' % ' '.join([hex(p) for p in repo.dirstate.parents()]))
170 fp.write('%s\n' % ' '.join([hex(p) for p in repo.dirstate.parents()]))
171 fp.write('%s\n' % ' '.join([hex(n) for n in stripnodes]))
171 fp.write('%s\n' % ' '.join([hex(n) for n in stripnodes]))
172 fp.close()
172 fp.close()
173
173
174 @classmethod
174 @classmethod
175 def clear(cls, repo):
175 def clear(cls, repo):
176 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
176 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
177
177
178 def cleanupoldbackups(repo):
178 def cleanupoldbackups(repo):
179 vfs = scmutil.vfs(repo.join(backupdir))
179 vfs = scmutil.vfs(repo.join(backupdir))
180 maxbackups = repo.ui.configint('shelve', 'maxbackups', 10)
180 maxbackups = repo.ui.configint('shelve', 'maxbackups', 10)
181 hgfiles = [f for f in vfs.listdir() if f.endswith('.hg')]
181 hgfiles = [f for f in vfs.listdir() if f.endswith('.hg')]
182 hgfiles = sorted([(vfs.stat(f).st_mtime, f) for f in hgfiles])
182 hgfiles = sorted([(vfs.stat(f).st_mtime, f) for f in hgfiles])
183 if 0 < maxbackups and maxbackups < len(hgfiles):
183 if 0 < maxbackups and maxbackups < len(hgfiles):
184 bordermtime = hgfiles[-maxbackups][0]
184 bordermtime = hgfiles[-maxbackups][0]
185 else:
185 else:
186 bordermtime = None
186 bordermtime = None
187 for mtime, f in hgfiles[:len(hgfiles) - maxbackups]:
187 for mtime, f in hgfiles[:len(hgfiles) - maxbackups]:
188 if mtime == bordermtime:
188 if mtime == bordermtime:
189 # keep it, because timestamp can't decide exact order of backups
189 # keep it, because timestamp can't decide exact order of backups
190 continue
190 continue
191 base = f[:-3]
191 base = f[:-3]
192 for ext in 'hg patch'.split():
192 for ext in 'hg patch'.split():
193 try:
193 try:
194 vfs.unlink(base + '.' + ext)
194 vfs.unlink(base + '.' + ext)
195 except OSError as err:
195 except OSError as err:
196 if err.errno != errno.ENOENT:
196 if err.errno != errno.ENOENT:
197 raise
197 raise
198
198
199 def _aborttransaction(repo):
199 def _aborttransaction(repo):
200 '''Abort current transaction for shelve/unshelve, but keep dirstate
200 '''Abort current transaction for shelve/unshelve, but keep dirstate
201 '''
201 '''
202 backupname = 'dirstate.shelve'
202 backupname = 'dirstate.shelve'
203 dirstatebackup = None
203 dirstatebackup = None
204 try:
204 try:
205 # create backup of (un)shelved dirstate, because aborting transaction
205 # create backup of (un)shelved dirstate, because aborting transaction
206 # should restore dirstate to one at the beginning of the
206 # should restore dirstate to one at the beginning of the
207 # transaction, which doesn't include the result of (un)shelving
207 # transaction, which doesn't include the result of (un)shelving
208 fp = repo.vfs.open(backupname, "w")
208 fp = repo.vfs.open(backupname, "w")
209 dirstatebackup = backupname
209 dirstatebackup = backupname
210 # clearing _dirty/_dirtypl of dirstate by _writedirstate below
210 # clearing _dirty/_dirtypl of dirstate by _writedirstate below
211 # is unintentional. but it doesn't cause problem in this case,
211 # is unintentional. but it doesn't cause problem in this case,
212 # because no code path refers them until transaction is aborted.
212 # because no code path refers them until transaction is aborted.
213 repo.dirstate._writedirstate(fp) # write in-memory changes forcibly
213 repo.dirstate._writedirstate(fp) # write in-memory changes forcibly
214
214
215 tr = repo.currenttransaction()
215 tr = repo.currenttransaction()
216 tr.abort()
216 tr.abort()
217
217
218 # restore to backuped dirstate
218 # restore to backuped dirstate
219 repo.vfs.rename(dirstatebackup, 'dirstate')
219 repo.vfs.rename(dirstatebackup, 'dirstate')
220 dirstatebackup = None
220 dirstatebackup = None
221 finally:
221 finally:
222 if dirstatebackup:
222 if dirstatebackup:
223 repo.vfs.unlink(dirstatebackup)
223 repo.vfs.unlink(dirstatebackup)
224
224
225 def createcmd(ui, repo, pats, opts):
225 def createcmd(ui, repo, pats, opts):
226 """subcommand that creates a new shelve"""
226 """subcommand that creates a new shelve"""
227 with repo.wlock():
227 with repo.wlock():
228 cmdutil.checkunfinished(repo)
228 cmdutil.checkunfinished(repo)
229 return _docreatecmd(ui, repo, pats, opts)
229 return _docreatecmd(ui, repo, pats, opts)
230
230
231 def _docreatecmd(ui, repo, pats, opts):
231 def _docreatecmd(ui, repo, pats, opts):
232 def mutableancestors(ctx):
232 def mutableancestors(ctx):
233 """return all mutable ancestors for ctx (included)
233 """return all mutable ancestors for ctx (included)
234
234
235 Much faster than the revset ancestors(ctx) & draft()"""
235 Much faster than the revset ancestors(ctx) & draft()"""
236 seen = set([nullrev])
236 seen = set([nullrev])
237 visit = collections.deque()
237 visit = collections.deque()
238 visit.append(ctx)
238 visit.append(ctx)
239 while visit:
239 while visit:
240 ctx = visit.popleft()
240 ctx = visit.popleft()
241 yield ctx.node()
241 yield ctx.node()
242 for parent in ctx.parents():
242 for parent in ctx.parents():
243 rev = parent.rev()
243 rev = parent.rev()
244 if rev not in seen:
244 if rev not in seen:
245 seen.add(rev)
245 seen.add(rev)
246 if parent.mutable():
246 if parent.mutable():
247 visit.append(parent)
247 visit.append(parent)
248
248
249 wctx = repo[None]
249 wctx = repo[None]
250 parents = wctx.parents()
250 parents = wctx.parents()
251 if len(parents) > 1:
251 if len(parents) > 1:
252 raise error.Abort(_('cannot shelve while merging'))
252 raise error.Abort(_('cannot shelve while merging'))
253 parent = parents[0]
253 parent = parents[0]
254
254
255 # we never need the user, so we use a generic user for all shelve operations
255 # we never need the user, so we use a generic user for all shelve operations
256 user = 'shelve@localhost'
256 user = 'shelve@localhost'
257 label = repo._activebookmark or parent.branch() or 'default'
257 label = repo._activebookmark or parent.branch() or 'default'
258
258
259 # slashes aren't allowed in filenames, therefore we rename it
259 # slashes aren't allowed in filenames, therefore we rename it
260 label = label.replace('/', '_')
260 label = label.replace('/', '_')
261
261
262 def gennames():
262 def gennames():
263 yield label
263 yield label
264 for i in xrange(1, 100):
264 for i in xrange(1, 100):
265 yield '%s-%02d' % (label, i)
265 yield '%s-%02d' % (label, i)
266
266
267 if parent.node() != nullid:
267 if parent.node() != nullid:
268 desc = "changes to: %s" % parent.description().split('\n', 1)[0]
268 desc = "changes to: %s" % parent.description().split('\n', 1)[0]
269 else:
269 else:
270 desc = '(changes in empty repository)'
270 desc = '(changes in empty repository)'
271
271
272 if not opts['message']:
272 if not opts['message']:
273 opts['message'] = desc
273 opts['message'] = desc
274
274
275 name = opts['name']
275 name = opts['name']
276
276
277 lock = tr = None
277 lock = tr = None
278 try:
278 try:
279 lock = repo.lock()
279 lock = repo.lock()
280
280
281 # use an uncommitted transaction to generate the bundle to avoid
281 # use an uncommitted transaction to generate the bundle to avoid
282 # pull races. ensure we don't print the abort message to stderr.
282 # pull races. ensure we don't print the abort message to stderr.
283 tr = repo.transaction('commit', report=lambda x: None)
283 tr = repo.transaction('commit', report=lambda x: None)
284
284
285 if name:
285 if name:
286 if shelvedfile(repo, name, 'hg').exists():
286 if shelvedfile(repo, name, 'hg').exists():
287 raise error.Abort(_("a shelved change named '%s' already exists"
287 raise error.Abort(_("a shelved change named '%s' already exists"
288 ) % name)
288 ) % name)
289 else:
289 else:
290 for n in gennames():
290 for n in gennames():
291 if not shelvedfile(repo, n, 'hg').exists():
291 if not shelvedfile(repo, n, 'hg').exists():
292 name = n
292 name = n
293 break
293 break
294 else:
294 else:
295 raise error.Abort(_("too many shelved changes named '%s'") %
295 raise error.Abort(_("too many shelved changes named '%s'") %
296 label)
296 label)
297
297
298 # ensure we are not creating a subdirectory or a hidden file
298 # ensure we are not creating a subdirectory or a hidden file
299 if '/' in name or '\\' in name:
299 if '/' in name or '\\' in name:
300 raise error.Abort(_('shelved change names may not contain slashes'))
300 raise error.Abort(_('shelved change names may not contain slashes'))
301 if name.startswith('.'):
301 if name.startswith('.'):
302 raise error.Abort(_("shelved change names may not start with '.'"))
302 raise error.Abort(_("shelved change names may not start with '.'"))
303 interactive = opts.get('interactive', False)
303 interactive = opts.get('interactive', False)
304 includeunknown = (opts.get('unknown', False) and
304 includeunknown = (opts.get('unknown', False) and
305 not opts.get('addremove', False))
305 not opts.get('addremove', False))
306
306
307 extra={}
307 extra={}
308 if includeunknown:
308 if includeunknown:
309 s = repo.status(match=scmutil.match(repo[None], pats, opts),
309 s = repo.status(match=scmutil.match(repo[None], pats, opts),
310 unknown=True)
310 unknown=True)
311 if s.unknown:
311 if s.unknown:
312 extra['shelve_unknown'] = '\0'.join(s.unknown)
312 extra['shelve_unknown'] = '\0'.join(s.unknown)
313 repo[None].add(s.unknown)
313 repo[None].add(s.unknown)
314
314
315 def commitfunc(ui, repo, message, match, opts):
315 def commitfunc(ui, repo, message, match, opts):
316 hasmq = util.safehasattr(repo, 'mq')
316 hasmq = util.safehasattr(repo, 'mq')
317 if hasmq:
317 if hasmq:
318 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
318 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
319 backup = repo.ui.backupconfig('phases', 'new-commit')
319 backup = repo.ui.backupconfig('phases', 'new-commit')
320 try:
320 try:
321 repo.ui. setconfig('phases', 'new-commit', phases.secret)
321 repo.ui. setconfig('phases', 'new-commit', phases.secret)
322 editor = cmdutil.getcommiteditor(editform='shelve.shelve',
322 editor = cmdutil.getcommiteditor(editform='shelve.shelve',
323 **opts)
323 **opts)
324 return repo.commit(message, user, opts.get('date'), match,
324 return repo.commit(message, user, opts.get('date'), match,
325 editor=editor, extra=extra)
325 editor=editor, extra=extra)
326 finally:
326 finally:
327 repo.ui.restoreconfig(backup)
327 repo.ui.restoreconfig(backup)
328 if hasmq:
328 if hasmq:
329 repo.mq.checkapplied = saved
329 repo.mq.checkapplied = saved
330
330
331 def interactivecommitfunc(ui, repo, *pats, **opts):
331 def interactivecommitfunc(ui, repo, *pats, **opts):
332 match = scmutil.match(repo['.'], pats, {})
332 match = scmutil.match(repo['.'], pats, {})
333 message = opts['message']
333 message = opts['message']
334 return commitfunc(ui, repo, message, match, opts)
334 return commitfunc(ui, repo, message, match, opts)
335 if not interactive:
335 if not interactive:
336 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
336 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
337 else:
337 else:
338 node = cmdutil.dorecord(ui, repo, interactivecommitfunc, None,
338 node = cmdutil.dorecord(ui, repo, interactivecommitfunc, None,
339 False, cmdutil.recordfilter, *pats, **opts)
339 False, cmdutil.recordfilter, *pats, **opts)
340 if not node:
340 if not node:
341 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
341 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
342 if stat.deleted:
342 if stat.deleted:
343 ui.status(_("nothing changed (%d missing files, see "
343 ui.status(_("nothing changed (%d missing files, see "
344 "'hg status')\n") % len(stat.deleted))
344 "'hg status')\n") % len(stat.deleted))
345 else:
345 else:
346 ui.status(_("nothing changed\n"))
346 ui.status(_("nothing changed\n"))
347 return 1
347 return 1
348
348
349 bases = list(mutableancestors(repo[node]))
349 bases = list(mutableancestors(repo[node]))
350 shelvedfile(repo, name, 'hg').writebundle(bases, node)
350 shelvedfile(repo, name, 'hg').writebundle(bases, node)
351 cmdutil.export(repo, [node],
351 cmdutil.export(repo, [node],
352 fp=shelvedfile(repo, name, 'patch').opener('wb'),
352 fp=shelvedfile(repo, name, 'patch').opener('wb'),
353 opts=mdiff.diffopts(git=True))
353 opts=mdiff.diffopts(git=True))
354
354
355
355
356 if ui.formatted():
356 if ui.formatted():
357 desc = util.ellipsis(desc, ui.termwidth())
357 desc = util.ellipsis(desc, ui.termwidth())
358 ui.status(_('shelved as %s\n') % name)
358 ui.status(_('shelved as %s\n') % name)
359 hg.update(repo, parent.node())
359 hg.update(repo, parent.node())
360
360
361 _aborttransaction(repo)
361 _aborttransaction(repo)
362 finally:
362 finally:
363 lockmod.release(tr, lock)
363 lockmod.release(tr, lock)
364
364
365 def cleanupcmd(ui, repo):
365 def cleanupcmd(ui, repo):
366 """subcommand that deletes all shelves"""
366 """subcommand that deletes all shelves"""
367
367
368 with repo.wlock():
368 with repo.wlock():
369 for (name, _type) in repo.vfs.readdir('shelved'):
369 for (name, _type) in repo.vfs.readdir('shelved'):
370 suffix = name.rsplit('.', 1)[-1]
370 suffix = name.rsplit('.', 1)[-1]
371 if suffix in ('hg', 'patch'):
371 if suffix in ('hg', 'patch'):
372 shelvedfile(repo, name).movetobackup()
372 shelvedfile(repo, name).movetobackup()
373 cleanupoldbackups(repo)
373 cleanupoldbackups(repo)
374
374
375 def deletecmd(ui, repo, pats):
375 def deletecmd(ui, repo, pats):
376 """subcommand that deletes a specific shelve"""
376 """subcommand that deletes a specific shelve"""
377 if not pats:
377 if not pats:
378 raise error.Abort(_('no shelved changes specified!'))
378 raise error.Abort(_('no shelved changes specified!'))
379 with repo.wlock():
379 with repo.wlock():
380 try:
380 try:
381 for name in pats:
381 for name in pats:
382 for suffix in 'hg patch'.split():
382 for suffix in 'hg patch'.split():
383 shelvedfile(repo, name, suffix).movetobackup()
383 shelvedfile(repo, name, suffix).movetobackup()
384 cleanupoldbackups(repo)
384 cleanupoldbackups(repo)
385 except OSError as err:
385 except OSError as err:
386 if err.errno != errno.ENOENT:
386 if err.errno != errno.ENOENT:
387 raise
387 raise
388 raise error.Abort(_("shelved change '%s' not found") % name)
388 raise error.Abort(_("shelved change '%s' not found") % name)
389
389
390 def listshelves(repo):
390 def listshelves(repo):
391 """return all shelves in repo as list of (time, filename)"""
391 """return all shelves in repo as list of (time, filename)"""
392 try:
392 try:
393 names = repo.vfs.readdir('shelved')
393 names = repo.vfs.readdir('shelved')
394 except OSError as err:
394 except OSError as err:
395 if err.errno != errno.ENOENT:
395 if err.errno != errno.ENOENT:
396 raise
396 raise
397 return []
397 return []
398 info = []
398 info = []
399 for (name, _type) in names:
399 for (name, _type) in names:
400 pfx, sfx = name.rsplit('.', 1)
400 pfx, sfx = name.rsplit('.', 1)
401 if not pfx or sfx != 'patch':
401 if not pfx or sfx != 'patch':
402 continue
402 continue
403 st = shelvedfile(repo, name).stat()
403 st = shelvedfile(repo, name).stat()
404 info.append((st.st_mtime, shelvedfile(repo, pfx).filename()))
404 info.append((st.st_mtime, shelvedfile(repo, pfx).filename()))
405 return sorted(info, reverse=True)
405 return sorted(info, reverse=True)
406
406
407 def listcmd(ui, repo, pats, opts):
407 def listcmd(ui, repo, pats, opts):
408 """subcommand that displays the list of shelves"""
408 """subcommand that displays the list of shelves"""
409 pats = set(pats)
409 pats = set(pats)
410 width = 80
410 width = 80
411 if not ui.plain():
411 if not ui.plain():
412 width = ui.termwidth()
412 width = ui.termwidth()
413 namelabel = 'shelve.newest'
413 namelabel = 'shelve.newest'
414 for mtime, name in listshelves(repo):
414 for mtime, name in listshelves(repo):
415 sname = util.split(name)[1]
415 sname = util.split(name)[1]
416 if pats and sname not in pats:
416 if pats and sname not in pats:
417 continue
417 continue
418 ui.write(sname, label=namelabel)
418 ui.write(sname, label=namelabel)
419 namelabel = 'shelve.name'
419 namelabel = 'shelve.name'
420 if ui.quiet:
420 if ui.quiet:
421 ui.write('\n')
421 ui.write('\n')
422 continue
422 continue
423 ui.write(' ' * (16 - len(sname)))
423 ui.write(' ' * (16 - len(sname)))
424 used = 16
424 used = 16
425 age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True)
425 age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True)
426 ui.write(age, label='shelve.age')
426 ui.write(age, label='shelve.age')
427 ui.write(' ' * (12 - len(age)))
427 ui.write(' ' * (12 - len(age)))
428 used += 12
428 used += 12
429 with open(name + '.patch', 'rb') as fp:
429 with open(name + '.patch', 'rb') as fp:
430 while True:
430 while True:
431 line = fp.readline()
431 line = fp.readline()
432 if not line:
432 if not line:
433 break
433 break
434 if not line.startswith('#'):
434 if not line.startswith('#'):
435 desc = line.rstrip()
435 desc = line.rstrip()
436 if ui.formatted():
436 if ui.formatted():
437 desc = util.ellipsis(desc, width - used)
437 desc = util.ellipsis(desc, width - used)
438 ui.write(desc)
438 ui.write(desc)
439 break
439 break
440 ui.write('\n')
440 ui.write('\n')
441 if not (opts['patch'] or opts['stat']):
441 if not (opts['patch'] or opts['stat']):
442 continue
442 continue
443 difflines = fp.readlines()
443 difflines = fp.readlines()
444 if opts['patch']:
444 if opts['patch']:
445 for chunk, label in patch.difflabel(iter, difflines):
445 for chunk, label in patch.difflabel(iter, difflines):
446 ui.write(chunk, label=label)
446 ui.write(chunk, label=label)
447 if opts['stat']:
447 if opts['stat']:
448 for chunk, label in patch.diffstatui(difflines, width=width,
448 for chunk, label in patch.diffstatui(difflines, width=width,
449 git=True):
449 git=True):
450 ui.write(chunk, label=label)
450 ui.write(chunk, label=label)
451
451
452 def singlepatchcmds(ui, repo, pats, opts, subcommand):
452 def singlepatchcmds(ui, repo, pats, opts, subcommand):
453 """subcommand that displays a single shelf"""
453 """subcommand that displays a single shelf"""
454 if len(pats) != 1:
454 if len(pats) != 1:
455 raise error.Abort(_("--%s expects a single shelf") % subcommand)
455 raise error.Abort(_("--%s expects a single shelf") % subcommand)
456 shelfname = pats[0]
456 shelfname = pats[0]
457
457
458 if not shelvedfile(repo, shelfname, 'patch').exists():
458 if not shelvedfile(repo, shelfname, 'patch').exists():
459 raise error.Abort(_("cannot find shelf %s") % shelfname)
459 raise error.Abort(_("cannot find shelf %s") % shelfname)
460
460
461 listcmd(ui, repo, pats, opts)
461 listcmd(ui, repo, pats, opts)
462
462
463 def checkparents(repo, state):
463 def checkparents(repo, state):
464 """check parent while resuming an unshelve"""
464 """check parent while resuming an unshelve"""
465 if state.parents != repo.dirstate.parents():
465 if state.parents != repo.dirstate.parents():
466 raise error.Abort(_('working directory parents do not match unshelve '
466 raise error.Abort(_('working directory parents do not match unshelve '
467 'state'))
467 'state'))
468
468
469 def pathtofiles(repo, files):
469 def pathtofiles(repo, files):
470 cwd = repo.getcwd()
470 cwd = repo.getcwd()
471 return [repo.pathto(f, cwd) for f in files]
471 return [repo.pathto(f, cwd) for f in files]
472
472
473 def unshelveabort(ui, repo, state, opts):
473 def unshelveabort(ui, repo, state, opts):
474 """subcommand that abort an in-progress unshelve"""
474 """subcommand that abort an in-progress unshelve"""
475 with repo.lock():
475 with repo.lock():
476 try:
476 try:
477 checkparents(repo, state)
477 checkparents(repo, state)
478
478
479 util.rename(repo.join('unshelverebasestate'),
479 util.rename(repo.join('unshelverebasestate'),
480 repo.join('rebasestate'))
480 repo.join('rebasestate'))
481 try:
481 try:
482 rebase.rebase(ui, repo, **{
482 rebase.rebase(ui, repo, **{
483 'abort' : True
483 'abort' : True
484 })
484 })
485 except Exception:
485 except Exception:
486 util.rename(repo.join('rebasestate'),
486 util.rename(repo.join('rebasestate'),
487 repo.join('unshelverebasestate'))
487 repo.join('unshelverebasestate'))
488 raise
488 raise
489
489
490 mergefiles(ui, repo, state.wctx, state.pendingctx)
490 mergefiles(ui, repo, state.wctx, state.pendingctx)
491 repair.strip(ui, repo, state.stripnodes, backup=False,
491 repair.strip(ui, repo, state.stripnodes, backup=False,
492 topic='shelve')
492 topic='shelve')
493 finally:
493 finally:
494 shelvedstate.clear(repo)
494 shelvedstate.clear(repo)
495 ui.warn(_("unshelve of '%s' aborted\n") % state.name)
495 ui.warn(_("unshelve of '%s' aborted\n") % state.name)
496
496
497 def mergefiles(ui, repo, wctx, shelvectx):
497 def mergefiles(ui, repo, wctx, shelvectx):
498 """updates to wctx and merges the changes from shelvectx into the
498 """updates to wctx and merges the changes from shelvectx into the
499 dirstate."""
499 dirstate."""
500 oldquiet = ui.quiet
500 oldquiet = ui.quiet
501 try:
501 try:
502 ui.quiet = True
502 ui.quiet = True
503 hg.update(repo, wctx.node())
503 hg.update(repo, wctx.node())
504 files = []
504 files = []
505 files.extend(shelvectx.files())
505 files.extend(shelvectx.files())
506 files.extend(shelvectx.parents()[0].files())
506 files.extend(shelvectx.parents()[0].files())
507
507
508 # revert will overwrite unknown files, so move them out of the way
508 # revert will overwrite unknown files, so move them out of the way
509 for file in repo.status(unknown=True).unknown:
509 for file in repo.status(unknown=True).unknown:
510 if file in files:
510 if file in files:
511 util.rename(file, scmutil.origpath(ui, repo, file))
511 util.rename(file, scmutil.origpath(ui, repo, file))
512 ui.pushbuffer(True)
512 ui.pushbuffer(True)
513 cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
513 cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
514 *pathtofiles(repo, files),
514 *pathtofiles(repo, files),
515 **{'no_backup': True})
515 **{'no_backup': True})
516 ui.popbuffer()
516 ui.popbuffer()
517 finally:
517 finally:
518 ui.quiet = oldquiet
518 ui.quiet = oldquiet
519
519
520 def unshelvecleanup(ui, repo, name, opts):
520 def unshelvecleanup(ui, repo, name, opts):
521 """remove related files after an unshelve"""
521 """remove related files after an unshelve"""
522 if not opts['keep']:
522 if not opts['keep']:
523 for filetype in 'hg patch'.split():
523 for filetype in 'hg patch'.split():
524 shelvedfile(repo, name, filetype).movetobackup()
524 shelvedfile(repo, name, filetype).movetobackup()
525 cleanupoldbackups(repo)
525 cleanupoldbackups(repo)
526
526
527 def unshelvecontinue(ui, repo, state, opts):
527 def unshelvecontinue(ui, repo, state, opts):
528 """subcommand to continue an in-progress unshelve"""
528 """subcommand to continue an in-progress unshelve"""
529 # We're finishing off a merge. First parent is our original
529 # We're finishing off a merge. First parent is our original
530 # parent, second is the temporary "fake" commit we're unshelving.
530 # parent, second is the temporary "fake" commit we're unshelving.
531 with repo.lock():
531 with repo.lock():
532 checkparents(repo, state)
532 checkparents(repo, state)
533 ms = merge.mergestate.read(repo)
533 ms = merge.mergestate.read(repo)
534 if [f for f in ms if ms[f] == 'u']:
534 if [f for f in ms if ms[f] == 'u']:
535 raise error.Abort(
535 raise error.Abort(
536 _("unresolved conflicts, can't continue"),
536 _("unresolved conflicts, can't continue"),
537 hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
537 hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
538
538
539 util.rename(repo.join('unshelverebasestate'),
539 util.rename(repo.join('unshelverebasestate'),
540 repo.join('rebasestate'))
540 repo.join('rebasestate'))
541 try:
541 try:
542 rebase.rebase(ui, repo, **{
542 rebase.rebase(ui, repo, **{
543 'continue' : True
543 'continue' : True
544 })
544 })
545 except Exception:
545 except Exception:
546 util.rename(repo.join('rebasestate'),
546 util.rename(repo.join('rebasestate'),
547 repo.join('unshelverebasestate'))
547 repo.join('unshelverebasestate'))
548 raise
548 raise
549
549
550 shelvectx = repo['tip']
550 shelvectx = repo['tip']
551 if not shelvectx in state.pendingctx.children():
551 if not shelvectx in state.pendingctx.children():
552 # rebase was a no-op, so it produced no child commit
552 # rebase was a no-op, so it produced no child commit
553 shelvectx = state.pendingctx
553 shelvectx = state.pendingctx
554 else:
554 else:
555 # only strip the shelvectx if the rebase produced it
555 # only strip the shelvectx if the rebase produced it
556 state.stripnodes.append(shelvectx.node())
556 state.stripnodes.append(shelvectx.node())
557
557
558 mergefiles(ui, repo, state.wctx, shelvectx)
558 mergefiles(ui, repo, state.wctx, shelvectx)
559
559
560 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
560 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
561 shelvedstate.clear(repo)
561 shelvedstate.clear(repo)
562 unshelvecleanup(ui, repo, state.name, opts)
562 unshelvecleanup(ui, repo, state.name, opts)
563 ui.status(_("unshelve of '%s' complete\n") % state.name)
563 ui.status(_("unshelve of '%s' complete\n") % state.name)
564
564
565 @command('unshelve',
565 @command('unshelve',
566 [('a', 'abort', None,
566 [('a', 'abort', None,
567 _('abort an incomplete unshelve operation')),
567 _('abort an incomplete unshelve operation')),
568 ('c', 'continue', None,
568 ('c', 'continue', None,
569 _('continue an incomplete unshelve operation')),
569 _('continue an incomplete unshelve operation')),
570 ('k', 'keep', None,
570 ('k', 'keep', None,
571 _('keep shelve after unshelving')),
571 _('keep shelve after unshelving')),
572 ('t', 'tool', '', _('specify merge tool')),
572 ('t', 'tool', '', _('specify merge tool')),
573 ('', 'date', '',
573 ('', 'date', '',
574 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
574 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
575 _('hg unshelve [SHELVED]'))
575 _('hg unshelve [SHELVED]'))
576 def unshelve(ui, repo, *shelved, **opts):
576 def unshelve(ui, repo, *shelved, **opts):
577 """restore a shelved change to the working directory
577 """restore a shelved change to the working directory
578
578
579 This command accepts an optional name of a shelved change to
579 This command accepts an optional name of a shelved change to
580 restore. If none is given, the most recent shelved change is used.
580 restore. If none is given, the most recent shelved change is used.
581
581
582 If a shelved change is applied successfully, the bundle that
582 If a shelved change is applied successfully, the bundle that
583 contains the shelved changes is moved to a backup location
583 contains the shelved changes is moved to a backup location
584 (.hg/shelve-backup).
584 (.hg/shelve-backup).
585
585
586 Since you can restore a shelved change on top of an arbitrary
586 Since you can restore a shelved change on top of an arbitrary
587 commit, it is possible that unshelving will result in a conflict
587 commit, it is possible that unshelving will result in a conflict
588 between your changes and the commits you are unshelving onto. If
588 between your changes and the commits you are unshelving onto. If
589 this occurs, you must resolve the conflict, then use
589 this occurs, you must resolve the conflict, then use
590 ``--continue`` to complete the unshelve operation. (The bundle
590 ``--continue`` to complete the unshelve operation. (The bundle
591 will not be moved until you successfully complete the unshelve.)
591 will not be moved until you successfully complete the unshelve.)
592
592
593 (Alternatively, you can use ``--abort`` to abandon an unshelve
593 (Alternatively, you can use ``--abort`` to abandon an unshelve
594 that causes a conflict. This reverts the unshelved changes, and
594 that causes a conflict. This reverts the unshelved changes, and
595 leaves the bundle in place.)
595 leaves the bundle in place.)
596
596
597 After a successful unshelve, the shelved changes are stored in a
597 After a successful unshelve, the shelved changes are stored in a
598 backup directory. Only the N most recent backups are kept. N
598 backup directory. Only the N most recent backups are kept. N
599 defaults to 10 but can be overridden using the ``shelve.maxbackups``
599 defaults to 10 but can be overridden using the ``shelve.maxbackups``
600 configuration option.
600 configuration option.
601
601
602 .. container:: verbose
602 .. container:: verbose
603
603
604 Timestamp in seconds is used to decide order of backups. More
604 Timestamp in seconds is used to decide order of backups. More
605 than ``maxbackups`` backups are kept, if same timestamp
605 than ``maxbackups`` backups are kept, if same timestamp
606 prevents from deciding exact order of them, for safety.
606 prevents from deciding exact order of them, for safety.
607 """
607 """
608 with repo.wlock():
608 with repo.wlock():
609 return _dounshelve(ui, repo, *shelved, **opts)
609 return _dounshelve(ui, repo, *shelved, **opts)
610
610
611 def _dounshelve(ui, repo, *shelved, **opts):
611 def _dounshelve(ui, repo, *shelved, **opts):
612 abortf = opts['abort']
612 abortf = opts['abort']
613 continuef = opts['continue']
613 continuef = opts['continue']
614 if not abortf and not continuef:
614 if not abortf and not continuef:
615 cmdutil.checkunfinished(repo)
615 cmdutil.checkunfinished(repo)
616
616
617 if abortf or continuef:
617 if abortf or continuef:
618 if abortf and continuef:
618 if abortf and continuef:
619 raise error.Abort(_('cannot use both abort and continue'))
619 raise error.Abort(_('cannot use both abort and continue'))
620 if shelved:
620 if shelved:
621 raise error.Abort(_('cannot combine abort/continue with '
621 raise error.Abort(_('cannot combine abort/continue with '
622 'naming a shelved change'))
622 'naming a shelved change'))
623 if abortf and opts.get('tool', False):
623 if abortf and opts.get('tool', False):
624 ui.warn(_('tool option will be ignored\n'))
624 ui.warn(_('tool option will be ignored\n'))
625
625
626 try:
626 try:
627 state = shelvedstate.load(repo)
627 state = shelvedstate.load(repo)
628 except IOError as err:
628 except IOError as err:
629 if err.errno != errno.ENOENT:
629 if err.errno != errno.ENOENT:
630 raise
630 raise
631 raise error.Abort(_('no unshelve operation underway'))
631 raise error.Abort(_('no unshelve operation underway'))
632
632
633 if abortf:
633 if abortf:
634 return unshelveabort(ui, repo, state, opts)
634 return unshelveabort(ui, repo, state, opts)
635 elif continuef:
635 elif continuef:
636 return unshelvecontinue(ui, repo, state, opts)
636 return unshelvecontinue(ui, repo, state, opts)
637 elif len(shelved) > 1:
637 elif len(shelved) > 1:
638 raise error.Abort(_('can only unshelve one change at a time'))
638 raise error.Abort(_('can only unshelve one change at a time'))
639 elif not shelved:
639 elif not shelved:
640 shelved = listshelves(repo)
640 shelved = listshelves(repo)
641 if not shelved:
641 if not shelved:
642 raise error.Abort(_('no shelved changes to apply!'))
642 raise error.Abort(_('no shelved changes to apply!'))
643 basename = util.split(shelved[0][1])[1]
643 basename = util.split(shelved[0][1])[1]
644 ui.status(_("unshelving change '%s'\n") % basename)
644 ui.status(_("unshelving change '%s'\n") % basename)
645 else:
645 else:
646 basename = shelved[0]
646 basename = shelved[0]
647
647
648 if not shelvedfile(repo, basename, 'patch').exists():
648 if not shelvedfile(repo, basename, 'patch').exists():
649 raise error.Abort(_("shelved change '%s' not found") % basename)
649 raise error.Abort(_("shelved change '%s' not found") % basename)
650
650
651 oldquiet = ui.quiet
651 oldquiet = ui.quiet
652 lock = tr = None
652 lock = tr = None
653 forcemerge = ui.backupconfig('ui', 'forcemerge')
653 forcemerge = ui.backupconfig('ui', 'forcemerge')
654 try:
654 try:
655 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'unshelve')
655 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'unshelve')
656 lock = repo.lock()
656 lock = repo.lock()
657
657
658 tr = repo.transaction('unshelve', report=lambda x: None)
658 tr = repo.transaction('unshelve', report=lambda x: None)
659 oldtiprev = len(repo)
659 oldtiprev = len(repo)
660
660
661 pctx = repo['.']
661 pctx = repo['.']
662 tmpwctx = pctx
662 tmpwctx = pctx
663 # The goal is to have a commit structure like so:
663 # The goal is to have a commit structure like so:
664 # ...-> pctx -> tmpwctx -> shelvectx
664 # ...-> pctx -> tmpwctx -> shelvectx
665 # where tmpwctx is an optional commit with the user's pending changes
665 # where tmpwctx is an optional commit with the user's pending changes
666 # and shelvectx is the unshelved changes. Then we merge it all down
666 # and shelvectx is the unshelved changes. Then we merge it all down
667 # to the original pctx.
667 # to the original pctx.
668
668
669 # Store pending changes in a commit and remember added in case a shelve
669 # Store pending changes in a commit and remember added in case a shelve
670 # contains unknown files that are part of the pending change
670 # contains unknown files that are part of the pending change
671 s = repo.status()
671 s = repo.status()
672 addedbefore = frozenset(s.added)
672 addedbefore = frozenset(s.added)
673 if s.modified or s.added or s.removed or s.deleted:
673 if s.modified or s.added or s.removed or s.deleted:
674 ui.status(_("temporarily committing pending changes "
674 ui.status(_("temporarily committing pending changes "
675 "(restore with 'hg unshelve --abort')\n"))
675 "(restore with 'hg unshelve --abort')\n"))
676 def commitfunc(ui, repo, message, match, opts):
676 def commitfunc(ui, repo, message, match, opts):
677 hasmq = util.safehasattr(repo, 'mq')
677 hasmq = util.safehasattr(repo, 'mq')
678 if hasmq:
678 if hasmq:
679 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
679 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
680
680
681 backup = repo.ui.backupconfig('phases', 'new-commit')
681 backup = repo.ui.backupconfig('phases', 'new-commit')
682 try:
682 try:
683 repo.ui.setconfig('phases', 'new-commit', phases.secret)
683 repo.ui.setconfig('phases', 'new-commit', phases.secret)
684 return repo.commit(message, 'shelve@localhost',
684 return repo.commit(message, 'shelve@localhost',
685 opts.get('date'), match)
685 opts.get('date'), match)
686 finally:
686 finally:
687 repo.ui.restoreconfig(backup)
687 repo.ui.restoreconfig(backup)
688 if hasmq:
688 if hasmq:
689 repo.mq.checkapplied = saved
689 repo.mq.checkapplied = saved
690
690
691 tempopts = {}
691 tempopts = {}
692 tempopts['message'] = "pending changes temporary commit"
692 tempopts['message'] = "pending changes temporary commit"
693 tempopts['date'] = opts.get('date')
693 tempopts['date'] = opts.get('date')
694 ui.quiet = True
694 ui.quiet = True
695 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
695 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
696 tmpwctx = repo[node]
696 tmpwctx = repo[node]
697
697
698 ui.quiet = True
698 ui.quiet = True
699 shelvedfile(repo, basename, 'hg').applybundle()
699 shelvedfile(repo, basename, 'hg').applybundle()
700
700
701 ui.quiet = oldquiet
701 ui.quiet = oldquiet
702
702
703 shelvectx = repo['tip']
703 shelvectx = repo['tip']
704
704
705 # If the shelve is not immediately on top of the commit
705 # If the shelve is not immediately on top of the commit
706 # we'll be merging with, rebase it to be on top.
706 # we'll be merging with, rebase it to be on top.
707 if tmpwctx.node() != shelvectx.parents()[0].node():
707 if tmpwctx.node() != shelvectx.parents()[0].node():
708 ui.status(_('rebasing shelved changes\n'))
708 ui.status(_('rebasing shelved changes\n'))
709 try:
709 try:
710 rebase.rebase(ui, repo, **{
710 rebase.rebase(ui, repo, **{
711 'rev' : [shelvectx.rev()],
711 'rev' : [shelvectx.rev()],
712 'dest' : str(tmpwctx.rev()),
712 'dest' : str(tmpwctx.rev()),
713 'keep' : True,
713 'keep' : True,
714 'tool' : opts.get('tool', ''),
714 'tool' : opts.get('tool', ''),
715 })
715 })
716 except error.InterventionRequired:
716 except error.InterventionRequired:
717 tr.close()
717 tr.close()
718
718
719 stripnodes = [repo.changelog.node(rev)
719 stripnodes = [repo.changelog.node(rev)
720 for rev in xrange(oldtiprev, len(repo))]
720 for rev in xrange(oldtiprev, len(repo))]
721 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes)
721 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes)
722
722
723 util.rename(repo.join('rebasestate'),
723 util.rename(repo.join('rebasestate'),
724 repo.join('unshelverebasestate'))
724 repo.join('unshelverebasestate'))
725 raise error.InterventionRequired(
725 raise error.InterventionRequired(
726 _("unresolved conflicts (see 'hg resolve', then "
726 _("unresolved conflicts (see 'hg resolve', then "
727 "'hg unshelve --continue')"))
727 "'hg unshelve --continue')"))
728
728
729 # refresh ctx after rebase completes
729 # refresh ctx after rebase completes
730 shelvectx = repo['tip']
730 shelvectx = repo['tip']
731
731
732 if not shelvectx in tmpwctx.children():
732 if not shelvectx in tmpwctx.children():
733 # rebase was a no-op, so it produced no child commit
733 # rebase was a no-op, so it produced no child commit
734 shelvectx = tmpwctx
734 shelvectx = tmpwctx
735
735
736 mergefiles(ui, repo, pctx, shelvectx)
736 mergefiles(ui, repo, pctx, shelvectx)
737
737
738 # Forget any files that were unknown before the shelve, unknown before
738 # Forget any files that were unknown before the shelve, unknown before
739 # unshelve started, but are now added.
739 # unshelve started, but are now added.
740 shelveunknown = shelvectx.extra().get('shelve_unknown')
740 shelveunknown = shelvectx.extra().get('shelve_unknown')
741 if shelveunknown:
741 if shelveunknown:
742 shelveunknown = frozenset(shelveunknown.split('\0'))
742 shelveunknown = frozenset(shelveunknown.split('\0'))
743 addedafter = frozenset(repo.status().added)
743 addedafter = frozenset(repo.status().added)
744 toforget = (addedafter & shelveunknown) - addedbefore
744 toforget = (addedafter & shelveunknown) - addedbefore
745 repo[None].forget(toforget)
745 repo[None].forget(toforget)
746
746
747 shelvedstate.clear(repo)
747 shelvedstate.clear(repo)
748
748
749 # The transaction aborting will strip all the commits for us,
749 # The transaction aborting will strip all the commits for us,
750 # but it doesn't update the inmemory structures, so addchangegroup
750 # but it doesn't update the inmemory structures, so addchangegroup
751 # hooks still fire and try to operate on the missing commits.
751 # hooks still fire and try to operate on the missing commits.
752 # Clean up manually to prevent this.
752 # Clean up manually to prevent this.
753 repo.unfiltered().changelog.strip(oldtiprev, tr)
753 repo.unfiltered().changelog.strip(oldtiprev, tr)
754
754
755 unshelvecleanup(ui, repo, basename, opts)
755 unshelvecleanup(ui, repo, basename, opts)
756
756
757 _aborttransaction(repo)
757 _aborttransaction(repo)
758 finally:
758 finally:
759 ui.quiet = oldquiet
759 ui.quiet = oldquiet
760 if tr:
760 if tr:
761 tr.release()
761 tr.release()
762 lockmod.release(lock)
762 lockmod.release(lock)
763 ui.restoreconfig(forcemerge)
763 ui.restoreconfig(forcemerge)
764
764
765 @command('shelve',
765 @command('shelve',
766 [('A', 'addremove', None,
766 [('A', 'addremove', None,
767 _('mark new/missing files as added/removed before shelving')),
767 _('mark new/missing files as added/removed before shelving')),
768 ('u', 'unknown', None,
768 ('u', 'unknown', None,
769 _('Store unknown files in the shelve')),
769 _('store unknown files in the shelve')),
770 ('', 'cleanup', None,
770 ('', 'cleanup', None,
771 _('delete all shelved changes')),
771 _('delete all shelved changes')),
772 ('', 'date', '',
772 ('', 'date', '',
773 _('shelve with the specified commit date'), _('DATE')),
773 _('shelve with the specified commit date'), _('DATE')),
774 ('d', 'delete', None,
774 ('d', 'delete', None,
775 _('delete the named shelved change(s)')),
775 _('delete the named shelved change(s)')),
776 ('e', 'edit', False,
776 ('e', 'edit', False,
777 _('invoke editor on commit messages')),
777 _('invoke editor on commit messages')),
778 ('l', 'list', None,
778 ('l', 'list', None,
779 _('list current shelves')),
779 _('list current shelves')),
780 ('m', 'message', '',
780 ('m', 'message', '',
781 _('use text as shelve message'), _('TEXT')),
781 _('use text as shelve message'), _('TEXT')),
782 ('n', 'name', '',
782 ('n', 'name', '',
783 _('use the given name for the shelved commit'), _('NAME')),
783 _('use the given name for the shelved commit'), _('NAME')),
784 ('p', 'patch', None,
784 ('p', 'patch', None,
785 _('show patch')),
785 _('show patch')),
786 ('i', 'interactive', None,
786 ('i', 'interactive', None,
787 _('interactive mode, only works while creating a shelve')),
787 _('interactive mode, only works while creating a shelve')),
788 ('', 'stat', None,
788 ('', 'stat', None,
789 _('output diffstat-style summary of changes'))] + commands.walkopts,
789 _('output diffstat-style summary of changes'))] + commands.walkopts,
790 _('hg shelve [OPTION]... [FILE]...'))
790 _('hg shelve [OPTION]... [FILE]...'))
791 def shelvecmd(ui, repo, *pats, **opts):
791 def shelvecmd(ui, repo, *pats, **opts):
792 '''save and set aside changes from the working directory
792 '''save and set aside changes from the working directory
793
793
794 Shelving takes files that "hg status" reports as not clean, saves
794 Shelving takes files that "hg status" reports as not clean, saves
795 the modifications to a bundle (a shelved change), and reverts the
795 the modifications to a bundle (a shelved change), and reverts the
796 files so that their state in the working directory becomes clean.
796 files so that their state in the working directory becomes clean.
797
797
798 To restore these changes to the working directory, using "hg
798 To restore these changes to the working directory, using "hg
799 unshelve"; this will work even if you switch to a different
799 unshelve"; this will work even if you switch to a different
800 commit.
800 commit.
801
801
802 When no files are specified, "hg shelve" saves all not-clean
802 When no files are specified, "hg shelve" saves all not-clean
803 files. If specific files or directories are named, only changes to
803 files. If specific files or directories are named, only changes to
804 those files are shelved.
804 those files are shelved.
805
805
806 Each shelved change has a name that makes it easier to find later.
806 Each shelved change has a name that makes it easier to find later.
807 The name of a shelved change defaults to being based on the active
807 The name of a shelved change defaults to being based on the active
808 bookmark, or if there is no active bookmark, the current named
808 bookmark, or if there is no active bookmark, the current named
809 branch. To specify a different name, use ``--name``.
809 branch. To specify a different name, use ``--name``.
810
810
811 To see a list of existing shelved changes, use the ``--list``
811 To see a list of existing shelved changes, use the ``--list``
812 option. For each shelved change, this will print its name, age,
812 option. For each shelved change, this will print its name, age,
813 and description; use ``--patch`` or ``--stat`` for more details.
813 and description; use ``--patch`` or ``--stat`` for more details.
814
814
815 To delete specific shelved changes, use ``--delete``. To delete
815 To delete specific shelved changes, use ``--delete``. To delete
816 all shelved changes, use ``--cleanup``.
816 all shelved changes, use ``--cleanup``.
817 '''
817 '''
818 allowables = [
818 allowables = [
819 ('addremove', set(['create'])), # 'create' is pseudo action
819 ('addremove', set(['create'])), # 'create' is pseudo action
820 ('unknown', set(['create'])),
820 ('unknown', set(['create'])),
821 ('cleanup', set(['cleanup'])),
821 ('cleanup', set(['cleanup'])),
822 # ('date', set(['create'])), # ignored for passing '--date "0 0"' in tests
822 # ('date', set(['create'])), # ignored for passing '--date "0 0"' in tests
823 ('delete', set(['delete'])),
823 ('delete', set(['delete'])),
824 ('edit', set(['create'])),
824 ('edit', set(['create'])),
825 ('list', set(['list'])),
825 ('list', set(['list'])),
826 ('message', set(['create'])),
826 ('message', set(['create'])),
827 ('name', set(['create'])),
827 ('name', set(['create'])),
828 ('patch', set(['patch', 'list'])),
828 ('patch', set(['patch', 'list'])),
829 ('stat', set(['stat', 'list'])),
829 ('stat', set(['stat', 'list'])),
830 ]
830 ]
831 def checkopt(opt):
831 def checkopt(opt):
832 if opts[opt]:
832 if opts[opt]:
833 for i, allowable in allowables:
833 for i, allowable in allowables:
834 if opts[i] and opt not in allowable:
834 if opts[i] and opt not in allowable:
835 raise error.Abort(_("options '--%s' and '--%s' may not be "
835 raise error.Abort(_("options '--%s' and '--%s' may not be "
836 "used together") % (opt, i))
836 "used together") % (opt, i))
837 return True
837 return True
838 if checkopt('cleanup'):
838 if checkopt('cleanup'):
839 if pats:
839 if pats:
840 raise error.Abort(_("cannot specify names when using '--cleanup'"))
840 raise error.Abort(_("cannot specify names when using '--cleanup'"))
841 return cleanupcmd(ui, repo)
841 return cleanupcmd(ui, repo)
842 elif checkopt('delete'):
842 elif checkopt('delete'):
843 return deletecmd(ui, repo, pats)
843 return deletecmd(ui, repo, pats)
844 elif checkopt('list'):
844 elif checkopt('list'):
845 return listcmd(ui, repo, pats, opts)
845 return listcmd(ui, repo, pats, opts)
846 elif checkopt('patch'):
846 elif checkopt('patch'):
847 return singlepatchcmds(ui, repo, pats, opts, subcommand='patch')
847 return singlepatchcmds(ui, repo, pats, opts, subcommand='patch')
848 elif checkopt('stat'):
848 elif checkopt('stat'):
849 return singlepatchcmds(ui, repo, pats, opts, subcommand='stat')
849 return singlepatchcmds(ui, repo, pats, opts, subcommand='stat')
850 else:
850 else:
851 return createcmd(ui, repo, pats, opts)
851 return createcmd(ui, repo, pats, opts)
852
852
853 def extsetup(ui):
853 def extsetup(ui):
854 cmdutil.unfinishedstates.append(
854 cmdutil.unfinishedstates.append(
855 [shelvedstate._filename, False, False,
855 [shelvedstate._filename, False, False,
856 _('unshelve already in progress'),
856 _('unshelve already in progress'),
857 _("use 'hg unshelve --continue' or 'hg unshelve --abort'")])
857 _("use 'hg unshelve --continue' or 'hg unshelve --abort'")])
858 cmdutil.afterresolvedstates.append(
858 cmdutil.afterresolvedstates.append(
859 [shelvedstate._filename, _('hg unshelve --continue')])
859 [shelvedstate._filename, _('hg unshelve --continue')])
@@ -1,1316 +1,1316 b''
1 $ cat <<EOF >> $HGRCPATH
1 $ cat <<EOF >> $HGRCPATH
2 > [extensions]
2 > [extensions]
3 > mq =
3 > mq =
4 > shelve =
4 > shelve =
5 > [defaults]
5 > [defaults]
6 > diff = --nodates --git
6 > diff = --nodates --git
7 > qnew = --date '0 0'
7 > qnew = --date '0 0'
8 > [shelve]
8 > [shelve]
9 > maxbackups = 2
9 > maxbackups = 2
10 > EOF
10 > EOF
11
11
12 $ hg init repo
12 $ hg init repo
13 $ cd repo
13 $ cd repo
14 $ mkdir a b
14 $ mkdir a b
15 $ echo a > a/a
15 $ echo a > a/a
16 $ echo b > b/b
16 $ echo b > b/b
17 $ echo c > c
17 $ echo c > c
18 $ echo d > d
18 $ echo d > d
19 $ echo x > x
19 $ echo x > x
20 $ hg addremove -q
20 $ hg addremove -q
21
21
22 shelve has a help message
22 shelve has a help message
23 $ hg shelve -h
23 $ hg shelve -h
24 hg shelve [OPTION]... [FILE]...
24 hg shelve [OPTION]... [FILE]...
25
25
26 save and set aside changes from the working directory
26 save and set aside changes from the working directory
27
27
28 Shelving takes files that "hg status" reports as not clean, saves the
28 Shelving takes files that "hg status" reports as not clean, saves the
29 modifications to a bundle (a shelved change), and reverts the files so
29 modifications to a bundle (a shelved change), and reverts the files so
30 that their state in the working directory becomes clean.
30 that their state in the working directory becomes clean.
31
31
32 To restore these changes to the working directory, using "hg unshelve";
32 To restore these changes to the working directory, using "hg unshelve";
33 this will work even if you switch to a different commit.
33 this will work even if you switch to a different commit.
34
34
35 When no files are specified, "hg shelve" saves all not-clean files. If
35 When no files are specified, "hg shelve" saves all not-clean files. If
36 specific files or directories are named, only changes to those files are
36 specific files or directories are named, only changes to those files are
37 shelved.
37 shelved.
38
38
39 Each shelved change has a name that makes it easier to find later. The
39 Each shelved change has a name that makes it easier to find later. The
40 name of a shelved change defaults to being based on the active bookmark,
40 name of a shelved change defaults to being based on the active bookmark,
41 or if there is no active bookmark, the current named branch. To specify a
41 or if there is no active bookmark, the current named branch. To specify a
42 different name, use "--name".
42 different name, use "--name".
43
43
44 To see a list of existing shelved changes, use the "--list" option. For
44 To see a list of existing shelved changes, use the "--list" option. For
45 each shelved change, this will print its name, age, and description; use "
45 each shelved change, this will print its name, age, and description; use "
46 --patch" or "--stat" for more details.
46 --patch" or "--stat" for more details.
47
47
48 To delete specific shelved changes, use "--delete". To delete all shelved
48 To delete specific shelved changes, use "--delete". To delete all shelved
49 changes, use "--cleanup".
49 changes, use "--cleanup".
50
50
51 (use "hg help -e shelve" to show help for the shelve extension)
51 (use "hg help -e shelve" to show help for the shelve extension)
52
52
53 options ([+] can be repeated):
53 options ([+] can be repeated):
54
54
55 -A --addremove mark new/missing files as added/removed before
55 -A --addremove mark new/missing files as added/removed before
56 shelving
56 shelving
57 -u --unknown Store unknown files in the shelve
57 -u --unknown store unknown files in the shelve
58 --cleanup delete all shelved changes
58 --cleanup delete all shelved changes
59 --date DATE shelve with the specified commit date
59 --date DATE shelve with the specified commit date
60 -d --delete delete the named shelved change(s)
60 -d --delete delete the named shelved change(s)
61 -e --edit invoke editor on commit messages
61 -e --edit invoke editor on commit messages
62 -l --list list current shelves
62 -l --list list current shelves
63 -m --message TEXT use text as shelve message
63 -m --message TEXT use text as shelve message
64 -n --name NAME use the given name for the shelved commit
64 -n --name NAME use the given name for the shelved commit
65 -p --patch show patch
65 -p --patch show patch
66 -i --interactive interactive mode, only works while creating a shelve
66 -i --interactive interactive mode, only works while creating a shelve
67 --stat output diffstat-style summary of changes
67 --stat output diffstat-style summary of changes
68 -I --include PATTERN [+] include names matching the given patterns
68 -I --include PATTERN [+] include names matching the given patterns
69 -X --exclude PATTERN [+] exclude names matching the given patterns
69 -X --exclude PATTERN [+] exclude names matching the given patterns
70 --mq operate on patch repository
70 --mq operate on patch repository
71
71
72 (some details hidden, use --verbose to show complete help)
72 (some details hidden, use --verbose to show complete help)
73
73
74 shelving in an empty repo should be possible
74 shelving in an empty repo should be possible
75 (this tests also that editor is not invoked, if '--edit' is not
75 (this tests also that editor is not invoked, if '--edit' is not
76 specified)
76 specified)
77
77
78 $ HGEDITOR=cat hg shelve
78 $ HGEDITOR=cat hg shelve
79 shelved as default
79 shelved as default
80 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
80 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
81
81
82 $ hg unshelve
82 $ hg unshelve
83 unshelving change 'default'
83 unshelving change 'default'
84
84
85 $ hg commit -q -m 'initial commit'
85 $ hg commit -q -m 'initial commit'
86
86
87 $ hg shelve
87 $ hg shelve
88 nothing changed
88 nothing changed
89 [1]
89 [1]
90
90
91 make sure shelve files were backed up
91 make sure shelve files were backed up
92
92
93 $ ls .hg/shelve-backup
93 $ ls .hg/shelve-backup
94 default.hg
94 default.hg
95 default.patch
95 default.patch
96
96
97 create an mq patch - shelving should work fine with a patch applied
97 create an mq patch - shelving should work fine with a patch applied
98
98
99 $ echo n > n
99 $ echo n > n
100 $ hg add n
100 $ hg add n
101 $ hg commit n -m second
101 $ hg commit n -m second
102 $ hg qnew second.patch
102 $ hg qnew second.patch
103
103
104 shelve a change that we will delete later
104 shelve a change that we will delete later
105
105
106 $ echo a >> a/a
106 $ echo a >> a/a
107 $ hg shelve
107 $ hg shelve
108 shelved as default
108 shelved as default
109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110
110
111 set up some more complex changes to shelve
111 set up some more complex changes to shelve
112
112
113 $ echo a >> a/a
113 $ echo a >> a/a
114 $ hg mv b b.rename
114 $ hg mv b b.rename
115 moving b/b to b.rename/b (glob)
115 moving b/b to b.rename/b (glob)
116 $ hg cp c c.copy
116 $ hg cp c c.copy
117 $ hg status -C
117 $ hg status -C
118 M a/a
118 M a/a
119 A b.rename/b
119 A b.rename/b
120 b/b
120 b/b
121 A c.copy
121 A c.copy
122 c
122 c
123 R b/b
123 R b/b
124
124
125 prevent some foot-shooting
125 prevent some foot-shooting
126
126
127 $ hg shelve -n foo/bar
127 $ hg shelve -n foo/bar
128 abort: shelved change names may not contain slashes
128 abort: shelved change names may not contain slashes
129 [255]
129 [255]
130 $ hg shelve -n .baz
130 $ hg shelve -n .baz
131 abort: shelved change names may not start with '.'
131 abort: shelved change names may not start with '.'
132 [255]
132 [255]
133
133
134 the common case - no options or filenames
134 the common case - no options or filenames
135
135
136 $ hg shelve
136 $ hg shelve
137 shelved as default-01
137 shelved as default-01
138 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
138 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
139 $ hg status -C
139 $ hg status -C
140
140
141 ensure that our shelved changes exist
141 ensure that our shelved changes exist
142
142
143 $ hg shelve -l
143 $ hg shelve -l
144 default-01 (*)* changes to: [mq]: second.patch (glob)
144 default-01 (*)* changes to: [mq]: second.patch (glob)
145 default (*)* changes to: [mq]: second.patch (glob)
145 default (*)* changes to: [mq]: second.patch (glob)
146
146
147 $ hg shelve -l -p default
147 $ hg shelve -l -p default
148 default (*)* changes to: [mq]: second.patch (glob)
148 default (*)* changes to: [mq]: second.patch (glob)
149
149
150 diff --git a/a/a b/a/a
150 diff --git a/a/a b/a/a
151 --- a/a/a
151 --- a/a/a
152 +++ b/a/a
152 +++ b/a/a
153 @@ -1,1 +1,2 @@
153 @@ -1,1 +1,2 @@
154 a
154 a
155 +a
155 +a
156
156
157 $ hg shelve --list --addremove
157 $ hg shelve --list --addremove
158 abort: options '--list' and '--addremove' may not be used together
158 abort: options '--list' and '--addremove' may not be used together
159 [255]
159 [255]
160
160
161 delete our older shelved change
161 delete our older shelved change
162
162
163 $ hg shelve -d default
163 $ hg shelve -d default
164 $ hg qfinish -a -q
164 $ hg qfinish -a -q
165
165
166 ensure shelve backups aren't overwritten
166 ensure shelve backups aren't overwritten
167
167
168 $ ls .hg/shelve-backup/
168 $ ls .hg/shelve-backup/
169 default-1.hg
169 default-1.hg
170 default-1.patch
170 default-1.patch
171 default.hg
171 default.hg
172 default.patch
172 default.patch
173
173
174 local edits should not prevent a shelved change from applying
174 local edits should not prevent a shelved change from applying
175
175
176 $ printf "z\na\n" > a/a
176 $ printf "z\na\n" > a/a
177 $ hg unshelve --keep
177 $ hg unshelve --keep
178 unshelving change 'default-01'
178 unshelving change 'default-01'
179 temporarily committing pending changes (restore with 'hg unshelve --abort')
179 temporarily committing pending changes (restore with 'hg unshelve --abort')
180 rebasing shelved changes
180 rebasing shelved changes
181 rebasing 4:32c69314e062 "changes to: [mq]: second.patch" (tip)
181 rebasing 4:32c69314e062 "changes to: [mq]: second.patch" (tip)
182 merging a/a
182 merging a/a
183
183
184 $ hg revert --all -q
184 $ hg revert --all -q
185 $ rm a/a.orig b.rename/b c.copy
185 $ rm a/a.orig b.rename/b c.copy
186
186
187 apply it and make sure our state is as expected
187 apply it and make sure our state is as expected
188
188
189 (this also tests that same timestamp prevents backups from being
189 (this also tests that same timestamp prevents backups from being
190 removed, even though there are more than 'maxbackups' backups)
190 removed, even though there are more than 'maxbackups' backups)
191
191
192 $ f -t .hg/shelve-backup/default.hg
192 $ f -t .hg/shelve-backup/default.hg
193 .hg/shelve-backup/default.hg: file
193 .hg/shelve-backup/default.hg: file
194 $ touch -t 200001010000 .hg/shelve-backup/default.hg
194 $ touch -t 200001010000 .hg/shelve-backup/default.hg
195 $ f -t .hg/shelve-backup/default-1.hg
195 $ f -t .hg/shelve-backup/default-1.hg
196 .hg/shelve-backup/default-1.hg: file
196 .hg/shelve-backup/default-1.hg: file
197 $ touch -t 200001010000 .hg/shelve-backup/default-1.hg
197 $ touch -t 200001010000 .hg/shelve-backup/default-1.hg
198
198
199 $ hg unshelve
199 $ hg unshelve
200 unshelving change 'default-01'
200 unshelving change 'default-01'
201 $ hg status -C
201 $ hg status -C
202 M a/a
202 M a/a
203 A b.rename/b
203 A b.rename/b
204 b/b
204 b/b
205 A c.copy
205 A c.copy
206 c
206 c
207 R b/b
207 R b/b
208 $ hg shelve -l
208 $ hg shelve -l
209
209
210 (both of default.hg and default-1.hg should be still kept, because it
210 (both of default.hg and default-1.hg should be still kept, because it
211 is difficult to decide actual order of them from same timestamp)
211 is difficult to decide actual order of them from same timestamp)
212
212
213 $ ls .hg/shelve-backup/
213 $ ls .hg/shelve-backup/
214 default-01.hg
214 default-01.hg
215 default-01.patch
215 default-01.patch
216 default-1.hg
216 default-1.hg
217 default-1.patch
217 default-1.patch
218 default.hg
218 default.hg
219 default.patch
219 default.patch
220
220
221 $ hg unshelve
221 $ hg unshelve
222 abort: no shelved changes to apply!
222 abort: no shelved changes to apply!
223 [255]
223 [255]
224 $ hg unshelve foo
224 $ hg unshelve foo
225 abort: shelved change 'foo' not found
225 abort: shelved change 'foo' not found
226 [255]
226 [255]
227
227
228 named shelves, specific filenames, and "commit messages" should all work
228 named shelves, specific filenames, and "commit messages" should all work
229 (this tests also that editor is invoked, if '--edit' is specified)
229 (this tests also that editor is invoked, if '--edit' is specified)
230
230
231 $ hg status -C
231 $ hg status -C
232 M a/a
232 M a/a
233 A b.rename/b
233 A b.rename/b
234 b/b
234 b/b
235 A c.copy
235 A c.copy
236 c
236 c
237 R b/b
237 R b/b
238 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
238 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
239 wat
239 wat
240
240
241
241
242 HG: Enter commit message. Lines beginning with 'HG:' are removed.
242 HG: Enter commit message. Lines beginning with 'HG:' are removed.
243 HG: Leave message empty to abort commit.
243 HG: Leave message empty to abort commit.
244 HG: --
244 HG: --
245 HG: user: shelve@localhost
245 HG: user: shelve@localhost
246 HG: branch 'default'
246 HG: branch 'default'
247 HG: changed a/a
247 HG: changed a/a
248
248
249 expect "a" to no longer be present, but status otherwise unchanged
249 expect "a" to no longer be present, but status otherwise unchanged
250
250
251 $ hg status -C
251 $ hg status -C
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 --stat
257 $ hg shelve -l --stat
258 wibble (*) wat (glob)
258 wibble (*) wat (glob)
259 a/a | 1 +
259 a/a | 1 +
260 1 files changed, 1 insertions(+), 0 deletions(-)
260 1 files changed, 1 insertions(+), 0 deletions(-)
261
261
262 and now "a/a" should reappear
262 and now "a/a" should reappear
263
263
264 $ cd a
264 $ cd a
265 $ hg unshelve -q wibble
265 $ hg unshelve -q wibble
266 $ cd ..
266 $ cd ..
267 $ hg status -C
267 $ hg status -C
268 M a/a
268 M a/a
269 A b.rename/b
269 A b.rename/b
270 b/b
270 b/b
271 A c.copy
271 A c.copy
272 c
272 c
273 R b/b
273 R b/b
274
274
275 ensure old shelve backups are being deleted automatically
275 ensure old shelve backups are being deleted automatically
276
276
277 $ ls .hg/shelve-backup/
277 $ ls .hg/shelve-backup/
278 default-01.hg
278 default-01.hg
279 default-01.patch
279 default-01.patch
280 wibble.hg
280 wibble.hg
281 wibble.patch
281 wibble.patch
282
282
283 cause unshelving to result in a merge with 'a' conflicting
283 cause unshelving to result in a merge with 'a' conflicting
284
284
285 $ hg shelve -q
285 $ hg shelve -q
286 $ echo c>>a/a
286 $ echo c>>a/a
287 $ hg commit -m second
287 $ hg commit -m second
288 $ hg tip --template '{files}\n'
288 $ hg tip --template '{files}\n'
289 a/a
289 a/a
290
290
291 add an unrelated change that should be preserved
291 add an unrelated change that should be preserved
292
292
293 $ mkdir foo
293 $ mkdir foo
294 $ echo foo > foo/foo
294 $ echo foo > foo/foo
295 $ hg add foo/foo
295 $ hg add foo/foo
296
296
297 force a conflicted merge to occur
297 force a conflicted merge to occur
298
298
299 $ hg unshelve
299 $ hg unshelve
300 unshelving change 'default'
300 unshelving change 'default'
301 temporarily committing pending changes (restore with 'hg unshelve --abort')
301 temporarily committing pending changes (restore with 'hg unshelve --abort')
302 rebasing shelved changes
302 rebasing shelved changes
303 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
303 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
304 merging a/a
304 merging a/a
305 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
305 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
306 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
306 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
307 [1]
307 [1]
308
308
309 ensure that we have a merge with unresolved conflicts
309 ensure that we have a merge with unresolved conflicts
310
310
311 $ hg heads -q --template '{rev}\n'
311 $ hg heads -q --template '{rev}\n'
312 5
312 5
313 4
313 4
314 $ hg parents -q --template '{rev}\n'
314 $ hg parents -q --template '{rev}\n'
315 4
315 4
316 5
316 5
317 $ hg status
317 $ hg status
318 M a/a
318 M a/a
319 M b.rename/b
319 M b.rename/b
320 M c.copy
320 M c.copy
321 R b/b
321 R b/b
322 ? a/a.orig
322 ? a/a.orig
323 $ hg diff
323 $ hg diff
324 diff --git a/a/a b/a/a
324 diff --git a/a/a b/a/a
325 --- a/a/a
325 --- a/a/a
326 +++ b/a/a
326 +++ b/a/a
327 @@ -1,2 +1,6 @@
327 @@ -1,2 +1,6 @@
328 a
328 a
329 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
329 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
330 c
330 c
331 +=======
331 +=======
332 +a
332 +a
333 +>>>>>>> source: 32c69314e062 - shelve: changes to: [mq]: second.patch
333 +>>>>>>> source: 32c69314e062 - shelve: changes to: [mq]: second.patch
334 diff --git a/b/b b/b.rename/b
334 diff --git a/b/b b/b.rename/b
335 rename from b/b
335 rename from b/b
336 rename to b.rename/b
336 rename to b.rename/b
337 diff --git a/c b/c.copy
337 diff --git a/c b/c.copy
338 copy from c
338 copy from c
339 copy to c.copy
339 copy to c.copy
340 $ hg resolve -l
340 $ hg resolve -l
341 U a/a
341 U a/a
342
342
343 $ hg shelve
343 $ hg shelve
344 abort: unshelve already in progress
344 abort: unshelve already in progress
345 (use 'hg unshelve --continue' or 'hg unshelve --abort')
345 (use 'hg unshelve --continue' or 'hg unshelve --abort')
346 [255]
346 [255]
347
347
348 abort the unshelve and be happy
348 abort the unshelve and be happy
349
349
350 $ hg status
350 $ hg status
351 M a/a
351 M a/a
352 M b.rename/b
352 M b.rename/b
353 M c.copy
353 M c.copy
354 R b/b
354 R b/b
355 ? a/a.orig
355 ? a/a.orig
356 $ hg unshelve -a
356 $ hg unshelve -a
357 rebase aborted
357 rebase aborted
358 unshelve of 'default' aborted
358 unshelve of 'default' aborted
359 $ hg heads -q
359 $ hg heads -q
360 3:2e69b451d1ea
360 3:2e69b451d1ea
361 $ hg parents
361 $ hg parents
362 changeset: 3:2e69b451d1ea
362 changeset: 3:2e69b451d1ea
363 tag: tip
363 tag: tip
364 user: test
364 user: test
365 date: Thu Jan 01 00:00:00 1970 +0000
365 date: Thu Jan 01 00:00:00 1970 +0000
366 summary: second
366 summary: second
367
367
368 $ hg resolve -l
368 $ hg resolve -l
369 $ hg status
369 $ hg status
370 A foo/foo
370 A foo/foo
371 ? a/a.orig
371 ? a/a.orig
372
372
373 try to continue with no unshelve underway
373 try to continue with no unshelve underway
374
374
375 $ hg unshelve -c
375 $ hg unshelve -c
376 abort: no unshelve operation underway
376 abort: no unshelve operation underway
377 [255]
377 [255]
378 $ hg status
378 $ hg status
379 A foo/foo
379 A foo/foo
380 ? a/a.orig
380 ? a/a.orig
381
381
382 redo the unshelve to get a conflict
382 redo the unshelve to get a conflict
383
383
384 $ hg unshelve -q
384 $ hg unshelve -q
385 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
385 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
386 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
386 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
387 [1]
387 [1]
388
388
389 attempt to continue
389 attempt to continue
390
390
391 $ hg unshelve -c
391 $ hg unshelve -c
392 abort: unresolved conflicts, can't continue
392 abort: unresolved conflicts, can't continue
393 (see 'hg resolve', then 'hg unshelve --continue')
393 (see 'hg resolve', then 'hg unshelve --continue')
394 [255]
394 [255]
395
395
396 $ hg revert -r . a/a
396 $ hg revert -r . a/a
397 $ hg resolve -m a/a
397 $ hg resolve -m a/a
398 (no more unresolved files)
398 (no more unresolved files)
399 continue: hg unshelve --continue
399 continue: hg unshelve --continue
400
400
401 $ hg commit -m 'commit while unshelve in progress'
401 $ hg commit -m 'commit while unshelve in progress'
402 abort: unshelve already in progress
402 abort: unshelve already in progress
403 (use 'hg unshelve --continue' or 'hg unshelve --abort')
403 (use 'hg unshelve --continue' or 'hg unshelve --abort')
404 [255]
404 [255]
405
405
406 $ hg unshelve -c
406 $ hg unshelve -c
407 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
407 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
408 unshelve of 'default' complete
408 unshelve of 'default' complete
409
409
410 ensure the repo is as we hope
410 ensure the repo is as we hope
411
411
412 $ hg parents
412 $ hg parents
413 changeset: 3:2e69b451d1ea
413 changeset: 3:2e69b451d1ea
414 tag: tip
414 tag: tip
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:00 1970 +0000
416 date: Thu Jan 01 00:00:00 1970 +0000
417 summary: second
417 summary: second
418
418
419 $ hg heads -q
419 $ hg heads -q
420 3:2e69b451d1ea
420 3:2e69b451d1ea
421
421
422 $ hg status -C
422 $ hg status -C
423 A b.rename/b
423 A b.rename/b
424 b/b
424 b/b
425 A c.copy
425 A c.copy
426 c
426 c
427 A foo/foo
427 A foo/foo
428 R b/b
428 R b/b
429 ? a/a.orig
429 ? a/a.orig
430
430
431 there should be no shelves left
431 there should be no shelves left
432
432
433 $ hg shelve -l
433 $ hg shelve -l
434
434
435 #if execbit
435 #if execbit
436
436
437 ensure that metadata-only changes are shelved
437 ensure that metadata-only changes are shelved
438
438
439 $ chmod +x a/a
439 $ chmod +x a/a
440 $ hg shelve -q -n execbit a/a
440 $ hg shelve -q -n execbit a/a
441 $ hg status a/a
441 $ hg status a/a
442 $ hg unshelve -q execbit
442 $ hg unshelve -q execbit
443 $ hg status a/a
443 $ hg status a/a
444 M a/a
444 M a/a
445 $ hg revert a/a
445 $ hg revert a/a
446
446
447 #endif
447 #endif
448
448
449 #if symlink
449 #if symlink
450
450
451 $ rm a/a
451 $ rm a/a
452 $ ln -s foo a/a
452 $ ln -s foo a/a
453 $ hg shelve -q -n symlink a/a
453 $ hg shelve -q -n symlink a/a
454 $ hg status a/a
454 $ hg status a/a
455 $ hg unshelve -q symlink
455 $ hg unshelve -q symlink
456 $ hg status a/a
456 $ hg status a/a
457 M a/a
457 M a/a
458 $ hg revert a/a
458 $ hg revert a/a
459
459
460 #endif
460 #endif
461
461
462 set up another conflict between a commit and a shelved change
462 set up another conflict between a commit and a shelved change
463
463
464 $ hg revert -q -C -a
464 $ hg revert -q -C -a
465 $ rm a/a.orig b.rename/b c.copy
465 $ rm a/a.orig b.rename/b c.copy
466 $ echo a >> a/a
466 $ echo a >> a/a
467 $ hg shelve -q
467 $ hg shelve -q
468 $ echo x >> a/a
468 $ echo x >> a/a
469 $ hg ci -m 'create conflict'
469 $ hg ci -m 'create conflict'
470 $ hg add foo/foo
470 $ hg add foo/foo
471
471
472 if we resolve a conflict while unshelving, the unshelve should succeed
472 if we resolve a conflict while unshelving, the unshelve should succeed
473
473
474 $ hg unshelve --tool :merge-other --keep
474 $ hg unshelve --tool :merge-other --keep
475 unshelving change 'default'
475 unshelving change 'default'
476 temporarily committing pending changes (restore with 'hg unshelve --abort')
476 temporarily committing pending changes (restore with 'hg unshelve --abort')
477 rebasing shelved changes
477 rebasing shelved changes
478 rebasing 6:2f694dd83a13 "changes to: second" (tip)
478 rebasing 6:2f694dd83a13 "changes to: second" (tip)
479 merging a/a
479 merging a/a
480 $ hg parents -q
480 $ hg parents -q
481 4:33f7f61e6c5e
481 4:33f7f61e6c5e
482 $ hg shelve -l
482 $ hg shelve -l
483 default (*)* changes to: second (glob)
483 default (*)* changes to: second (glob)
484 $ hg status
484 $ hg status
485 M a/a
485 M a/a
486 A foo/foo
486 A foo/foo
487 $ cat a/a
487 $ cat a/a
488 a
488 a
489 c
489 c
490 a
490 a
491 $ cat > a/a << EOF
491 $ cat > a/a << EOF
492 > a
492 > a
493 > c
493 > c
494 > x
494 > x
495 > EOF
495 > EOF
496
496
497 $ HGMERGE=true hg unshelve
497 $ HGMERGE=true hg unshelve
498 unshelving change 'default'
498 unshelving change 'default'
499 temporarily committing pending changes (restore with 'hg unshelve --abort')
499 temporarily committing pending changes (restore with 'hg unshelve --abort')
500 rebasing shelved changes
500 rebasing shelved changes
501 rebasing 6:2f694dd83a13 "changes to: second" (tip)
501 rebasing 6:2f694dd83a13 "changes to: second" (tip)
502 merging a/a
502 merging a/a
503 note: rebase of 6:2f694dd83a13 created no changes to commit
503 note: rebase of 6:2f694dd83a13 created no changes to commit
504 $ hg parents -q
504 $ hg parents -q
505 4:33f7f61e6c5e
505 4:33f7f61e6c5e
506 $ hg shelve -l
506 $ hg shelve -l
507 $ hg status
507 $ hg status
508 A foo/foo
508 A foo/foo
509 $ cat a/a
509 $ cat a/a
510 a
510 a
511 c
511 c
512 x
512 x
513
513
514 test keep and cleanup
514 test keep and cleanup
515
515
516 $ hg shelve
516 $ hg shelve
517 shelved as default
517 shelved as default
518 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
518 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
519 $ hg shelve --list
519 $ hg shelve --list
520 default (*)* changes to: create conflict (glob)
520 default (*)* changes to: create conflict (glob)
521 $ hg unshelve -k
521 $ hg unshelve -k
522 unshelving change 'default'
522 unshelving change 'default'
523 $ hg shelve --list
523 $ hg shelve --list
524 default (*)* changes to: create conflict (glob)
524 default (*)* changes to: create conflict (glob)
525 $ hg shelve --cleanup
525 $ hg shelve --cleanup
526 $ hg shelve --list
526 $ hg shelve --list
527
527
528 $ hg shelve --cleanup --delete
528 $ hg shelve --cleanup --delete
529 abort: options '--cleanup' and '--delete' may not be used together
529 abort: options '--cleanup' and '--delete' may not be used together
530 [255]
530 [255]
531 $ hg shelve --cleanup --patch
531 $ hg shelve --cleanup --patch
532 abort: options '--cleanup' and '--patch' may not be used together
532 abort: options '--cleanup' and '--patch' may not be used together
533 [255]
533 [255]
534 $ hg shelve --cleanup --message MESSAGE
534 $ hg shelve --cleanup --message MESSAGE
535 abort: options '--cleanup' and '--message' may not be used together
535 abort: options '--cleanup' and '--message' may not be used together
536 [255]
536 [255]
537
537
538 test bookmarks
538 test bookmarks
539
539
540 $ hg bookmark test
540 $ hg bookmark test
541 $ hg bookmark
541 $ hg bookmark
542 * test 4:33f7f61e6c5e
542 * test 4:33f7f61e6c5e
543 $ hg shelve
543 $ hg shelve
544 shelved as test
544 shelved as test
545 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
545 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
546 $ hg bookmark
546 $ hg bookmark
547 * test 4:33f7f61e6c5e
547 * test 4:33f7f61e6c5e
548 $ hg unshelve
548 $ hg unshelve
549 unshelving change 'test'
549 unshelving change 'test'
550 $ hg bookmark
550 $ hg bookmark
551 * test 4:33f7f61e6c5e
551 * test 4:33f7f61e6c5e
552
552
553 shelve should still work even if mq is disabled
553 shelve should still work even if mq is disabled
554
554
555 $ hg --config extensions.mq=! shelve
555 $ hg --config extensions.mq=! shelve
556 shelved as test
556 shelved as test
557 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
557 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
558 $ hg --config extensions.mq=! shelve --list
558 $ hg --config extensions.mq=! shelve --list
559 test (*)* changes to: create conflict (glob)
559 test (*)* changes to: create conflict (glob)
560 $ hg bookmark
560 $ hg bookmark
561 * test 4:33f7f61e6c5e
561 * test 4:33f7f61e6c5e
562 $ hg --config extensions.mq=! unshelve
562 $ hg --config extensions.mq=! unshelve
563 unshelving change 'test'
563 unshelving change 'test'
564 $ hg bookmark
564 $ hg bookmark
565 * test 4:33f7f61e6c5e
565 * test 4:33f7f61e6c5e
566
566
567 shelve should leave dirstate clean (issue4055)
567 shelve should leave dirstate clean (issue4055)
568
568
569 $ cd ..
569 $ cd ..
570 $ hg init shelverebase
570 $ hg init shelverebase
571 $ cd shelverebase
571 $ cd shelverebase
572 $ printf 'x\ny\n' > x
572 $ printf 'x\ny\n' > x
573 $ echo z > z
573 $ echo z > z
574 $ hg commit -Aqm xy
574 $ hg commit -Aqm xy
575 $ echo z >> x
575 $ echo z >> x
576 $ hg commit -Aqm z
576 $ hg commit -Aqm z
577 $ hg up 0
577 $ hg up 0
578 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
579 $ printf 'a\nx\ny\nz\n' > x
579 $ printf 'a\nx\ny\nz\n' > x
580 $ hg commit -Aqm xyz
580 $ hg commit -Aqm xyz
581 $ echo c >> z
581 $ echo c >> z
582 $ hg shelve
582 $ hg shelve
583 shelved as default
583 shelved as default
584 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
585 $ hg rebase -d 1 --config extensions.rebase=
585 $ hg rebase -d 1 --config extensions.rebase=
586 rebasing 2:323bfa07f744 "xyz" (tip)
586 rebasing 2:323bfa07f744 "xyz" (tip)
587 merging x
587 merging x
588 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
588 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
589 $ hg unshelve
589 $ hg unshelve
590 unshelving change 'default'
590 unshelving change 'default'
591 rebasing shelved changes
591 rebasing shelved changes
592 rebasing 4:82a0d7d6ba61 "changes to: xyz" (tip)
592 rebasing 4:82a0d7d6ba61 "changes to: xyz" (tip)
593 $ hg status
593 $ hg status
594 M z
594 M z
595
595
596 $ cd ..
596 $ cd ..
597
597
598 shelve should only unshelve pending changes (issue4068)
598 shelve should only unshelve pending changes (issue4068)
599
599
600 $ hg init onlypendingchanges
600 $ hg init onlypendingchanges
601 $ cd onlypendingchanges
601 $ cd onlypendingchanges
602 $ touch a
602 $ touch a
603 $ hg ci -Aqm a
603 $ hg ci -Aqm a
604 $ touch b
604 $ touch b
605 $ hg ci -Aqm b
605 $ hg ci -Aqm b
606 $ hg up -q 0
606 $ hg up -q 0
607 $ touch c
607 $ touch c
608 $ hg ci -Aqm c
608 $ hg ci -Aqm c
609
609
610 $ touch d
610 $ touch d
611 $ hg add d
611 $ hg add d
612 $ hg shelve
612 $ hg shelve
613 shelved as default
613 shelved as default
614 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
614 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
615 $ hg up -q 1
615 $ hg up -q 1
616 $ hg unshelve
616 $ hg unshelve
617 unshelving change 'default'
617 unshelving change 'default'
618 rebasing shelved changes
618 rebasing shelved changes
619 rebasing 3:958bcbd1776e "changes to: c" (tip)
619 rebasing 3:958bcbd1776e "changes to: c" (tip)
620 $ hg status
620 $ hg status
621 A d
621 A d
622
622
623 unshelve should work on an ancestor of the original commit
623 unshelve should work on an ancestor of the original commit
624
624
625 $ hg shelve
625 $ hg shelve
626 shelved as default
626 shelved as default
627 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
627 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
628 $ hg up 0
628 $ hg up 0
629 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
629 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
630 $ hg unshelve
630 $ hg unshelve
631 unshelving change 'default'
631 unshelving change 'default'
632 rebasing shelved changes
632 rebasing shelved changes
633 rebasing 3:013284d9655e "changes to: b" (tip)
633 rebasing 3:013284d9655e "changes to: b" (tip)
634 $ hg status
634 $ hg status
635 A d
635 A d
636
636
637 test bug 4073 we need to enable obsolete markers for it
637 test bug 4073 we need to enable obsolete markers for it
638
638
639 $ cat >> $HGRCPATH << EOF
639 $ cat >> $HGRCPATH << EOF
640 > [experimental]
640 > [experimental]
641 > evolution=createmarkers
641 > evolution=createmarkers
642 > EOF
642 > EOF
643 $ hg shelve
643 $ hg shelve
644 shelved as default
644 shelved as default
645 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
645 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
646 $ hg debugobsolete `hg --debug id -i -r 1`
646 $ hg debugobsolete `hg --debug id -i -r 1`
647 $ hg unshelve
647 $ hg unshelve
648 unshelving change 'default'
648 unshelving change 'default'
649
649
650 unshelve should leave unknown files alone (issue4113)
650 unshelve should leave unknown files alone (issue4113)
651
651
652 $ echo e > e
652 $ echo e > e
653 $ hg shelve
653 $ hg shelve
654 shelved as default
654 shelved as default
655 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
655 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
656 $ hg status
656 $ hg status
657 ? e
657 ? e
658 $ hg unshelve
658 $ hg unshelve
659 unshelving change 'default'
659 unshelving change 'default'
660 $ hg status
660 $ hg status
661 A d
661 A d
662 ? e
662 ? e
663 $ cat e
663 $ cat e
664 e
664 e
665
665
666 unshelve should keep a copy of unknown files
666 unshelve should keep a copy of unknown files
667
667
668 $ hg add e
668 $ hg add e
669 $ hg shelve
669 $ hg shelve
670 shelved as default
670 shelved as default
671 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
671 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
672 $ echo z > e
672 $ echo z > e
673 $ hg unshelve
673 $ hg unshelve
674 unshelving change 'default'
674 unshelving change 'default'
675 $ cat e
675 $ cat e
676 e
676 e
677 $ cat e.orig
677 $ cat e.orig
678 z
678 z
679
679
680
680
681 unshelve and conflicts with tracked and untracked files
681 unshelve and conflicts with tracked and untracked files
682
682
683 preparing:
683 preparing:
684
684
685 $ rm *.orig
685 $ rm *.orig
686 $ hg ci -qm 'commit stuff'
686 $ hg ci -qm 'commit stuff'
687 $ hg phase -p null:
687 $ hg phase -p null:
688
688
689 no other changes - no merge:
689 no other changes - no merge:
690
690
691 $ echo f > f
691 $ echo f > f
692 $ hg add f
692 $ hg add f
693 $ hg shelve
693 $ hg shelve
694 shelved as default
694 shelved as default
695 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
695 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
696 $ echo g > f
696 $ echo g > f
697 $ hg unshelve
697 $ hg unshelve
698 unshelving change 'default'
698 unshelving change 'default'
699 $ hg st
699 $ hg st
700 A f
700 A f
701 ? f.orig
701 ? f.orig
702 $ cat f
702 $ cat f
703 f
703 f
704 $ cat f.orig
704 $ cat f.orig
705 g
705 g
706
706
707 other uncommitted changes - merge:
707 other uncommitted changes - merge:
708
708
709 $ hg st
709 $ hg st
710 A f
710 A f
711 ? f.orig
711 ? f.orig
712 $ hg shelve
712 $ hg shelve
713 shelved as default
713 shelved as default
714 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
714 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
715 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
715 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
716 o 4 changes to: commit stuff shelve@localhost
716 o 4 changes to: commit stuff shelve@localhost
717 |
717 |
718 $ hg log -G --template '{rev} {desc|firstline} {author}'
718 $ hg log -G --template '{rev} {desc|firstline} {author}'
719 @ 3 commit stuff test
719 @ 3 commit stuff test
720 |
720 |
721 | o 2 c test
721 | o 2 c test
722 |/
722 |/
723 o 0 a test
723 o 0 a test
724
724
725 $ mv f.orig f
725 $ mv f.orig f
726 $ echo 1 > a
726 $ echo 1 > a
727 $ hg unshelve --date '1073741824 0'
727 $ hg unshelve --date '1073741824 0'
728 unshelving change 'default'
728 unshelving change 'default'
729 temporarily committing pending changes (restore with 'hg unshelve --abort')
729 temporarily committing pending changes (restore with 'hg unshelve --abort')
730 rebasing shelved changes
730 rebasing shelved changes
731 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
731 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
732 merging f
732 merging f
733 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
733 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
734 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
734 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
735 [1]
735 [1]
736 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
736 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
737 @ 5 changes to: commit stuff shelve@localhost 1970-01-01 00:00 +0000
737 @ 5 changes to: commit stuff shelve@localhost 1970-01-01 00:00 +0000
738 |
738 |
739 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
739 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
740 |/
740 |/
741 o 3 commit stuff test 1970-01-01 00:00 +0000
741 o 3 commit stuff test 1970-01-01 00:00 +0000
742 |
742 |
743 | o 2 c test 1970-01-01 00:00 +0000
743 | o 2 c test 1970-01-01 00:00 +0000
744 |/
744 |/
745 o 0 a test 1970-01-01 00:00 +0000
745 o 0 a test 1970-01-01 00:00 +0000
746
746
747 $ hg st
747 $ hg st
748 M f
748 M f
749 ? f.orig
749 ? f.orig
750 $ cat f
750 $ cat f
751 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
751 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
752 g
752 g
753 =======
753 =======
754 f
754 f
755 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
755 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
756 $ cat f.orig
756 $ cat f.orig
757 g
757 g
758 $ hg unshelve --abort -t false
758 $ hg unshelve --abort -t false
759 tool option will be ignored
759 tool option will be ignored
760 rebase aborted
760 rebase aborted
761 unshelve of 'default' aborted
761 unshelve of 'default' aborted
762 $ hg st
762 $ hg st
763 M a
763 M a
764 ? f.orig
764 ? f.orig
765 $ cat f.orig
765 $ cat f.orig
766 g
766 g
767 $ hg unshelve
767 $ hg unshelve
768 unshelving change 'default'
768 unshelving change 'default'
769 temporarily committing pending changes (restore with 'hg unshelve --abort')
769 temporarily committing pending changes (restore with 'hg unshelve --abort')
770 rebasing shelved changes
770 rebasing shelved changes
771 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
771 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
772 $ hg st
772 $ hg st
773 M a
773 M a
774 A f
774 A f
775 ? f.orig
775 ? f.orig
776
776
777 other committed changes - merge:
777 other committed changes - merge:
778
778
779 $ hg shelve f
779 $ hg shelve f
780 shelved as default
780 shelved as default
781 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
781 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
782 $ hg ci a -m 'intermediate other change'
782 $ hg ci a -m 'intermediate other change'
783 $ mv f.orig f
783 $ mv f.orig f
784 $ hg unshelve
784 $ hg unshelve
785 unshelving change 'default'
785 unshelving change 'default'
786 rebasing shelved changes
786 rebasing shelved changes
787 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
787 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
788 merging f
788 merging f
789 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
789 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
790 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
790 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
791 [1]
791 [1]
792 $ hg st
792 $ hg st
793 M f
793 M f
794 ? f.orig
794 ? f.orig
795 $ cat f
795 $ cat f
796 <<<<<<< dest: * - test: intermediate other change (glob)
796 <<<<<<< dest: * - test: intermediate other change (glob)
797 g
797 g
798 =======
798 =======
799 f
799 f
800 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
800 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
801 $ cat f.orig
801 $ cat f.orig
802 g
802 g
803 $ hg unshelve --abort
803 $ hg unshelve --abort
804 rebase aborted
804 rebase aborted
805 unshelve of 'default' aborted
805 unshelve of 'default' aborted
806 $ hg st
806 $ hg st
807 ? f.orig
807 ? f.orig
808 $ cat f.orig
808 $ cat f.orig
809 g
809 g
810 $ hg shelve --delete default
810 $ hg shelve --delete default
811
811
812 Recreate some conflict again
812 Recreate some conflict again
813
813
814 $ cd ../repo
814 $ cd ../repo
815 $ hg up -C -r 3
815 $ hg up -C -r 3
816 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
816 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
817 (leaving bookmark test)
817 (leaving bookmark test)
818 $ echo y >> a/a
818 $ echo y >> a/a
819 $ hg shelve
819 $ hg shelve
820 shelved as default
820 shelved as default
821 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
821 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
822 $ hg up test
822 $ hg up test
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 (activating bookmark test)
824 (activating bookmark test)
825 $ hg bookmark
825 $ hg bookmark
826 * test 4:33f7f61e6c5e
826 * test 4:33f7f61e6c5e
827 $ hg unshelve
827 $ hg unshelve
828 unshelving change 'default'
828 unshelving change 'default'
829 rebasing shelved changes
829 rebasing shelved changes
830 rebasing 5:e42a7da90865 "changes to: second" (tip)
830 rebasing 5:e42a7da90865 "changes to: second" (tip)
831 merging a/a
831 merging a/a
832 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
832 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
833 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
833 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
834 [1]
834 [1]
835 $ hg bookmark
835 $ hg bookmark
836 test 4:33f7f61e6c5e
836 test 4:33f7f61e6c5e
837
837
838 Test that resolving all conflicts in one direction (so that the rebase
838 Test that resolving all conflicts in one direction (so that the rebase
839 is a no-op), works (issue4398)
839 is a no-op), works (issue4398)
840
840
841 $ hg revert -a -r .
841 $ hg revert -a -r .
842 reverting a/a (glob)
842 reverting a/a (glob)
843 $ hg resolve -m a/a
843 $ hg resolve -m a/a
844 (no more unresolved files)
844 (no more unresolved files)
845 continue: hg unshelve --continue
845 continue: hg unshelve --continue
846 $ hg unshelve -c
846 $ hg unshelve -c
847 rebasing 5:e42a7da90865 "changes to: second" (tip)
847 rebasing 5:e42a7da90865 "changes to: second" (tip)
848 note: rebase of 5:e42a7da90865 created no changes to commit
848 note: rebase of 5:e42a7da90865 created no changes to commit
849 unshelve of 'default' complete
849 unshelve of 'default' complete
850 $ hg bookmark
850 $ hg bookmark
851 * test 4:33f7f61e6c5e
851 * test 4:33f7f61e6c5e
852 $ hg diff
852 $ hg diff
853 $ hg status
853 $ hg status
854 ? a/a.orig
854 ? a/a.orig
855 ? foo/foo
855 ? foo/foo
856 $ hg summary
856 $ hg summary
857 parent: 4:33f7f61e6c5e tip
857 parent: 4:33f7f61e6c5e tip
858 create conflict
858 create conflict
859 branch: default
859 branch: default
860 bookmarks: *test
860 bookmarks: *test
861 commit: 2 unknown (clean)
861 commit: 2 unknown (clean)
862 update: (current)
862 update: (current)
863 phases: 5 draft
863 phases: 5 draft
864
864
865 $ hg shelve --delete --stat
865 $ hg shelve --delete --stat
866 abort: options '--delete' and '--stat' may not be used together
866 abort: options '--delete' and '--stat' may not be used together
867 [255]
867 [255]
868 $ hg shelve --delete --name NAME
868 $ hg shelve --delete --name NAME
869 abort: options '--delete' and '--name' may not be used together
869 abort: options '--delete' and '--name' may not be used together
870 [255]
870 [255]
871
871
872 Test interactive shelve
872 Test interactive shelve
873 $ cat <<EOF >> $HGRCPATH
873 $ cat <<EOF >> $HGRCPATH
874 > [ui]
874 > [ui]
875 > interactive = true
875 > interactive = true
876 > EOF
876 > EOF
877 $ echo 'a' >> a/b
877 $ echo 'a' >> a/b
878 $ cat a/a >> a/b
878 $ cat a/a >> a/b
879 $ echo 'x' >> a/b
879 $ echo 'x' >> a/b
880 $ mv a/b a/a
880 $ mv a/b a/a
881 $ echo 'a' >> foo/foo
881 $ echo 'a' >> foo/foo
882 $ hg st
882 $ hg st
883 M a/a
883 M a/a
884 ? a/a.orig
884 ? a/a.orig
885 ? foo/foo
885 ? foo/foo
886 $ cat a/a
886 $ cat a/a
887 a
887 a
888 a
888 a
889 c
889 c
890 x
890 x
891 x
891 x
892 $ cat foo/foo
892 $ cat foo/foo
893 foo
893 foo
894 a
894 a
895 $ hg shelve --interactive --config ui.interactive=false
895 $ hg shelve --interactive --config ui.interactive=false
896 abort: running non-interactively
896 abort: running non-interactively
897 [255]
897 [255]
898 $ hg shelve --interactive << EOF
898 $ hg shelve --interactive << EOF
899 > y
899 > y
900 > y
900 > y
901 > n
901 > n
902 > EOF
902 > EOF
903 diff --git a/a/a b/a/a
903 diff --git a/a/a b/a/a
904 2 hunks, 2 lines changed
904 2 hunks, 2 lines changed
905 examine changes to 'a/a'? [Ynesfdaq?] y
905 examine changes to 'a/a'? [Ynesfdaq?] y
906
906
907 @@ -1,3 +1,4 @@
907 @@ -1,3 +1,4 @@
908 +a
908 +a
909 a
909 a
910 c
910 c
911 x
911 x
912 record change 1/2 to 'a/a'? [Ynesfdaq?] y
912 record change 1/2 to 'a/a'? [Ynesfdaq?] y
913
913
914 @@ -1,3 +2,4 @@
914 @@ -1,3 +2,4 @@
915 a
915 a
916 c
916 c
917 x
917 x
918 +x
918 +x
919 record change 2/2 to 'a/a'? [Ynesfdaq?] n
919 record change 2/2 to 'a/a'? [Ynesfdaq?] n
920
920
921 shelved as test
921 shelved as test
922 merging a/a
922 merging a/a
923 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
923 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
924 $ cat a/a
924 $ cat a/a
925 a
925 a
926 c
926 c
927 x
927 x
928 x
928 x
929 $ cat foo/foo
929 $ cat foo/foo
930 foo
930 foo
931 a
931 a
932 $ hg st
932 $ hg st
933 M a/a
933 M a/a
934 ? foo/foo
934 ? foo/foo
935 $ hg bookmark
935 $ hg bookmark
936 * test 4:33f7f61e6c5e
936 * test 4:33f7f61e6c5e
937 $ hg unshelve
937 $ hg unshelve
938 unshelving change 'test'
938 unshelving change 'test'
939 temporarily committing pending changes (restore with 'hg unshelve --abort')
939 temporarily committing pending changes (restore with 'hg unshelve --abort')
940 rebasing shelved changes
940 rebasing shelved changes
941 rebasing 6:96a1354f65f6 "changes to: create conflict" (tip)
941 rebasing 6:96a1354f65f6 "changes to: create conflict" (tip)
942 merging a/a
942 merging a/a
943 $ hg bookmark
943 $ hg bookmark
944 * test 4:33f7f61e6c5e
944 * test 4:33f7f61e6c5e
945 $ cat a/a
945 $ cat a/a
946 a
946 a
947 a
947 a
948 c
948 c
949 x
949 x
950 x
950 x
951
951
952 shelve --patch and shelve --stat should work with a single valid shelfname
952 shelve --patch and shelve --stat should work with a single valid shelfname
953
953
954 $ hg up --clean .
954 $ hg up --clean .
955 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
955 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
956 (leaving bookmark test)
956 (leaving bookmark test)
957 $ hg shelve --list
957 $ hg shelve --list
958 $ echo 'patch a' > shelf-patch-a
958 $ echo 'patch a' > shelf-patch-a
959 $ hg add shelf-patch-a
959 $ hg add shelf-patch-a
960 $ hg shelve
960 $ hg shelve
961 shelved as default
961 shelved as default
962 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
962 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
963 $ echo 'patch b' > shelf-patch-b
963 $ echo 'patch b' > shelf-patch-b
964 $ hg add shelf-patch-b
964 $ hg add shelf-patch-b
965 $ hg shelve
965 $ hg shelve
966 shelved as default-01
966 shelved as default-01
967 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
967 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
968 $ hg shelve --patch default default-01
968 $ hg shelve --patch default default-01
969 abort: --patch expects a single shelf
969 abort: --patch expects a single shelf
970 [255]
970 [255]
971 $ hg shelve --stat default default-01
971 $ hg shelve --stat default default-01
972 abort: --stat expects a single shelf
972 abort: --stat expects a single shelf
973 [255]
973 [255]
974 $ hg shelve --patch default
974 $ hg shelve --patch default
975 default (*)* changes to: create conflict (glob)
975 default (*)* changes to: create conflict (glob)
976
976
977 diff --git a/shelf-patch-a b/shelf-patch-a
977 diff --git a/shelf-patch-a b/shelf-patch-a
978 new file mode 100644
978 new file mode 100644
979 --- /dev/null
979 --- /dev/null
980 +++ b/shelf-patch-a
980 +++ b/shelf-patch-a
981 @@ -0,0 +1,1 @@
981 @@ -0,0 +1,1 @@
982 +patch a
982 +patch a
983 $ hg shelve --stat default
983 $ hg shelve --stat default
984 default (*)* changes to: create conflict (glob)
984 default (*)* changes to: create conflict (glob)
985 shelf-patch-a | 1 +
985 shelf-patch-a | 1 +
986 1 files changed, 1 insertions(+), 0 deletions(-)
986 1 files changed, 1 insertions(+), 0 deletions(-)
987 $ hg shelve --patch nonexistentshelf
987 $ hg shelve --patch nonexistentshelf
988 abort: cannot find shelf nonexistentshelf
988 abort: cannot find shelf nonexistentshelf
989 [255]
989 [255]
990 $ hg shelve --stat nonexistentshelf
990 $ hg shelve --stat nonexistentshelf
991 abort: cannot find shelf nonexistentshelf
991 abort: cannot find shelf nonexistentshelf
992 [255]
992 [255]
993
993
994 $ cd ..
994 $ cd ..
995
995
996 Shelve from general delta repo uses bundle2 on disk
996 Shelve from general delta repo uses bundle2 on disk
997 --------------------------------------------------
997 --------------------------------------------------
998
998
999 no general delta
999 no general delta
1000
1000
1001 $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
1001 $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
1002 requesting all changes
1002 requesting all changes
1003 adding changesets
1003 adding changesets
1004 adding manifests
1004 adding manifests
1005 adding file changes
1005 adding file changes
1006 added 5 changesets with 8 changes to 6 files
1006 added 5 changesets with 8 changes to 6 files
1007 updating to branch default
1007 updating to branch default
1008 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1008 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1009 $ cd bundle1
1009 $ cd bundle1
1010 $ echo babar > jungle
1010 $ echo babar > jungle
1011 $ hg add jungle
1011 $ hg add jungle
1012 $ hg shelve
1012 $ hg shelve
1013 shelved as default
1013 shelved as default
1014 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1014 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1015 $ hg debugbundle .hg/shelved/*.hg
1015 $ hg debugbundle .hg/shelved/*.hg
1016 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1016 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1017 $ cd ..
1017 $ cd ..
1018
1018
1019 with general delta
1019 with general delta
1020
1020
1021 $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
1021 $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
1022 requesting all changes
1022 requesting all changes
1023 adding changesets
1023 adding changesets
1024 adding manifests
1024 adding manifests
1025 adding file changes
1025 adding file changes
1026 added 5 changesets with 8 changes to 6 files
1026 added 5 changesets with 8 changes to 6 files
1027 updating to branch default
1027 updating to branch default
1028 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1028 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1029 $ cd bundle2
1029 $ cd bundle2
1030 $ echo babar > jungle
1030 $ echo babar > jungle
1031 $ hg add jungle
1031 $ hg add jungle
1032 $ hg shelve
1032 $ hg shelve
1033 shelved as default
1033 shelved as default
1034 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1034 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1035 $ hg debugbundle .hg/shelved/*.hg
1035 $ hg debugbundle .hg/shelved/*.hg
1036 Stream params: {'Compression': 'BZ'}
1036 Stream params: {'Compression': 'BZ'}
1037 changegroup -- "{'version': '02'}"
1037 changegroup -- "{'version': '02'}"
1038 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1038 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1039 $ cd ..
1039 $ cd ..
1040
1040
1041 Test visibility of in-memory changes inside transaction to external hook
1041 Test visibility of in-memory changes inside transaction to external hook
1042 ------------------------------------------------------------------------
1042 ------------------------------------------------------------------------
1043
1043
1044 $ cd repo
1044 $ cd repo
1045
1045
1046 $ echo xxxx >> x
1046 $ echo xxxx >> x
1047 $ hg commit -m "#5: changes to invoke rebase"
1047 $ hg commit -m "#5: changes to invoke rebase"
1048
1048
1049 $ cat > $TESTTMP/checkvisibility.sh <<EOF
1049 $ cat > $TESTTMP/checkvisibility.sh <<EOF
1050 > echo "==== \$1:"
1050 > echo "==== \$1:"
1051 > hg parents --template "VISIBLE {rev}:{node|short}\n"
1051 > hg parents --template "VISIBLE {rev}:{node|short}\n"
1052 > # test that pending changes are hidden
1052 > # test that pending changes are hidden
1053 > unset HG_PENDING
1053 > unset HG_PENDING
1054 > hg parents --template "ACTUAL {rev}:{node|short}\n"
1054 > hg parents --template "ACTUAL {rev}:{node|short}\n"
1055 > echo "===="
1055 > echo "===="
1056 > EOF
1056 > EOF
1057
1057
1058 $ cat >> .hg/hgrc <<EOF
1058 $ cat >> .hg/hgrc <<EOF
1059 > [defaults]
1059 > [defaults]
1060 > # to fix hash id of temporary revisions
1060 > # to fix hash id of temporary revisions
1061 > unshelve = --date '0 0'
1061 > unshelve = --date '0 0'
1062 > EOF
1062 > EOF
1063
1063
1064 "hg unshelve" at REV5 implies steps below:
1064 "hg unshelve" at REV5 implies steps below:
1065
1065
1066 (1) commit changes in the working directory (REV6)
1066 (1) commit changes in the working directory (REV6)
1067 (2) unbundle shelved revision (REV7)
1067 (2) unbundle shelved revision (REV7)
1068 (3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
1068 (3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
1069 (4) rebase: commit merged revision (REV8)
1069 (4) rebase: commit merged revision (REV8)
1070 (5) rebase: update to REV6 (REV8 => REV6)
1070 (5) rebase: update to REV6 (REV8 => REV6)
1071 (6) update to REV5 (REV6 => REV5)
1071 (6) update to REV5 (REV6 => REV5)
1072 (7) abort transaction
1072 (7) abort transaction
1073
1073
1074 == test visibility to external preupdate hook
1074 == test visibility to external preupdate hook
1075
1075
1076 $ cat >> .hg/hgrc <<EOF
1076 $ cat >> .hg/hgrc <<EOF
1077 > [hooks]
1077 > [hooks]
1078 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
1078 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
1079 > EOF
1079 > EOF
1080
1080
1081 $ echo nnnn >> n
1081 $ echo nnnn >> n
1082
1082
1083 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1083 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1084 ==== before-unshelving:
1084 ==== before-unshelving:
1085 VISIBLE 5:703117a2acfb
1085 VISIBLE 5:703117a2acfb
1086 ACTUAL 5:703117a2acfb
1086 ACTUAL 5:703117a2acfb
1087 ====
1087 ====
1088
1088
1089 $ hg unshelve --keep default
1089 $ hg unshelve --keep default
1090 temporarily committing pending changes (restore with 'hg unshelve --abort')
1090 temporarily committing pending changes (restore with 'hg unshelve --abort')
1091 rebasing shelved changes
1091 rebasing shelved changes
1092 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1092 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1093 ==== preupdate:
1093 ==== preupdate:
1094 VISIBLE 6:66b86db80ee4
1094 VISIBLE 6:66b86db80ee4
1095 ACTUAL 5:703117a2acfb
1095 ACTUAL 5:703117a2acfb
1096 ====
1096 ====
1097 ==== preupdate:
1097 ==== preupdate:
1098 VISIBLE 8:a0e04704317e
1098 VISIBLE 8:a0e04704317e
1099 ACTUAL 5:703117a2acfb
1099 ACTUAL 5:703117a2acfb
1100 ====
1100 ====
1101 ==== preupdate:
1101 ==== preupdate:
1102 VISIBLE 6:66b86db80ee4
1102 VISIBLE 6:66b86db80ee4
1103 ACTUAL 5:703117a2acfb
1103 ACTUAL 5:703117a2acfb
1104 ====
1104 ====
1105
1105
1106 $ cat >> .hg/hgrc <<EOF
1106 $ cat >> .hg/hgrc <<EOF
1107 > [hooks]
1107 > [hooks]
1108 > preupdate.visibility =
1108 > preupdate.visibility =
1109 > EOF
1109 > EOF
1110
1110
1111 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1111 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1112 ==== after-unshelving:
1112 ==== after-unshelving:
1113 VISIBLE 5:703117a2acfb
1113 VISIBLE 5:703117a2acfb
1114 ACTUAL 5:703117a2acfb
1114 ACTUAL 5:703117a2acfb
1115 ====
1115 ====
1116
1116
1117 == test visibility to external update hook
1117 == test visibility to external update hook
1118
1118
1119 $ hg update -q -C 5
1119 $ hg update -q -C 5
1120
1120
1121 $ cat >> .hg/hgrc <<EOF
1121 $ cat >> .hg/hgrc <<EOF
1122 > [hooks]
1122 > [hooks]
1123 > update.visibility = sh $TESTTMP/checkvisibility.sh update
1123 > update.visibility = sh $TESTTMP/checkvisibility.sh update
1124 > EOF
1124 > EOF
1125
1125
1126 $ echo nnnn >> n
1126 $ echo nnnn >> n
1127
1127
1128 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1128 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1129 ==== before-unshelving:
1129 ==== before-unshelving:
1130 VISIBLE 5:703117a2acfb
1130 VISIBLE 5:703117a2acfb
1131 ACTUAL 5:703117a2acfb
1131 ACTUAL 5:703117a2acfb
1132 ====
1132 ====
1133
1133
1134 $ hg unshelve --keep default
1134 $ hg unshelve --keep default
1135 temporarily committing pending changes (restore with 'hg unshelve --abort')
1135 temporarily committing pending changes (restore with 'hg unshelve --abort')
1136 rebasing shelved changes
1136 rebasing shelved changes
1137 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1137 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1138 ==== update:
1138 ==== update:
1139 VISIBLE 6:66b86db80ee4
1139 VISIBLE 6:66b86db80ee4
1140 VISIBLE 7:206bf5d4f922
1140 VISIBLE 7:206bf5d4f922
1141 ACTUAL 5:703117a2acfb
1141 ACTUAL 5:703117a2acfb
1142 ====
1142 ====
1143 ==== update:
1143 ==== update:
1144 VISIBLE 6:66b86db80ee4
1144 VISIBLE 6:66b86db80ee4
1145 ACTUAL 5:703117a2acfb
1145 ACTUAL 5:703117a2acfb
1146 ====
1146 ====
1147 ==== update:
1147 ==== update:
1148 VISIBLE 5:703117a2acfb
1148 VISIBLE 5:703117a2acfb
1149 ACTUAL 5:703117a2acfb
1149 ACTUAL 5:703117a2acfb
1150 ====
1150 ====
1151
1151
1152 $ cat >> .hg/hgrc <<EOF
1152 $ cat >> .hg/hgrc <<EOF
1153 > [hooks]
1153 > [hooks]
1154 > update.visibility =
1154 > update.visibility =
1155 > EOF
1155 > EOF
1156
1156
1157 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1157 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1158 ==== after-unshelving:
1158 ==== after-unshelving:
1159 VISIBLE 5:703117a2acfb
1159 VISIBLE 5:703117a2acfb
1160 ACTUAL 5:703117a2acfb
1160 ACTUAL 5:703117a2acfb
1161 ====
1161 ====
1162
1162
1163 $ cd ..
1163 $ cd ..
1164
1164
1165 test .orig files go where the user wants them to
1165 test .orig files go where the user wants them to
1166 ---------------------------------------------------------------
1166 ---------------------------------------------------------------
1167 $ hg init salvage
1167 $ hg init salvage
1168 $ cd salvage
1168 $ cd salvage
1169 $ echo 'content' > root
1169 $ echo 'content' > root
1170 $ hg commit -A -m 'root' -q
1170 $ hg commit -A -m 'root' -q
1171 $ echo '' > root
1171 $ echo '' > root
1172 $ hg shelve -q
1172 $ hg shelve -q
1173 $ echo 'contADDent' > root
1173 $ echo 'contADDent' > root
1174 $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
1174 $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
1175 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1175 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1176 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1176 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1177 [1]
1177 [1]
1178 $ ls .hg/origbackups
1178 $ ls .hg/origbackups
1179 root.orig
1179 root.orig
1180 $ rm -rf .hg/origbackups
1180 $ rm -rf .hg/origbackups
1181
1181
1182 test Abort unshelve always gets user out of the unshelved state
1182 test Abort unshelve always gets user out of the unshelved state
1183 ---------------------------------------------------------------
1183 ---------------------------------------------------------------
1184 Wreak havoc on the unshelve process
1184 Wreak havoc on the unshelve process
1185 $ rm .hg/unshelverebasestate
1185 $ rm .hg/unshelverebasestate
1186 $ hg unshelve --abort
1186 $ hg unshelve --abort
1187 unshelve of 'default' aborted
1187 unshelve of 'default' aborted
1188 abort: (No such file or directory|The system cannot find the file specified) (re)
1188 abort: (No such file or directory|The system cannot find the file specified) (re)
1189 [255]
1189 [255]
1190 Can the user leave the current state?
1190 Can the user leave the current state?
1191 $ hg up -C .
1191 $ hg up -C .
1192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1193
1193
1194 Try again but with a corrupted shelve state file
1194 Try again but with a corrupted shelve state file
1195 $ hg strip -r 2 -r 1 -q
1195 $ hg strip -r 2 -r 1 -q
1196 $ hg up -r 0 -q
1196 $ hg up -r 0 -q
1197 $ echo '' > root
1197 $ echo '' > root
1198 $ hg shelve -q
1198 $ hg shelve -q
1199 $ echo 'contADDent' > root
1199 $ echo 'contADDent' > root
1200 $ hg unshelve -q
1200 $ hg unshelve -q
1201 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1201 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1202 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1202 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1203 [1]
1203 [1]
1204 $ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
1204 $ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
1205 $ mv ../corrupt-shelvedstate .hg/histedit-state
1205 $ mv ../corrupt-shelvedstate .hg/histedit-state
1206 $ hg unshelve --abort 2>&1 | grep 'rebase aborted'
1206 $ hg unshelve --abort 2>&1 | grep 'rebase aborted'
1207 rebase aborted
1207 rebase aborted
1208 $ hg up -C .
1208 $ hg up -C .
1209 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1209 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1210
1210
1211 $ cd ..
1211 $ cd ..
1212
1212
1213 Keep active bookmark while (un)shelving even on shared repo (issue4940)
1213 Keep active bookmark while (un)shelving even on shared repo (issue4940)
1214 -----------------------------------------------------------------------
1214 -----------------------------------------------------------------------
1215
1215
1216 $ cat <<EOF >> $HGRCPATH
1216 $ cat <<EOF >> $HGRCPATH
1217 > [extensions]
1217 > [extensions]
1218 > share =
1218 > share =
1219 > EOF
1219 > EOF
1220
1220
1221 $ hg bookmarks -R repo
1221 $ hg bookmarks -R repo
1222 test 4:33f7f61e6c5e
1222 test 4:33f7f61e6c5e
1223 $ hg share -B repo share
1223 $ hg share -B repo share
1224 updating working directory
1224 updating working directory
1225 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1225 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1226 $ cd share
1226 $ cd share
1227
1227
1228 $ hg bookmarks
1228 $ hg bookmarks
1229 test 4:33f7f61e6c5e
1229 test 4:33f7f61e6c5e
1230 $ hg bookmarks foo
1230 $ hg bookmarks foo
1231 $ hg bookmarks
1231 $ hg bookmarks
1232 * foo 5:703117a2acfb
1232 * foo 5:703117a2acfb
1233 test 4:33f7f61e6c5e
1233 test 4:33f7f61e6c5e
1234 $ echo x >> x
1234 $ echo x >> x
1235 $ hg shelve
1235 $ hg shelve
1236 shelved as foo
1236 shelved as foo
1237 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1237 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1238 $ hg bookmarks
1238 $ hg bookmarks
1239 * foo 5:703117a2acfb
1239 * foo 5:703117a2acfb
1240 test 4:33f7f61e6c5e
1240 test 4:33f7f61e6c5e
1241
1241
1242 $ hg unshelve
1242 $ hg unshelve
1243 unshelving change 'foo'
1243 unshelving change 'foo'
1244 $ hg bookmarks
1244 $ hg bookmarks
1245 * foo 5:703117a2acfb
1245 * foo 5:703117a2acfb
1246 test 4:33f7f61e6c5e
1246 test 4:33f7f61e6c5e
1247
1247
1248 $ cd ..
1248 $ cd ..
1249
1249
1250 Shelve and unshelve unknown files. For the purposes of unshelve, a shelved
1250 Shelve and unshelve unknown files. For the purposes of unshelve, a shelved
1251 unknown file is the same as a shelved added file, except that it will be in
1251 unknown file is the same as a shelved added file, except that it will be in
1252 unknown state after unshelve if and only if it was either absent or unknown
1252 unknown state after unshelve if and only if it was either absent or unknown
1253 before the unshelve operation.
1253 before the unshelve operation.
1254
1254
1255 $ hg init unknowns
1255 $ hg init unknowns
1256 $ cd unknowns
1256 $ cd unknowns
1257
1257
1258 The simplest case is if I simply have an unknown file that I shelve and unshelve
1258 The simplest case is if I simply have an unknown file that I shelve and unshelve
1259
1259
1260 $ echo unknown > unknown
1260 $ echo unknown > unknown
1261 $ hg status
1261 $ hg status
1262 ? unknown
1262 ? unknown
1263 $ hg shelve --unknown
1263 $ hg shelve --unknown
1264 shelved as default
1264 shelved as default
1265 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1265 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1266 $ hg status
1266 $ hg status
1267 $ hg unshelve
1267 $ hg unshelve
1268 unshelving change 'default'
1268 unshelving change 'default'
1269 $ hg status
1269 $ hg status
1270 ? unknown
1270 ? unknown
1271 $ rm unknown
1271 $ rm unknown
1272
1272
1273 If I shelve, add the file, and unshelve, does it stay added?
1273 If I shelve, add the file, and unshelve, does it stay added?
1274
1274
1275 $ echo unknown > unknown
1275 $ echo unknown > unknown
1276 $ hg shelve -u
1276 $ hg shelve -u
1277 shelved as default
1277 shelved as default
1278 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1278 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1279 $ hg status
1279 $ hg status
1280 $ touch unknown
1280 $ touch unknown
1281 $ hg add unknown
1281 $ hg add unknown
1282 $ hg status
1282 $ hg status
1283 A unknown
1283 A unknown
1284 $ hg unshelve
1284 $ hg unshelve
1285 unshelving change 'default'
1285 unshelving change 'default'
1286 temporarily committing pending changes (restore with 'hg unshelve --abort')
1286 temporarily committing pending changes (restore with 'hg unshelve --abort')
1287 rebasing shelved changes
1287 rebasing shelved changes
1288 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1288 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1289 merging unknown
1289 merging unknown
1290 $ hg status
1290 $ hg status
1291 A unknown
1291 A unknown
1292 $ hg forget unknown
1292 $ hg forget unknown
1293 $ rm unknown
1293 $ rm unknown
1294
1294
1295 And if I shelve, commit, then unshelve, does it become modified?
1295 And if I shelve, commit, then unshelve, does it become modified?
1296
1296
1297 $ echo unknown > unknown
1297 $ echo unknown > unknown
1298 $ hg shelve -u
1298 $ hg shelve -u
1299 shelved as default
1299 shelved as default
1300 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1300 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1301 $ hg status
1301 $ hg status
1302 $ touch unknown
1302 $ touch unknown
1303 $ hg add unknown
1303 $ hg add unknown
1304 $ hg commit -qm "Add unknown"
1304 $ hg commit -qm "Add unknown"
1305 $ hg status
1305 $ hg status
1306 $ hg unshelve
1306 $ hg unshelve
1307 unshelving change 'default'
1307 unshelving change 'default'
1308 rebasing shelved changes
1308 rebasing shelved changes
1309 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1309 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1310 merging unknown
1310 merging unknown
1311 $ hg status
1311 $ hg status
1312 M unknown
1312 M unknown
1313 $ hg remove --force unknown
1313 $ hg remove --force unknown
1314 $ hg commit -qm "Remove unknown"
1314 $ hg commit -qm "Remove unknown"
1315
1315
1316 $ cd ..
1316 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now