threads / patch / 1829

patch, 11 partsMake "empty patch" checking optional in "series" command.

Subject: [patch 02/11] Make "empty patch" checking optional in "series" command.

## tl;dr

12 messages between Sep 16, 2005 and Sep 17, 2005. Diffs are folded; open one to read it.

replies: 11people: 2as markdown or json

Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · lore

[patch 01/11] Fix typo: comitter->committer

Found casually in commit.__init__, while profiling stg series. And yes, I went checking that git has no typo.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/git.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Show changes to stgit/git.py +1 −1
diff --git a/stgit/git.py b/stgit/git.py
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -56,7 +56,7 @@ class Commit:
                 self.__parent = field[1]
             if field[0] == 'author':
                 self.__author = field[1]
-            if field[0] == 'comitter':
+            if field[0] == 'committer':
                 self.__committer = field[1]
         self.__log = ''.join(lines[i:])
 
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

That's just too slow, and quilt doesn't do it, so user will live with it. Don't know if there's a reason to allow dropping the fanciness here entirely, but I think there's no user doing one-liner scripts with quilt series. And anyway, for that you can do "stg applied; stg unapplied".

Actually, with this patch you must ask explicitly the checking.
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/series.py |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
Show changes to stgit/commands/series.py +7 −4
diff --git a/stgit/commands/series.py b/stgit/commands/series.py
--- a/stgit/commands/series.py
+++ b/stgit/commands/series.py
@@ -31,7 +31,10 @@ Show all the patches in the series. The 
 with a '+' and the unapplied ones with a '-'. The current patch is
 prefixed with a '>'. Empty patches are prefixed with a '0'."""
 
-options = []
+options = [make_option('-e', '--empty',
+                       help = 'check whether patches are empty '
+                       '(much slower)',
+                       action = 'store_true') ]
 
 
 def func(parser, options, args):
@@ -43,19 +46,19 @@ def func(parser, options, args):
     applied = crt_series.get_applied()
     if len(applied) > 0:
         for p in applied [0:-1]:
-            if crt_series.empty_patch(p):
+            if options.empty and crt_series.empty_patch(p):
                 print '0', p
             else:
                 print '+', p
         p = applied[-1]
 
-        if crt_series.empty_patch(p):
+        if options.empty and crt_series.empty_patch(p):
             print '0>%s' % p
         else:
             print '> %s' % p
 
     for p in crt_series.get_unapplied():
-        if crt_series.empty_patch(p):
+        if options.empty and crt_series.empty_patch(p):
             print '0', p
         else:
             print '-', p
Catalin Marinas· Sep 17, 2005, 08:17 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

Re: [patch 02/11] Make "empty patch" checking optional in "series" command.

On Fri, 2005-09-16 at 21:35 +0200, Paolo 'Blaisorblade' Giarrusso wrote:
Show 6 quoted lines
> That's just too slow, and quilt doesn't do it, so user will live with it.
> Don't know if there's a reason to allow dropping the fanciness here
> entirely, but I think there's no user doing one-liner scripts with quilt
> series. And anyway, for that you can do "stg applied; stg unapplied".
> 
> Actually, with this patch you must ask explicitly the checking.
All the 11 patches applied. Thanks.

One note about this one - we could store the tree id as well in the patch information since it is generated by git.commit() anyway and it would make the checking simpler. Anyway, in the meantime this patch is OK.

-- 
Catalin
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 03/11] stg diff / files: don't update directory cache unless needed

Do git-update-cache only when diffing with the working tree, not otherwise. Spending something like 1min for a stg files is bad - yes, my laptop was really busy and the Linux tree was probably cache-cold, but that's just not needed.

Also, in diffstat we currently do it both by hand and by calling git.diff. And in files there's no need at all for that - even the comments says that "files" has only to do with committed changes.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/git.py |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)
Show changes to stgit/git.py +1 −3
diff --git a/stgit/git.py b/stgit/git.py
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -376,11 +376,11 @@ def status(files = [], modified = False,
 def diff(files = [], rev1 = 'HEAD', rev2 = None, out_fd = None):
     """Show the diff between rev1 and rev2
     """
-    os.system('git-update-cache --refresh > /dev/null')
 
     if rev2:
         diff_str = _output(['git-diff-tree', '-p', rev1, rev2] + files)
     else:
+        os.system('git-update-cache --refresh > /dev/null')
         diff_str = _output(['git-diff-cache', '-p', rev1] + files)
 
     if out_fd:
@@ -392,7 +392,6 @@ def diffstat(files = [], rev1 = 'HEAD', 
     """Return the diffstat between rev1 and rev2
     """
 
-    os.system('git-update-cache --refresh > /dev/null')
     p=popen2.Popen3('git-apply --stat')
     diff(files, rev1, rev2, p.tochild)
     p.tochild.close()
@@ -404,7 +403,6 @@ def diffstat(files = [], rev1 = 'HEAD', 
 def files(rev1, rev2):
     """Return the files modified between rev1 and rev2
     """
-    os.system('git-update-cache --refresh > /dev/null')
 
     str = ''
     for line in _output_lines('git-diff-tree -r %s %s' % (rev1, rev2)):
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 04/11] Fix "mail" command when description contains "From" lines

For kernel patches, the "From" line from the email is often preserved in the patch itself, and the one from the email is sometimes lost, so I add an explicit one. And mail barfes on this. Fix it up.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/mail.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Show changes to stgit/commands/mail.py +1 −1
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -122,7 +122,7 @@ def __parse_addresses(string):
         elif re.match('(to|cc|bcc):\s+', line, re.I):
             to_addr_list += __addr_list(line)
 
-    if len(from_addr_list) != 1:
+    if len(from_addr_list) == 0:
         raise CmdException, 'No "From" address'
     if len(to_addr_list) == 0:
         raise CmdException, 'No "To/Cc/Bcc" addresses'
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 05/11] Make "stg files" output match "quilt files" one

I'm used to doing vi $(quilt files), which is impossible with stgit. Add an option (-b/--base) to request the normal behaviour, but make it non-default as the current output is useful.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/files.py |    5 +++++
 stgit/git.py            |   10 ++++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)
Show changes to 2 files +15 −0

stgit/commands/files.py, stgit/git.py

diff --git a/stgit/commands/files.py b/stgit/commands/files.py
--- a/stgit/commands/files.py
+++ b/stgit/commands/files.py
@@ -35,6 +35,9 @@ command. Use the 'diff' or 'status' comm
 
 options = [make_option('-s', '--stat',
                        help = 'show the diff stat',
+                       action = 'store_true'),
+           make_option('-b', '--bare',
+                       help = 'bare file names (useful for scripting)',
                        action = 'store_true')]
 
 
@@ -53,5 +56,7 @@ def func(parser, options, args):
 
     if options.stat:
         print git.diffstat(rev1 = rev1, rev2 = rev2)
+    elif options.bare:
+        print git.barefiles(rev1, rev2)
     else:
         print git.files(rev1, rev2)
diff --git a/stgit/git.py b/stgit/git.py
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -410,6 +410,16 @@ def files(rev1, rev2):
 
     return str.rstrip()
 
+def barefiles(rev1, rev2):
+    """Return the files modified between rev1 and rev2, without status info
+    """
+
+    str = ''
+    for line in _output_lines('git-diff-tree -r %s %s' % (rev1, rev2)):
+        str += '%s\n' % line.rstrip().split(' ',4)[-1].split('\t',1)[-1]
+
+    return str.rstrip()
+
 def checkout(files = [], tree_id = None, force = False):
     """Check out the given or all files
     """
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 06/11] Avoid allowing --undo if it doesn't change anything

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

Avoid top/bottom backup files identical to current ones. Simply remove them.

Also, change restore_old_boundaries() to handle gracefully the new situation rather than print an exception.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/push.py |    6 ++++--
 stgit/stack.py         |   17 +++++++++++++----
 2 files changed, 17 insertions(+), 6 deletions(-)
Show changes to 2 files +17 −6

stgit/commands/push.py, stgit/stack.py

diff --git a/stgit/commands/push.py b/stgit/commands/push.py
--- a/stgit/commands/push.py
+++ b/stgit/commands/push.py
@@ -66,8 +66,10 @@ def func(parser, options, args):
         print 'Undoing the "%s" push...' % patch,
         sys.stdout.flush()
         resolved_all()
-        crt_series.undo_push()
-        print 'done'
+        if crt_series.undo_push():
+            print 'done'
+        else:
+            print 'done (patch unchanged)'
         print_crt_patch()
 
         return
diff --git a/stgit/stack.py b/stgit/stack.py
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -170,7 +170,11 @@ class Patch:
 
     def set_bottom(self, string, backup = False):
         if backup:
-            self.__set_field('bottom.old', self.__get_field('bottom'))
+            curr = self.__get_field('bottom')
+            if curr != string:
+                self.__set_field('bottom.old', curr)
+            else:
+                self.__set_field('bottom.old', None)
         self.__set_field('bottom', string)
 
     def get_top(self):
@@ -178,7 +182,11 @@ class Patch:
 
     def set_top(self, string, backup = False):
         if backup:
-            self.__set_field('top.old', self.__get_field('top'))
+            curr = self.__get_field('top')
+            if curr != string:
+                self.__set_field('top.old', curr)
+            else:
+                self.__set_field('top.old', None)
         self.__set_field('top', string)
 
     def restore_old_boundaries(self):
@@ -188,8 +196,9 @@ class Patch:
         if top and bottom:
             self.__set_field('bottom', bottom)
             self.__set_field('top', top)
+            return True
         else:
-            raise StackException, 'No patch undo information'
+            return False
 
     def get_description(self):
         return self.__get_field('description', True)
@@ -571,7 +580,7 @@ class Series:
         patch = Patch(name, self.__patch_dir)
         git.reset()
         self.pop_patch(name)
-        patch.restore_old_boundaries()
+        return patch.restore_old_boundaries()
 
     def pop_patch(self, name):
         """Pops the top patch from the stack
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 07/11] Implement fast-forward when only tree (but not commits) match

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

