Allow only certain gitk exit codes as valid
[stgit] / stgit / commands / log.py
index 033c797..52d55a5 100644 (file)
@@ -20,6 +20,8 @@ from optparse import OptionParser, make_option
 from pydoc import pager
 from stgit.commands.common import *
 from stgit import stack, git
+from stgit.out import *
+from stgit.run import Run
 
 help = 'display the patch changelog'
 usage = """%prog [options] [patch]
@@ -36,39 +38,77 @@ can be one of the following:
   push(f) - the patch was fast-forwarded
   undo    - the patch boundaries were restored to the old values
 
-Note that only the diffs shown in the 'refresh' and 'undo' actions are
-meaningful for the patch changes. The 'push' actions represent the
-changes to the entire base of the current patch. Conflicts reset the
-patch content and a subsequent 'refresh' will show the entire patch."""
+Note that only the diffs shown in the 'refresh', 'undo' and 'sync'
+actions are meaningful for the patch changes. The 'push' actions
+represent the changes to the entire base of the current
+patch. Conflicts reset the patch content and a subsequent 'refresh'
+will show the entire patch."""
 
+directory = DirectoryHasRepository()
 options = [make_option('-b', '--branch',
                        help = 'use BRANCH instead of the default one'),
            make_option('-p', '--patch',
                        help = 'show the refresh diffs',
                        action = 'store_true'),
+           make_option('-n', '--number', type = 'int',
+                       help = 'limit the output to NUMBER commits'),
+           make_option('-f', '--full',
+                       help = 'show the full commit ids',
+                       action = 'store_true'),
            make_option('-g', '--graphical',
                        help = 'run gitk instead of printing',
                        action = 'store_true')]
 
-def show_log(log, show_patch):
+def show_log(log, options):
     """List the patch changelog
     """
     commit = git.get_commit(log)
-    diff_str = ''
+    if options.number != None:
+        n = options.number
+    else:
+        n = -1
+    diff_list = []
     while commit:
-        descr = commit.get_log().rstrip()
+        if n == 0:
+            # limit the output
+            break
+
+        log = commit.get_log().split('\n')
+
+        cmd_rev = log[0].split()
+        if len(cmd_rev) >= 2:
+            cmd = cmd_rev[0]
+            rev = cmd_rev[1]
+        elif len(cmd_rev) == 1:
+            cmd = cmd_rev[0]
+            rev = ''
+        else:
+            cmd = rev = ''
 
-        if show_patch:
-            if descr.startswith('refresh') or descr.startswith('undo'):
-                diff_str = '%s%s\n' % (diff_str,
-                                       git.pretty_commit(commit.get_id_hash()))
+        if options.patch:
+            if cmd in ['refresh', 'undo', 'sync', 'edit']:
+                diff_list.append(git.pretty_commit(commit.get_id_hash()))
+
+                # limiter decrement
+                n -= 1
         else:
+            if len(log) >= 3:
+                notes = log[2]
+            else:
+                notes = ''
             author_name, author_email, author_date = \
                          name_email_date(commit.get_author())
             secs, tz = author_date.split()
             date = '%s %s' % (time.ctime(int(secs)), tz)
 
-            print descr, date
+            if options.full:
+                out.stdout('%-7s %-40s %s' % (cmd[:7], rev[:40], date))
+            else:
+                out.stdout('%-8s [%-7s] %-28s  %s' % \
+                           (rev[:8], cmd[:7], notes[:28], date))
+
+            # limiter decrement
+            n -= 1
 
         parent = commit.get_parent()
         if parent:
@@ -76,8 +116,8 @@ def show_log(log, show_patch):
         else:
             commit = None
 
-    if show_patch and diff_str:
-        pager(diff_str.rstrip())
+    if options.patch and diff_list:
+        pager('\n'.join(diff_list).rstrip())
 
 def func(parser, options, args):
     """Show the patch changelog
@@ -88,7 +128,8 @@ def func(parser, options, args):
             raise CmdException, 'No patches applied'
     elif len(args) == 1:
         name = args[0]
-        if not name in crt_series.get_applied() + crt_series.get_unapplied():
+        if not name in crt_series.get_applied() + crt_series.get_unapplied() + \
+               crt_series.get_hidden():
             raise CmdException, 'Unknown patch "%s"' % name
     else:
         parser.error('incorrect number of arguments')
@@ -100,7 +141,7 @@ def func(parser, options, args):
         raise CmdException, 'No changelog for patch "%s"' % name
 
     if options.graphical:
-        if os.system('gitk %s' % log) != 0:
-            raise CmdException, 'gitk execution failed'
+        # discard the exit codes generated by SIGINT, SIGKILL, SIGTERM
+        Run('gitk', log).returns([0, -2, -9, -15]).run()
     else:
-        show_log(log, options.patch)
+        show_log(log, options)