Show More
@@ -163,8 +163,10 b' import sys' | |||||
163 | from mercurial import cmdutil |
|
163 | from mercurial import cmdutil | |
164 | from mercurial import discovery |
|
164 | from mercurial import discovery | |
165 | from mercurial import error |
|
165 | from mercurial import error | |
|
166 | from mercurial import changegroup | |||
166 | from mercurial import copies |
|
167 | from mercurial import copies | |
167 | from mercurial import context |
|
168 | from mercurial import context | |
|
169 | from mercurial import exchange | |||
168 | from mercurial import extensions |
|
170 | from mercurial import extensions | |
169 | from mercurial import hg |
|
171 | from mercurial import hg | |
170 | from mercurial import node |
|
172 | from mercurial import node | |
@@ -206,6 +208,7 b' class histeditstate(object):' | |||||
206 | self.parentctxnode = parentctxnode |
|
208 | self.parentctxnode = parentctxnode | |
207 | self.lock = lock |
|
209 | self.lock = lock | |
208 | self.wlock = wlock |
|
210 | self.wlock = wlock | |
|
211 | self.backupfile = None | |||
209 | if replacements is None: |
|
212 | if replacements is None: | |
210 | self.replacements = [] |
|
213 | self.replacements = [] | |
211 | else: |
|
214 | else: | |
@@ -223,15 +226,17 b' class histeditstate(object):' | |||||
223 | try: |
|
226 | try: | |
224 | data = pickle.load(fp) |
|
227 | data = pickle.load(fp) | |
225 | parentctxnode, rules, keep, topmost, replacements = data |
|
228 | parentctxnode, rules, keep, topmost, replacements = data | |
|
229 | backupfile = None | |||
226 | except pickle.UnpicklingError: |
|
230 | except pickle.UnpicklingError: | |
227 | data = self._load() |
|
231 | data = self._load() | |
228 | parentctxnode, rules, keep, topmost, replacements = data |
|
232 | parentctxnode, rules, keep, topmost, replacements, backupfile = data | |
229 |
|
233 | |||
230 | self.parentctxnode = parentctxnode |
|
234 | self.parentctxnode = parentctxnode | |
231 | self.rules = rules |
|
235 | self.rules = rules | |
232 | self.keep = keep |
|
236 | self.keep = keep | |
233 | self.topmost = topmost |
|
237 | self.topmost = topmost | |
234 | self.replacements = replacements |
|
238 | self.replacements = replacements | |
|
239 | self.backupfile = backupfile | |||
235 |
|
240 | |||
236 | def write(self): |
|
241 | def write(self): | |
237 | fp = self.repo.vfs('histedit-state', 'w') |
|
242 | fp = self.repo.vfs('histedit-state', 'w') | |
@@ -246,6 +251,7 b' class histeditstate(object):' | |||||
246 | for replacement in self.replacements: |
|
251 | for replacement in self.replacements: | |
247 | fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r) |
|
252 | fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r) | |
248 | for r in replacement[1]))) |
|
253 | for r in replacement[1]))) | |
|
254 | fp.write('%s\n' % self.backupfile) | |||
249 | fp.close() |
|
255 | fp.close() | |
250 |
|
256 | |||
251 | def _load(self): |
|
257 | def _load(self): | |
@@ -288,9 +294,12 b' class histeditstate(object):' | |||||
288 | replacements.append((original, succ)) |
|
294 | replacements.append((original, succ)) | |
289 | index += 1 |
|
295 | index += 1 | |
290 |
|
296 | |||
|
297 | backupfile = lines[index] | |||
|
298 | index += 1 | |||
|
299 | ||||
291 | fp.close() |
|
300 | fp.close() | |
292 |
|
301 | |||
293 | return parentctxnode, rules, keep, topmost, replacements |
|
302 | return parentctxnode, rules, keep, topmost, replacements, backupfile | |
294 |
|
303 | |||
295 | def clear(self): |
|
304 | def clear(self): | |
296 | self.repo.vfs.unlink('histedit-state') |
|
305 | self.repo.vfs.unlink('histedit-state') | |
@@ -695,6 +704,16 b' def _histedit(ui, repo, state, *freeargs' | |||||
695 | state.read() |
|
704 | state.read() | |
696 | mapping, tmpnodes, leafs, _ntm = processreplacement(state) |
|
705 | mapping, tmpnodes, leafs, _ntm = processreplacement(state) | |
697 | ui.debug('restore wc to old parent %s\n' % node.short(state.topmost)) |
|
706 | ui.debug('restore wc to old parent %s\n' % node.short(state.topmost)) | |
|
707 | ||||
|
708 | # Recover our old commits if necessary | |||
|
709 | if not state.topmost in repo and state.backupfile: | |||
|
710 | backupfile = repo.join(state.backupfile) | |||
|
711 | f = hg.openpath(ui, backupfile) | |||
|
712 | gen = exchange.readbundle(ui, f, backupfile) | |||
|
713 | changegroup.addchangegroup(repo, gen, 'histedit', | |||
|
714 | 'bundle:' + backupfile) | |||
|
715 | os.remove(backupfile) | |||
|
716 | ||||
698 | # check whether we should update away |
|
717 | # check whether we should update away | |
699 | parentnodes = [c.node() for c in repo[None].parents()] |
|
718 | parentnodes = [c.node() for c in repo[None].parents()] | |
700 | for n in leafs | set([state.parentctxnode]): |
|
719 | for n in leafs | set([state.parentctxnode]): | |
@@ -753,6 +772,13 b' def _histedit(ui, repo, state, *freeargs' | |||||
753 | state.topmost = topmost |
|
772 | state.topmost = topmost | |
754 | state.replacements = replacements |
|
773 | state.replacements = replacements | |
755 |
|
774 | |||
|
775 | # Create a backup so we can always abort completely. | |||
|
776 | backupfile = None | |||
|
777 | if not obsolete.isenabled(repo, obsolete.createmarkersopt): | |||
|
778 | backupfile = repair._bundle(repo, [parentctxnode], [topmost], root, | |||
|
779 | 'histedit') | |||
|
780 | state.backupfile = backupfile | |||
|
781 | ||||
756 | while state.rules: |
|
782 | while state.rules: | |
757 | state.write() |
|
783 | state.write() | |
758 | action, ha = state.rules.pop(0) |
|
784 | action, ha = state.rules.pop(0) |
@@ -147,6 +147,34 b" qnew should fail while we're in the midd" | |||||
147 | $ hg cat e |
|
147 | $ hg cat e | |
148 | a |
|
148 | a | |
149 |
|
149 | |||
|
150 | Stripping necessary commits should not break --abort | |||
|
151 | ||||
|
152 | $ hg histedit 1a60820cd1f6 --commands - 2>&1 << EOF| fixbundle | |||
|
153 | > edit 1a60820cd1f6 wat | |||
|
154 | > pick a5e1ba2f7afb foobaz | |||
|
155 | > pick b5f70786f9b0 g | |||
|
156 | > EOF | |||
|
157 | 0 files updated, 0 files merged, 2 files removed, 0 files unresolved | |||
|
158 | Make changes as needed, you may commit or record as needed now. | |||
|
159 | When you are finished, run hg histedit --continue to resume. | |||
|
160 | ||||
|
161 | $ mv .hg/histedit-state .hg/histedit-state.bak | |||
|
162 | $ hg strip -q -r b5f70786f9b0 | |||
|
163 | $ mv .hg/histedit-state.bak .hg/histedit-state | |||
|
164 | $ hg histedit --abort | |||
|
165 | adding changesets | |||
|
166 | adding manifests | |||
|
167 | adding file changes | |||
|
168 | added 1 changesets with 1 changes to 3 files | |||
|
169 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
170 | $ hg log -r . | |||
|
171 | changeset: 6:b5f70786f9b0 | |||
|
172 | tag: tip | |||
|
173 | user: test | |||
|
174 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
175 | summary: f | |||
|
176 | ||||
|
177 | ||||
150 | check histedit_source |
|
178 | check histedit_source | |
151 |
|
179 | |||
152 | $ hg log --debug --rev 5 |
|
180 | $ hg log --debug --rev 5 |
General Comments 0
You need to be logged in to leave comments.
Login now