When the "bottom" commit and the HEAD don't match, but they refer to the same tree (for instance after a refresh where only the description changed), we can still fast-forward, by keeping the same top tree and calling git-commit-tree (which only requires the tree object) with the new parent. I've altered git.commit to allow this.

Btw, I've also avoided the use of .commitmsg and switched to piping the description.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/git.py   |   30 ++++++++++++++++--------------
 stgit/stack.py |   35 +++++++++++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 18 deletions(-)
Show changes to 2 files +47 −18

stgit/git.py, stgit/stack.py

diff --git a/stgit/git.py b/stgit/git.py
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -119,8 +119,12 @@ def _output(cmd):
         raise GitException, '%s failed' % str(cmd)
     return string
 
-def _output_one_line(cmd):
+def _output_one_line(cmd, file_desc = None):
     p=popen2.Popen3(cmd)
+    if file_desc != None:
+        for line in file_desc:
+            p.tochild.write(line)
+        p.tochild.close()
     string = p.fromchild.readline().strip()
     if p.wait():
         raise GitException, '%s failed' % str(cmd)
@@ -286,7 +290,7 @@ def update_cache(files = [], force = Fal
     return True
 
 def commit(message, files = [], parents = [], allowempty = False,
-           cache_update = True,
+           cache_update = True, tree_id = None,
            author_name = None, author_email = None, author_date = None,
            committer_name = None, committer_email = None):
     """Commit the current tree to repository
@@ -298,15 +302,15 @@ def commit(message, files = [], parents 
             raise GitException, 'No changes to commit'
 
     # get the commit message
-    f = file('.commitmsg', 'w+')
-    if message[-1:] == '\n':
-        f.write(message)
-    else:
-        print >> f, message
-    f.close()
+    if message[-1:] != '\n':
+        message += '\n'
 
+    must_switch = True
     # write the index to repository
-    tree_id = _output_one_line('git-write-tree')
+    if tree_id == None:
+        tree_id = _output_one_line('git-write-tree')
+    else:
+        must_switch = False
 
     # the commit
     cmd = ''
@@ -326,11 +330,9 @@ def commit(message, files = [], parents 
     for p in parents:
         cmd += ' -p %s' % p
 
-    cmd += ' < .commitmsg'
-
-    commit_id = _output_one_line(cmd)
-    __set_head(commit_id)
-    os.remove('.commitmsg')
+    commit_id = _output_one_line(cmd, message)
+    if must_switch:
+        __set_head(commit_id)
 
     return commit_id
 
diff --git a/stgit/stack.py b/stgit/stack.py
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -495,13 +495,40 @@ class Series:
             # top != bottom always since we have a commit for each patch
             if head == bottom:
                 # reset the backup information
-                patch.set_bottom(bottom, backup = True)
+                patch.set_bottom(head, backup = True)
                 patch.set_top(top, backup = True)
 
             else:
-                top = head
-                # stop the fast-forwarding, must do a real merge
-                break
+                head_tree = git.get_commit(head).get_tree()
+                bottom_tree = git.get_commit(bottom).get_tree()
+                if head_tree == bottom_tree:
+                    # We must just reparent this patch and create a new commit
+                    # for it
+                    descr = patch.get_description()
+                    author_name = patch.get_authname()
+                    author_email = patch.get_authemail()
+                    author_date = patch.get_authdate()
+                    committer_name = patch.get_commname()
+                    committer_email = patch.get_commemail()
+
+                    top_tree = git.get_commit(top).get_tree()
+
+                    top = git.commit(message = descr, parents = [head],
+                                     cache_update = False,
+                                     tree_id = top_tree,
+                                     allowempty = True,
+                                     author_name = author_name,
+                                     author_email = author_email,
+                                     author_date = author_date,
+                                     committer_name = committer_name,
+                                     committer_email = committer_email)
+
+                    patch.set_bottom(head, backup = True)
+                    patch.set_top(top, backup = True)
+                else:
+                    top = head
+                    # stop the fast-forwarding, must do a real merge
+                    break
 
             forwarded+=1
             unapplied.remove(name)
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 08/11] Fix "stg clean" when stack is empty

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
It crashes on accessing 1st element of an empty array.
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/clean.py |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
Show changes to stgit/commands/clean.py +2 −1
diff --git a/stgit/commands/clean.py b/stgit/commands/clean.py
--- a/stgit/commands/clean.py
+++ b/stgit/commands/clean.py
@@ -65,7 +65,8 @@ def func(parser, options, args):
 
     if options.applied:
         applied = crt_series.get_applied()
-        crt_series.pop_patch(applied[0])
+        if applied != []:
+            crt_series.pop_patch(applied[0])
         __delete_empty(applied, True)
 
     if options.unapplied:
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 09/11] Allow mailing a given patch list

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

I tried to mail a cherry-picked subset of my series and that didn't work - using stg export and quilt was even worse, so I had to code something.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/mail.py |   15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)
Show changes to stgit/commands/mail.py +6 −9
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -26,7 +26,7 @@ from stgit.config import config
 
 
 help = 'send a patch or series of patches by e-mail'
-usage = """%prog [options] [<patch>]
+usage = """%prog [options] [<patch> [<patch2...]]
 
 Send a patch or a range of patches (defaulting to the applied patches)
 by e-mail using the 'smtpserver' configuration option. The From
@@ -265,9 +265,6 @@ def func(parser, options, args):
     """Send the patches by e-mail using the patchmail.tmpl file as
     a template
     """
-    if len(args) > 1:
-        parser.error('incorrect number of arguments')
-
     if not config.has_option('stgit', 'smtpserver'):
         raise CmdException, 'smtpserver not defined'
     smtpserver = config.get('stgit', 'smtpserver')
@@ -281,11 +278,11 @@ def func(parser, options, args):
 
     applied = crt_series.get_applied()
 
-    if len(args) == 1:
-        if args[0] in applied:
-            patches = [args[0]]
-        else:
-            raise CmdException, 'Patch "%s" not applied' % args[0]
+    if len(args) >= 1:
+        for patch in args:
+            if not patch in applied:
+                raise CmdException, 'Patch "%s" not applied' % patch
+            patches = args
     elif options.all:
         patches = applied
     elif options.range:
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 10/11] Fix "stg mail" address parsing for hyphen

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

Tried sending an email cc'ing LKML - watched my postfix queue - and saw kernel@vger.kernel.org as delivery address! What had happened? StGIT didn't like "linux-kernel" ! Fix the regexp.

I just added an hyphen to both sections (yes, there are plenty of domain names including hyphens, and I tested the problem there too). Don't know if other chars are missing.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/mail.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Show changes to stgit/commands/mail.py +1 −1
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -112,7 +112,7 @@ def __parse_addresses(string):
     """Return a two elements tuple: (from, [to])
     """
     def __addr_list(string):
-        return re.split('.*?([\w\.]+@[\w\.]+)', string)[1:-1:2]
+        return re.split('.*?([-\w\.]+@[-\w\.]+)', string)[1:-1:2]
 
     from_addr_list = []
     to_addr_list = []
Paolo 'Blaisorblade' Giarrusso· Sep 16, 2005, 19:35 UTC · re: Paolo 'Blaisorblade' Giarrusso · lore

[patch 11/11] Detect description in quilt patches

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

The current logic imports the whole quilt patch as description - the changes themselves are correctly applied, luckily, but the description must be fixed up by hand. So, detect "Index: " lines as patch start. I've heard rumors that also Subversion generates this format, so we become compatible with it, too.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---
 stgit/commands/imprt.py |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
Show changes to stgit/commands/imprt.py +2 −1
diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py
--- a/stgit/commands/imprt.py
+++ b/stgit/commands/imprt.py
@@ -96,7 +96,8 @@ def __parse_mail(filename = None):
 
     # the rest of the patch description
     for line in f:
-        if re.match('---\s*$', line) or re.match('diff -', line):
+        if re.match('---\s*$', line) or re.match('diff -', line) or \
+                re.match('^Index: ', line):
             break
         else:
             descr += line

← back to recent threads