summaryrefslogtreecommitdiff
path: root/git-svn.perl
diff options
context:
space:
mode:
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-xgit-svn.perl73
1 files changed, 59 insertions, 14 deletions
diff --git a/git-svn.perl b/git-svn.perl
index 33e9266..37976f2 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,
+ $_git_format);
$Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -82,6 +83,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
'repack-flags|repack-args|repack-opts=s' =>
\$Git::SVN::_repack_flags,
'use-log-author' => \$Git::SVN::_use_log_author,
+ 'add-author-from' => \$Git::SVN::_add_author_from,
%remote_opts );
my ($_trunk, $_tags, $_branches, $_stdlayout);
@@ -188,7 +190,7 @@ my %cmd = (
{ 'url' => \$_url, } ],
'blame' => [ \&Git::SVN::Log::cmd_blame,
"Show what revision and author last modified each line of a file",
- {} ],
+ { 'git-format' => \$_git_format } ],
);
my $cmd;
@@ -226,7 +228,7 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) {
my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
read_repo_config(\%opts);
-Getopt::Long::Configure('pass_through') if ($cmd && $cmd eq 'log');
+Getopt::Long::Configure('pass_through') if ($cmd && ($cmd eq 'log' || $cmd eq 'blame'));
my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
'minimize-connections' => \$Git::SVN::Migration::_minimize,
'id|i=s' => \$Git::SVN::default_ref_id,
@@ -617,7 +619,7 @@ sub cmd_create_ignore {
print GITIGNORE "$s\n";
close(GITIGNORE)
or fatal("Failed to close `$ignore': $!");
- command_noisy('add', $ignore);
+ command_noisy('add', '-f', $ignore);
});
}
@@ -1014,17 +1016,28 @@ sub get_commit_entry {
my ($msg_fh, $ctx) = command_output_pipe('cat-file',
$type, $treeish);
my $in_msg = 0;
+ my $author;
+ my $saw_from = 0;
while (<$msg_fh>) {
if (!$in_msg) {
$in_msg = 1 if (/^\s*$/);
+ $author = $1 if (/^author (.*>)/);
} elsif (/^git-svn-id: /) {
# skip this for now, we regenerate the
# correct one on re-fetch anyways
# TODO: set *:merge properties or like...
} else {
+ if (/^From:/ || /^Signed-off-by:/) {
+ $saw_from = 1;
+ }
print $log_fh $_ or croak $!;
}
}
+ if ($Git::SVN::_add_author_from && defined($author)
+ && !$saw_from) {
+ print $log_fh "\nFrom: $author\n"
+ or croak $!;
+ }
command_close_pipe($msg_fh, $ctx);
}
close $log_fh or croak $!;
@@ -1251,7 +1264,7 @@ use constant rev_map_fmt => 'NH40';
use vars qw/$default_repo_id $default_ref_id $_no_metadata $_follow_parent
$_repack $_repack_flags $_use_svm_props $_head
$_use_svnsync_props $no_reuse_existing $_minimize_url
- $_use_log_author/;
+ $_use_log_author $_add_author_from/;
use Carp qw/croak/;
use File::Path qw/mkpath/;
use File::Copy qw/copy/;
@@ -3671,7 +3684,7 @@ sub escape_uri_only {
my ($uri) = @_;
my @tmp;
foreach (split m{/}, $uri) {
- s/([^\w.%-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
+ s/([^\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
push @tmp, $_;
}
join('/', @tmp);
@@ -4466,19 +4479,51 @@ out:
}
sub cmd_blame {
- my $path = shift;
+ my $path = pop;
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 ($_git_format) {
+ ($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;
+ }
+ } else {
+ ($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);
+ }
}
- print $line;
}
command_close_pipe($fh, $ctx);
}