##// END OF EJS Templates
shelve: add interactive mode...
Laurent Charignon -
r24478:95cbc77c default
parent child Browse files
Show More
@@ -1,725 +1,732 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 from mercurial.i18n import _
24 from mercurial.i18n import _
25 from mercurial.node import nullid, nullrev, bin, hex
25 from mercurial.node import nullid, nullrev, bin, hex
26 from mercurial import changegroup, cmdutil, scmutil, phases, commands
26 from mercurial import changegroup, cmdutil, scmutil, phases, commands
27 from mercurial import error, hg, mdiff, merge, patch, repair, util
27 from mercurial import error, hg, mdiff, merge, patch, repair, util
28 from mercurial import templatefilters, exchange, bundlerepo
28 from mercurial import templatefilters, exchange, bundlerepo
29 from mercurial import lock as lockmod
29 from mercurial import lock as lockmod
30 from hgext import rebase
30 from hgext import rebase
31 import errno
31 import errno
32
32
33 cmdtable = {}
33 cmdtable = {}
34 command = cmdutil.command(cmdtable)
34 command = cmdutil.command(cmdtable)
35 testedwith = 'internal'
35 testedwith = 'internal'
36
36
37 class shelvedfile(object):
37 class shelvedfile(object):
38 """Helper for the file storing a single shelve
38 """Helper for the file storing a single shelve
39
39
40 Handles common functions on shelve files (.hg/.patch) using
40 Handles common functions on shelve files (.hg/.patch) using
41 the vfs layer"""
41 the vfs layer"""
42 def __init__(self, repo, name, filetype=None):
42 def __init__(self, repo, name, filetype=None):
43 self.repo = repo
43 self.repo = repo
44 self.name = name
44 self.name = name
45 self.vfs = scmutil.vfs(repo.join('shelved'))
45 self.vfs = scmutil.vfs(repo.join('shelved'))
46 self.ui = self.repo.ui
46 self.ui = self.repo.ui
47 if filetype:
47 if filetype:
48 self.fname = name + '.' + filetype
48 self.fname = name + '.' + filetype
49 else:
49 else:
50 self.fname = name
50 self.fname = name
51
51
52 def exists(self):
52 def exists(self):
53 return self.vfs.exists(self.fname)
53 return self.vfs.exists(self.fname)
54
54
55 def filename(self):
55 def filename(self):
56 return self.vfs.join(self.fname)
56 return self.vfs.join(self.fname)
57
57
58 def unlink(self):
58 def unlink(self):
59 util.unlink(self.filename())
59 util.unlink(self.filename())
60
60
61 def stat(self):
61 def stat(self):
62 return self.vfs.stat(self.fname)
62 return self.vfs.stat(self.fname)
63
63
64 def opener(self, mode='rb'):
64 def opener(self, mode='rb'):
65 try:
65 try:
66 return self.vfs(self.fname, mode)
66 return self.vfs(self.fname, mode)
67 except IOError, err:
67 except IOError, err:
68 if err.errno != errno.ENOENT:
68 if err.errno != errno.ENOENT:
69 raise
69 raise
70 raise util.Abort(_("shelved change '%s' not found") % self.name)
70 raise util.Abort(_("shelved change '%s' not found") % self.name)
71
71
72 def applybundle(self):
72 def applybundle(self):
73 fp = self.opener()
73 fp = self.opener()
74 try:
74 try:
75 gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs)
75 gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs)
76 changegroup.addchangegroup(self.repo, gen, 'unshelve',
76 changegroup.addchangegroup(self.repo, gen, 'unshelve',
77 'bundle:' + self.vfs.join(self.fname),
77 'bundle:' + self.vfs.join(self.fname),
78 targetphase=phases.secret)
78 targetphase=phases.secret)
79 finally:
79 finally:
80 fp.close()
80 fp.close()
81
81
82 def bundlerepo(self):
82 def bundlerepo(self):
83 return bundlerepo.bundlerepository(self.repo.baseui, self.repo.root,
83 return bundlerepo.bundlerepository(self.repo.baseui, self.repo.root,
84 self.vfs.join(self.fname))
84 self.vfs.join(self.fname))
85 def writebundle(self, cg):
85 def writebundle(self, cg):
86 changegroup.writebundle(self.ui, cg, self.fname, 'HG10UN', self.vfs)
86 changegroup.writebundle(self.ui, cg, self.fname, 'HG10UN', self.vfs)
87
87
88 class shelvedstate(object):
88 class shelvedstate(object):
89 """Handle persistence during unshelving operations.
89 """Handle persistence during unshelving operations.
90
90
91 Handles saving and restoring a shelved state. Ensures that different
91 Handles saving and restoring a shelved state. Ensures that different
92 versions of a shelved state are possible and handles them appropriately.
92 versions of a shelved state are possible and handles them appropriately.
93 """
93 """
94 _version = 1
94 _version = 1
95 _filename = 'shelvedstate'
95 _filename = 'shelvedstate'
96
96
97 @classmethod
97 @classmethod
98 def load(cls, repo):
98 def load(cls, repo):
99 fp = repo.vfs(cls._filename)
99 fp = repo.vfs(cls._filename)
100 try:
100 try:
101 version = int(fp.readline().strip())
101 version = int(fp.readline().strip())
102
102
103 if version != cls._version:
103 if version != cls._version:
104 raise util.Abort(_('this version of shelve is incompatible '
104 raise util.Abort(_('this version of shelve is incompatible '
105 'with the version used in this repo'))
105 'with the version used in this repo'))
106 name = fp.readline().strip()
106 name = fp.readline().strip()
107 wctx = fp.readline().strip()
107 wctx = fp.readline().strip()
108 pendingctx = fp.readline().strip()
108 pendingctx = fp.readline().strip()
109 parents = [bin(h) for h in fp.readline().split()]
109 parents = [bin(h) for h in fp.readline().split()]
110 stripnodes = [bin(h) for h in fp.readline().split()]
110 stripnodes = [bin(h) for h in fp.readline().split()]
111 finally:
111 finally:
112 fp.close()
112 fp.close()
113
113
114 obj = cls()
114 obj = cls()
115 obj.name = name
115 obj.name = name
116 obj.wctx = repo[bin(wctx)]
116 obj.wctx = repo[bin(wctx)]
117 obj.pendingctx = repo[bin(pendingctx)]
117 obj.pendingctx = repo[bin(pendingctx)]
118 obj.parents = parents
118 obj.parents = parents
119 obj.stripnodes = stripnodes
119 obj.stripnodes = stripnodes
120
120
121 return obj
121 return obj
122
122
123 @classmethod
123 @classmethod
124 def save(cls, repo, name, originalwctx, pendingctx, stripnodes):
124 def save(cls, repo, name, originalwctx, pendingctx, stripnodes):
125 fp = repo.vfs(cls._filename, 'wb')
125 fp = repo.vfs(cls._filename, 'wb')
126 fp.write('%i\n' % cls._version)
126 fp.write('%i\n' % cls._version)
127 fp.write('%s\n' % name)
127 fp.write('%s\n' % name)
128 fp.write('%s\n' % hex(originalwctx.node()))
128 fp.write('%s\n' % hex(originalwctx.node()))
129 fp.write('%s\n' % hex(pendingctx.node()))
129 fp.write('%s\n' % hex(pendingctx.node()))
130 fp.write('%s\n' % ' '.join([hex(p) for p in repo.dirstate.parents()]))
130 fp.write('%s\n' % ' '.join([hex(p) for p in repo.dirstate.parents()]))
131 fp.write('%s\n' % ' '.join([hex(n) for n in stripnodes]))
131 fp.write('%s\n' % ' '.join([hex(n) for n in stripnodes]))
132 fp.close()
132 fp.close()
133
133
134 @classmethod
134 @classmethod
135 def clear(cls, repo):
135 def clear(cls, repo):
136 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
136 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
137
137
138 def createcmd(ui, repo, pats, opts):
138 def createcmd(ui, repo, pats, opts):
139 """subcommand that creates a new shelve"""
139 """subcommand that creates a new shelve"""
140
140
141 def publicancestors(ctx):
141 def publicancestors(ctx):
142 """Compute the public ancestors of a commit.
142 """Compute the public ancestors of a commit.
143
143
144 Much faster than the revset ancestors(ctx) & draft()"""
144 Much faster than the revset ancestors(ctx) & draft()"""
145 seen = set([nullrev])
145 seen = set([nullrev])
146 visit = util.deque()
146 visit = util.deque()
147 visit.append(ctx)
147 visit.append(ctx)
148 while visit:
148 while visit:
149 ctx = visit.popleft()
149 ctx = visit.popleft()
150 yield ctx.node()
150 yield ctx.node()
151 for parent in ctx.parents():
151 for parent in ctx.parents():
152 rev = parent.rev()
152 rev = parent.rev()
153 if rev not in seen:
153 if rev not in seen:
154 seen.add(rev)
154 seen.add(rev)
155 if parent.mutable():
155 if parent.mutable():
156 visit.append(parent)
156 visit.append(parent)
157
157
158 wctx = repo[None]
158 wctx = repo[None]
159 parents = wctx.parents()
159 parents = wctx.parents()
160 if len(parents) > 1:
160 if len(parents) > 1:
161 raise util.Abort(_('cannot shelve while merging'))
161 raise util.Abort(_('cannot shelve while merging'))
162 parent = parents[0]
162 parent = parents[0]
163
163
164 # we never need the user, so we use a generic user for all shelve operations
164 # we never need the user, so we use a generic user for all shelve operations
165 user = 'shelve@localhost'
165 user = 'shelve@localhost'
166 label = repo._bookmarkcurrent or parent.branch() or 'default'
166 label = repo._bookmarkcurrent or parent.branch() or 'default'
167
167
168 # slashes aren't allowed in filenames, therefore we rename it
168 # slashes aren't allowed in filenames, therefore we rename it
169 label = label.replace('/', '_')
169 label = label.replace('/', '_')
170
170
171 def gennames():
171 def gennames():
172 yield label
172 yield label
173 for i in xrange(1, 100):
173 for i in xrange(1, 100):
174 yield '%s-%02d' % (label, i)
174 yield '%s-%02d' % (label, i)
175
175
176 def commitfunc(ui, repo, message, match, opts):
176 def commitfunc(ui, repo, message, match, opts):
177 hasmq = util.safehasattr(repo, 'mq')
177 hasmq = util.safehasattr(repo, 'mq')
178 if hasmq:
178 if hasmq:
179 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
179 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
180 backup = repo.ui.backupconfig('phases', 'new-commit')
180 backup = repo.ui.backupconfig('phases', 'new-commit')
181 try:
181 try:
182 repo.ui. setconfig('phases', 'new-commit', phases.secret)
182 repo.ui. setconfig('phases', 'new-commit', phases.secret)
183 editor = cmdutil.getcommiteditor(editform='shelve.shelve', **opts)
183 editor = cmdutil.getcommiteditor(editform='shelve.shelve', **opts)
184 return repo.commit(message, user, opts.get('date'), match,
184 return repo.commit(message, user, opts.get('date'), match,
185 editor=editor)
185 editor=editor)
186 finally:
186 finally:
187 repo.ui.restoreconfig(backup)
187 repo.ui.restoreconfig(backup)
188 if hasmq:
188 if hasmq:
189 repo.mq.checkapplied = saved
189 repo.mq.checkapplied = saved
190
190
191 if parent.node() != nullid:
191 if parent.node() != nullid:
192 desc = "changes to '%s'" % parent.description().split('\n', 1)[0]
192 desc = "changes to '%s'" % parent.description().split('\n', 1)[0]
193 else:
193 else:
194 desc = '(changes in empty repository)'
194 desc = '(changes in empty repository)'
195
195
196 if not opts['message']:
196 if not opts['message']:
197 opts['message'] = desc
197 opts['message'] = desc
198
198
199 name = opts['name']
199 name = opts['name']
200
200
201 wlock = lock = tr = bms = None
201 wlock = lock = tr = bms = None
202 try:
202 try:
203 wlock = repo.wlock()
203 wlock = repo.wlock()
204 lock = repo.lock()
204 lock = repo.lock()
205
205
206 bms = repo._bookmarks.copy()
206 bms = repo._bookmarks.copy()
207 # use an uncommitted transaction to generate the bundle to avoid
207 # use an uncommitted transaction to generate the bundle to avoid
208 # pull races. ensure we don't print the abort message to stderr.
208 # pull races. ensure we don't print the abort message to stderr.
209 tr = repo.transaction('commit', report=lambda x: None)
209 tr = repo.transaction('commit', report=lambda x: None)
210
210
211 if name:
211 if name:
212 if shelvedfile(repo, name, 'hg').exists():
212 if shelvedfile(repo, name, 'hg').exists():
213 raise util.Abort(_("a shelved change named '%s' already exists")
213 raise util.Abort(_("a shelved change named '%s' already exists")
214 % name)
214 % name)
215 else:
215 else:
216 for n in gennames():
216 for n in gennames():
217 if not shelvedfile(repo, n, 'hg').exists():
217 if not shelvedfile(repo, n, 'hg').exists():
218 name = n
218 name = n
219 break
219 break
220 else:
220 else:
221 raise util.Abort(_("too many shelved changes named '%s'") %
221 raise util.Abort(_("too many shelved changes named '%s'") %
222 label)
222 label)
223
223
224 # ensure we are not creating a subdirectory or a hidden file
224 # ensure we are not creating a subdirectory or a hidden file
225 if '/' in name or '\\' in name:
225 if '/' in name or '\\' in name:
226 raise util.Abort(_('shelved change names may not contain slashes'))
226 raise util.Abort(_('shelved change names may not contain slashes'))
227 if name.startswith('.'):
227 if name.startswith('.'):
228 raise util.Abort(_("shelved change names may not start with '.'"))
228 raise util.Abort(_("shelved change names may not start with '.'"))
229 interactive = opts.get('interactive', False)
229 interactive = opts.get('interactive', False)
230
230
231 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
231 def interactivecommitfunc(ui, repo, *pats, **opts):
232
232 match = scmutil.match(repo['.'], pats, {})
233 message = opts['message']
234 return commitfunc(ui, repo, message, match, opts)
235 if not interactive:
236 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
237 else:
238 node = cmdutil.dorecord(ui, repo, interactivecommitfunc, 'commit',
239 False, cmdutil.recordfilter, *pats, **opts)
233 if not node:
240 if not node:
234 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
241 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
235 if stat.deleted:
242 if stat.deleted:
236 ui.status(_("nothing changed (%d missing files, see "
243 ui.status(_("nothing changed (%d missing files, see "
237 "'hg status')\n") % len(stat.deleted))
244 "'hg status')\n") % len(stat.deleted))
238 else:
245 else:
239 ui.status(_("nothing changed\n"))
246 ui.status(_("nothing changed\n"))
240 return 1
247 return 1
241
248
242 bases = list(publicancestors(repo[node]))
249 bases = list(publicancestors(repo[node]))
243 cg = changegroup.changegroupsubset(repo, bases, [node], 'shelve')
250 cg = changegroup.changegroupsubset(repo, bases, [node], 'shelve')
244 shelvedfile(repo, name, 'hg').writebundle(cg)
251 shelvedfile(repo, name, 'hg').writebundle(cg)
245 cmdutil.export(repo, [node],
252 cmdutil.export(repo, [node],
246 fp=shelvedfile(repo, name, 'patch').opener('wb'),
253 fp=shelvedfile(repo, name, 'patch').opener('wb'),
247 opts=mdiff.diffopts(git=True))
254 opts=mdiff.diffopts(git=True))
248
255
249
256
250 if ui.formatted():
257 if ui.formatted():
251 desc = util.ellipsis(desc, ui.termwidth())
258 desc = util.ellipsis(desc, ui.termwidth())
252 ui.status(_('shelved as %s\n') % name)
259 ui.status(_('shelved as %s\n') % name)
253 hg.update(repo, parent.node())
260 hg.update(repo, parent.node())
254 finally:
261 finally:
255 if bms:
262 if bms:
256 # restore old bookmarks
263 # restore old bookmarks
257 repo._bookmarks.update(bms)
264 repo._bookmarks.update(bms)
258 repo._bookmarks.write()
265 repo._bookmarks.write()
259 if tr:
266 if tr:
260 tr.abort()
267 tr.abort()
261 lockmod.release(lock, wlock)
268 lockmod.release(lock, wlock)
262
269
263 def cleanupcmd(ui, repo):
270 def cleanupcmd(ui, repo):
264 """subcommand that deletes all shelves"""
271 """subcommand that deletes all shelves"""
265
272
266 wlock = None
273 wlock = None
267 try:
274 try:
268 wlock = repo.wlock()
275 wlock = repo.wlock()
269 for (name, _type) in repo.vfs.readdir('shelved'):
276 for (name, _type) in repo.vfs.readdir('shelved'):
270 suffix = name.rsplit('.', 1)[-1]
277 suffix = name.rsplit('.', 1)[-1]
271 if suffix in ('hg', 'patch'):
278 if suffix in ('hg', 'patch'):
272 shelvedfile(repo, name).unlink()
279 shelvedfile(repo, name).unlink()
273 finally:
280 finally:
274 lockmod.release(wlock)
281 lockmod.release(wlock)
275
282
276 def deletecmd(ui, repo, pats):
283 def deletecmd(ui, repo, pats):
277 """subcommand that deletes a specific shelve"""
284 """subcommand that deletes a specific shelve"""
278 if not pats:
285 if not pats:
279 raise util.Abort(_('no shelved changes specified!'))
286 raise util.Abort(_('no shelved changes specified!'))
280 wlock = None
287 wlock = None
281 try:
288 try:
282 wlock = repo.wlock()
289 wlock = repo.wlock()
283 try:
290 try:
284 for name in pats:
291 for name in pats:
285 for suffix in 'hg patch'.split():
292 for suffix in 'hg patch'.split():
286 shelvedfile(repo, name, suffix).unlink()
293 shelvedfile(repo, name, suffix).unlink()
287 except OSError, err:
294 except OSError, err:
288 if err.errno != errno.ENOENT:
295 if err.errno != errno.ENOENT:
289 raise
296 raise
290 raise util.Abort(_("shelved change '%s' not found") % name)
297 raise util.Abort(_("shelved change '%s' not found") % name)
291 finally:
298 finally:
292 lockmod.release(wlock)
299 lockmod.release(wlock)
293
300
294 def listshelves(repo):
301 def listshelves(repo):
295 """return all shelves in repo as list of (time, filename)"""
302 """return all shelves in repo as list of (time, filename)"""
296 try:
303 try:
297 names = repo.vfs.readdir('shelved')
304 names = repo.vfs.readdir('shelved')
298 except OSError, err:
305 except OSError, err:
299 if err.errno != errno.ENOENT:
306 if err.errno != errno.ENOENT:
300 raise
307 raise
301 return []
308 return []
302 info = []
309 info = []
303 for (name, _type) in names:
310 for (name, _type) in names:
304 pfx, sfx = name.rsplit('.', 1)
311 pfx, sfx = name.rsplit('.', 1)
305 if not pfx or sfx != 'patch':
312 if not pfx or sfx != 'patch':
306 continue
313 continue
307 st = shelvedfile(repo, name).stat()
314 st = shelvedfile(repo, name).stat()
308 info.append((st.st_mtime, shelvedfile(repo, pfx).filename()))
315 info.append((st.st_mtime, shelvedfile(repo, pfx).filename()))
309 return sorted(info, reverse=True)
316 return sorted(info, reverse=True)
310
317
311 def listcmd(ui, repo, pats, opts):
318 def listcmd(ui, repo, pats, opts):
312 """subcommand that displays the list of shelves"""
319 """subcommand that displays the list of shelves"""
313 pats = set(pats)
320 pats = set(pats)
314 width = 80
321 width = 80
315 if not ui.plain():
322 if not ui.plain():
316 width = ui.termwidth()
323 width = ui.termwidth()
317 namelabel = 'shelve.newest'
324 namelabel = 'shelve.newest'
318 for mtime, name in listshelves(repo):
325 for mtime, name in listshelves(repo):
319 sname = util.split(name)[1]
326 sname = util.split(name)[1]
320 if pats and sname not in pats:
327 if pats and sname not in pats:
321 continue
328 continue
322 ui.write(sname, label=namelabel)
329 ui.write(sname, label=namelabel)
323 namelabel = 'shelve.name'
330 namelabel = 'shelve.name'
324 if ui.quiet:
331 if ui.quiet:
325 ui.write('\n')
332 ui.write('\n')
326 continue
333 continue
327 ui.write(' ' * (16 - len(sname)))
334 ui.write(' ' * (16 - len(sname)))
328 used = 16
335 used = 16
329 age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True)
336 age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True)
330 ui.write(age, label='shelve.age')
337 ui.write(age, label='shelve.age')
331 ui.write(' ' * (12 - len(age)))
338 ui.write(' ' * (12 - len(age)))
332 used += 12
339 used += 12
333 fp = open(name + '.patch', 'rb')
340 fp = open(name + '.patch', 'rb')
334 try:
341 try:
335 while True:
342 while True:
336 line = fp.readline()
343 line = fp.readline()
337 if not line:
344 if not line:
338 break
345 break
339 if not line.startswith('#'):
346 if not line.startswith('#'):
340 desc = line.rstrip()
347 desc = line.rstrip()
341 if ui.formatted():
348 if ui.formatted():
342 desc = util.ellipsis(desc, width - used)
349 desc = util.ellipsis(desc, width - used)
343 ui.write(desc)
350 ui.write(desc)
344 break
351 break
345 ui.write('\n')
352 ui.write('\n')
346 if not (opts['patch'] or opts['stat']):
353 if not (opts['patch'] or opts['stat']):
347 continue
354 continue
348 difflines = fp.readlines()
355 difflines = fp.readlines()
349 if opts['patch']:
356 if opts['patch']:
350 for chunk, label in patch.difflabel(iter, difflines):
357 for chunk, label in patch.difflabel(iter, difflines):
351 ui.write(chunk, label=label)
358 ui.write(chunk, label=label)
352 if opts['stat']:
359 if opts['stat']:
353 for chunk, label in patch.diffstatui(difflines, width=width,
360 for chunk, label in patch.diffstatui(difflines, width=width,
354 git=True):
361 git=True):
355 ui.write(chunk, label=label)
362 ui.write(chunk, label=label)
356 finally:
363 finally:
357 fp.close()
364 fp.close()
358
365
359 def checkparents(repo, state):
366 def checkparents(repo, state):
360 """check parent while resuming an unshelve"""
367 """check parent while resuming an unshelve"""
361 if state.parents != repo.dirstate.parents():
368 if state.parents != repo.dirstate.parents():
362 raise util.Abort(_('working directory parents do not match unshelve '
369 raise util.Abort(_('working directory parents do not match unshelve '
363 'state'))
370 'state'))
364
371
365 def pathtofiles(repo, files):
372 def pathtofiles(repo, files):
366 cwd = repo.getcwd()
373 cwd = repo.getcwd()
367 return [repo.pathto(f, cwd) for f in files]
374 return [repo.pathto(f, cwd) for f in files]
368
375
369 def unshelveabort(ui, repo, state, opts):
376 def unshelveabort(ui, repo, state, opts):
370 """subcommand that abort an in-progress unshelve"""
377 """subcommand that abort an in-progress unshelve"""
371 wlock = repo.wlock()
378 wlock = repo.wlock()
372 lock = None
379 lock = None
373 try:
380 try:
374 checkparents(repo, state)
381 checkparents(repo, state)
375
382
376 util.rename(repo.join('unshelverebasestate'),
383 util.rename(repo.join('unshelverebasestate'),
377 repo.join('rebasestate'))
384 repo.join('rebasestate'))
378 try:
385 try:
379 rebase.rebase(ui, repo, **{
386 rebase.rebase(ui, repo, **{
380 'abort' : True
387 'abort' : True
381 })
388 })
382 except Exception:
389 except Exception:
383 util.rename(repo.join('rebasestate'),
390 util.rename(repo.join('rebasestate'),
384 repo.join('unshelverebasestate'))
391 repo.join('unshelverebasestate'))
385 raise
392 raise
386
393
387 lock = repo.lock()
394 lock = repo.lock()
388
395
389 mergefiles(ui, repo, state.wctx, state.pendingctx)
396 mergefiles(ui, repo, state.wctx, state.pendingctx)
390
397
391 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
398 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
392 shelvedstate.clear(repo)
399 shelvedstate.clear(repo)
393 ui.warn(_("unshelve of '%s' aborted\n") % state.name)
400 ui.warn(_("unshelve of '%s' aborted\n") % state.name)
394 finally:
401 finally:
395 lockmod.release(lock, wlock)
402 lockmod.release(lock, wlock)
396
403
397 def mergefiles(ui, repo, wctx, shelvectx):
404 def mergefiles(ui, repo, wctx, shelvectx):
398 """updates to wctx and merges the changes from shelvectx into the
405 """updates to wctx and merges the changes from shelvectx into the
399 dirstate."""
406 dirstate."""
400 oldquiet = ui.quiet
407 oldquiet = ui.quiet
401 try:
408 try:
402 ui.quiet = True
409 ui.quiet = True
403 hg.update(repo, wctx.node())
410 hg.update(repo, wctx.node())
404 files = []
411 files = []
405 files.extend(shelvectx.files())
412 files.extend(shelvectx.files())
406 files.extend(shelvectx.parents()[0].files())
413 files.extend(shelvectx.parents()[0].files())
407
414
408 # revert will overwrite unknown files, so move them out of the way
415 # revert will overwrite unknown files, so move them out of the way
409 for file in repo.status(unknown=True).unknown:
416 for file in repo.status(unknown=True).unknown:
410 if file in files:
417 if file in files:
411 util.rename(file, file + ".orig")
418 util.rename(file, file + ".orig")
412 ui.pushbuffer(True)
419 ui.pushbuffer(True)
413 cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
420 cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
414 *pathtofiles(repo, files),
421 *pathtofiles(repo, files),
415 **{'no_backup': True})
422 **{'no_backup': True})
416 ui.popbuffer()
423 ui.popbuffer()
417 finally:
424 finally:
418 ui.quiet = oldquiet
425 ui.quiet = oldquiet
419
426
420 def unshelvecleanup(ui, repo, name, opts):
427 def unshelvecleanup(ui, repo, name, opts):
421 """remove related files after an unshelve"""
428 """remove related files after an unshelve"""
422 if not opts['keep']:
429 if not opts['keep']:
423 for filetype in 'hg patch'.split():
430 for filetype in 'hg patch'.split():
424 shelvedfile(repo, name, filetype).unlink()
431 shelvedfile(repo, name, filetype).unlink()
425
432
426 def unshelvecontinue(ui, repo, state, opts):
433 def unshelvecontinue(ui, repo, state, opts):
427 """subcommand to continue an in-progress unshelve"""
434 """subcommand to continue an in-progress unshelve"""
428 # We're finishing off a merge. First parent is our original
435 # We're finishing off a merge. First parent is our original
429 # parent, second is the temporary "fake" commit we're unshelving.
436 # parent, second is the temporary "fake" commit we're unshelving.
430 wlock = repo.wlock()
437 wlock = repo.wlock()
431 lock = None
438 lock = None
432 try:
439 try:
433 checkparents(repo, state)
440 checkparents(repo, state)
434 ms = merge.mergestate(repo)
441 ms = merge.mergestate(repo)
435 if [f for f in ms if ms[f] == 'u']:
442 if [f for f in ms if ms[f] == 'u']:
436 raise util.Abort(
443 raise util.Abort(
437 _("unresolved conflicts, can't continue"),
444 _("unresolved conflicts, can't continue"),
438 hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
445 hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
439
446
440 lock = repo.lock()
447 lock = repo.lock()
441
448
442 util.rename(repo.join('unshelverebasestate'),
449 util.rename(repo.join('unshelverebasestate'),
443 repo.join('rebasestate'))
450 repo.join('rebasestate'))
444 try:
451 try:
445 rebase.rebase(ui, repo, **{
452 rebase.rebase(ui, repo, **{
446 'continue' : True
453 'continue' : True
447 })
454 })
448 except Exception:
455 except Exception:
449 util.rename(repo.join('rebasestate'),
456 util.rename(repo.join('rebasestate'),
450 repo.join('unshelverebasestate'))
457 repo.join('unshelverebasestate'))
451 raise
458 raise
452
459
453 shelvectx = repo['tip']
460 shelvectx = repo['tip']
454 if not shelvectx in state.pendingctx.children():
461 if not shelvectx in state.pendingctx.children():
455 # rebase was a no-op, so it produced no child commit
462 # rebase was a no-op, so it produced no child commit
456 shelvectx = state.pendingctx
463 shelvectx = state.pendingctx
457 else:
464 else:
458 # only strip the shelvectx if the rebase produced it
465 # only strip the shelvectx if the rebase produced it
459 state.stripnodes.append(shelvectx.node())
466 state.stripnodes.append(shelvectx.node())
460
467
461 mergefiles(ui, repo, state.wctx, shelvectx)
468 mergefiles(ui, repo, state.wctx, shelvectx)
462
469
463 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
470 repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve')
464 shelvedstate.clear(repo)
471 shelvedstate.clear(repo)
465 unshelvecleanup(ui, repo, state.name, opts)
472 unshelvecleanup(ui, repo, state.name, opts)
466 ui.status(_("unshelve of '%s' complete\n") % state.name)
473 ui.status(_("unshelve of '%s' complete\n") % state.name)
467 finally:
474 finally:
468 lockmod.release(lock, wlock)
475 lockmod.release(lock, wlock)
469
476
470 @command('unshelve',
477 @command('unshelve',
471 [('a', 'abort', None,
478 [('a', 'abort', None,
472 _('abort an incomplete unshelve operation')),
479 _('abort an incomplete unshelve operation')),
473 ('c', 'continue', None,
480 ('c', 'continue', None,
474 _('continue an incomplete unshelve operation')),
481 _('continue an incomplete unshelve operation')),
475 ('', 'keep', None,
482 ('', 'keep', None,
476 _('keep shelve after unshelving')),
483 _('keep shelve after unshelving')),
477 ('', 'date', '',
484 ('', 'date', '',
478 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
485 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
479 _('hg unshelve [SHELVED]'))
486 _('hg unshelve [SHELVED]'))
480 def unshelve(ui, repo, *shelved, **opts):
487 def unshelve(ui, repo, *shelved, **opts):
481 """restore a shelved change to the working directory
488 """restore a shelved change to the working directory
482
489
483 This command accepts an optional name of a shelved change to
490 This command accepts an optional name of a shelved change to
484 restore. If none is given, the most recent shelved change is used.
491 restore. If none is given, the most recent shelved change is used.
485
492
486 If a shelved change is applied successfully, the bundle that
493 If a shelved change is applied successfully, the bundle that
487 contains the shelved changes is deleted afterwards.
494 contains the shelved changes is deleted afterwards.
488
495
489 Since you can restore a shelved change on top of an arbitrary
496 Since you can restore a shelved change on top of an arbitrary
490 commit, it is possible that unshelving will result in a conflict
497 commit, it is possible that unshelving will result in a conflict
491 between your changes and the commits you are unshelving onto. If
498 between your changes and the commits you are unshelving onto. If
492 this occurs, you must resolve the conflict, then use
499 this occurs, you must resolve the conflict, then use
493 ``--continue`` to complete the unshelve operation. (The bundle
500 ``--continue`` to complete the unshelve operation. (The bundle
494 will not be deleted until you successfully complete the unshelve.)
501 will not be deleted until you successfully complete the unshelve.)
495
502
496 (Alternatively, you can use ``--abort`` to abandon an unshelve
503 (Alternatively, you can use ``--abort`` to abandon an unshelve
497 that causes a conflict. This reverts the unshelved changes, and
504 that causes a conflict. This reverts the unshelved changes, and
498 does not delete the bundle.)
505 does not delete the bundle.)
499 """
506 """
500 abortf = opts['abort']
507 abortf = opts['abort']
501 continuef = opts['continue']
508 continuef = opts['continue']
502 if not abortf and not continuef:
509 if not abortf and not continuef:
503 cmdutil.checkunfinished(repo)
510 cmdutil.checkunfinished(repo)
504
511
505 if abortf or continuef:
512 if abortf or continuef:
506 if abortf and continuef:
513 if abortf and continuef:
507 raise util.Abort(_('cannot use both abort and continue'))
514 raise util.Abort(_('cannot use both abort and continue'))
508 if shelved:
515 if shelved:
509 raise util.Abort(_('cannot combine abort/continue with '
516 raise util.Abort(_('cannot combine abort/continue with '
510 'naming a shelved change'))
517 'naming a shelved change'))
511
518
512 try:
519 try:
513 state = shelvedstate.load(repo)
520 state = shelvedstate.load(repo)
514 except IOError, err:
521 except IOError, err:
515 if err.errno != errno.ENOENT:
522 if err.errno != errno.ENOENT:
516 raise
523 raise
517 raise util.Abort(_('no unshelve operation underway'))
524 raise util.Abort(_('no unshelve operation underway'))
518
525
519 if abortf:
526 if abortf:
520 return unshelveabort(ui, repo, state, opts)
527 return unshelveabort(ui, repo, state, opts)
521 elif continuef:
528 elif continuef:
522 return unshelvecontinue(ui, repo, state, opts)
529 return unshelvecontinue(ui, repo, state, opts)
523 elif len(shelved) > 1:
530 elif len(shelved) > 1:
524 raise util.Abort(_('can only unshelve one change at a time'))
531 raise util.Abort(_('can only unshelve one change at a time'))
525 elif not shelved:
532 elif not shelved:
526 shelved = listshelves(repo)
533 shelved = listshelves(repo)
527 if not shelved:
534 if not shelved:
528 raise util.Abort(_('no shelved changes to apply!'))
535 raise util.Abort(_('no shelved changes to apply!'))
529 basename = util.split(shelved[0][1])[1]
536 basename = util.split(shelved[0][1])[1]
530 ui.status(_("unshelving change '%s'\n") % basename)
537 ui.status(_("unshelving change '%s'\n") % basename)
531 else:
538 else:
532 basename = shelved[0]
539 basename = shelved[0]
533
540
534 if not shelvedfile(repo, basename, 'patch').exists():
541 if not shelvedfile(repo, basename, 'patch').exists():
535 raise util.Abort(_("shelved change '%s' not found") % basename)
542 raise util.Abort(_("shelved change '%s' not found") % basename)
536
543
537 oldquiet = ui.quiet
544 oldquiet = ui.quiet
538 wlock = lock = tr = None
545 wlock = lock = tr = None
539 try:
546 try:
540 lock = repo.lock()
547 lock = repo.lock()
541 wlock = repo.wlock()
548 wlock = repo.wlock()
542
549
543 tr = repo.transaction('unshelve', report=lambda x: None)
550 tr = repo.transaction('unshelve', report=lambda x: None)
544 oldtiprev = len(repo)
551 oldtiprev = len(repo)
545
552
546 pctx = repo['.']
553 pctx = repo['.']
547 tmpwctx = pctx
554 tmpwctx = pctx
548 # The goal is to have a commit structure like so:
555 # The goal is to have a commit structure like so:
549 # ...-> pctx -> tmpwctx -> shelvectx
556 # ...-> pctx -> tmpwctx -> shelvectx
550 # where tmpwctx is an optional commit with the user's pending changes
557 # where tmpwctx is an optional commit with the user's pending changes
551 # and shelvectx is the unshelved changes. Then we merge it all down
558 # and shelvectx is the unshelved changes. Then we merge it all down
552 # to the original pctx.
559 # to the original pctx.
553
560
554 # Store pending changes in a commit
561 # Store pending changes in a commit
555 s = repo.status()
562 s = repo.status()
556 if s.modified or s.added or s.removed or s.deleted:
563 if s.modified or s.added or s.removed or s.deleted:
557 ui.status(_("temporarily committing pending changes "
564 ui.status(_("temporarily committing pending changes "
558 "(restore with 'hg unshelve --abort')\n"))
565 "(restore with 'hg unshelve --abort')\n"))
559 def commitfunc(ui, repo, message, match, opts):
566 def commitfunc(ui, repo, message, match, opts):
560 hasmq = util.safehasattr(repo, 'mq')
567 hasmq = util.safehasattr(repo, 'mq')
561 if hasmq:
568 if hasmq:
562 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
569 saved, repo.mq.checkapplied = repo.mq.checkapplied, False
563
570
564 backup = repo.ui.backupconfig('phases', 'new-commit')
571 backup = repo.ui.backupconfig('phases', 'new-commit')
565 try:
572 try:
566 repo.ui. setconfig('phases', 'new-commit', phases.secret)
573 repo.ui. setconfig('phases', 'new-commit', phases.secret)
567 return repo.commit(message, 'shelve@localhost',
574 return repo.commit(message, 'shelve@localhost',
568 opts.get('date'), match)
575 opts.get('date'), match)
569 finally:
576 finally:
570 repo.ui.restoreconfig(backup)
577 repo.ui.restoreconfig(backup)
571 if hasmq:
578 if hasmq:
572 repo.mq.checkapplied = saved
579 repo.mq.checkapplied = saved
573
580
574 tempopts = {}
581 tempopts = {}
575 tempopts['message'] = "pending changes temporary commit"
582 tempopts['message'] = "pending changes temporary commit"
576 tempopts['date'] = opts.get('date')
583 tempopts['date'] = opts.get('date')
577 ui.quiet = True
584 ui.quiet = True
578 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
585 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
579 tmpwctx = repo[node]
586 tmpwctx = repo[node]
580
587
581 ui.quiet = True
588 ui.quiet = True
582 shelvedfile(repo, basename, 'hg').applybundle()
589 shelvedfile(repo, basename, 'hg').applybundle()
583
590
584 ui.quiet = oldquiet
591 ui.quiet = oldquiet
585
592
586 shelvectx = repo['tip']
593 shelvectx = repo['tip']
587
594
588 # If the shelve is not immediately on top of the commit
595 # If the shelve is not immediately on top of the commit
589 # we'll be merging with, rebase it to be on top.
596 # we'll be merging with, rebase it to be on top.
590 if tmpwctx.node() != shelvectx.parents()[0].node():
597 if tmpwctx.node() != shelvectx.parents()[0].node():
591 ui.status(_('rebasing shelved changes\n'))
598 ui.status(_('rebasing shelved changes\n'))
592 try:
599 try:
593 rebase.rebase(ui, repo, **{
600 rebase.rebase(ui, repo, **{
594 'rev' : [shelvectx.rev()],
601 'rev' : [shelvectx.rev()],
595 'dest' : str(tmpwctx.rev()),
602 'dest' : str(tmpwctx.rev()),
596 'keep' : True,
603 'keep' : True,
597 })
604 })
598 except error.InterventionRequired:
605 except error.InterventionRequired:
599 tr.close()
606 tr.close()
600
607
601 stripnodes = [repo.changelog.node(rev)
608 stripnodes = [repo.changelog.node(rev)
602 for rev in xrange(oldtiprev, len(repo))]
609 for rev in xrange(oldtiprev, len(repo))]
603 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes)
610 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes)
604
611
605 util.rename(repo.join('rebasestate'),
612 util.rename(repo.join('rebasestate'),
606 repo.join('unshelverebasestate'))
613 repo.join('unshelverebasestate'))
607 raise error.InterventionRequired(
614 raise error.InterventionRequired(
608 _("unresolved conflicts (see 'hg resolve', then "
615 _("unresolved conflicts (see 'hg resolve', then "
609 "'hg unshelve --continue')"))
616 "'hg unshelve --continue')"))
610
617
611 # refresh ctx after rebase completes
618 # refresh ctx after rebase completes
612 shelvectx = repo['tip']
619 shelvectx = repo['tip']
613
620
614 if not shelvectx in tmpwctx.children():
621 if not shelvectx in tmpwctx.children():
615 # rebase was a no-op, so it produced no child commit
622 # rebase was a no-op, so it produced no child commit
616 shelvectx = tmpwctx
623 shelvectx = tmpwctx
617
624
618 mergefiles(ui, repo, pctx, shelvectx)
625 mergefiles(ui, repo, pctx, shelvectx)
619 shelvedstate.clear(repo)
626 shelvedstate.clear(repo)
620
627
621 # The transaction aborting will strip all the commits for us,
628 # The transaction aborting will strip all the commits for us,
622 # but it doesn't update the inmemory structures, so addchangegroup
629 # but it doesn't update the inmemory structures, so addchangegroup
623 # hooks still fire and try to operate on the missing commits.
630 # hooks still fire and try to operate on the missing commits.
624 # Clean up manually to prevent this.
631 # Clean up manually to prevent this.
625 repo.unfiltered().changelog.strip(oldtiprev, tr)
632 repo.unfiltered().changelog.strip(oldtiprev, tr)
626
633
627 unshelvecleanup(ui, repo, basename, opts)
634 unshelvecleanup(ui, repo, basename, opts)
628 finally:
635 finally:
629 ui.quiet = oldquiet
636 ui.quiet = oldquiet
630 if tr:
637 if tr:
631 tr.release()
638 tr.release()
632 lockmod.release(lock, wlock)
639 lockmod.release(lock, wlock)
633
640
634 @command('shelve',
641 @command('shelve',
635 [('A', 'addremove', None,
642 [('A', 'addremove', None,
636 _('mark new/missing files as added/removed before shelving')),
643 _('mark new/missing files as added/removed before shelving')),
637 ('', 'cleanup', None,
644 ('', 'cleanup', None,
638 _('delete all shelved changes')),
645 _('delete all shelved changes')),
639 ('', 'date', '',
646 ('', 'date', '',
640 _('shelve with the specified commit date'), _('DATE')),
647 _('shelve with the specified commit date'), _('DATE')),
641 ('d', 'delete', None,
648 ('d', 'delete', None,
642 _('delete the named shelved change(s)')),
649 _('delete the named shelved change(s)')),
643 ('e', 'edit', False,
650 ('e', 'edit', False,
644 _('invoke editor on commit messages')),
651 _('invoke editor on commit messages')),
645 ('l', 'list', None,
652 ('l', 'list', None,
646 _('list current shelves')),
653 _('list current shelves')),
647 ('m', 'message', '',
654 ('m', 'message', '',
648 _('use text as shelve message'), _('TEXT')),
655 _('use text as shelve message'), _('TEXT')),
649 ('n', 'name', '',
656 ('n', 'name', '',
650 _('use the given name for the shelved commit'), _('NAME')),
657 _('use the given name for the shelved commit'), _('NAME')),
651 ('p', 'patch', None,
658 ('p', 'patch', None,
652 _('show patch')),
659 _('show patch')),
653 ('i', 'interactive', None,
660 ('i', 'interactive', None,
654 _('interactive mode, only works while creating a shelve')),
661 _('interactive mode, only works while creating a shelve')),
655 ('', 'stat', None,
662 ('', 'stat', None,
656 _('output diffstat-style summary of changes'))] + commands.walkopts,
663 _('output diffstat-style summary of changes'))] + commands.walkopts,
657 _('hg shelve [OPTION]... [FILE]...'))
664 _('hg shelve [OPTION]... [FILE]...'))
658 def shelvecmd(ui, repo, *pats, **opts):
665 def shelvecmd(ui, repo, *pats, **opts):
659 '''save and set aside changes from the working directory
666 '''save and set aside changes from the working directory
660
667
661 Shelving takes files that "hg status" reports as not clean, saves
668 Shelving takes files that "hg status" reports as not clean, saves
662 the modifications to a bundle (a shelved change), and reverts the
669 the modifications to a bundle (a shelved change), and reverts the
663 files so that their state in the working directory becomes clean.
670 files so that their state in the working directory becomes clean.
664
671
665 To restore these changes to the working directory, using "hg
672 To restore these changes to the working directory, using "hg
666 unshelve"; this will work even if you switch to a different
673 unshelve"; this will work even if you switch to a different
667 commit.
674 commit.
668
675
669 When no files are specified, "hg shelve" saves all not-clean
676 When no files are specified, "hg shelve" saves all not-clean
670 files. If specific files or directories are named, only changes to
677 files. If specific files or directories are named, only changes to
671 those files are shelved.
678 those files are shelved.
672
679
673 Each shelved change has a name that makes it easier to find later.
680 Each shelved change has a name that makes it easier to find later.
674 The name of a shelved change defaults to being based on the active
681 The name of a shelved change defaults to being based on the active
675 bookmark, or if there is no active bookmark, the current named
682 bookmark, or if there is no active bookmark, the current named
676 branch. To specify a different name, use ``--name``.
683 branch. To specify a different name, use ``--name``.
677
684
678 To see a list of existing shelved changes, use the ``--list``
685 To see a list of existing shelved changes, use the ``--list``
679 option. For each shelved change, this will print its name, age,
686 option. For each shelved change, this will print its name, age,
680 and description; use ``--patch`` or ``--stat`` for more details.
687 and description; use ``--patch`` or ``--stat`` for more details.
681
688
682 To delete specific shelved changes, use ``--delete``. To delete
689 To delete specific shelved changes, use ``--delete``. To delete
683 all shelved changes, use ``--cleanup``.
690 all shelved changes, use ``--cleanup``.
684 '''
691 '''
685 cmdutil.checkunfinished(repo)
692 cmdutil.checkunfinished(repo)
686
693
687 allowables = [
694 allowables = [
688 ('addremove', 'create'), # 'create' is pseudo action
695 ('addremove', 'create'), # 'create' is pseudo action
689 ('cleanup', 'cleanup'),
696 ('cleanup', 'cleanup'),
690 # ('date', 'create'), # ignored for passing '--date "0 0"' in tests
697 # ('date', 'create'), # ignored for passing '--date "0 0"' in tests
691 ('delete', 'delete'),
698 ('delete', 'delete'),
692 ('edit', 'create'),
699 ('edit', 'create'),
693 ('list', 'list'),
700 ('list', 'list'),
694 ('message', 'create'),
701 ('message', 'create'),
695 ('name', 'create'),
702 ('name', 'create'),
696 ('patch', 'list'),
703 ('patch', 'list'),
697 ('stat', 'list'),
704 ('stat', 'list'),
698 ]
705 ]
699 def checkopt(opt):
706 def checkopt(opt):
700 if opts[opt]:
707 if opts[opt]:
701 for i, allowable in allowables:
708 for i, allowable in allowables:
702 if opts[i] and opt != allowable:
709 if opts[i] and opt != allowable:
703 raise util.Abort(_("options '--%s' and '--%s' may not be "
710 raise util.Abort(_("options '--%s' and '--%s' may not be "
704 "used together") % (opt, i))
711 "used together") % (opt, i))
705 return True
712 return True
706 if checkopt('cleanup'):
713 if checkopt('cleanup'):
707 if pats:
714 if pats:
708 raise util.Abort(_("cannot specify names when using '--cleanup'"))
715 raise util.Abort(_("cannot specify names when using '--cleanup'"))
709 return cleanupcmd(ui, repo)
716 return cleanupcmd(ui, repo)
710 elif checkopt('delete'):
717 elif checkopt('delete'):
711 return deletecmd(ui, repo, pats)
718 return deletecmd(ui, repo, pats)
712 elif checkopt('list'):
719 elif checkopt('list'):
713 return listcmd(ui, repo, pats, opts)
720 return listcmd(ui, repo, pats, opts)
714 else:
721 else:
715 for i in ('patch', 'stat'):
722 for i in ('patch', 'stat'):
716 if opts[i]:
723 if opts[i]:
717 raise util.Abort(_("option '--%s' may not be "
724 raise util.Abort(_("option '--%s' may not be "
718 "used when shelving a change") % (i,))
725 "used when shelving a change") % (i,))
719 return createcmd(ui, repo, pats, opts)
726 return createcmd(ui, repo, pats, opts)
720
727
721 def extsetup(ui):
728 def extsetup(ui):
722 cmdutil.unfinishedstates.append(
729 cmdutil.unfinishedstates.append(
723 [shelvedstate._filename, False, False,
730 [shelvedstate._filename, False, False,
724 _('unshelve already in progress'),
731 _('unshelve already in progress'),
725 _("use 'hg unshelve --continue' or 'hg unshelve --abort'")])
732 _("use 'hg unshelve --continue' or 'hg unshelve --abort'")])
@@ -1,794 +1,866 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 > EOF
8 > EOF
9
9
10 $ hg init repo
10 $ hg init repo
11 $ cd repo
11 $ cd repo
12 $ mkdir a b
12 $ mkdir a b
13 $ echo a > a/a
13 $ echo a > a/a
14 $ echo b > b/b
14 $ echo b > b/b
15 $ echo c > c
15 $ echo c > c
16 $ echo d > d
16 $ echo d > d
17 $ echo x > x
17 $ echo x > x
18 $ hg addremove -q
18 $ hg addremove -q
19
19
20 shelve has a help message
20 shelve has a help message
21 $ hg shelve -h
21 $ hg shelve -h
22 hg shelve [OPTION]... [FILE]...
22 hg shelve [OPTION]... [FILE]...
23
23
24 save and set aside changes from the working directory
24 save and set aside changes from the working directory
25
25
26 Shelving takes files that "hg status" reports as not clean, saves the
26 Shelving takes files that "hg status" reports as not clean, saves the
27 modifications to a bundle (a shelved change), and reverts the files so
27 modifications to a bundle (a shelved change), and reverts the files so
28 that their state in the working directory becomes clean.
28 that their state in the working directory becomes clean.
29
29
30 To restore these changes to the working directory, using "hg unshelve";
30 To restore these changes to the working directory, using "hg unshelve";
31 this will work even if you switch to a different commit.
31 this will work even if you switch to a different commit.
32
32
33 When no files are specified, "hg shelve" saves all not-clean files. If
33 When no files are specified, "hg shelve" saves all not-clean files. If
34 specific files or directories are named, only changes to those files are
34 specific files or directories are named, only changes to those files are
35 shelved.
35 shelved.
36
36
37 Each shelved change has a name that makes it easier to find later. The
37 Each shelved change has a name that makes it easier to find later. The
38 name of a shelved change defaults to being based on the active bookmark,
38 name of a shelved change defaults to being based on the active bookmark,
39 or if there is no active bookmark, the current named branch. To specify a
39 or if there is no active bookmark, the current named branch. To specify a
40 different name, use "--name".
40 different name, use "--name".
41
41
42 To see a list of existing shelved changes, use the "--list" option. For
42 To see a list of existing shelved changes, use the "--list" option. For
43 each shelved change, this will print its name, age, and description; use "
43 each shelved change, this will print its name, age, and description; use "
44 --patch" or "--stat" for more details.
44 --patch" or "--stat" for more details.
45
45
46 To delete specific shelved changes, use "--delete". To delete all shelved
46 To delete specific shelved changes, use "--delete". To delete all shelved
47 changes, use "--cleanup".
47 changes, use "--cleanup".
48
48
49 (use "hg help -e shelve" to show help for the shelve extension)
49 (use "hg help -e shelve" to show help for the shelve extension)
50
50
51 options ([+] can be repeated):
51 options ([+] can be repeated):
52
52
53 -A --addremove mark new/missing files as added/removed before
53 -A --addremove mark new/missing files as added/removed before
54 shelving
54 shelving
55 --cleanup delete all shelved changes
55 --cleanup delete all shelved changes
56 --date DATE shelve with the specified commit date
56 --date DATE shelve with the specified commit date
57 -d --delete delete the named shelved change(s)
57 -d --delete delete the named shelved change(s)
58 -e --edit invoke editor on commit messages
58 -e --edit invoke editor on commit messages
59 -l --list list current shelves
59 -l --list list current shelves
60 -m --message TEXT use text as shelve message
60 -m --message TEXT use text as shelve message
61 -n --name NAME use the given name for the shelved commit
61 -n --name NAME use the given name for the shelved commit
62 -p --patch show patch
62 -p --patch show patch
63 -i --interactive interactive mode, only works while creating a shelve
63 -i --interactive interactive mode, only works while creating a shelve
64 --stat output diffstat-style summary of changes
64 --stat output diffstat-style summary of changes
65 -I --include PATTERN [+] include names matching the given patterns
65 -I --include PATTERN [+] include names matching the given patterns
66 -X --exclude PATTERN [+] exclude names matching the given patterns
66 -X --exclude PATTERN [+] exclude names matching the given patterns
67 --mq operate on patch repository
67 --mq operate on patch repository
68
68
69 (some details hidden, use --verbose to show complete help)
69 (some details hidden, use --verbose to show complete help)
70
70
71 shelving in an empty repo should be possible
71 shelving in an empty repo should be possible
72 (this tests also that editor is not invoked, if '--edit' is not
72 (this tests also that editor is not invoked, if '--edit' is not
73 specified)
73 specified)
74
74
75 $ HGEDITOR=cat hg shelve
75 $ HGEDITOR=cat hg shelve
76 shelved as default
76 shelved as default
77 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
77 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
78
78
79 $ hg unshelve
79 $ hg unshelve
80 unshelving change 'default'
80 unshelving change 'default'
81
81
82 $ hg commit -q -m 'initial commit'
82 $ hg commit -q -m 'initial commit'
83
83
84 $ hg shelve
84 $ hg shelve
85 nothing changed
85 nothing changed
86 [1]
86 [1]
87
87
88 create an mq patch - shelving should work fine with a patch applied
88 create an mq patch - shelving should work fine with a patch applied
89
89
90 $ echo n > n
90 $ echo n > n
91 $ hg add n
91 $ hg add n
92 $ hg commit n -m second
92 $ hg commit n -m second
93 $ hg qnew second.patch
93 $ hg qnew second.patch
94
94
95 shelve a change that we will delete later
95 shelve a change that we will delete later
96
96
97 $ echo a >> a/a
97 $ echo a >> a/a
98 $ hg shelve
98 $ hg shelve
99 shelved as default
99 shelved as default
100 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
101
101
102 set up some more complex changes to shelve
102 set up some more complex changes to shelve
103
103
104 $ echo a >> a/a
104 $ echo a >> a/a
105 $ hg mv b b.rename
105 $ hg mv b b.rename
106 moving b/b to b.rename/b (glob)
106 moving b/b to b.rename/b (glob)
107 $ hg cp c c.copy
107 $ hg cp c c.copy
108 $ hg status -C
108 $ hg status -C
109 M a/a
109 M a/a
110 A b.rename/b
110 A b.rename/b
111 b/b
111 b/b
112 A c.copy
112 A c.copy
113 c
113 c
114 R b/b
114 R b/b
115
115
116 prevent some foot-shooting
116 prevent some foot-shooting
117
117
118 $ hg shelve -n foo/bar
118 $ hg shelve -n foo/bar
119 abort: shelved change names may not contain slashes
119 abort: shelved change names may not contain slashes
120 [255]
120 [255]
121 $ hg shelve -n .baz
121 $ hg shelve -n .baz
122 abort: shelved change names may not start with '.'
122 abort: shelved change names may not start with '.'
123 [255]
123 [255]
124
124
125 the common case - no options or filenames
125 the common case - no options or filenames
126
126
127 $ hg shelve
127 $ hg shelve
128 shelved as default-01
128 shelved as default-01
129 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
129 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
130 $ hg status -C
130 $ hg status -C
131
131
132 ensure that our shelved changes exist
132 ensure that our shelved changes exist
133
133
134 $ hg shelve -l
134 $ hg shelve -l
135 default-01 (*)* changes to '[mq]: second.patch' (glob)
135 default-01 (*)* changes to '[mq]: second.patch' (glob)
136 default (*)* changes to '[mq]: second.patch' (glob)
136 default (*)* changes to '[mq]: second.patch' (glob)
137
137
138 $ hg shelve -l -p default
138 $ hg shelve -l -p default
139 default (*)* changes to '[mq]: second.patch' (glob)
139 default (*)* changes to '[mq]: second.patch' (glob)
140
140
141 diff --git a/a/a b/a/a
141 diff --git a/a/a b/a/a
142 --- a/a/a
142 --- a/a/a
143 +++ b/a/a
143 +++ b/a/a
144 @@ -1,1 +1,2 @@
144 @@ -1,1 +1,2 @@
145 a
145 a
146 +a
146 +a
147
147
148 $ hg shelve --list --addremove
148 $ hg shelve --list --addremove
149 abort: options '--list' and '--addremove' may not be used together
149 abort: options '--list' and '--addremove' may not be used together
150 [255]
150 [255]
151
151
152 delete our older shelved change
152 delete our older shelved change
153
153
154 $ hg shelve -d default
154 $ hg shelve -d default
155 $ hg qfinish -a -q
155 $ hg qfinish -a -q
156
156
157 local edits should not prevent a shelved change from applying
157 local edits should not prevent a shelved change from applying
158
158
159 $ printf "z\na\n" > a/a
159 $ printf "z\na\n" > a/a
160 $ hg unshelve --keep
160 $ hg unshelve --keep
161 unshelving change 'default-01'
161 unshelving change 'default-01'
162 temporarily committing pending changes (restore with 'hg unshelve --abort')
162 temporarily committing pending changes (restore with 'hg unshelve --abort')
163 rebasing shelved changes
163 rebasing shelved changes
164 rebasing 4:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
164 rebasing 4:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
165 merging a/a
165 merging a/a
166
166
167 $ hg revert --all -q
167 $ hg revert --all -q
168 $ rm a/a.orig b.rename/b c.copy
168 $ rm a/a.orig b.rename/b c.copy
169
169
170 apply it and make sure our state is as expected
170 apply it and make sure our state is as expected
171
171
172 $ hg unshelve
172 $ hg unshelve
173 unshelving change 'default-01'
173 unshelving change 'default-01'
174 $ hg status -C
174 $ hg status -C
175 M a/a
175 M a/a
176 A b.rename/b
176 A b.rename/b
177 b/b
177 b/b
178 A c.copy
178 A c.copy
179 c
179 c
180 R b/b
180 R b/b
181 $ hg shelve -l
181 $ hg shelve -l
182
182
183 $ hg unshelve
183 $ hg unshelve
184 abort: no shelved changes to apply!
184 abort: no shelved changes to apply!
185 [255]
185 [255]
186 $ hg unshelve foo
186 $ hg unshelve foo
187 abort: shelved change 'foo' not found
187 abort: shelved change 'foo' not found
188 [255]
188 [255]
189
189
190 named shelves, specific filenames, and "commit messages" should all work
190 named shelves, specific filenames, and "commit messages" should all work
191 (this tests also that editor is invoked, if '--edit' is specified)
191 (this tests also that editor is invoked, if '--edit' is specified)
192
192
193 $ hg status -C
193 $ hg status -C
194 M a/a
194 M a/a
195 A b.rename/b
195 A b.rename/b
196 b/b
196 b/b
197 A c.copy
197 A c.copy
198 c
198 c
199 R b/b
199 R b/b
200 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
200 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
201 wat
201 wat
202
202
203
203
204 HG: Enter commit message. Lines beginning with 'HG:' are removed.
204 HG: Enter commit message. Lines beginning with 'HG:' are removed.
205 HG: Leave message empty to abort commit.
205 HG: Leave message empty to abort commit.
206 HG: --
206 HG: --
207 HG: user: shelve@localhost
207 HG: user: shelve@localhost
208 HG: branch 'default'
208 HG: branch 'default'
209 HG: changed a/a
209 HG: changed a/a
210
210
211 expect "a" to no longer be present, but status otherwise unchanged
211 expect "a" to no longer be present, but status otherwise unchanged
212
212
213 $ hg status -C
213 $ hg status -C
214 A b.rename/b
214 A b.rename/b
215 b/b
215 b/b
216 A c.copy
216 A c.copy
217 c
217 c
218 R b/b
218 R b/b
219 $ hg shelve -l --stat
219 $ hg shelve -l --stat
220 wibble (*) wat (glob)
220 wibble (*) wat (glob)
221 a/a | 1 +
221 a/a | 1 +
222 1 files changed, 1 insertions(+), 0 deletions(-)
222 1 files changed, 1 insertions(+), 0 deletions(-)
223
223
224 and now "a/a" should reappear
224 and now "a/a" should reappear
225
225
226 $ cd a
226 $ cd a
227 $ hg unshelve -q wibble
227 $ hg unshelve -q wibble
228 $ cd ..
228 $ cd ..
229 $ hg status -C
229 $ hg status -C
230 M a/a
230 M a/a
231 A b.rename/b
231 A b.rename/b
232 b/b
232 b/b
233 A c.copy
233 A c.copy
234 c
234 c
235 R b/b
235 R b/b
236
236
237 cause unshelving to result in a merge with 'a' conflicting
237 cause unshelving to result in a merge with 'a' conflicting
238
238
239 $ hg shelve -q
239 $ hg shelve -q
240 $ echo c>>a/a
240 $ echo c>>a/a
241 $ hg commit -m second
241 $ hg commit -m second
242 $ hg tip --template '{files}\n'
242 $ hg tip --template '{files}\n'
243 a/a
243 a/a
244
244
245 add an unrelated change that should be preserved
245 add an unrelated change that should be preserved
246
246
247 $ mkdir foo
247 $ mkdir foo
248 $ echo foo > foo/foo
248 $ echo foo > foo/foo
249 $ hg add foo/foo
249 $ hg add foo/foo
250
250
251 force a conflicted merge to occur
251 force a conflicted merge to occur
252
252
253 $ hg unshelve
253 $ hg unshelve
254 unshelving change 'default'
254 unshelving change 'default'
255 temporarily committing pending changes (restore with 'hg unshelve --abort')
255 temporarily committing pending changes (restore with 'hg unshelve --abort')
256 rebasing shelved changes
256 rebasing shelved changes
257 rebasing 5:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
257 rebasing 5:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
258 merging a/a
258 merging a/a
259 warning: conflicts during merge.
259 warning: conflicts during merge.
260 merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
260 merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
261 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
261 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
262 [1]
262 [1]
263
263
264 ensure that we have a merge with unresolved conflicts
264 ensure that we have a merge with unresolved conflicts
265
265
266 $ hg heads -q --template '{rev}\n'
266 $ hg heads -q --template '{rev}\n'
267 5
267 5
268 4
268 4
269 $ hg parents -q --template '{rev}\n'
269 $ hg parents -q --template '{rev}\n'
270 4
270 4
271 5
271 5
272 $ hg status
272 $ hg status
273 M a/a
273 M a/a
274 M b.rename/b
274 M b.rename/b
275 M c.copy
275 M c.copy
276 R b/b
276 R b/b
277 ? a/a.orig
277 ? a/a.orig
278 $ hg diff
278 $ hg diff
279 diff --git a/a/a b/a/a
279 diff --git a/a/a b/a/a
280 --- a/a/a
280 --- a/a/a
281 +++ b/a/a
281 +++ b/a/a
282 @@ -1,2 +1,6 @@
282 @@ -1,2 +1,6 @@
283 a
283 a
284 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
284 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
285 c
285 c
286 +=======
286 +=======
287 +a
287 +a
288 +>>>>>>> source: 4702e8911fe0 - shelve: changes to '[mq]: second.patch'
288 +>>>>>>> source: 4702e8911fe0 - shelve: changes to '[mq]: second.patch'
289 diff --git a/b/b b/b.rename/b
289 diff --git a/b/b b/b.rename/b
290 rename from b/b
290 rename from b/b
291 rename to b.rename/b
291 rename to b.rename/b
292 diff --git a/c b/c.copy
292 diff --git a/c b/c.copy
293 copy from c
293 copy from c
294 copy to c.copy
294 copy to c.copy
295 $ hg resolve -l
295 $ hg resolve -l
296 U a/a
296 U a/a
297
297
298 $ hg shelve
298 $ hg shelve
299 abort: unshelve already in progress
299 abort: unshelve already in progress
300 (use 'hg unshelve --continue' or 'hg unshelve --abort')
300 (use 'hg unshelve --continue' or 'hg unshelve --abort')
301 [255]
301 [255]
302
302
303 abort the unshelve and be happy
303 abort the unshelve and be happy
304
304
305 $ hg status
305 $ hg status
306 M a/a
306 M a/a
307 M b.rename/b
307 M b.rename/b
308 M c.copy
308 M c.copy
309 R b/b
309 R b/b
310 ? a/a.orig
310 ? a/a.orig
311 $ hg unshelve -a
311 $ hg unshelve -a
312 rebase aborted
312 rebase aborted
313 unshelve of 'default' aborted
313 unshelve of 'default' aborted
314 $ hg heads -q
314 $ hg heads -q
315 3:2e69b451d1ea
315 3:2e69b451d1ea
316 $ hg parents
316 $ hg parents
317 changeset: 3:2e69b451d1ea
317 changeset: 3:2e69b451d1ea
318 tag: tip
318 tag: tip
319 user: test
319 user: test
320 date: Thu Jan 01 00:00:00 1970 +0000
320 date: Thu Jan 01 00:00:00 1970 +0000
321 summary: second
321 summary: second
322
322
323 $ hg resolve -l
323 $ hg resolve -l
324 $ hg status
324 $ hg status
325 A foo/foo
325 A foo/foo
326 ? a/a.orig
326 ? a/a.orig
327
327
328 try to continue with no unshelve underway
328 try to continue with no unshelve underway
329
329
330 $ hg unshelve -c
330 $ hg unshelve -c
331 abort: no unshelve operation underway
331 abort: no unshelve operation underway
332 [255]
332 [255]
333 $ hg status
333 $ hg status
334 A foo/foo
334 A foo/foo
335 ? a/a.orig
335 ? a/a.orig
336
336
337 redo the unshelve to get a conflict
337 redo the unshelve to get a conflict
338
338
339 $ hg unshelve -q
339 $ hg unshelve -q
340 warning: conflicts during merge.
340 warning: conflicts during merge.
341 merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
341 merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
342 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
342 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
343 [1]
343 [1]
344
344
345 attempt to continue
345 attempt to continue
346
346
347 $ hg unshelve -c
347 $ hg unshelve -c
348 abort: unresolved conflicts, can't continue
348 abort: unresolved conflicts, can't continue
349 (see 'hg resolve', then 'hg unshelve --continue')
349 (see 'hg resolve', then 'hg unshelve --continue')
350 [255]
350 [255]
351
351
352 $ hg revert -r . a/a
352 $ hg revert -r . a/a
353 $ hg resolve -m a/a
353 $ hg resolve -m a/a
354 (no more unresolved files)
354 (no more unresolved files)
355
355
356 $ hg commit -m 'commit while unshelve in progress'
356 $ hg commit -m 'commit while unshelve in progress'
357 abort: unshelve already in progress
357 abort: unshelve already in progress
358 (use 'hg unshelve --continue' or 'hg unshelve --abort')
358 (use 'hg unshelve --continue' or 'hg unshelve --abort')
359 [255]
359 [255]
360
360
361 $ hg unshelve -c
361 $ hg unshelve -c
362 rebasing 5:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
362 rebasing 5:4702e8911fe0 "changes to '[mq]: second.patch'" (tip)
363 unshelve of 'default' complete
363 unshelve of 'default' complete
364
364
365 ensure the repo is as we hope
365 ensure the repo is as we hope
366
366
367 $ hg parents
367 $ hg parents
368 changeset: 3:2e69b451d1ea
368 changeset: 3:2e69b451d1ea
369 tag: tip
369 tag: tip
370 user: test
370 user: test
371 date: Thu Jan 01 00:00:00 1970 +0000
371 date: Thu Jan 01 00:00:00 1970 +0000
372 summary: second
372 summary: second
373
373
374 $ hg heads -q
374 $ hg heads -q
375 3:2e69b451d1ea
375 3:2e69b451d1ea
376
376
377 $ hg status -C
377 $ hg status -C
378 A b.rename/b
378 A b.rename/b
379 b/b
379 b/b
380 A c.copy
380 A c.copy
381 c
381 c
382 A foo/foo
382 A foo/foo
383 R b/b
383 R b/b
384 ? a/a.orig
384 ? a/a.orig
385
385
386 there should be no shelves left
386 there should be no shelves left
387
387
388 $ hg shelve -l
388 $ hg shelve -l
389
389
390 #if execbit
390 #if execbit
391
391
392 ensure that metadata-only changes are shelved
392 ensure that metadata-only changes are shelved
393
393
394 $ chmod +x a/a
394 $ chmod +x a/a
395 $ hg shelve -q -n execbit a/a
395 $ hg shelve -q -n execbit a/a
396 $ hg status a/a
396 $ hg status a/a
397 $ hg unshelve -q execbit
397 $ hg unshelve -q execbit
398 $ hg status a/a
398 $ hg status a/a
399 M a/a
399 M a/a
400 $ hg revert a/a
400 $ hg revert a/a
401
401
402 #endif
402 #endif
403
403
404 #if symlink
404 #if symlink
405
405
406 $ rm a/a
406 $ rm a/a
407 $ ln -s foo a/a
407 $ ln -s foo a/a
408 $ hg shelve -q -n symlink a/a
408 $ hg shelve -q -n symlink a/a
409 $ hg status a/a
409 $ hg status a/a
410 $ hg unshelve -q symlink
410 $ hg unshelve -q symlink
411 $ hg status a/a
411 $ hg status a/a
412 M a/a
412 M a/a
413 $ hg revert a/a
413 $ hg revert a/a
414
414
415 #endif
415 #endif
416
416
417 set up another conflict between a commit and a shelved change
417 set up another conflict between a commit and a shelved change
418
418
419 $ hg revert -q -C -a
419 $ hg revert -q -C -a
420 $ rm a/a.orig b.rename/b c.copy
420 $ rm a/a.orig b.rename/b c.copy
421 $ echo a >> a/a
421 $ echo a >> a/a
422 $ hg shelve -q
422 $ hg shelve -q
423 $ echo x >> a/a
423 $ echo x >> a/a
424 $ hg ci -m 'create conflict'
424 $ hg ci -m 'create conflict'
425 $ hg add foo/foo
425 $ hg add foo/foo
426
426
427 if we resolve a conflict while unshelving, the unshelve should succeed
427 if we resolve a conflict while unshelving, the unshelve should succeed
428
428
429 $ HGMERGE=true hg unshelve
429 $ HGMERGE=true hg unshelve
430 unshelving change 'default'
430 unshelving change 'default'
431 temporarily committing pending changes (restore with 'hg unshelve --abort')
431 temporarily committing pending changes (restore with 'hg unshelve --abort')
432 rebasing shelved changes
432 rebasing shelved changes
433 rebasing 6:c5e6910e7601 "changes to 'second'" (tip)
433 rebasing 6:c5e6910e7601 "changes to 'second'" (tip)
434 merging a/a
434 merging a/a
435 note: rebase of 6:c5e6910e7601 created no changes to commit
435 note: rebase of 6:c5e6910e7601 created no changes to commit
436 $ hg parents -q
436 $ hg parents -q
437 4:33f7f61e6c5e
437 4:33f7f61e6c5e
438 $ hg shelve -l
438 $ hg shelve -l
439 $ hg status
439 $ hg status
440 A foo/foo
440 A foo/foo
441 $ cat a/a
441 $ cat a/a
442 a
442 a
443 c
443 c
444 x
444 x
445
445
446 test keep and cleanup
446 test keep and cleanup
447
447
448 $ hg shelve
448 $ hg shelve
449 shelved as default
449 shelved as default
450 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
450 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
451 $ hg shelve --list
451 $ hg shelve --list
452 default (*) changes to 'create conflict' (glob)
452 default (*) changes to 'create conflict' (glob)
453 $ hg unshelve --keep
453 $ hg unshelve --keep
454 unshelving change 'default'
454 unshelving change 'default'
455 $ hg shelve --list
455 $ hg shelve --list
456 default (*) changes to 'create conflict' (glob)
456 default (*) changes to 'create conflict' (glob)
457 $ hg shelve --cleanup
457 $ hg shelve --cleanup
458 $ hg shelve --list
458 $ hg shelve --list
459
459
460 $ hg shelve --cleanup --delete
460 $ hg shelve --cleanup --delete
461 abort: options '--cleanup' and '--delete' may not be used together
461 abort: options '--cleanup' and '--delete' may not be used together
462 [255]
462 [255]
463 $ hg shelve --cleanup --patch
463 $ hg shelve --cleanup --patch
464 abort: options '--cleanup' and '--patch' may not be used together
464 abort: options '--cleanup' and '--patch' may not be used together
465 [255]
465 [255]
466 $ hg shelve --cleanup --message MESSAGE
466 $ hg shelve --cleanup --message MESSAGE
467 abort: options '--cleanup' and '--message' may not be used together
467 abort: options '--cleanup' and '--message' may not be used together
468 [255]
468 [255]
469
469
470 test bookmarks
470 test bookmarks
471
471
472 $ hg bookmark test
472 $ hg bookmark test
473 $ hg bookmark
473 $ hg bookmark
474 * test 4:33f7f61e6c5e
474 * test 4:33f7f61e6c5e
475 $ hg shelve
475 $ hg shelve
476 shelved as test
476 shelved as test
477 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
477 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
478 $ hg bookmark
478 $ hg bookmark
479 * test 4:33f7f61e6c5e
479 * test 4:33f7f61e6c5e
480 $ hg unshelve
480 $ hg unshelve
481 unshelving change 'test'
481 unshelving change 'test'
482 $ hg bookmark
482 $ hg bookmark
483 * test 4:33f7f61e6c5e
483 * test 4:33f7f61e6c5e
484
484
485 shelve should still work even if mq is disabled
485 shelve should still work even if mq is disabled
486
486
487 $ hg --config extensions.mq=! shelve
487 $ hg --config extensions.mq=! shelve
488 shelved as test
488 shelved as test
489 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
489 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
490 $ hg --config extensions.mq=! shelve --list
490 $ hg --config extensions.mq=! shelve --list
491 test (*) changes to 'create conflict' (glob)
491 test (*) changes to 'create conflict' (glob)
492 $ hg --config extensions.mq=! unshelve
492 $ hg --config extensions.mq=! unshelve
493 unshelving change 'test'
493 unshelving change 'test'
494
494
495 shelve should leave dirstate clean (issue4055)
495 shelve should leave dirstate clean (issue4055)
496
496
497 $ cd ..
497 $ cd ..
498 $ hg init shelverebase
498 $ hg init shelverebase
499 $ cd shelverebase
499 $ cd shelverebase
500 $ printf 'x\ny\n' > x
500 $ printf 'x\ny\n' > x
501 $ echo z > z
501 $ echo z > z
502 $ hg commit -Aqm xy
502 $ hg commit -Aqm xy
503 $ echo z >> x
503 $ echo z >> x
504 $ hg commit -Aqm z
504 $ hg commit -Aqm z
505 $ hg up 0
505 $ hg up 0
506 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
506 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
507 $ printf 'a\nx\ny\nz\n' > x
507 $ printf 'a\nx\ny\nz\n' > x
508 $ hg commit -Aqm xyz
508 $ hg commit -Aqm xyz
509 $ echo c >> z
509 $ echo c >> z
510 $ hg shelve
510 $ hg shelve
511 shelved as default
511 shelved as default
512 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
512 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
513 $ hg rebase -d 1 --config extensions.rebase=
513 $ hg rebase -d 1 --config extensions.rebase=
514 rebasing 2:323bfa07f744 "xyz" (tip)
514 rebasing 2:323bfa07f744 "xyz" (tip)
515 merging x
515 merging x
516 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
516 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
517 $ hg unshelve
517 $ hg unshelve
518 unshelving change 'default'
518 unshelving change 'default'
519 rebasing shelved changes
519 rebasing shelved changes
520 rebasing 4:b8fefe789ed0 "changes to 'xyz'" (tip)
520 rebasing 4:b8fefe789ed0 "changes to 'xyz'" (tip)
521 $ hg status
521 $ hg status
522 M z
522 M z
523
523
524 $ cd ..
524 $ cd ..
525
525
526 shelve should only unshelve pending changes (issue4068)
526 shelve should only unshelve pending changes (issue4068)
527
527
528 $ hg init onlypendingchanges
528 $ hg init onlypendingchanges
529 $ cd onlypendingchanges
529 $ cd onlypendingchanges
530 $ touch a
530 $ touch a
531 $ hg ci -Aqm a
531 $ hg ci -Aqm a
532 $ touch b
532 $ touch b
533 $ hg ci -Aqm b
533 $ hg ci -Aqm b
534 $ hg up -q 0
534 $ hg up -q 0
535 $ touch c
535 $ touch c
536 $ hg ci -Aqm c
536 $ hg ci -Aqm c
537
537
538 $ touch d
538 $ touch d
539 $ hg add d
539 $ hg add d
540 $ hg shelve
540 $ hg shelve
541 shelved as default
541 shelved as default
542 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
542 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
543 $ hg up -q 1
543 $ hg up -q 1
544 $ hg unshelve
544 $ hg unshelve
545 unshelving change 'default'
545 unshelving change 'default'
546 rebasing shelved changes
546 rebasing shelved changes
547 rebasing 3:0cae6656c016 "changes to 'c'" (tip)
547 rebasing 3:0cae6656c016 "changes to 'c'" (tip)
548 $ hg status
548 $ hg status
549 A d
549 A d
550
550
551 unshelve should work on an ancestor of the original commit
551 unshelve should work on an ancestor of the original commit
552
552
553 $ hg shelve
553 $ hg shelve
554 shelved as default
554 shelved as default
555 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
555 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
556 $ hg up 0
556 $ hg up 0
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 unshelve
558 $ hg unshelve
559 unshelving change 'default'
559 unshelving change 'default'
560 rebasing shelved changes
560 rebasing shelved changes
561 rebasing 3:be58f65f55fb "changes to 'b'" (tip)
561 rebasing 3:be58f65f55fb "changes to 'b'" (tip)
562 $ hg status
562 $ hg status
563 A d
563 A d
564
564
565 test bug 4073 we need to enable obsolete markers for it
565 test bug 4073 we need to enable obsolete markers for it
566
566
567 $ cat >> $HGRCPATH << EOF
567 $ cat >> $HGRCPATH << EOF
568 > [experimental]
568 > [experimental]
569 > evolution=createmarkers
569 > evolution=createmarkers
570 > EOF
570 > EOF
571 $ hg shelve
571 $ hg shelve
572 shelved as default
572 shelved as default
573 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
573 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
574 $ hg debugobsolete `hg --debug id -i -r 1`
574 $ hg debugobsolete `hg --debug id -i -r 1`
575 $ hg unshelve
575 $ hg unshelve
576 unshelving change 'default'
576 unshelving change 'default'
577
577
578 unshelve should leave unknown files alone (issue4113)
578 unshelve should leave unknown files alone (issue4113)
579
579
580 $ echo e > e
580 $ echo e > e
581 $ hg shelve
581 $ hg shelve
582 shelved as default
582 shelved as default
583 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
583 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
584 $ hg status
584 $ hg status
585 ? e
585 ? e
586 $ hg unshelve
586 $ hg unshelve
587 unshelving change 'default'
587 unshelving change 'default'
588 $ hg status
588 $ hg status
589 A d
589 A d
590 ? e
590 ? e
591 $ cat e
591 $ cat e
592 e
592 e
593
593
594 unshelve should keep a copy of unknown files
594 unshelve should keep a copy of unknown files
595
595
596 $ hg add e
596 $ hg add e
597 $ hg shelve
597 $ hg shelve
598 shelved as default
598 shelved as default
599 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
599 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
600 $ echo z > e
600 $ echo z > e
601 $ hg unshelve
601 $ hg unshelve
602 unshelving change 'default'
602 unshelving change 'default'
603 $ cat e
603 $ cat e
604 e
604 e
605 $ cat e.orig
605 $ cat e.orig
606 z
606 z
607
607
608
608
609 unshelve and conflicts with tracked and untracked files
609 unshelve and conflicts with tracked and untracked files
610
610
611 preparing:
611 preparing:
612
612
613 $ rm *.orig
613 $ rm *.orig
614 $ hg ci -qm 'commit stuff'
614 $ hg ci -qm 'commit stuff'
615 $ hg phase -p null:
615 $ hg phase -p null:
616
616
617 no other changes - no merge:
617 no other changes - no merge:
618
618
619 $ echo f > f
619 $ echo f > f
620 $ hg add f
620 $ hg add f
621 $ hg shelve
621 $ hg shelve
622 shelved as default
622 shelved as default
623 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
623 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
624 $ echo g > f
624 $ echo g > f
625 $ hg unshelve
625 $ hg unshelve
626 unshelving change 'default'
626 unshelving change 'default'
627 $ hg st
627 $ hg st
628 A f
628 A f
629 ? f.orig
629 ? f.orig
630 $ cat f
630 $ cat f
631 f
631 f
632 $ cat f.orig
632 $ cat f.orig
633 g
633 g
634
634
635 other uncommitted changes - merge:
635 other uncommitted changes - merge:
636
636
637 $ hg st
637 $ hg st
638 A f
638 A f
639 ? f.orig
639 ? f.orig
640 $ hg shelve
640 $ hg shelve
641 shelved as default
641 shelved as default
642 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
642 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
643 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
643 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
644 o 4 changes to 'commit stuff' shelve@localhost
644 o 4 changes to 'commit stuff' shelve@localhost
645 |
645 |
646 $ hg log -G --template '{rev} {desc|firstline} {author}'
646 $ hg log -G --template '{rev} {desc|firstline} {author}'
647 @ 3 commit stuff test
647 @ 3 commit stuff test
648 |
648 |
649 | o 2 c test
649 | o 2 c test
650 |/
650 |/
651 o 0 a test
651 o 0 a test
652
652
653 $ mv f.orig f
653 $ mv f.orig f
654 $ echo 1 > a
654 $ echo 1 > a
655 $ hg unshelve --date '1073741824 0'
655 $ hg unshelve --date '1073741824 0'
656 unshelving change 'default'
656 unshelving change 'default'
657 temporarily committing pending changes (restore with 'hg unshelve --abort')
657 temporarily committing pending changes (restore with 'hg unshelve --abort')
658 rebasing shelved changes
658 rebasing shelved changes
659 rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
659 rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
660 merging f
660 merging f
661 warning: conflicts during merge.
661 warning: conflicts during merge.
662 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
662 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
663 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
663 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
664 [1]
664 [1]
665 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
665 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
666 @ 5 changes to 'commit stuff' shelve@localhost 1970-01-01 00:00 +0000
666 @ 5 changes to 'commit stuff' shelve@localhost 1970-01-01 00:00 +0000
667 |
667 |
668 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
668 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
669 |/
669 |/
670 o 3 commit stuff test 1970-01-01 00:00 +0000
670 o 3 commit stuff test 1970-01-01 00:00 +0000
671 |
671 |
672 | o 2 c test 1970-01-01 00:00 +0000
672 | o 2 c test 1970-01-01 00:00 +0000
673 |/
673 |/
674 o 0 a test 1970-01-01 00:00 +0000
674 o 0 a test 1970-01-01 00:00 +0000
675
675
676 $ hg st
676 $ hg st
677 M f
677 M f
678 ? f.orig
678 ? f.orig
679 $ cat f
679 $ cat f
680 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
680 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
681 g
681 g
682 =======
682 =======
683 f
683 f
684 >>>>>>> source: 23b29cada8ba - shelve: changes to 'commit stuff'
684 >>>>>>> source: 23b29cada8ba - shelve: changes to 'commit stuff'
685 $ cat f.orig
685 $ cat f.orig
686 g
686 g
687 $ hg unshelve --abort
687 $ hg unshelve --abort
688 rebase aborted
688 rebase aborted
689 unshelve of 'default' aborted
689 unshelve of 'default' aborted
690 $ hg st
690 $ hg st
691 M a
691 M a
692 ? f.orig
692 ? f.orig
693 $ cat f.orig
693 $ cat f.orig
694 g
694 g
695 $ hg unshelve
695 $ hg unshelve
696 unshelving change 'default'
696 unshelving change 'default'
697 temporarily committing pending changes (restore with 'hg unshelve --abort')
697 temporarily committing pending changes (restore with 'hg unshelve --abort')
698 rebasing shelved changes
698 rebasing shelved changes
699 rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
699 rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
700 $ hg st
700 $ hg st
701 M a
701 M a
702 A f
702 A f
703 ? f.orig
703 ? f.orig
704
704
705 other committed changes - merge:
705 other committed changes - merge:
706
706
707 $ hg shelve f
707 $ hg shelve f
708 shelved as default
708 shelved as default
709 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
709 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
710 $ hg ci a -m 'intermediate other change'
710 $ hg ci a -m 'intermediate other change'
711 $ mv f.orig f
711 $ mv f.orig f
712 $ hg unshelve
712 $ hg unshelve
713 unshelving change 'default'
713 unshelving change 'default'
714 rebasing shelved changes
714 rebasing shelved changes
715 rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
715 rebasing 5:23b29cada8ba "changes to 'commit stuff'" (tip)
716 merging f
716 merging f
717 warning: conflicts during merge.
717 warning: conflicts during merge.
718 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
718 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
719 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
719 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
720 [1]
720 [1]
721 $ hg st
721 $ hg st
722 M f
722 M f
723 ? f.orig
723 ? f.orig
724 $ cat f
724 $ cat f
725 <<<<<<< dest: * - test: intermediate other change (glob)
725 <<<<<<< dest: * - test: intermediate other change (glob)
726 g
726 g
727 =======
727 =======
728 f
728 f
729 >>>>>>> source: 23b29cada8ba - shelve: changes to 'commit stuff'
729 >>>>>>> source: 23b29cada8ba - shelve: changes to 'commit stuff'
730 $ cat f.orig
730 $ cat f.orig
731 g
731 g
732 $ hg unshelve --abort
732 $ hg unshelve --abort
733 rebase aborted
733 rebase aborted
734 unshelve of 'default' aborted
734 unshelve of 'default' aborted
735 $ hg st
735 $ hg st
736 ? f.orig
736 ? f.orig
737 $ cat f.orig
737 $ cat f.orig
738 g
738 g
739 $ hg shelve --delete default
739 $ hg shelve --delete default
740
740
741 Recreate some conflict again
741 Recreate some conflict again
742
742
743 $ cd ../repo
743 $ cd ../repo
744 $ hg up -C -r 3
744 $ hg up -C -r 3
745 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
745 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
746 (leaving bookmark test)
746 (leaving bookmark test)
747 $ echo y >> a/a
747 $ echo y >> a/a
748 $ hg shelve
748 $ hg shelve
749 shelved as default
749 shelved as default
750 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
750 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
751 $ hg up test
751 $ hg up test
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 (activating bookmark test)
753 (activating bookmark test)
754 $ hg unshelve
754 $ hg unshelve
755 unshelving change 'default'
755 unshelving change 'default'
756 rebasing shelved changes
756 rebasing shelved changes
757 rebasing 5:4b555fdb4e96 "changes to 'second'" (tip)
757 rebasing 5:4b555fdb4e96 "changes to 'second'" (tip)
758 merging a/a
758 merging a/a
759 warning: conflicts during merge.
759 warning: conflicts during merge.
760 merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
760 merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
761 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
761 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
762 [1]
762 [1]
763
763
764 Test that resolving all conflicts in one direction (so that the rebase
764 Test that resolving all conflicts in one direction (so that the rebase
765 is a no-op), works (issue4398)
765 is a no-op), works (issue4398)
766
766
767 $ hg revert -a -r .
767 $ hg revert -a -r .
768 reverting a/a (glob)
768 reverting a/a (glob)
769 $ hg resolve -m a/a
769 $ hg resolve -m a/a
770 (no more unresolved files)
770 (no more unresolved files)
771 $ hg unshelve -c
771 $ hg unshelve -c
772 rebasing 5:4b555fdb4e96 "changes to 'second'" (tip)
772 rebasing 5:4b555fdb4e96 "changes to 'second'" (tip)
773 note: rebase of 5:4b555fdb4e96 created no changes to commit
773 note: rebase of 5:4b555fdb4e96 created no changes to commit
774 unshelve of 'default' complete
774 unshelve of 'default' complete
775 $ hg diff
775 $ hg diff
776 $ hg status
776 $ hg status
777 ? a/a.orig
777 ? a/a.orig
778 ? foo/foo
778 ? foo/foo
779 $ hg summary
779 $ hg summary
780 parent: 4:33f7f61e6c5e tip
780 parent: 4:33f7f61e6c5e tip
781 create conflict
781 create conflict
782 branch: default
782 branch: default
783 bookmarks: *test
783 bookmarks: *test
784 commit: 2 unknown (clean)
784 commit: 2 unknown (clean)
785 update: (current)
785 update: (current)
786
786
787 $ hg shelve --delete --stat
787 $ hg shelve --delete --stat
788 abort: options '--delete' and '--stat' may not be used together
788 abort: options '--delete' and '--stat' may not be used together
789 [255]
789 [255]
790 $ hg shelve --delete --name NAME
790 $ hg shelve --delete --name NAME
791 abort: options '--delete' and '--name' may not be used together
791 abort: options '--delete' and '--name' may not be used together
792 [255]
792 [255]
793
793
794 Test interactive shelve
795 $ cat <<EOF >> $HGRCPATH
796 > [ui]
797 > interactive = true
798 > EOF
799 $ echo 'a' >> a/b
800 $ cat a/a >> a/b
801 $ echo 'x' >> a/b
802 $ mv a/b a/a
803 $ echo 'a' >> foo/foo
804 $ hg st
805 M a/a
806 ? a/a.orig
807 ? foo/foo
808 $ cat a/a
809 a
810 a
811 c
812 x
813 x
814 $ cat foo/foo
815 foo
816 a
817 $ hg shelve --interactive << EOF
818 > y
819 > y
820 > n
821 > EOF
822 diff --git a/a/a b/a/a
823 2 hunks, 2 lines changed
824 examine changes to 'a/a'? [Ynesfdaq?] y
825
826 @@ -1,3 +1,4 @@
827 +a
828 a
829 c
830 x
831 record change 1/2 to 'a/a'? [Ynesfdaq?] y
832
833 @@ -1,3 +2,4 @@
834 a
835 c
836 x
837 +x
838 record change 2/2 to 'a/a'? [Ynesfdaq?] n
839
840 shelved as test
841 merging a/a
842 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
843 $ cat a/a
844 a
845 c
846 x
847 x
848 $ cat foo/foo
849 foo
850 a
851 $ hg st
852 M a/a
853 ? foo/foo
854 $ hg unshelve
855 unshelving change 'test'
856 temporarily committing pending changes (restore with 'hg unshelve --abort')
857 rebasing shelved changes
858 rebasing 6:65b5d1c34c34 "changes to 'create conflict'" (tip)
859 merging a/a
860 $ cat a/a
861 a
862 a
863 c
864 x
865 x
794 $ cd ..
866 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now