chiark / gitweb /
Infrastructure for current directory handling
[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
25 help = 'display the patch changelog'
26 usage = """%prog [options] [patch]
27
28 List all the current and past commit ids of the given patch. The
29 --graphical option invokes gitk instead of printing. The changelog
30 commit messages have the form '<action> <new-patch-id>'. The <action>
31 can be one of the following:
32
33   new     - new patch created
34   refresh - local changes were added to the patch
35   push    - the patch was cleanly pushed onto the stack
36   push(m) - the patch was pushed onto the stack with a three-way merge
37   push(f) - the patch was fast-forwarded
38   undo    - the patch boundaries were restored to the old values
39
40 Note that only the diffs shown in the 'refresh', 'undo' and 'sync'
41 actions are meaningful for the patch changes. The 'push' actions
42 represent the changes to the entire base of the current
43 patch. Conflicts reset the patch content and a subsequent 'refresh'
44 will show the entire patch."""
45
46 directory = DirectoryHasRepository()
47 options = [make_option('-b', '--branch',
48                        help = 'use BRANCH instead of the default one'),
49            make_option('-p', '--patch',
50                        help = 'show the refresh diffs',
51                        action = 'store_true'),
52            make_option('-f', '--full',
53                        help = 'show the full commit ids',
54                        action = 'store_true'),
55            make_option('-g', '--graphical',
56                        help = 'run gitk instead of printing',
57                        action = 'store_true')]
58
59 def show_log(log, options):
60     """List the patch changelog
61     """
62     commit = git.get_commit(log)
63     diff_str = ''
64     while commit:
65         log = commit.get_log().split('\n')
66
67         cmd_rev = log[0].split()
68         if len(cmd_rev) >= 2:
69             cmd = cmd_rev[0]
70             rev = cmd_rev[1]
71         elif len(cmd_rev) == 1:
72             cmd = cmd_rev[0]
73             rev = ''
74         else:
75             cmd = rev = ''
76
77         if options.patch:
78             if cmd in ['refresh', 'undo', 'sync']:
79                 diff_str = '%s%s\n' % (diff_str,
80                                        git.pretty_commit(commit.get_id_hash()))
81         else:
82             if len(log) >= 3:
83                 notes = log[2]
84             else:
85                 notes = ''
86             author_name, author_email, author_date = \
87                          name_email_date(commit.get_author())
88             secs, tz = author_date.split()
89             date = '%s %s' % (time.ctime(int(secs)), tz)
90
91             if options.full:
92                 out.stdout('%-7s %-40s %s' % (cmd[:7], rev[:40], date))
93             else:
94                 out.stdout('%-8s [%-7s] %-28s  %s' % \
95                            (rev[:8], cmd[:7], notes[:28], date))
96
97         parent = commit.get_parent()
98         if parent:
99             commit = git.get_commit(parent)
100         else:
101             commit = None
102
103     if options.patch and diff_str:
104         pager(diff_str.rstrip())
105
106 def func(parser, options, args):
107     """Show the patch changelog
108     """
109     if len(args) == 0:
110         name = crt_series.get_current()
111         if not name:
112             raise CmdException, 'No patches applied'
113     elif len(args) == 1:
114         name = args[0]
115         if not name in crt_series.get_applied() + crt_series.get_unapplied() + \
116                crt_series.get_hidden():
117             raise CmdException, 'Unknown patch "%s"' % name
118     else:
119         parser.error('incorrect number of arguments')
120
121     patch = crt_series.get_patch(name)
122
123     log = patch.get_log()
124     if not log:
125         raise CmdException, 'No changelog for patch "%s"' % name
126
127     if options.graphical:
128         if os.system('gitk %s' % log) != 0:
129             raise CmdException, 'gitk execution failed'
130     else:
131         show_log(log, options)