X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/stgit/blobdiff_plain/edddb24917ca00327b45fb8764455679f1ef6b09..594aa463c1852f77b89bdce853da4e7052d7cdd2:/stgit/commands/log.py diff --git a/stgit/commands/log.py b/stgit/commands/log.py index 56f7e0a..3370e6c 100644 --- a/stgit/commands/log.py +++ b/stgit/commands/log.py @@ -1,5 +1,8 @@ +# -*- coding: utf-8 -*- + __copyright__ = """ Copyright (C) 2006, Catalin Marinas +Copyright (C) 2008, Karl Hasselström This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as @@ -15,132 +18,74 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -import sys, os, time -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] - -List all the current and past commit ids of the given patch. The ---graphical option invokes gitk instead of printing. The changelog -commit messages have the form ' '. The -can be one of the following: - - new - new patch created - refresh - local changes were added to the patch - push - the patch was cleanly pushed onto the stack - push(m) - the patch was pushed onto the stack with a three-way merge - 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', '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, options): - """List the patch changelog - """ - commit = git.get_commit(log) - if options.number != None: - n = options.number - else: - n = -1 - diff_list = [] - while commit: - 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 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) - - 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: - commit = git.get_commit(parent) - else: - commit = None - - if options.patch and diff_list: - pager('\n'.join(diff_list).rstrip()) +import os.path +from optparse import make_option +from stgit import argparse, run +from stgit.argparse import opt +from stgit.commands import common +from stgit.lib import log +from stgit.out import out + +help = 'Display the patch changelog' +kind = 'stack' +usage = ['[options] []'] +description = """ +List the history of the patch stack: the stack log. If one or more +patch names are given, limit the list to the log entries that touch +the named patches. + +"stg undo" and "stg redo" let you step back and forth in the patch +stack. "stg reset" lets you go directly to any state.""" + +args = [argparse.patch_range(argparse.applied_patches, + argparse.unapplied_patches, + argparse.hidden_patches)] +options = [ + opt('-b', '--branch', args = [argparse.stg_branches], + short = 'Use BRANCH instead of the default one'), + opt('-d', '--diff', action = 'store_true', + short = 'Show the refresh diffs'), + opt('-n', '--number', type = 'int', + short = 'Limit the output to NUMBER commits'), + opt('-f', '--full', action = 'store_true', + short = 'Show the full commit ids'), + opt('-g', '--graphical', action = 'store_true', + short = 'Run gitk instead of printing')] + +directory = common.DirectoryHasRepositoryLib() + +def show_log(stacklog, pathlim, num, full, show_diff): + cmd = ['git', 'log'] + if num != None and num > 0: + cmd.append('-%d' % num) + if show_diff: + cmd.append('-p') + elif not full: + cmd.append('--pretty=format:%h %aD %s') + run.Run(*(cmd + [stacklog.sha1, '--'] + pathlim)).run() def func(parser, options, args): - """Show the patch changelog - """ - if len(args) == 0: - name = crt_series.get_current() - if not name: - raise CmdException, 'No patches applied' - elif len(args) == 1: - name = args[0] - if not name in crt_series.get_applied() + crt_series.get_unapplied() + \ - crt_series.get_hidden(): - raise CmdException, 'Unknown patch "%s"' % name + if options.branch: + stack = directory.repository.get_stack(options.branch) else: - parser.error('incorrect number of arguments') - - patch = crt_series.get_patch(name) - - log = patch.get_log() - if not log: - raise CmdException, 'No changelog for patch "%s"' % name + stack = directory.repository.current_stack + patches = common.parse_patches(args, list(stack.patchorder.all)) + logref = log.log_ref(stack.name) + try: + logcommit = stack.repository.refs.get(logref) + except KeyError: + out.info('Log is empty') + return + stacklog = log.get_log_entry(stack.repository, logref, logcommit) + pathlim = [os.path.join('patches', pn) for pn in patches] if options.graphical: - Run('gitk', log).run(exitcode = False) + for o in ['diff', 'number', 'full']: + if getattr(options, o): + parser.error('cannot combine --graphical and --%s' % o) + # Discard the exit codes generated by SIGINT, SIGKILL, and SIGTERM. + run.Run(*(['gitk', stacklog.simplified.sha1, '--'] + pathlim) + ).returns([0, -2, -9, -15]).run() else: - show_log(log, options) + show_log(stacklog.simplified, pathlim, + options.number, options.full, options.diff)