All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Grimm <koreth@midwinter.com>
To: git@vger.kernel.org
Subject: [PATCH] Add svn-compatible "blame" output format to git-svn
Date: Sat, 10 May 2008 14:25:04 -0700	[thread overview]
Message-ID: <20080510212504.GA26701@midwinter.com> (raw)

git-svn blame produces output in the format of git blame; in environments
where there are scripts that read the output of svn blame, it's useful
to be able to use them with the output of git-svn blame.

This also fixes a bug in the initial git-svn blame implementation; it was
bombing out on uncommitted local changes.

Signed-off-by: Steven Grimm <koreth@midwinter.com>
---

	I'd actually argue that the svn-compatible format should be the
	default one, with git-compatible available as an option, but if
	there are existing scripts that consume git-svn blame's output,
	I don't want to break them.

	I suspect there aren't any since git-svn blame is relatively new.

 Documentation/git-svn.txt |   11 ++++++++-
 git-svn.perl              |   51 +++++++++++++++++++++++++++++++++++++--------
 2 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index f4ba105..8071347 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -168,9 +168,16 @@ Any other arguments are passed directly to `git log'
 'blame'::
        Show what revision and author last modified each line of a file. This is
        identical to `git blame', but SVN revision numbers are shown instead of git
-       commit hashes.
+       commit hashes. Changes that haven't been committed to SVN yet are
+       listed as SVN revision 0.
 +
-All arguments are passed directly to `git blame'.
+All arguments are passed directly to `git blame', except the following:
++
+--svn-format;;
+	Produce output in the same format as `svn blame'. In this mode,
+	uncommitted changes in the working copy are ignored (the version
+	of the file from the HEAD revision is annotated) and whitespace
+	characters in author names are replaced with underscores.
 
 --
 'find-rev'::
diff --git a/git-svn.perl b/git-svn.perl
index e47b1ea..9570deb 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -65,7 +65,8 @@ my ($_stdin, $_help, $_edit,
 	$_template, $_shared,
 	$_version, $_fetch_all, $_no_rebase,
 	$_merge, $_strategy, $_dry_run, $_local,
-	$_prefix, $_no_checkout, $_url, $_verbose);
+	$_prefix, $_no_checkout, $_url, $_verbose,
+	$_svn_format);
 $Git::SVN::_follow_parent = 1;
 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
                     'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -188,7 +189,7 @@ my %cmd = (
 		    { 'url' => \$_url, } ],
 	'blame' => [ \&Git::SVN::Log::cmd_blame,
 	            "Show what revision and author last modified each line of a file",
-	            {} ],
+		    { 'svn-format' => \$_svn_format } ],
 );
 
 my $cmd;
@@ -4473,14 +4474,46 @@ sub cmd_blame {
 	config_pager();
 	run_pager();
 
-	my ($fh, $ctx) = command_output_pipe('blame', @_, $path);
-	while (my $line = <$fh>) {
-		if ($line =~ /^\^?([[:xdigit:]]+)\s/) {
-			my (undef, $rev, undef) = ::cmt_metadata($1);
-			$rev = sprintf('%-10s', $rev);
-			$line =~ s/^\^?[[:xdigit:]]+(\s)/$rev$1/;
+	my ($fh, $ctx, $rev);
+
+	if ($_svn_format) {
+		($fh, $ctx) = command_output_pipe('blame', @_, '-p', 'HEAD',
+						     '--', $path);
+		my ($sha1);
+		my %authors;
+		while (my $line = <$fh>) {
+			if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
+				$sha1 = $1;
+				(undef, $rev, undef) = ::cmt_metadata($1);
+				$rev = '0' if (!$rev);
+			}
+			elsif ($line =~ /^author (.*)/) {
+				$authors{$rev} = $1;
+				$authors{$rev} =~ s/\s/_/g;
+			}
+			elsif ($line =~ /^\t(.*)$/) {
+				printf("%6s %10s %s\n", $rev, $authors{$rev}, $1);
+			}
+		}
+	} else {
+		($fh, $ctx) = command_output_pipe('blame', @_, $path);
+		while (my $line = <$fh>) {
+			if ($line =~ /^\^?([[:xdigit:]]+)\s/) {
+				# Uncommitted edits show up as a rev ID of
+				# all zeros, which we can't look up with
+				# cmt_metadata
+				if ($1 !~ /^0+$/) {
+					(undef, $rev, undef) =
+						::cmt_metadata($1);
+					$rev = '0' if (!$rev);
+				} else {
+					$rev = '0';
+				}
+				$rev = sprintf('%-10s', $rev);
+				$line =~ s/^\^?[[:xdigit:]]+(\s)/$rev$1/;
+			}
+			print $line;
 		}
-		print $line;
 	}
 	command_close_pipe($fh, $ctx);
 }
-- 
1.5.5.49.gf43e2

             reply	other threads:[~2008-05-10 21:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-10 21:25 Steven Grimm [this message]
2008-05-11  2:36 ` [PATCH] Add svn-compatible "blame" output format to git-svn Junio C Hamano
2008-05-11  5:11   ` [PATCH v2] " Steven Grimm
2008-05-11  7:42     ` Eric Wong
2008-05-11  6:36   ` [PATCH] " Teemu Likonen
2008-05-11 13:46     ` Tim Stoakes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080510212504.GA26701@midwinter.com \
    --to=koreth@midwinter.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.