+# -*- coding: utf-8 -*-
+
__copyright__ = """
Copyright (C) 2006, Catalin Marinas <catalin.marinas@gmail.com>
+Copyright (C) 2008, Karl Hasselström <kha@treskal.com>
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
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
-import sys, os, time
-from pydoc import pager
+import os.path
+from optparse import make_option
+from stgit import run
from stgit.argparse import opt
-from stgit.commands.common import *
-from stgit import stack, git
-from stgit.out import *
-from stgit.run import Run
+from stgit.commands import common
+from stgit.lib import log
+from stgit.out import out
help = 'Display the patch changelog'
-kind = 'patch'
-usage = ['[options] [patch]']
+kind = 'stack'
+usage = ['[options] [<patches>]']
description = """
-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 '<action> <new-patch-id>'. The <action>
-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
+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.
-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."""
+"stg undo" and "stg redo" let you step back and forth in the patch
+stack. "stg reset" lets you go directly to any state."""
options = [
opt('-b', '--branch',
opt('-g', '--graphical', action = 'store_true',
short = 'Run gitk instead of printing')]
-directory = DirectoryHasRepository(log = False)
-
-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()))
+directory = common.DirectoryHasRepositoryLib()
- # 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())
+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:
- # discard the exit codes generated by SIGINT, SIGKILL, SIGTERM
- Run('gitk', log).returns([0, -2, -9, -15]).run()
+ 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)
+++ /dev/null
-#!/bin/sh
-#
-# Copyright (c) 2006 Catalin Marinas
-#
-
-test_description='Test the patch history generation.
-
-'
-
-. ./test-lib.sh
-
-test_expect_success \
- 'Initialize the StGIT repository' \
- '
- stg init
- '
-
-test_expect_success \
- 'Create the first patch' \
- '
- stg new foo -m "Foo Patch" &&
- echo foo > test && echo foo2 >> test &&
- git add test &&
- stg refresh --annotate="foo notes"
- '
-
-test_expect_success \
- 'Create the second patch' \
- '
- stg new bar -m "Bar Patch" &&
- echo bar >> test &&
- stg refresh
- '
-
-test_expect_success \
- 'Check the "new" and "refresh" logs' \
- '
- stg log --full foo | grep -q -e "^refresh" &&
- stg log --full | grep -q -e "^refresh"
- '
-
-test_expect_success \
- 'Check the log annotation' \
- '
- stg log foo | grep -q -e "\[refresh\] foo notes " &&
- stg log bar | grep -q -e "\[refresh\] " &&
- stg refresh -p foo --annotate="foo notes 2" &&
- stg log foo | grep -q -v -e "\[refresh\] foo notes " &&
- stg log foo | grep -q -e "\[refresh\] foo notes 2"
- '
-
-test_expect_success \
- 'Check the "push" log' \
- '
- stg pop &&
- echo foo > test2 && git add test2 && stg refresh &&
- stg push &&
- stg log --full | grep -q -e "^push "
- '
-
-test_expect_success \
- 'Check the "push(f)" log' \
- '
- stg pop &&
- stg edit -m "Foo2 Patch" &&
- stg push &&
- stg log --full | grep -q -e "^push(f) "
- '
-
-test_expect_success \
- 'Check the "push(m)" log' \
- '
- stg pop &&
- echo foo2 > test && stg refresh &&
- stg push &&
- stg log --full | grep -q -e "^push(m) "
- '
-
-test_expect_success \
- 'Check the "push(c)" log' \
- '
- echo bar > test && stg refresh &&
- stg pop &&
- echo foo > test && stg refresh &&
- conflict_old stg push &&
- stg log --full | grep -q -e "^push(c) "
- '
-
-test_expect_success \
- 'Check the push "undo" log' \
- '
- stg push --undo &&
- stg log --full bar | grep -q -e "^undo "
- '
-
-test_expect_success \
- 'Check the refresh "undo" log' \
- '
- stg refresh --undo &&
- stg log --full | grep -q -e "^undo "
- '
-
-test_done