]> asedeno.scripts.mit.edu Git - git.git/blobdiff - git-svn.perl
Remove a CURLOPT_HTTPHEADER (un)setting
[git.git] / git-svn.perl
index b45c7e3266176336a4d8c6deeaa051c6fd0e9be6..d411a343170cf8dce9d968b84f123855b03e53d3 100755 (executable)
@@ -396,6 +396,7 @@ sub cmd_set_tree {
        }
        $gs->set_tree($_) foreach @revs;
        print "Done committing ",scalar @revs," revisions to SVN\n";
+       unlink $gs->{index};
 }
 
 sub cmd_dcommit {
@@ -514,6 +515,7 @@ sub cmd_dcommit {
                        $last_rev = $cmt_rev;
                }
        }
+       unlink $gs->{index};
 }
 
 sub cmd_find_rev {
@@ -1374,6 +1376,7 @@ sub fetch_all {
 
        ($base, $head) = parse_revision_argument($base, $head);
        $ra->gs_fetch_loop_common($base, $head, \@gs, \@globs);
+       unlink $_->{index} foreach @gs;
 }
 
 sub read_all_remotes {
@@ -1904,7 +1907,7 @@ sub last_rev_commit {
                ($self->{last_rev}, $self->{last_commit}) = (undef, undef);
                return (undef, undef);
        }
-       my ($rev, $commit) = $self->rev_map_max;
+       my ($rev, $commit) = $self->rev_map_max(1);
        ($self->{last_rev}, $self->{last_commit}) = ($rev, $commit);
        return ($rev, $commit);
 }
@@ -2363,11 +2366,20 @@ sub make_log_entry {
 
        my ($commit_name, $commit_email) = ($name, $email);
        if ($_use_log_author) {
-               if ($log_entry{log} =~ /From:\s+(.*?)\s+<(.*)>\s*\n/) {
-                       ($name, $email) = ($1, $2);
-               } elsif ($log_entry{log} =~
-                                     /Signed-off-by:\s+(.*?)\s+<(.*)>\s*\n/) {
+               my $name_field;
+               if ($log_entry{log} =~ /From:\s+(.*\S)\s*\n/i) {
+                       $name_field = $1;
+               } elsif ($log_entry{log} =~ /Signed-off-by:\s+(.*\S)\s*\n/i) {
+                       $name_field = $1;
+               }
+               if (!defined $name_field) {
+                       #
+               } elsif ($name_field =~ /(.*?)\s+<(.*)>/) {
                        ($name, $email) = ($1, $2);
+               } elsif ($name_field =~ /(.*)@/) {
+                       ($name, $email) = ($1, $name_field);
+               } else {
+                       ($name, $email) = ($name_field, 'unknown');
                }
        }
        if (defined $headrev && $self->use_svm_props) {
@@ -2534,11 +2546,16 @@ sub rebuild {
 #     * 4 bytes for the integer representing an SVN revision number
 #     * 20 bytes representing the sha1 of a git commit
 #   - No empty padding records like the old format
+#     (except the last record, which can be overwritten)
 #   - new records are written append-only since SVN revision numbers
 #     increase monotonically
 #   - lookups on SVN revision number are done via a binary search
-#   - Piping the file to xxd(1) -c24 is a good way of dumping it for
-#     viewing or editing, should the need ever arise.
+#   - Piping the file to xxd -c24 is a good way of dumping it for
+#     viewing or editing (piped back through xxd -r), should the need
+#     ever arise.
+#   - The last record can be padding revision with an all-zero sha1
+#     This is used to optimize fetch performance when using multiple
+#     "fetch" directives in .git/config
 #
 # These files are disposable unless noMetadata or useSvmProps is set
 
@@ -2548,16 +2565,32 @@ sub _rev_map_set {
        my $size = (stat($fh))[7];
        ($size % 24) == 0 or croak "inconsistent size: $size";
 
+       my $wr_offset = 0;
        if ($size > 0) {
                sysseek($fh, -24, SEEK_END) or croak "seek: $!";
                my $read = sysread($fh, my $buf, 24) or croak "read: $!";
                $read == 24 or croak "read only $read bytes (!= 24)";
                my ($last_rev, $last_commit) = unpack(rev_map_fmt, $buf);
-               if ($last_rev >= $rev) {
-                       croak "last_rev is higher!: $last_rev >= $rev";
+               if ($last_commit eq ('0' x40)) {
+                       if ($size >= 48) {
+                               sysseek($fh, -48, SEEK_END) or croak "seek: $!";
+                               $read = sysread($fh, $buf, 24) or
+                                   croak "read: $!";
+                               $read == 24 or
+                                   croak "read only $read bytes (!= 24)";
+                               ($last_rev, $last_commit) =
+                                   unpack(rev_map_fmt, $buf);
+                               if ($last_commit eq ('0' x40)) {
+                                       croak "inconsistent .rev_map\n";
+                               }
+                       }
+                       if ($last_rev >= $rev) {
+                               croak "last_rev is higher!: $last_rev >= $rev";
+                       }
+                       $wr_offset = -24;
                }
        }
-       sysseek($fh, 0, SEEK_END) or croak "seek: $!";
+       sysseek($fh, $wr_offset, SEEK_END) or croak "seek: $!";
        syswrite($fh, pack(rev_map_fmt, $rev, $commit), 24) == 24 or
          croak "write: $!";
 }
@@ -2599,7 +2632,7 @@ sub rev_map_set {
                                            "$db => $db_lock ($!)\n";
        }
 
-       sysopen(my $fh, $db_lock, O_RDWR | O_APPEND | O_CREAT)
+       sysopen(my $fh, $db_lock, O_RDWR | O_CREAT)
             or croak "Couldn't open $db_lock: $!\n";
        _rev_map_set($fh, $rev, $commit);
        if ($sync) {
@@ -2622,25 +2655,40 @@ sub rev_map_set {
        }
 }
 
+# If want_commit, this will return an array of (rev, commit) where
+# commit _must_ be a valid commit in the archive.
+# Otherwise, it'll return the max revision (whether or not the
+# commit is valid or just a 0x40 placeholder).
 sub rev_map_max {
-       my ($self) = @_;
+       my ($self, $want_commit) = @_;
        $self->rebuild;
        my $map_path = $self->map_path;
-       stat $map_path or return wantarray ? (0, undef) : 0;
+       stat $map_path or return $want_commit ? (0, undef) : 0;
        sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
        my $size = (stat($fh))[7];
        ($size % 24) == 0 or croak "inconsistent size: $size";
 
        if ($size == 0) {
                close $fh or croak "close: $!";
-               return wantarray ? (0, undef) : 0;
+               return $want_commit ? (0, undef) : 0;
        }
 
-       sysseek($fh, -24, SEEK_END);
+       sysseek($fh, -24, SEEK_END) or croak "seek: $!";
        sysread($fh, my $buf, 24) == 24 or croak "read: $!";
-       close $fh or croak "close: $!";
        my ($r, $c) = unpack(rev_map_fmt, $buf);
-       wantarray ? ($r, $c) : $r;
+       if ($want_commit && $c eq ('0' x40)) {
+               if ($size < 48) {
+                       return $want_commit ? (0, undef) : 0;
+               }
+               sysseek($fh, -48, SEEK_END) or croak "seek: $!";
+               sysread($fh, $buf, 24) == 24 or croak "read: $!";
+               ($r, $c) = unpack(rev_map_fmt, $buf);
+               if ($c eq ('0'x40)) {
+                       croak "Penultimate record is all-zeroes in $map_path";
+               }
+       }
+       close $fh or croak "close: $!";
+       $want_commit ? ($r, $c) : $r;
 }
 
 sub rev_map_get {
@@ -2672,7 +2720,7 @@ sub rev_map_get {
                        $u = $i - 24;
                } else { # $r == $rev
                        close($fh) or croak "close: $!";
-                       return $c;
+                       return $c eq ('0' x 40) ? undef : $c;
                }
        }
        close($fh) or croak "close: $!";
@@ -2997,6 +3045,20 @@ sub add_file {
 
 sub add_directory {
        my ($self, $path, $cp_path, $cp_rev) = @_;
+       my $gpath = $self->git_path($path);
+       if ($gpath eq '') {
+               my ($ls, $ctx) = command_output_pipe(qw/ls-tree
+                                                    -r --name-only -z/,
+                                                    $self->{c});
+               local $/ = "\0";
+               while (<$ls>) {
+                       chomp;
+                       $self->{gii}->remove($_);
+                       print "\tD\t$_\n" unless $::_q;
+               }
+               command_close_pipe($ls, $ctx);
+               $self->{empty}->{$path} = 0;
+       }
        my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#);
        delete $self->{empty}->{$dir};
        $self->{empty}->{$path} = 1;
@@ -3863,6 +3925,13 @@ sub gs_fetch_loop_common {
                                $ra_invalid = undef;
                        }
                }
+               # pre-fill the .rev_db since it'll eventually get filled in
+               # with '0' x40 if something new gets committed
+               foreach my $gs (@$gsv) {
+                       next if $gs->rev_map_max >= $max;
+                       next if defined $gs->rev_map_get($max);
+                       $gs->rev_map_set($max, 0 x40);
+               }
                foreach my $g (@$globs) {
                        my $k = "svn-remote.$g->{remote}.$g->{t}-maxRev";
                        Git::SVN::tmp_config($k, $max);
@@ -4037,39 +4106,7 @@ sub cmt_showable {
 }
 
 sub log_use_color {
-       return 1 if $color;
-       my ($dc, $dcvar);
-       $dcvar = 'color.diff';
-       $dc = `git-config --get $dcvar`;
-       if ($dc eq '') {
-               # nothing at all; fallback to "diff.color"
-               $dcvar = 'diff.color';
-               $dc = `git-config --get $dcvar`;
-       }
-       chomp($dc);
-       if ($dc eq 'auto') {
-               my $pc;
-               $pc = `git-config --get color.pager`;
-               if ($pc eq '') {
-                       # does not have it -- fallback to pager.color
-                       $pc = `git-config --bool --get pager.color`;
-               }
-               else {
-                       $pc = `git-config --bool --get color.pager`;
-                       if ($?) {
-                               $pc = 'false';
-                       }
-               }
-               chomp($pc);
-               if (-t *STDOUT || (defined $pager && $pc eq 'true')) {
-                       return ($ENV{TERM} && $ENV{TERM} ne 'dumb');
-               }
-               return 0;
-       }
-       return 0 if $dc eq 'never';
-       return 1 if $dc eq 'always';
-       chomp($dc = `git-config --bool --get $dcvar`);
-       return ($dc eq 'true');
+       return $color || Git->repository->get_colorbool('color.diff');
 }
 
 sub git_svn_log_cmd {
@@ -4128,6 +4165,7 @@ sub config_pager {
        } elsif (length $pager == 0 || $pager eq 'cat') {
                $pager = undef;
        }
+       $ENV{GIT_PAGER_IN_USE} = defined($pager);
 }
 
 sub run_pager {