Allows to refresh a non-top applied patch.
[stgit] / stgit / commands / refresh.py
index 81e3066..2d164cd 100644 (file)
@@ -26,7 +26,15 @@ from stgit.config import config
 
 
 help = 'generate a new commit for the current patch'
-usage = '%prog [options]'
+usage = """%prog [options] [<files...>]
+
+Include the latest tree changes in the current patch. This command
+generates a new GIT commit object with the patch details, the previous
+one no longer being visible. The patch attributes like author,
+committer and description can be changed with the command line
+options. The '--force' option is useful when a commit object was
+created with a different tool but the changes need to be included in
+the current patch."""
 
 options = [make_option('-f', '--force',
                        help = 'force the refresh even if HEAD and '\
@@ -36,9 +44,17 @@ options = [make_option('-f', '--force',
                        help = 'invoke an editor for the patch '\
                        'description',
                        action = 'store_true'),
+           make_option('-s', '--showpatch',
+                       help = 'show the patch content in the editor buffer',
+                       action = 'store_true'),
+           make_option('--undo',
+                       help = 'revert the commit generated by the last refresh',
+                       action = 'store_true'),
            make_option('-m', '--message',
                        help = 'use MESSAGE as the patch ' \
                        'description'),
+           make_option('-a', '--author', metavar = '"NAME <EMAIL>"',
+                       help = 'use "NAME <EMAIL>" as the author details'),
            make_option('--authname',
                        help = 'use AUTHNAME as the author name'),
            make_option('--authemail',
@@ -49,45 +65,88 @@ options = [make_option('-f', '--force',
                        help = 'use COMMNAME as the committer name'),
            make_option('--commemail',
                        help = 'use COMMEMAIL as the committer ' \
-                       'e-mail')]
+                       'e-mail'),
+           make_option('-p', '--patch',
+                       help = 'refresh (applied) PATCH instead of the top one'),
+           make_option('--sign',
+                       help = 'add Signed-off-by line',
+                       action = 'store_true'),
+           make_option('--ack',
+                       help = 'add Acked-by line',
+                       action = 'store_true')]
 
 
 def func(parser, options, args):
-    if len(args) != 0:
-        parser.error('incorrect number of arguments')
-
-    if config.has_option('stgit', 'autoresolved'):
-        autoresolved = config.get('stgit', 'autoresolved')
-    else:
-        autoresolved = 'no'
+    autoresolved = config.get('stgit', 'autoresolved')
 
     if autoresolved != 'yes':
         check_conflicts()
 
-    patch = crt_series.get_current()
-    if not patch:
-        raise CmdException, 'No patches applied'
+    if options.patch:
+        if args:
+            raise CmdException, \
+                  'Only full refresh is available with the --patch option'
+        patch = options.patch
+        if not crt_series.patch_applied(patch):
+            raise CmdException, 'Patches "%s" not applied' % patch
+    else:
+        patch = crt_series.get_current()
+        if not patch:
+            raise CmdException, 'No patches applied'
 
     if not options.force:
         check_head_top_equal()
 
+    if options.undo:
+        print 'Undoing the "%s" refresh...' % patch,
+        sys.stdout.flush()
+        crt_series.undo_refresh()
+        print 'done'
+        return
+
+    if options.author:
+        options.authname, options.authemail = name_email(options.author)
+
+    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'
+    else:
+        sign_str = None
+
     if git.local_changes() \
            or not crt_series.head_top_equal() \
            or options.edit or options.message \
            or options.authname or options.authemail or options.authdate \
-           or options.commname or options.commemail:
+           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]
+            pop_patches(between, keep = True)
+
         print 'Refreshing patch "%s"...' % patch,
         sys.stdout.flush()
 
         if autoresolved == 'yes':
             resolved_all()
-        crt_series.refresh_patch(message = options.message,
+        crt_series.refresh_patch(files = args,
+                                 message = options.message,
                                  edit = options.edit,
+                                 show_patch = options.showpatch,
                                  author_name = options.authname,
                                  author_email = options.authemail,
                                  author_date = options.authdate,
                                  committer_name = options.commname,
-                                 committer_email = options.commemail)
+                                 committer_email = options.commemail,
+                                 backup = True, sign_str = sign_str)
+
+        if options.patch:
+            between.reverse()
+            push_patches(between)
 
         print 'done'
     else: