test format-patch -s: make sure MIME content type is shown as needed
[gitweb.git] / git-svn.perl
index d3c8cd0b8e3cfb97c6deb2453097c6f2e16e3bcf..ec25ea4231a062e05753f4f93a757a41062a0364 100755 (executable)
@@ -390,7 +390,8 @@ sub cmd_dcommit {
                     "If these changes depend on each other, re-running ",
                     "without --no-rebase will be required."
        }
-       foreach my $d (@$linear_refs) {
+       while (1) {
+               my $d = shift @$linear_refs or last;
                unless (defined $last_rev) {
                        (undef, $last_rev, undef) = cmt_metadata("$d~1");
                        unless (defined $last_rev) {
@@ -423,14 +424,14 @@ sub cmd_dcommit {
 
                        # we always want to rebase against the current HEAD,
                        # not any head that was passed to us
-                       my @diff = command('diff-tree', 'HEAD',
+                       my @diff = command('diff-tree', $d,
                                           $gs->refname, '--');
                        my @finish;
                        if (@diff) {
                                @finish = rebase_cmd();
-                               print STDERR "W: HEAD and ", $gs->refname,
+                               print STDERR "W: $d and ", $gs->refname,
                                             " differ, using @finish:\n",
-                                            "@diff";
+                                            join("\n", @diff), "\n";
                        } else {
                                print "No changes between current HEAD and ",
                                      $gs->refname,
@@ -439,6 +440,45 @@ sub cmd_dcommit {
                                @finish = qw/reset --mixed/;
                        }
                        command_noisy(@finish, $gs->refname);
+                       if (@diff) {
+                               @refs = ();
+                               my ($url_, $rev_, $uuid_, $gs_) =
+                                             working_head_info($head, \@refs);
+                               my ($linear_refs_, $parents_) =
+                                             linearize_history($gs_, \@refs);
+                               if (scalar(@$linear_refs) !=
+                                   scalar(@$linear_refs_)) {
+                                       fatal "# of revisions changed ",
+                                         "\nbefore:\n",
+                                         join("\n", @$linear_refs),
+                                         "\n\nafter:\n",
+                                         join("\n", @$linear_refs_), "\n",
+                                         'If you are attempting to commit ',
+                                         "merges, try running:\n\t",
+                                         'git rebase --interactive',
+                                         '--preserve-merges ',
+                                         $gs->refname,
+                                         "\nBefore dcommitting";
+                               }
+                               if ($url_ ne $url) {
+                                       fatal "URL mismatch after rebase: ",
+                                             "$url_ != $url";
+                               }
+                               if ($uuid_ ne $uuid) {
+                                       fatal "uuid mismatch after rebase: ",
+                                             "$uuid_ != $uuid";
+                               }
+                               # remap parents
+                               my (%p, @l, $i);
+                               for ($i = 0; $i < scalar @$linear_refs; $i++) {
+                                       my $new = $linear_refs_->[$i] or next;
+                                       $p{$new} =
+                                               $parents->{$linear_refs->[$i]};
+                                       push @l, $new;
+                               }
+                               $parents = \%p;
+                               $linear_refs = \@l;
+                       }
                        $last_rev = $cmt_rev;
                }
        }
@@ -841,14 +881,9 @@ sub working_head_info {
 
 sub read_commit_parents {
        my ($parents, $c) = @_;
-       my ($fh, $ctx) = command_output_pipe(qw/cat-file commit/, $c);
-       while (<$fh>) {
-               chomp;
-               last if '';
-               /^parent ($sha1)/ or next;
-               push @{$parents->{$c}}, $1;
-       }
-       close $fh; # break the pipe
+       chomp(my $p = command_oneline(qw/rev-list --parents -1/, $c));
+       $p =~ s/^($c)\s*// or die "rev-list --parents -1 $c failed!\n";
+       @{$parents->{$c}} = split(/ /, $p);
 }
 
 sub linearize_history {
@@ -3013,7 +3048,7 @@ package Git::SVN::Ra;
 use vars qw/@ISA $config_dir $_log_window_size/;
 use strict;
 use warnings;
-my ($can_do_switch, %ignored_err, $RA);
+my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
 
 BEGIN {
        # enforce temporary pool usage for some simple functions
@@ -3174,7 +3209,11 @@ sub gs_do_switch {
                        $self->{url} = $full_url;
                        $reparented = 1;
                } else {
+                       $_[0] = undef;
+                       $self = undef;
+                       $RA = undef;
                        $ra = Git::SVN::Ra->new($full_url);
+                       $ra_invalid = 1;
                }
        }
        $ra ||= $self;
@@ -3234,6 +3273,7 @@ sub gs_fetch_loop_common {
        my $inc = $_log_window_size;
        my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
        my $longest_path = longest_common_path($gsv, $globs);
+       my $ra_url = $self->{url};
        while (1) {
                my %revs;
                my $err;
@@ -3295,6 +3335,13 @@ sub gs_fetch_loop_common {
                                        "$g->{t}-maxRev";
                                Git::SVN::tmp_config($k, $r);
                        }
+                       if ($ra_invalid) {
+                               $_[0] = undef;
+                               $self = undef;
+                               $RA = undef;
+                               $self = Git::SVN::Ra->new($ra_url);
+                               $ra_invalid = undef;
+                       }
                }
                # pre-fill the .rev_db since it'll eventually get filled in
                # with '0' x40 if something new gets committed
@@ -3569,7 +3616,7 @@ sub config_pager {
 }
 
 sub run_pager {
-       return unless -t *STDOUT;
+       return unless -t *STDOUT && defined $pager;
        pipe my $rfd, my $wfd or return;
        defined(my $pid = fork) or ::fatal "Can't fork: $!\n";
        if (!$pid) {