git-p4: support exclude paths
[gitweb.git] / git-svn.perl
index 074068c64b7d7cf2a049f4b3dcd59db9746a3785..05fb3582d92e05e6b95ff8f249ae2ecb9892b45b 100755 (executable)
@@ -186,6 +186,9 @@ BEGIN
                    "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;
@@ -1247,6 +1250,8 @@ package Git::SVN;
 use File::Copy qw/copy/;
 use IPC::Open3;
 
+my ($_gc_nr, $_gc_period);
+
 # properties that we do not log:
 my %SKIP_PROP;
 BEGIN {
@@ -1407,6 +1412,7 @@ sub read_all_remotes {
 }
 
 sub init_vars {
+       $_gc_nr = $_gc_period = 1000;
        if (defined $_repack || defined $_repack_flags) {
               warn "Repack options are obsolete; they have no effect.\n";
        }
@@ -2095,6 +2101,10 @@ sub restore_commit_header_env {
        }
 }
 
+sub gc {
+       command_noisy('gc', '--auto');
+};
+
 sub do_git_commit {
        my ($self, $log_entry) = @_;
        my $lr = $self->last_rev;
@@ -2148,6 +2158,10 @@ sub do_git_commit {
                                   0, $self->svm_uuid);
        }
        print " = $commit ($self->{ref_id})\n";
+       if (--$_gc_nr == 0) {
+               $_gc_nr = $_gc_period;
+               gc();
+       }
        return $commit;
 }
 
@@ -2218,7 +2232,12 @@ sub find_parent_branch {
                # 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) = ($new_url, '');
+               if ($u =~ s#^\Q$url\E(/|$)##) {
+                       $p = $u;
+                       $u = $url;
+               }
+               $gs = Git::SVN->init($u, $p, $self->{repo_id}, $ref_id, 1);
        }
        my ($r0, $parent) = $gs->find_rev_before($r, 1);
        if (!defined $r0 || !defined $parent) {
@@ -3975,6 +3994,7 @@ sub gs_fetch_loop_common {
                $max += $inc;
                $max = $head if ($max > $head);
        }
+       Git::SVN::gc();
 }
 
 sub match_globs {
@@ -4431,6 +4451,24 @@ sub cmd_show_log {
        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.