git-svn: support manually placed initial trees from fetch
[gitweb.git] / contrib / git-svn / git-svn.perl
index c91160d37f08a1c57448187e04c7c9edbab078c8..54f3d6312eadce9ae5fc59139ccd7e728c479025 100755 (executable)
@@ -262,7 +262,14 @@ sub fetch {
        } else {
                chdir $SVN_WC or croak $!;
                read_uuid();
-               $last_commit = file_to_s("$REV_DIR/$base->{revision}");
+               eval { $last_commit = file_to_s("$REV_DIR/$base->{revision}") };
+               # looks like a user manually cp'd and svn switch'ed
+               unless ($last_commit) {
+                       sys(qw/svn revert -R ./);
+                       assert_svn_wc_clean($base->{revision});
+                       $last_commit = git_commit($base, @parents);
+                       assert_tree($last_commit);
+               }
        }
        my @svn_up = qw(svn up);
        push @svn_up, '--ignore-externals' unless $_no_ignore_ext;
@@ -1220,23 +1227,30 @@ sub check_upgrade_needed {
 # fills %tree_map with a reverse mapping of trees to commits.  Useful
 # for finding parents to commit on.
 sub map_tree_joins {
+       my %seen;
        foreach my $br (@_branch_from) {
                my $pid = open my $pipe, '-|';
                defined $pid or croak $!;
                if ($pid == 0) {
-                       exec(qw(git-rev-list --pretty=raw), $br) or croak $?;
+                       exec(qw(git-rev-list --topo-order --pretty=raw), $br)
+                                                               or croak $?;
                }
                while (<$pipe>) {
                        if (/^commit ($sha1)$/o) {
                                my $commit = $1;
+
+                               # if we've seen a commit,
+                               # we've seen its parents
+                               last if $seen{$commit};
                                my ($tree) = (<$pipe> =~ /^tree ($sha1)$/o);
                                unless (defined $tree) {
                                        die "Failed to parse commit $commit\n";
                                }
                                push @{$tree_map{$tree}}, $commit;
+                               $seen{$commit} = 1;
                        }
                }
-               close $pipe or croak $?;
+               close $pipe; # we could be breaking the pipe early
        }
 }