chiark / gitweb /
Ignore the gitk exit code in 'stg log -g' (bug #10010)
[stgit] / stgit / commands / log.py
1 __copyright__ = """
2 Copyright (C) 2006, Catalin Marinas <catalin.marinas@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License version 2 as
6 published by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 """
17
18 import sys, os, time
19 from optparse import OptionParser, make_option
20 from pydoc import pager
21 from stgit.commands.common import *
22 from stgit import stack, git
23 from stgit.out import *
24 from stgit.run import Run
25
26 help = 'display the patch changelog'
27 usage = """%prog [options] [patch]
28
29 List all the current and past commit ids of the given patch. The
30 --graphical option invokes gitk instead of printing. The changelog
31 commit messages have the form '<action> <new-patch-id>'. The <action>
32 can be one of the following:
33
34   new     - new patch created
35   refresh - local changes were added to the patch
36   push    - the patch was cleanly pushed onto the stack
37   push(m) - the patch was pushed onto the stack with a three-way merge
38   push(f) - the patch was fast-forwarded
39   undo    - the patch boundaries were restored to the old values
40
41 Note that only the diffs shown in the 'refresh', 'undo' and 'sync'
42 actions are meaningful for the patch changes. The 'push' actions
43 represent the changes to the entire base of the current
44 patch. Conflicts reset the patch content and a subsequent 'refresh'
45 will show the entire patch."""
46
47 directory = DirectoryHasRepository()
48 options = [make_option('-b', '--branch',
49                        help = 'use BRANCH instead of the default one'),
50            make_option('-p', '--patch',
51                        help = 'show the refresh diffs',
52                        action = 'store_true'),
53            make_option('-n', '--number', type = 'int',
54                        help = 'limit the output to NUMBER commits'),
55            make_option('-f', '--full',
56                        help = 'show the full commit ids',
57                        action = 'store_true'),
58            make_option('-g', '--graphical',
59                        help = 'run gitk instead of printing',
60                        action = 'store_true')]
61
62 def show_log(log, options):
63     """List the patch changelog
64     """
65     commit = git.get_commit(log)
66     if options.number != None:
67         n = options.number
68     else:
69         n = -1
70     diff_list = []
71     while commit:
72         if n == 0:
73             # limit the output
74             break
75
76         log = commit.get_log().split('\n')
77
78         cmd_rev = log[0].split()
79         if len(cmd_rev) >= 2:
80             cmd = cmd_rev[0]
81             rev = cmd_rev[1]
82         elif len(cmd_rev) == 1:
83             cmd = cmd_rev[0]
84             rev = ''
85         else:
86             cmd = rev = ''
87
88         if options.patch:
89             if cmd in ['refresh', 'undo', 'sync', 'edit']:
90                 diff_list.append(git.pretty_commit(commit.get_id_hash()))
91
92                 # limiter decrement
93                 n -= 1
94         else:
95             if len(log) >= 3:
96                 notes = log[2]
97             else:
98                 notes = ''
99             author_name, author_email, author_date = \
100                          name_email_date(commit.get_author())
101             secs, tz = author_date.split()
102             date = '%s %s' % (time.ctime(int(secs)), tz)
103
104             if options.full:
105                 out.stdout('%-7s %-40s %s' % (cmd[:7], rev[:40], date))
106             else:
107                 out.stdout('%-8s [%-7s] %-28s  %s' % \
108                            (rev[:8], cmd[:7], notes[:28], date))
109
110             # limiter decrement
111             n -= 1
112
113         parent = commit.get_parent()
114         if parent:
115             commit = git.get_commit(parent)
116         else:
117             commit = None
118
119     if options.patch and diff_list:
120         pager('\n'.join(diff_list).rstrip())
121
122 def func(parser, options, args):
123     """Show the patch changelog
124     """
125     if len(args) == 0:
126         name = crt_series.get_current()
127         if not name:
128             raise CmdException, 'No patches applied'
129     elif len(args) == 1:
130         name = args[0]
131         if not name in crt_series.get_applied() + crt_series.get_unapplied() + \
132                crt_series.get_hidden():
133             raise CmdException, 'Unknown patch "%s"' % name
134     else:
135         parser.error('incorrect number of arguments')
136
137     patch = crt_series.get_patch(name)
138
139     log = patch.get_log()
140     if not log:
141         raise CmdException, 'No changelog for patch "%s"' % name
142
143     if options.graphical:
144         Run('gitk', log).run(exitcode = False)
145     else:
146         show_log(log, options)