git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[StGit PATCH 10/14] Move stack reset function to a shared location

From
Karl Hasselström <kha@treskal.com>
Date
Jun 12, 2008, 05:35 UTC
Message-ID
<20080612053508.23549.98668.stgit@yoghurt>
In-Reply-To
<20080612052913.23549.69687.stgit@yoghurt>

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 <kha@treskal.com>
---
 stgit/commands/reset.py  |   70 +++++-----------------------------------------
 stgit/lib/log.py         |   62 +++++++++++++++++++++++++++++++++++++++++
 stgit/lib/transaction.py |    3 +-
 3 files changed, 71 insertions(+), 64 deletions(-)
diff --git a/stgit/commands/reset.py b/stgit/commands/reset.py
index a7b5d35..5ad9914 100644
--- a/stgit/commands/reset.py
+++ b/stgit/commands/reset.py
@@ -47,67 +47,6 @@ directory = common.DirectoryHasRepositoryLib()
 options = [make_option('--hard', action = 'store_true',
                        help = 'discard changes in your index/worktree')]
 
-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))
-    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:
-            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, iw)
-    except transaction.TransactionHalted:
-        pass
-    return trans.run(iw)
-
 def func(parser, options, args):
     stack = directory.repository.current_stack
     if len(args) >= 1:
@@ -115,5 +54,10 @@ def func(parser, options, args):
         state = log.Log(stack.repository, ref, 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 3aec6e7..2449913 100644
--- a/stgit/lib/log.py
+++ b/stgit/lib/log.py
@@ -285,3 +285,65 @@ def copy_log(repo, src_branch, dst_branch, msg):
 
 def default_repo():
     return stack.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))
+    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:
+            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, iw)
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index 10c9b39..2003105 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -103,6 +103,7 @@ class StackTransaction(object):
     def __set_unapplied(self, val):
         self.__unapplied = list(val)
     unapplied = property(lambda self: self.__unapplied, __set_unapplied)
+    all_patches = property(lambda self: self.__applied + self.__unapplied)
     def __set_base(self, val):
         assert (not self.__applied
                 or self.patches[self.applied[0]].data.parent == val)
@@ -136,7 +137,7 @@ class StackTransaction(object):
         raise TransactionException(
             'Command aborted (all changes rolled back)')
     def __check_consistency(self):
-        remaining = set(self.__applied + self.__unapplied)
+        remaining = set(self.all_patches)
         for pn, commit in self.__patches.iteritems():
             if commit == None:
                 assert self.__stack.patches.exists(pn)
Previous: Karl HasselströmNext: Karl Hasselström
Message 28 of 32 in “Undo series”
  1. 00/14 Undo seriesKarl Hasselström, Jun 12, 2008
  2. 01/14 Fix typoKarl Hasselström, Jun 12, 2008
  3. 02/14 Library functions for tree and blob manipulationKarl Hasselström, Jun 12, 2008
  4. 03/14 Write to a stack log when stack is modifiedKarl Hasselström, Jun 12, 2008
  5. Catalin MarinasJun 17, 2008
  6. Karl HasselströmJun 17, 2008
  7. Karl HasselströmJun 17, 2008
  8. Catalin MarinasJun 17, 2008
  9. Karl HasselströmJun 17, 2008
  10. Catalin MarinasJun 18, 2008
  11. Karl HasselströmJun 18, 2008
  12. Catalin MarinasJun 18, 2008
  13. Karl HasselströmJun 18, 2008
  14. Catalin MarinasJun 19, 2008
  15. Karl HasselströmJun 19, 2008
  16. Catalin MarinasJun 20, 2008
  17. Karl HasselströmJun 23, 2008
  18. Catalin MarinasJul 12, 2008
  19. Karl HasselströmJul 14, 2008
  20. Karl HasselströmJul 1, 2008
  21. Catalin MarinasJul 3, 2008
  22. 04/14 Add utility function for reordering patchesKarl Hasselström, Jun 12, 2008
  23. 05/14 New command: stg resetKarl Hasselström, Jun 12, 2008
  24. 06/14 Log conflicts separatelyKarl Hasselström, Jun 12, 2008
  25. 07/14 Log conflicts separately for all commandsKarl Hasselström, Jun 12, 2008
  26. 08/14 Add a --hard flag to stg resetKarl Hasselström, Jun 12, 2008
  27. 09/14 Don't write a log entry if there were no changesKarl Hasselström, Jun 12, 2008
  28. 10/14 Move stack reset function to a shared locationKarl Hasselström, Jun 12, 2008
  29. 11/14 New command: stg undoKarl Hasselström, Jun 12, 2008
  30. 12/14 New command: stg redoKarl Hasselström, Jun 12, 2008
  31. 13/14 Log and undo external modificationsKarl Hasselström, Jun 12, 2008
  32. 14/14 Make "stg log" show stack log instead of patch logKarl Hasselström, Jun 12, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.