comparison hgext/shelve.py @ 30522:7b3136bc7bfd

shelve: make --keep option survive user intervention (issue5431) Currently if user runs 'hg unshelve --keep' and merge conflicts occur, the information about --keep provided by user is lost and shelf is deleted after 'hg unshelve --continue'. This is obviously not desired, so this patch fixes it.
author Kostia Balytskyi <ikostia@fb.com>
date Wed, 23 Nov 2016 14:58:52 -0800
parents 893be22cdb38
children 64b55bffc1c0
comparison
equal deleted inserted replaced
30521:86cd09bc13ba 30522:7b3136bc7bfd
157 Handles saving and restoring a shelved state. Ensures that different 157 Handles saving and restoring a shelved state. Ensures that different
158 versions of a shelved state are possible and handles them appropriately. 158 versions of a shelved state are possible and handles them appropriately.
159 """ 159 """
160 _version = 1 160 _version = 1
161 _filename = 'shelvedstate' 161 _filename = 'shelvedstate'
162 _keep = 'keep'
163 _nokeep = 'nokeep'
162 164
163 @classmethod 165 @classmethod
164 def load(cls, repo): 166 def load(cls, repo):
165 fp = repo.vfs(cls._filename) 167 fp = repo.vfs(cls._filename)
166 try: 168 try:
173 wctx = nodemod.bin(fp.readline().strip()) 175 wctx = nodemod.bin(fp.readline().strip())
174 pendingctx = nodemod.bin(fp.readline().strip()) 176 pendingctx = nodemod.bin(fp.readline().strip())
175 parents = [nodemod.bin(h) for h in fp.readline().split()] 177 parents = [nodemod.bin(h) for h in fp.readline().split()]
176 stripnodes = [nodemod.bin(h) for h in fp.readline().split()] 178 stripnodes = [nodemod.bin(h) for h in fp.readline().split()]
177 branchtorestore = fp.readline().strip() 179 branchtorestore = fp.readline().strip()
180 keep = fp.readline().strip() == cls._keep
178 except (ValueError, TypeError) as err: 181 except (ValueError, TypeError) as err:
179 raise error.CorruptedState(str(err)) 182 raise error.CorruptedState(str(err))
180 finally: 183 finally:
181 fp.close() 184 fp.close()
182 185
186 obj.wctx = repo[wctx] 189 obj.wctx = repo[wctx]
187 obj.pendingctx = repo[pendingctx] 190 obj.pendingctx = repo[pendingctx]
188 obj.parents = parents 191 obj.parents = parents
189 obj.stripnodes = stripnodes 192 obj.stripnodes = stripnodes
190 obj.branchtorestore = branchtorestore 193 obj.branchtorestore = branchtorestore
194 obj.keep = keep
191 except error.RepoLookupError as err: 195 except error.RepoLookupError as err:
192 raise error.CorruptedState(str(err)) 196 raise error.CorruptedState(str(err))
193 197
194 return obj 198 return obj
195 199
196 @classmethod 200 @classmethod
197 def save(cls, repo, name, originalwctx, pendingctx, stripnodes, 201 def save(cls, repo, name, originalwctx, pendingctx, stripnodes,
198 branchtorestore): 202 branchtorestore, keep=False):
199 fp = repo.vfs(cls._filename, 'wb') 203 fp = repo.vfs(cls._filename, 'wb')
200 fp.write('%i\n' % cls._version) 204 fp.write('%i\n' % cls._version)
201 fp.write('%s\n' % name) 205 fp.write('%s\n' % name)
202 fp.write('%s\n' % nodemod.hex(originalwctx.node())) 206 fp.write('%s\n' % nodemod.hex(originalwctx.node()))
203 fp.write('%s\n' % nodemod.hex(pendingctx.node())) 207 fp.write('%s\n' % nodemod.hex(pendingctx.node()))
204 fp.write('%s\n' % 208 fp.write('%s\n' %
205 ' '.join([nodemod.hex(p) for p in repo.dirstate.parents()])) 209 ' '.join([nodemod.hex(p) for p in repo.dirstate.parents()]))
206 fp.write('%s\n' % 210 fp.write('%s\n' %
207 ' '.join([nodemod.hex(n) for n in stripnodes])) 211 ' '.join([nodemod.hex(n) for n in stripnodes]))
208 fp.write('%s\n' % branchtorestore) 212 fp.write('%s\n' % branchtorestore)
213 fp.write('%s\n' % (cls._keep if keep else cls._nokeep))
209 fp.close() 214 fp.close()
210 215
211 @classmethod 216 @classmethod
212 def clear(cls, repo): 217 def clear(cls, repo):
213 util.unlinkpath(repo.join(cls._filename), ignoremissing=True) 218 util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
678 tr.close() 683 tr.close()
679 684
680 stripnodes = [repo.changelog.node(rev) 685 stripnodes = [repo.changelog.node(rev)
681 for rev in xrange(oldtiprev, len(repo))] 686 for rev in xrange(oldtiprev, len(repo))]
682 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes, 687 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes,
683 branchtorestore) 688 branchtorestore, opts.get('keep'))
684 689
685 util.rename(repo.join('rebasestate'), 690 util.rename(repo.join('rebasestate'),
686 repo.join('unshelverebasestate')) 691 repo.join('unshelverebasestate'))
687 raise error.InterventionRequired( 692 raise error.InterventionRequired(
688 _("unresolved conflicts (see 'hg resolve', then " 693 _("unresolved conflicts (see 'hg resolve', then "
780 if abortf and opts.get('tool', False): 785 if abortf and opts.get('tool', False):
781 ui.warn(_('tool option will be ignored\n')) 786 ui.warn(_('tool option will be ignored\n'))
782 787
783 try: 788 try:
784 state = shelvedstate.load(repo) 789 state = shelvedstate.load(repo)
790 if opts.get('keep') is None:
791 opts['keep'] = state.keep
785 except IOError as err: 792 except IOError as err:
786 if err.errno != errno.ENOENT: 793 if err.errno != errno.ENOENT:
787 raise 794 raise
788 cmdutil.wrongtooltocontinue(repo, _('unshelve')) 795 cmdutil.wrongtooltocontinue(repo, _('unshelve'))
789 except error.CorruptedState as err: 796 except error.CorruptedState as err: