Mercurial > hg
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: |