Show More
@@ -215,10 +215,10 b' editcomment = _("""# Edit history betwee' | |||||
215 | """) |
|
215 | """) | |
216 |
|
216 | |||
217 | class histeditstate(object): |
|
217 | class histeditstate(object): | |
218 |
def __init__(self, repo, parentctxnode=None, |
|
218 | def __init__(self, repo, parentctxnode=None, actions=None, keep=None, | |
219 | topmost=None, replacements=None, lock=None, wlock=None): |
|
219 | topmost=None, replacements=None, lock=None, wlock=None): | |
220 | self.repo = repo |
|
220 | self.repo = repo | |
221 |
self. |
|
221 | self.actions = actions | |
222 | self.keep = keep |
|
222 | self.keep = keep | |
223 | self.topmost = topmost |
|
223 | self.topmost = topmost | |
224 | self.parentctxnode = parentctxnode |
|
224 | self.parentctxnode = parentctxnode | |
@@ -248,7 +248,9 b' class histeditstate(object):' | |||||
248 | parentctxnode, rules, keep, topmost, replacements, backupfile = data |
|
248 | parentctxnode, rules, keep, topmost, replacements, backupfile = data | |
249 |
|
249 | |||
250 | self.parentctxnode = parentctxnode |
|
250 | self.parentctxnode = parentctxnode | |
251 | self.rules = rules |
|
251 | rules = "\n".join(["%s %s" % (verb, rest) for [verb, rest] in rules]) | |
|
252 | actions = parserules(rules, self) | |||
|
253 | self.actions = actions | |||
252 | self.keep = keep |
|
254 | self.keep = keep | |
253 | self.topmost = topmost |
|
255 | self.topmost = topmost | |
254 | self.replacements = replacements |
|
256 | self.replacements = replacements | |
@@ -260,10 +262,9 b' class histeditstate(object):' | |||||
260 | fp.write('%s\n' % node.hex(self.parentctxnode)) |
|
262 | fp.write('%s\n' % node.hex(self.parentctxnode)) | |
261 | fp.write('%s\n' % node.hex(self.topmost)) |
|
263 | fp.write('%s\n' % node.hex(self.topmost)) | |
262 | fp.write('%s\n' % self.keep) |
|
264 | fp.write('%s\n' % self.keep) | |
263 |
fp.write('%d\n' % len(self. |
|
265 | fp.write('%d\n' % len(self.actions)) | |
264 |
for |
|
266 | for action in self.actions: | |
265 |
fp.write('%s\n' % |
|
267 | fp.write('%s\n' % action.tostate()) | |
266 | fp.write('%s\n' % rule[1]) # remainder |
|
|||
267 | fp.write('%d\n' % len(self.replacements)) |
|
268 | fp.write('%d\n' % len(self.replacements)) | |
268 | for replacement in self.replacements: |
|
269 | for replacement in self.replacements: | |
269 | fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r) |
|
270 | fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r) | |
@@ -328,13 +329,6 b' class histeditstate(object):' | |||||
328 | def inprogress(self): |
|
329 | def inprogress(self): | |
329 | return self.repo.vfs.exists('histedit-state') |
|
330 | return self.repo.vfs.exists('histedit-state') | |
330 |
|
331 | |||
331 | @property |
|
|||
332 | def actions(self): |
|
|||
333 | actions = [] |
|
|||
334 | for (act, rest) in self.rules: |
|
|||
335 | actions.append(actiontable[act].fromrule(self, rest)) |
|
|||
336 | return actions |
|
|||
337 |
|
||||
338 |
|
332 | |||
339 | class histeditaction(object): |
|
333 | class histeditaction(object): | |
340 | def __init__(self, state, node): |
|
334 | def __init__(self, state, node): | |
@@ -953,10 +947,11 b' def _histedit(ui, repo, state, *freeargs' | |||||
953 | f = open(rules) |
|
947 | f = open(rules) | |
954 | rules = f.read() |
|
948 | rules = f.read() | |
955 | f.close() |
|
949 | f.close() | |
956 | rules = [l for l in (r.strip() for r in rules.splitlines()) |
|
950 | actions = parserules(rules, state) | |
957 | if l and not l.startswith('#')] |
|
951 | ctxs = [repo[act.nodetoverify()] \ | |
958 | rules = verifyrules(rules, state, [repo[c] for [_a, c] in state.rules]) |
|
952 | for act in state.actions if act.nodetoverify()] | |
959 | state.rules = rules |
|
953 | verifyactions(actions, state, ctxs) | |
|
954 | state.actions = actions | |||
960 | state.write() |
|
955 | state.write() | |
961 | return |
|
956 | return | |
962 | elif goal == 'abort': |
|
957 | elif goal == 'abort': | |
@@ -1037,14 +1032,13 b' def _histedit(ui, repo, state, *freeargs' | |||||
1037 | f = open(rules) |
|
1032 | f = open(rules) | |
1038 | rules = f.read() |
|
1033 | rules = f.read() | |
1039 | f.close() |
|
1034 | f.close() | |
1040 | rules = [l for l in (r.strip() for r in rules.splitlines()) |
|
1035 | actions = parserules(rules, state) | |
1041 | if l and not l.startswith('#')] |
|
1036 | verifyactions(actions, state, ctxs) | |
1042 | rules = verifyrules(rules, state, ctxs) |
|
|||
1043 |
|
1037 | |||
1044 | parentctxnode = repo[root].parents()[0].node() |
|
1038 | parentctxnode = repo[root].parents()[0].node() | |
1045 |
|
1039 | |||
1046 | state.parentctxnode = parentctxnode |
|
1040 | state.parentctxnode = parentctxnode | |
1047 |
state. |
|
1041 | state.actions = actions | |
1048 | state.topmost = topmost |
|
1042 | state.topmost = topmost | |
1049 | state.replacements = replacements |
|
1043 | state.replacements = replacements | |
1050 |
|
1044 | |||
@@ -1062,12 +1056,10 b' def _histedit(ui, repo, state, *freeargs' | |||||
1062 | zip(actions, actions[1:] + [None])): |
|
1056 | zip(actions, actions[1:] + [None])): | |
1063 | if action.verb == 'fold' and nextact and nextact.verb == 'fold': |
|
1057 | if action.verb == 'fold' and nextact and nextact.verb == 'fold': | |
1064 | state.actions[idx].__class__ = _multifold |
|
1058 | state.actions[idx].__class__ = _multifold | |
1065 | state.rules[idx] = '_multifold', action.nodetoverify() # TODO remove this |
|
|||
1066 |
|
1059 | |||
1067 | while state.actions: |
|
1060 | while state.actions: | |
1068 | state.write() |
|
1061 | state.write() | |
1069 | actobj = state.actions.pop(0) |
|
1062 | actobj = state.actions.pop(0) | |
1070 | state.rules.pop(0) # TODO remove this |
|
|||
1071 | ui.debug('histedit: processing %s %s\n' % (actobj.verb,\ |
|
1063 | ui.debug('histedit: processing %s %s\n' % (actobj.verb,\ | |
1072 | actobj.torule())) |
|
1064 | actobj.torule())) | |
1073 | parentctx, replacement_ = actobj.run() |
|
1065 | parentctx, replacement_ = actobj.run() | |
@@ -1121,7 +1113,6 b' def bootstrapcontinue(ui, state, opts):' | |||||
1121 | repo = state.repo |
|
1113 | repo = state.repo | |
1122 | if state.actions: |
|
1114 | if state.actions: | |
1123 | actobj = state.actions.pop(0) |
|
1115 | actobj = state.actions.pop(0) | |
1124 | state.rules.pop(0) # TODO remove this |
|
|||
1125 |
|
1116 | |||
1126 | if _isdirtywc(repo): |
|
1117 | if _isdirtywc(repo): | |
1127 | actobj.continuedirty() |
|
1118 | actobj.continuedirty() | |
@@ -1171,23 +1162,33 b' def ruleeditor(repo, ui, actions, editco' | |||||
1171 |
|
1162 | |||
1172 | return rules |
|
1163 | return rules | |
1173 |
|
1164 | |||
1174 |
def |
|
1165 | def parserules(rules, state): | |
1175 | """Verify that there exists exactly one edit rule per given changeset. |
|
1166 | """Read the histedit rules string and return list of action objects """ | |
1176 |
|
1167 | rules = [l for l in (r.strip() for r in rules.splitlines()) | ||
1177 | Will abort if there are to many or too few rules, a malformed rule, |
|
1168 | if l and not l.startswith('#')] | |
1178 | or a rule on a changeset outside of the user-given range. |
|
1169 | actions = [] | |
1179 | """ |
|
|||
1180 | parsed = [] |
|
|||
1181 | expected = set(c.hex() for c in ctxs) |
|
|||
1182 | seen = set() |
|
|||
1183 | for r in rules: |
|
1170 | for r in rules: | |
1184 | if ' ' not in r: |
|
1171 | if ' ' not in r: | |
1185 | raise error.Abort(_('malformed line "%s"') % r) |
|
1172 | raise error.Abort(_('malformed line "%s"') % r) | |
1186 | verb, rest = r.split(' ', 1) |
|
1173 | verb, rest = r.split(' ', 1) | |
1187 |
|
1174 | |||
1188 |
if verb not in actiontable |
|
1175 | if verb not in actiontable: | |
1189 | raise error.Abort(_('unknown action "%s"') % verb) |
|
1176 | raise error.Abort(_('unknown action "%s"') % verb) | |
|
1177 | ||||
1190 | action = actiontable[verb].fromrule(state, rest) |
|
1178 | action = actiontable[verb].fromrule(state, rest) | |
|
1179 | actions.append(action) | |||
|
1180 | return actions | |||
|
1181 | ||||
|
1182 | def verifyactions(actions, state, ctxs): | |||
|
1183 | """Verify that there exists exactly one action per given changeset and | |||
|
1184 | other constraints. | |||
|
1185 | ||||
|
1186 | Will abort if there are to many or too few rules, a malformed rule, | |||
|
1187 | or a rule on a changeset outside of the user-given range. | |||
|
1188 | """ | |||
|
1189 | expected = set(c.hex() for c in ctxs) | |||
|
1190 | seen = set() | |||
|
1191 | for action in actions: | |||
1191 | action.verify() |
|
1192 | action.verify() | |
1192 | constraints = action.constraints() |
|
1193 | constraints = action.constraints() | |
1193 | for constraint in constraints: |
|
1194 | for constraint in constraints: | |
@@ -1200,23 +1201,20 b' def verifyrules(rules, state, ctxs):' | |||||
1200 | if _constraints.noother in constraints and ha not in expected: |
|
1201 | if _constraints.noother in constraints and ha not in expected: | |
1201 | raise error.Abort( |
|
1202 | raise error.Abort( | |
1202 | _('may not use "%s" with changesets ' |
|
1203 | _('may not use "%s" with changesets ' | |
1203 | 'other than the ones listed') % verb) |
|
1204 | 'other than the ones listed') % action.verb) | |
1204 | if _constraints.forceother in constraints and ha in expected: |
|
1205 | if _constraints.forceother in constraints and ha in expected: | |
1205 | raise error.Abort( |
|
1206 | raise error.Abort( | |
1206 | _('may not use "%s" with changesets ' |
|
1207 | _('may not use "%s" with changesets ' | |
1207 | 'within the edited list') % verb) |
|
1208 | 'within the edited list') % action.verb) | |
1208 | if _constraints.noduplicates in constraints and ha in seen: |
|
1209 | if _constraints.noduplicates in constraints and ha in seen: | |
1209 | raise error.Abort(_('duplicated command for changeset %s') % |
|
1210 | raise error.Abort(_('duplicated command for changeset %s') % | |
1210 | ha[:12]) |
|
1211 | ha[:12]) | |
1211 | seen.add(ha) |
|
1212 | seen.add(ha) | |
1212 | rest = ha |
|
|||
1213 | parsed.append([verb, rest]) |
|
|||
1214 | missing = sorted(expected - seen) # sort to stabilize output |
|
1213 | missing = sorted(expected - seen) # sort to stabilize output | |
1215 | if missing: |
|
1214 | if missing: | |
1216 | raise error.Abort(_('missing rules for changeset %s') % |
|
1215 | raise error.Abort(_('missing rules for changeset %s') % | |
1217 | missing[0][:12], |
|
1216 | missing[0][:12], | |
1218 | hint=_('do you want to use the drop action?')) |
|
1217 | hint=_('do you want to use the drop action?')) | |
1219 | return parsed |
|
|||
1220 |
|
1218 | |||
1221 | def newnodestoabort(state): |
|
1219 | def newnodestoabort(state): | |
1222 | """process the list of replacements to return |
|
1220 | """process the list of replacements to return |
General Comments 0
You need to be logged in to leave comments.
Login now