"Show info about the latest SVN revision
on the current branch",
{ 'url' => \$_url, } ],
+ 'blame' => [ \&Git::SVN::Log::cmd_blame,
+ "Show what revision and author last modified each line of a file",
+ {} ],
);
my $cmd;
}
sub cmd_find_rev {
- my $revision_or_hash = shift;
+ my $revision_or_hash = shift or die "SVN or git revision required ",
+ "as a command-line argument\n";
my $result;
if ($revision_or_hash =~ /^r\d+$/) {
my $head = shift;
"wanted to set to: $gs->{url}\n";
}
command_oneline('config', $k, $gs->{url}) unless $orig_url;
- my $remote_path = "$ra->{svn_path}/$repo_path/*";
+ my $remote_path = "$ra->{svn_path}/$repo_path";
$remote_path =~ s#/+#/#g;
$remote_path =~ s#^/##g;
+ $remote_path .= "/*" if $remote_path !~ /\*/;
my ($n) = ($switch =~ /^--(\w+)/);
if (length $pfx && $pfx !~ m#/$#) {
die "--prefix='$pfx' must have a trailing slash '/'\n";
use File::Copy qw/copy/;
use IPC::Open3;
-my $_repack_nr;
+my ($_gc_nr, $_gc_period);
+
# properties that we do not log:
my %SKIP_PROP;
BEGIN {
}
sub init_vars {
- $_repack = 1000 unless (defined $_repack && $_repack > 0);
- $_repack_nr = $_repack;
- $_repack_flags ||= '-d';
+ $_gc_nr = $_gc_period = 1000;
+ if (defined $_repack || defined $_repack_flags) {
+ warn "Repack options are obsolete; they have no effect.\n";
+ }
}
sub verify_remotes_sanity {
$remotes->{$repo_id}->{$_});
}
my $p = $path;
+ my $rwr = rewrite_root({repo_id => $repo_id});
unless (defined $p) {
$p = $full_url;
- $p =~ s#^\Q$u\E(?:/|$)## or next;
+ my $z = $u;
+ if ($rwr) {
+ $z = $rwr;
+ }
+ $p =~ s#^\Q$z\E(?:/|$)## or next;
}
foreach my $f (keys %$fetch) {
next if $f ne $p;
foreach (sort keys %$dirent) {
next if $dirent->{$_}->{kind} != $SVN::Node::dir;
- $self->prop_walk($path . '/' . $_, $rev, $sub);
+ $self->prop_walk($p . $_, $rev, $sub);
}
}
}
}
+sub gc {
+ command_noisy('gc', '--auto');
+};
+
sub do_git_commit {
my ($self, $log_entry) = @_;
my $lr = $self->last_rev;
0, $self->svm_uuid);
}
print " = $commit ($self->{ref_id})\n";
- if ($_repack && (--$_repack_nr == 0)) {
- $_repack_nr = $_repack;
- # repack doesn't use any arguments with spaces in them, does it?
- print "Running git repack $_repack_flags ...\n";
- command_noisy('repack', split(/\s+/, $_repack_flags));
- print "Done repacking\n";
+ if (--$_gc_nr == 0) {
+ $_gc_nr = $_gc_period;
+ gc();
}
return $commit;
}
# just grow a tail if we're not unique enough :x
$ref_id .= '-' while find_ref($ref_id);
print STDERR "Initializing parent: $ref_id\n";
- $gs = Git::SVN->init($new_url, '', $ref_id, $ref_id, 1);
+ my ($u, $p, $repo_id) = ($new_url, '', $ref_id);
+ if ($u =~ s#^\Q$url\E(/|$)##) {
+ $p = $u;
+ $u = $url;
+ $repo_id = $self->{repo_id};
+ }
+ $gs = Git::SVN->init($u, $p, $repo_id, $ref_id, 1);
}
my ($r0, $parent) = $gs->find_rev_before($r, 1);
if (!defined $r0 || !defined $parent) {
my ($uri) = @_;
my @tmp;
foreach (split m{/}, $uri) {
- s/([^\w.-])/sprintf("%%%02X",ord($1))/eg;
+ s/([^\w.%-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
push @tmp, $_;
}
join('/', @tmp);
$max += $inc;
$max = $head if ($max > $head);
}
+ Git::SVN::gc();
}
sub match_globs {
print commit_log_separator unless $incremental || $oneline;
}
+sub cmd_blame {
+ my $path = shift;
+
+ 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/;
+ }
+ print $line;
+ }
+ command_close_pipe($fh, $ctx);
+}
+
package Git::SVN::Migration;
# these version numbers do NOT correspond to actual version numbers
# of git nor git-svn. They are just relative.