threads / patch / 43191

patch, 4 partsSeries short description

Subject: [PATCH 0/4] Series short description

## tl;dr

6 messages between Nov 23, 2006 and Nov 24, 2006. Diffs are folded; open one to read it.

replies: 5people: 2as markdown or json

Yann Dirson· Nov 23, 2006, 23:16 UTC · lore

The following adds a --patch flag to "stg refresh". I mainly needed it to edit the log message in patches down the stack, but with some work it could be used to record changes in another file and come back.

That would require to pop patches with --keep, and if we ask to only record a subset of the changes, we would need to implement "push --keep" first.

This patch is not perfect, since it reverses a list twice, but I did not find an elegant way to make it better. Python gurus, feel free to improve this :)

While I was at it, I noticed that "stg goto" need not revert the applied list if we're going to an unapplied patch (sorta compensate my extraneous revert above ;), and I noticed a DWIM behaviour on the (should-be)-erroneous "refresh --ack --sign".

-- 
Yann Dirson    <ydirson@altern.org> |
Debian-related: <dirson@debian.org> |   Support Debian GNU/Linux:
                                    |  Freedom, Power, Stability, Gratis
Yann Dirson· Nov 23, 2006, 23:16 UTC · re: Yann Dirson · lore

[PATCH 1/4] Make Series::patch_applied public.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 stgit/stack.py |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
Show changes to stgit/stack.py +4 −4
diff --git a/stgit/stack.py b/stgit/stack.py
index a477e7d..49cfebb 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -417,7 +417,7 @@ class Series:
     def __patch_is_current(self, patch):
         return patch.get_name() == read_string(self.__current_file)
 
-    def __patch_applied(self, name):
+    def patch_applied(self, name):
         """Return true if the patch exists in the applied list
         """
         return name in self.get_applied()
@@ -430,7 +430,7 @@ class Series:
     def patch_exists(self, name):
         """Return true if there is a patch with the given name, false
         otherwise."""
