From: Karl Hasselström Date: Sun, 21 Sep 2008 12:17:41 +0000 (+0200) Subject: Move stack reset function to a shared location X-Git-Tag: v0.15-rc1~142 X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/commitdiff_plain/4ae6b67e627318b3e61a2aadbf6506f6178982b9 Move stack reset function to a shared location Move reset_stack() from commands/reset.py to lib/log.py, so that more commands besides reset can use it. (No such commands exist currently, but undo and redo will use it.) Signed-off-by: Karl Hasselström --- diff --git a/stgit/commands/reset.py b/stgit/commands/reset.py index 593ed30..7ee8fb7 100644 --- a/stgit/commands/reset.py +++ b/stgit/commands/reset.py @@ -50,71 +50,6 @@ options = [ directory = common.DirectoryHasRepositoryLib() -def reset_stack(stack, iw, state, only_patches, hard): - only_patches = set(only_patches) - def mask(s): - if only_patches: - return s & only_patches - else: - return s - patches_to_reset = mask(set(state.applied + state.unapplied + state.hidden)) - existing_patches = set(stack.patchorder.all) - to_delete = mask(existing_patches - patches_to_reset) - trans = transaction.StackTransaction(stack, 'reset', discard_changes = hard) - - # If we have to change the stack base, we need to pop all patches - # first. - if not only_patches and trans.base != state.base: - trans.pop_patches(lambda pn: True) - out.info('Setting stack base to %s' % state.base.sha1) - trans.base = state.base - - # In one go, do all the popping we have to in order to pop the - # patches we're going to delete or modify. - def mod(pn): - if only_patches and not pn in only_patches: - return False - if pn in to_delete: - return True - if stack.patches.get(pn).commit != state.patches.get(pn, None): - return True - return False - trans.pop_patches(mod) - - # Delete and modify/create patches. We've previously popped all - # patches that we touch in this step. - trans.delete_patches(lambda pn: pn in to_delete) - for pn in patches_to_reset: - if pn in existing_patches: - if trans.patches[pn] == state.patches[pn]: - continue - else: - out.info('Resetting %s' % pn) - else: - if pn in state.hidden: - trans.hidden.append(pn) - else: - trans.unapplied.append(pn) - out.info('Resurrecting %s' % pn) - trans.patches[pn] = state.patches[pn] - - # Push/pop patches as necessary. - try: - if only_patches: - # Push all the patches that we've popped, if they still - # exist. - pushable = set(trans.unapplied) - for pn in stack.patchorder.applied: - if pn in pushable: - trans.push_patch(pn, iw) - else: - # Recreate the exact order specified by the goal state. - trans.reorder_patches(state.applied, state.unapplied, - state.hidden, iw) - except transaction.TransactionHalted: - pass - return trans.run(iw) - def func(parser, options, args): stack = directory.repository.current_stack if len(args) >= 1: @@ -123,5 +58,10 @@ def func(parser, options, args): stack.repository.rev_parse(ref)) else: raise common.CmdException('Wrong number of arguments') - return reset_stack(stack, stack.repository.default_iw, state, patches, - options.hard) + trans = transaction.StackTransaction(stack, 'reset', + discard_changes = options.hard) + try: + log.reset_stack(trans, stack.repository.default_iw, state, patches) + except transaction.TransactionHalted: + pass + return trans.run(stack.repository.default_iw) diff --git a/stgit/lib/log.py b/stgit/lib/log.py index 9568e8f..43f87ce 100644 --- a/stgit/lib/log.py +++ b/stgit/lib/log.py @@ -382,3 +382,68 @@ def copy_log(repo, src_branch, dst_branch, msg): def default_repo(): return libstack.Repository.default() + +def reset_stack(trans, iw, state, only_patches): + """Reset the stack to a given previous state. If C{only_patches} is + not empty, touch only patches whose names appear in it. + + @param only_patches: Reset only these patches + @type only_patches: iterable""" + only_patches = set(only_patches) + def mask(s): + if only_patches: + return s & only_patches + else: + return s + patches_to_reset = mask(set(state.applied + state.unapplied + state.hidden)) + existing_patches = set(trans.all_patches) + original_applied_order = list(trans.applied) + to_delete = mask(existing_patches - patches_to_reset) + + # If we have to change the stack base, we need to pop all patches + # first. + if not only_patches and trans.base != state.base: + trans.pop_patches(lambda pn: True) + out.info('Setting stack base to %s' % state.base.sha1) + trans.base = state.base + + # In one go, do all the popping we have to in order to pop the + # patches we're going to delete or modify. + def mod(pn): + if only_patches and not pn in only_patches: + return False + if pn in to_delete: + return True + if trans.patches[pn] != state.patches.get(pn, None): + return True + return False + trans.pop_patches(mod) + + # Delete and modify/create patches. We've previously popped all + # patches that we touch in this step. + trans.delete_patches(lambda pn: pn in to_delete) + for pn in patches_to_reset: + if pn in existing_patches: + if trans.patches[pn] == state.patches[pn]: + continue + else: + out.info('Resetting %s' % pn) + else: + if pn in state.hidden: + trans.hidden.append(pn) + else: + trans.unapplied.append(pn) + out.info('Resurrecting %s' % pn) + trans.patches[pn] = state.patches[pn] + + # Push/pop patches as necessary. + if only_patches: + # Push all the patches that we've popped, if they still + # exist. + pushable = set(trans.unapplied) + for pn in original_applied_order: + if pn in pushable: + trans.push_patch(pn, iw) + else: + # Recreate the exact order specified by the goal state. + trans.reorder_patches(state.applied, state.unapplied, state.hidden, iw) diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py index 84d72d5..1ab5f8b 100644 --- a/stgit/lib/transaction.py +++ b/stgit/lib/transaction.py @@ -109,6 +109,8 @@ class StackTransaction(object): def __set_hidden(self, val): self.__hidden = list(val) hidden = property(lambda self: self.__hidden, __set_hidden) + all_patches = property(lambda self: (self.__applied + self.__unapplied + + self.__hidden)) def __set_base(self, val): assert (not self.__applied or self.patches[self.applied[0]].data.parent == val) @@ -148,7 +150,7 @@ class StackTransaction(object): raise TransactionException( 'Command aborted (all changes rolled back)') def __check_consistency(self): - remaining = set(self.__applied + self.__unapplied + self.__hidden) + remaining = set(self.all_patches) for pn, commit in self.__patches.iteritems(): if commit == None: assert self.__stack.patches.exists(pn)