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

[StGit PATCH 07/10] Log conflicts separately

From
Karl Hasselström <kha@treskal.com>
Date
Apr 20, 2008, 22:11 UTC
Message-ID
<20080420221101.5837.13630.stgit@yoghurt>
In-Reply-To
<20080420215625.5837.82896.stgit@yoghurt>

This patch makes commands that produce a conflict log that final conflicting push separately from the rest of the command's effects. This makes it possible for the user to roll back just the final conflicting push if she desires. (Rolling back the whole operation is of course still possible, by resetting to the state yet another step back in the log.)

This change only applies to the new-infrastructure commands.
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
 stgit/lib/transaction.py |   47 +++++++++++++++++++++++++++++++---------------
 1 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index 4c3b448..92bcfd5 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -42,6 +42,7 @@ class StackTransaction(object):
         self.__patches = _TransPatchMap(stack)
         self.__applied = list(self.__stack.patchorder.applied)
         self.__unapplied = list(self.__stack.patchorder.unapplied)
+        self.__conflicting_push = None
         self.__error = None
         self.__current_tree = self.__stack.head.data.tree
         self.__base = self.__stack.base
@@ -121,19 +122,26 @@ class StackTransaction(object):
             out.error(self.__error)
 
         # Write patches.
-        for pn, commit in self.__patches.iteritems():
-            if self.__stack.patches.exists(pn):
-                p = self.__stack.patches.get(pn)
-                if commit == None:
-                    p.delete()
+        def write(msg):
+            for pn, commit in self.__patches.iteritems():
+                if self.__stack.patches.exists(pn):
+                    p = self.__stack.patches.get(pn)
+                    if commit == None:
+                        p.delete()
+                    else:
+                        p.set_commit(commit, msg)
                 else:
-                    p.set_commit(commit, self.__msg)
-            else:
-                self.__stack.patches.new(pn, commit, self.__msg)
-        _print_current_patch(self.__stack.patchorder.applied, self.__applied)
-        self.__stack.patchorder.applied = self.__applied
-        self.__stack.patchorder.unapplied = self.__unapplied
-        log.log_entry(self.__stack, self.__msg)
+                    self.__stack.patches.new(pn, commit, msg)
+            self.__stack.patchorder.applied = self.__applied
+            self.__stack.patchorder.unapplied = self.__unapplied
+            log.log_entry(self.__stack, msg)
+        old_applied = self.__stack.patchorder.applied
+        write(self.__msg)
+        if self.__conflicting_push != None:
+            self.__patches = _TransPatchMap(self.__stack)
+            self.__conflicting_push()
+            write(self.__msg + ' (CONFLICT)')
+        _print_current_patch(old_applied, self.__applied)
 
         if self.__error:
             return utils.STGIT_CONFLICT
@@ -223,18 +231,27 @@ class StackTransaction(object):
         cd = cd.set_tree(tree)
         if any(getattr(cd, a) != getattr(orig_cd, a) for a in
                ['parent', 'tree', 'author', 'message']):
-            self.patches[pn] = self.__stack.repository.commit(cd)
+            comm = self.__stack.repository.commit(cd)
         else:
+            comm = None
             s = ' (unmodified)'
-        del self.unapplied[self.unapplied.index(pn)]
-        self.applied.append(pn)
         out.info('Pushed %s%s' % (pn, s))
+        def update():
+            if comm:
+                self.patches[pn] = comm
+            del self.unapplied[self.unapplied.index(pn)]
+            self.applied.append(pn)
         if merge_conflict:
             # We've just caused conflicts, so we must allow them in
             # the final checkout.
             self.__allow_conflicts = lambda trans: True
 
+            # Save this update so that we can run it a little later.
+            self.__conflicting_push = update
             self.__halt('Merge conflict')
+        else:
+            # Update immediately.
+            update()
 
     def reorder_patches(self, applied, unapplied, iw = None):
         """Push and pop patches to attain the given ordering."""
Previous: Karl HasselströmNext: Karl Hasselström
Message 8 of 11 in “Updated "stg reset" series”
  1. 00/10 Updated "stg reset" seriesKarl Hasselström, Apr 20, 2008
  2. 01/10 Prevent most commands from running when there are conflictsKarl Hasselström, Apr 20, 2008
  3. 02/10 Add property with a list of all patch namesKarl Hasselström, Apr 20, 2008
  4. 03/10 Library functions for tree and blob manipulationKarl Hasselström, Apr 20, 2008
  5. 04/10 Write to a stack log when stack is modifiedKarl Hasselström, Apr 20, 2008
  6. 05/10 Add utility function for reordering patchesKarl Hasselström, Apr 20, 2008
  7. 06/10 New command: stg resetKarl Hasselström, Apr 20, 2008
  8. 07/10 Log conflicts separatelyKarl Hasselström, Apr 20, 2008
  9. 08/10 Log conflicts separately for all commandsKarl Hasselström, Apr 20, 2008
  10. 09/10 Add a --hard flag to stg resetKarl Hasselström, Apr 20, 2008
  11. 10/10 Don't write a log entry if there were no changesKarl Hasselström, Apr 20, 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.