-        return self.__patch_applied(name) or self.__patch_unapplied(name)
+        return self.patch_applied(name) or self.__patch_unapplied(name)
 
     def __begin_stack_check(self):
         """Save the current HEAD into .git/refs/heads/base if the stack
@@ -713,7 +713,7 @@ class Series:
                   before_existing = False, refresh = True):
         """Creates a new patch
         """
-        if self.__patch_applied(name) or self.__patch_unapplied(name):
+        if self.patch_applied(name) or self.__patch_unapplied(name):
             raise StackException, 'Patch "%s" already exists' % name
 
         if not message and can_edit:
@@ -773,7 +773,7 @@ class Series:
 
         if self.__patch_is_current(patch):
             self.pop_patch(name)
-        elif self.__patch_applied(name):
+        elif self.patch_applied(name):
             raise StackException, 'Cannot remove an applied patch, "%s", ' \
                   'which is not current' % name
Yann Dirson· Nov 23, 2006, 23:16 UTC · re: Yann Dirson · lore

[PATCH 2/4] Allows to refresh a non-top applied patch.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 stgit/commands/refresh.py |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)
Show changes to stgit/commands/refresh.py +22 −3
diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py
index 610d18a..ea0fe6f 100644
--- a/stgit/commands/refresh.py
+++ b/stgit/commands/refresh.py
@@ -66,6 +66,8 @@ options = [make_option('-f', '--force',
            make_option('--commemail',
                        help = 'use COMMEMAIL as the committer ' \
                        'e-mail'),
+           make_option('-p', '--patch',
+                       help = 'refresh named (applied) PATCH instead of the top one'),
            make_option('--sign',
                        help = 'add Signed-off-by line',
                        action = 'store_true'),
@@ -80,9 +82,15 @@ def func(parser, options, args):
     if autoresolved != 'yes':
         check_conflicts()
 
-    patch = crt_series.get_current()
-    if not patch:
-        raise CmdException, 'No patches applied'
+    if options.patch:
+        patch = options.patch
+        if not crt_series.patch_applied(patch):
+            raise CmdException, 'Patches "%s" not applied' % patch
+        origpatch = crt_series.get_current()
+    else:
+        patch = crt_series.get_current()
+        if not patch:
+            raise CmdException, 'No patches applied'
 
     if not options.force:
         check_head_top_equal()
@@ -110,6 +118,13 @@ def func(parser, options, args):
            or options.authname or options.authemail or options.authdate \
            or options.commname or options.commemail \
            or options.sign or options.ack:
+
+        if options.patch:
+            applied = crt_series.get_applied()
+            between = applied[applied.index(patch)+1:]
+            between.reverse()
+            pop_patches(between)
+
         print 'Refreshing patch "%s"...' % patch,
         sys.stdout.flush()
 
@@ -126,6 +141,10 @@ def func(parser, options, args):
                                  committer_email = options.commemail,
                                  backup = True, sign_str = sign_str)
 
+        if options.patch:
+            between.reverse()
+            push_patches(between)
+
         print 'done'
     else:
Yann Dirson· Nov 23, 2006, 23:17 UTC · re: Yann Dirson · lore

[PATCH 3/4] Optimize stg goto in the pop case.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 stgit/commands/goto.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Show changes to stgit/commands/goto.py +1 −1
diff --git a/stgit/commands/goto.py b/stgit/commands/goto.py
index 1b62d1c..e129b8d 100644
--- a/stgit/commands/goto.py
+++ b/stgit/commands/goto.py
@@ -45,11 +45,11 @@ def func(parser, options, args):
     check_head_top_equal()
 
     applied = crt_series.get_applied()
-    applied.reverse()
     unapplied = crt_series.get_unapplied()
     patch = args[0]
 
     if patch in applied:
+        applied.reverse()
         patches = applied[:applied.index(patch)]
         pop_patches(patches)
Yann Dirson· Nov 23, 2006, 23:17 UTC · re: Yann Dirson · lore

[PATCH 4/4] Bomb out when --ack and --sign are both passed to "refresh".

Old behaviour was silently ignoring --ack, which could be confusing.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 stgit/commands/refresh.py |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
Show changes to stgit/commands/refresh.py +2 −0
diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py
index ea0fe6f..aa5ff78 100644
--- a/stgit/commands/refresh.py
+++ b/stgit/commands/refresh.py
@@ -107,6 +107,8 @@ def func(parser, options, args):
 
     if options.sign:
         sign_str = 'Signed-off-by'
+        if options.ack:
+            raise CmdException, '--ack and --sign were both specified'
     elif options.ack:
         sign_str = 'Acked-by'
Catalin Marinas· Nov 24, 2006, 15:37 UTC · re: Yann Dirson · lore

Re: [PATCH 0/4] Series short description

On 23/11/06, Yann Dirson <ydirson@altern.org> wrote:
Show 5 quoted lines
> The following adds a --patch flag to "stg refresh".  I mainly needed it to
> edit the log message in patches down the stack, but with some work it could
> be used to record changes in another file and come back.
>
> That would require to pop patches with --keep,

pop_patches(keep=True) allows this (I already added it to your patch). This option actually applies the reverse of the patch between the current index and the bottom of the last patch to be popped. If it fails, it doesn't affect the current tree and reports an error.

> and if we ask to only record
> a subset of the changes, we would need to implement "push --keep" first.

The "push --keep" is a bit more complicated to implement since it would usually have to generate commits (pop doesn't need to) since usually the base of the pushed patches might have changed (especially with the refresh --patch). It is even more complicated if the changes you want to preserve affect a file modified by the pushed patches.

A solution I see is to generate a temporary diff, push the patches you want and fold this temporary diff (the diff can be temporarily written to a local file so that you don't lose them in case of an error or Ctrl-C). If the push fails (conflicts) or the diff no longer applies, just undo the push and re-apply the diff. There is no way to simply check whether all the patches apply (git-apply --check) since you can't generate a single diff for all the pushed patches (which might not be in the committed order).

← back to recent threads