X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-svn.perl;h=b28c5bbc7238120d1d98445f1bf0f116dd7a0b8a;hb=9d0524d42f340fc49f9e175d966afb7dce3854bb;hp=4288a05c166b0b75bba387c099daa8622fea487a;hpb=6f38e0372266b5d674972e7039f8bd4156589558;p=git.git diff --git a/git-svn.perl b/git-svn.perl index 4288a05c1..b28c5bbc7 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -69,7 +69,7 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, $_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit, $_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m, $_merge, $_strategy, $_dry_run, $_ignore_nodate, $_non_recursive, - $_username, $_config_dir, $_no_auth_cache, $_xfer_delta, + $_username, $_config_dir, $_no_auth_cache, $_pager, $_color); my (@_branch_from, %tree_map, %users, %rusers, %equiv); my ($_svn_can_do_switch); @@ -216,7 +216,7 @@ information. } sub version { - print "git-svn version $VERSION\n"; + print "git-svn version $VERSION (svn $SVN::Core::VERSION)\n"; exit 0; } @@ -512,15 +512,15 @@ sub dcommit { } return if $_dry_run; fetch(); - my @diff = command('diff-tree', $head, $gs, '--'); + my @diff = command('diff-tree', 'HEAD', $gs, '--'); my @finish; if (@diff) { @finish = qw/rebase/; push @finish, qw/--merge/ if $_merge; push @finish, "--strategy=$_strategy" if $_strategy; - print STDERR "W: $head and $gs differ, using @finish:\n", @diff; + print STDERR "W: HEAD and $gs differ, using @finish:\n", @diff; } else { - print "No changes between current $head and $gs\n", + print "No changes between current HEAD and $gs\n", "Resetting to the latest $gs\n"; @finish = qw/reset --mixed/; } @@ -1098,7 +1098,8 @@ sub read_uuid { sub verify_ref { my ($ref) = @_; - eval { command_oneline([ 'rev-parse', $ref ], { STDERR => 0 }) }; + eval { command_oneline([ 'rev-parse', '--verify', $ref ], + { STDERR => 0 }); }; } sub repo_path_split { @@ -2044,13 +2045,6 @@ sub libsvn_connect { config => $config, pool => SVN::Pool->new, auth_provider_callbacks => $callbacks); - - my $df = $ENV{GIT_SVN_DELTA_FETCH}; - if (defined $df) { - $_xfer_delta = $df; - } else { - $_xfer_delta = ($url =~ m#^file://#) ? undef : 1; - } $ra->{svn_path} = $url; $ra->{repos_root} = $ra->get_repos_root; $ra->{svn_path} =~ s#^\Q$ra->{repos_root}\E/*##; @@ -2082,49 +2076,6 @@ sub libsvn_dup_ra { auth auth_provider_callbacks repos_root svn_path/); } -sub libsvn_get_file { - my ($gui, $f, $rev, $chg, $untracked) = @_; - $f =~ s#^/##; - print "\t$chg\t$f\n" unless $_q; - - my ($hash, $pid, $in, $out); - my $pool = SVN::Pool->new; - defined($pid = open3($in, $out, '>&STDERR', - qw/git-hash-object -w --stdin/)) or croak $!; - # redirect STDOUT for SVN 1.1.x compatibility - open my $stdout, '>&', \*STDOUT or croak $!; - open STDOUT, '>&', $in or croak $!; - my ($r, $props) = $SVN->get_file($f, $rev, \*STDOUT, $pool); - $in->flush == 0 or croak $!; - open STDOUT, '>&', $stdout or croak $!; - close $in or croak $!; - close $stdout or croak $!; - $pool->clear; - chomp($hash = do { local $/; <$out> }); - close $out or croak $!; - waitpid $pid, 0; - $hash =~ /^$sha1$/o or die "not a sha1: $hash\n"; - - my $mode = exists $props->{'svn:executable'} ? '100755' : '100644'; - if (exists $props->{'svn:special'}) { - $mode = '120000'; - my $link = `git-cat-file blob $hash`; # no chomping symlinks - $link =~ s/^link // or die "svn:special file with contents: <", - $link, "> is not understood\n"; - defined($pid = open3($in, $out, '>&STDERR', - qw/git-hash-object -w --stdin/)) or croak $!; - print $in $link; - $in->flush == 0 or croak $!; - close $in or croak $!; - chomp($hash = do { local $/; <$out> }); - close $out or croak $!; - waitpid $pid, 0; - $hash =~ /^$sha1$/o or die "not a sha1: $hash\n"; - } - %{$untracked->{file_prop}->{$f}} = %$props; - print $gui $mode,' ',$hash,"\t",$f,"\0" or croak $!; -} - sub uri_encode { my ($f) = @_; $f =~ s#([^a-zA-Z0-9\*!\:_\./\-])#uc sprintf("%%%02x",ord($1))#eg; @@ -2232,10 +2183,6 @@ sub process_rm { } sub libsvn_fetch { - $_xfer_delta ? libsvn_fetch_delta(@_) : libsvn_fetch_full(@_); -} - -sub libsvn_fetch_delta { my ($last_commit, $paths, $rev, $author, $date, $msg) = @_; my $pool = SVN::Pool->new; my $ed = SVN::Git::Fetcher->new({ c => $last_commit, q => $_q }); @@ -2251,66 +2198,6 @@ sub libsvn_fetch_delta { libsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ed); } -sub libsvn_fetch_full { - my ($last_commit, $paths, $rev, $author, $date, $msg) = @_; - my ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/); - my %amr; - my $ut = { empty => {}, dir_prop => {}, file_prop => {} }; - my $p = $SVN->{svn_path}; - foreach my $f (keys %$paths) { - my $m = $paths->{$f}->action(); - if (length $p) { - $f =~ s#^/\Q$p\E/##; - next if $f =~ m#^/#; - } else { - $f =~ s#^/##; - } - if ($m =~ /^[DR]$/) { - my $t = process_rm($gui, $last_commit, $f, $_q); - if ($m eq 'D') { - $ut->{empty}->{$f} = 0 if $t == $SVN::Node::dir; - next; - } - # 'R' can be file replacements, too, right? - } - my $pool = SVN::Pool->new; - my $t = $SVN->check_path($f, $rev, $pool); - if ($t == $SVN::Node::file) { - if ($m =~ /^[AMR]$/) { - $amr{$f} = $m; - } else { - die "Unrecognized action: $m, ($f r$rev)\n"; - } - } elsif ($t == $SVN::Node::dir && $m =~ /^[AR]$/) { - my @traversed = (); - libsvn_traverse($gui, '', $f, $rev, \@traversed, $ut); - if (@traversed) { - foreach (@traversed) { - $amr{$_} = $m; - } - } else { - my ($dir, $file) = ($f =~ m#^(.*?)/?([^/]+)$#); - delete $ut->{empty}->{$dir}; - $ut->{empty}->{$f} = 1; - } - } - $pool->clear; - } - foreach (keys %amr) { - libsvn_get_file($gui, $_, $rev, $amr{$_}, $ut); - my ($d) = ($_ =~ m#^(.*?)/?(?:[^/]+)$#); - delete $ut->{empty}->{$d}; - } - unless (exists $ut->{dir_prop}->{''}) { - my $pool = SVN::Pool->new; - my (undef, undef, $props) = $SVN->get_dir('', $rev, $pool); - %{$ut->{dir_prop}->{''}} = %$props; - $pool->clear; - } - command_close_pipe($gui, $ctx); - libsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ut); -} - sub svn_grab_base_rev { my $c = eval { command_oneline([qw/rev-parse --verify/, "refs/remotes/$GIT_SVN^0"], @@ -2362,41 +2249,6 @@ sub libsvn_parse_revision { "Try using the command-line svn client instead\n"; } -sub libsvn_traverse { - my ($gui, $pfx, $path, $rev, $files, $untracked) = @_; - my $cwd = length $pfx ? "$pfx/$path" : $path; - my $pool = SVN::Pool->new; - $cwd =~ s#^\Q$SVN->{svn_path}\E##; - my $nr = 0; - my ($dirent, $r, $props) = $SVN->get_dir($cwd, $rev, $pool); - %{$untracked->{dir_prop}->{$cwd}} = %$props; - foreach my $d (keys %$dirent) { - my $t = $dirent->{$d}->kind; - if ($t == $SVN::Node::dir) { - my $i = libsvn_traverse($gui, $cwd, $d, $rev, - $files, $untracked); - if ($i) { - $nr += $i; - } else { - $untracked->{empty}->{"$cwd/$d"} = 1; - } - } elsif ($t == $SVN::Node::file) { - $nr++; - my $file = "$cwd/$d"; - if (defined $files) { - push @$files, $file; - } else { - libsvn_get_file($gui, $file, $rev, 'A', - $untracked); - my ($dir) = ($file =~ m#^(.*?)/?(?:[^/]+)$#); - delete $untracked->{empty}->{$dir}; - } - } - } - $pool->clear; - $nr; -} - sub libsvn_traverse_ignore { my ($fh, $path, $r) = @_; $path =~ s#^/+##g; @@ -2488,8 +2340,8 @@ sub libsvn_find_parent_branch { print STDERR "Found branch parent: ($GIT_SVN) $parent\n"; command_noisy('read-tree', $parent); unless (libsvn_can_do_switch()) { - return libsvn_fetch_full($parent, $paths, $rev, - $author, $date, $msg); + return _libsvn_new_tree($paths, $rev, $author, $date, + $msg, [$parent]); } # do_switch works with svn/trunk >= r22312, but that is not # included with SVN 1.4.2 (the latest version at the moment), @@ -2514,7 +2366,7 @@ sub libsvn_find_parent_branch { sub libsvn_get_log { my ($ra, @args) = @_; - $args[4]-- if $args[4] && $_xfer_delta && ! $_follow_parent; + $args[4]-- if $args[4] && ! $_follow_parent; if ($SVN::Core::VERSION le '1.2.0') { splice(@args, 3, 1); } @@ -2525,28 +2377,23 @@ sub libsvn_new_tree { if (my $log_entry = libsvn_find_parent_branch(@_)) { return $log_entry; } - my ($paths, $rev, $author, $date, $msg) = @_; - my $ut; - if ($_xfer_delta) { - my $pool = SVN::Pool->new; - my $ed = SVN::Git::Fetcher->new({q => $_q}); - my $reporter = $SVN->do_update($rev, '', 1, $ed, $pool); - my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : (); - $reporter->set_path('', $rev, 1, @lock, $pool); - $reporter->finish_report($pool); - $pool->clear; - unless ($ed->{git_commit_ok}) { - die "SVN connection failed somewhere...\n"; - } - $ut = $ed; - } else { - $ut = { empty => {}, dir_prop => {}, file_prop => {} }; - my ($gui, $ctx) = command_input_pipe(qw/update-index - -z --index-info/); - libsvn_traverse($gui, '', $SVN->{svn_path}, $rev, undef, $ut); - command_close_pipe($gui, $ctx); + my ($paths, $rev, $author, $date, $msg) = @_; # $pool is last + _libsvn_new_tree($paths, $rev, $author, $date, $msg, []); +} + +sub _libsvn_new_tree { + my ($paths, $rev, $author, $date, $msg, $parents) = @_; + my $pool = SVN::Pool->new; + my $ed = SVN::Git::Fetcher->new({q => $_q}); + my $reporter = $SVN->do_update($rev, '', 1, $ed, $pool); + my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : (); + $reporter->set_path('', $rev, 1, @lock, $pool); + $reporter->finish_report($pool); + $pool->clear; + unless ($ed->{git_commit_ok}) { + die "SVN connection failed somewhere...\n"; } - libsvn_log_entry($rev, $author, $date, $msg, [], $ut); + libsvn_log_entry($rev, $author, $date, $msg, $parents, $ed); } sub find_graft_path_commit { @@ -2634,7 +2481,7 @@ sub libsvn_ls_fullurl { my $pool = SVN::Pool->new; my $r = defined $_revision ? $_revision : $ra->get_latest_revnum; my ($dirent, undef, undef) = $ra->get_dir('', $r, $pool); - foreach my $d (keys %$dirent) { + foreach my $d (sort keys %$dirent) { if ($dirent->{$d}->kind == $SVN::Node::dir) { push @ret, "$d/"; # add '/' for compat with cli svn }