X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-svn.perl;h=b311c3d030caa6ae2888730383cf40e7b549af95;hb=5a990e45f920b50aa6b81823120223fb50f56d97;hp=4530ffe42c66713f1dc9e79b3ad62124338405de;hpb=868227b0d1f3a295ea9afe7a3be3a1fbdff62442;p=git.git diff --git a/git-svn.perl b/git-svn.perl index 4530ffe42..b311c3d03 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -31,6 +31,7 @@ use File::Basename qw/dirname basename/; use File::Path qw/mkpath/; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev pass_through/; use File::Spec qw//; +use File::Copy qw/copy/; use POSIX qw/strftime/; use IPC::Open3; use Memoize; @@ -77,9 +78,6 @@ my %cmt_opts = ( 'edit|e' => \$_edit, 'copy-similarity|C=i'=> \$_cp_similarity ); -# yes, 'native' sets "\n". Patches to fix this for non-*nix systems welcome: -my %EOL = ( CR => "\015", LF => "\012", CRLF => "\015\012", native => "\012" ); - my %cmd = ( fetch => [ \&fetch, "Download new revisions from SVN", { 'revision|r=s' => \$_revision, %fc_opts } ], @@ -147,7 +145,7 @@ init_vars(); load_authors() if $_authors; load_all_refs() if $_branch_all_refs; svn_compat_check() unless $_use_lib; -migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init)$/; +migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init|commit-diff)$/; $cmd{$cmd}->[0]->(@ARGV); exit 0; @@ -502,6 +500,8 @@ sub commit_lib { my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : (); my $commit_msg = "$GIT_SVN_DIR/.svn-commit.tmp.$$"; + my $repo; + ($repo, $SVN_PATH) = repo_path_split($SVN_URL); set_svn_commit_env(); foreach my $c (@revs) { my $log_msg = get_commit_message($c, $commit_msg); @@ -510,6 +510,8 @@ sub commit_lib { # can't track down... (it's probably in the SVN code) defined(my $pid = open my $fh, '-|') or croak $!; if (!$pid) { + $SVN_LOG = libsvn_connect($repo); + $SVN = libsvn_connect($repo); my $ed = SVN::Git::Editor->new( { r => $r_last, ra => $SVN, @@ -1160,27 +1162,24 @@ sub repo_path_split { } } - my ($url, $path) = ($full_url =~ m!^([a-z\+]+://[^/]*)(.*)$!i); - $path =~ s#^/+##; - my @paths = split(m#/+#, $path); - if ($_use_lib) { - while (1) { - $SVN = libsvn_connect($url); - last if (defined $SVN && - defined eval { $SVN->get_latest_revnum }); - my $n = shift @paths || last; - $url .= "/$n"; - } + my $tmp = libsvn_connect($full_url); + my $url = $tmp->get_repos_root; + $full_url =~ s#^\Q$url\E/*##; + push @repo_path_split_cache, qr/^(\Q$url\E)/; + return ($url, $full_url); } else { + my ($url, $path) = ($full_url =~ m!^([a-z\+]+://[^/]*)(.*)$!i); + $path =~ s#^/+##; + my @paths = split(m#/+#, $path); while (quiet_run(qw/svn ls --non-interactive/, $url)) { my $n = shift @paths || last; $url .= "/$n"; } + push @repo_path_split_cache, qr/^(\Q$url\E)/; + $path = join('/',@paths); + return ($url, $path); } - push @repo_path_split_cache, qr/^(\Q$url\E)/; - $path = join('/',@paths); - return ($url, $path); } sub setup_git_svn { @@ -1760,43 +1759,6 @@ sub svn_info { sub sys { system(@_) == 0 or croak $? } -sub eol_cp { - my ($from, $to) = @_; - my $es = svn_propget_base('svn:eol-style', $to); - open my $rfd, '<', $from or croak $!; - binmode $rfd or croak $!; - open my $wfd, '>', $to or croak $!; - binmode $wfd or croak $!; - eol_cp_fd($rfd, $wfd, $es); - close $rfd or croak $!; - close $wfd or croak $!; -} - -sub eol_cp_fd { - my ($rfd, $wfd, $es) = @_; - my $eol = defined $es ? $EOL{$es} : undef; - my $buf; - use bytes; - while (1) { - my ($r, $w, $t); - defined($r = sysread($rfd, $buf, 4096)) or croak $!; - return unless $r; - if ($eol) { - if ($buf =~ /\015$/) { - my $c; - defined($r = sysread($rfd,$c,1)) or croak $!; - $buf .= $c if $r > 0; - } - $buf =~ s/(?:\015\012|\015|\012)/$eol/gs; - $r = length($buf); - } - for ($w = 0; $w < $r; $w += $t) { - $t = syswrite($wfd, $buf, $r - $w, $w) or croak $!; - } - } - no bytes; -} - sub do_update_index { my ($z_cmd, $cmd, $no_text_base) = @_; @@ -1824,9 +1786,11 @@ sub do_update_index { 'text-base',"$f.svn-base"); $tb =~ s#^/##; } + my @s = stat($x); unlink $x or croak $!; - eol_cp($tb, $x); + copy($tb, $x); chmod(($mode &~ umask), $x) or croak $!; + utime $s[8], $s[9], $x; } print $ui $x,"\0"; } @@ -2617,7 +2581,9 @@ sub libsvn_connect { sub libsvn_get_file { my ($gui, $f, $rev) = @_; my $p = $f; - return unless ($p =~ s#^\Q$SVN_PATH\E/##); + if (length $SVN_PATH > 0) { + return unless ($p =~ s#^\Q$SVN_PATH\E/##); + } my ($hash, $pid, $in, $out); my $pool = SVN::Pool->new; @@ -2664,6 +2630,7 @@ sub libsvn_log_entry { if (defined $_authors && ! defined $users{$author}) { die "Author: $author not defined in $_authors file\n"; } + $msg = '' if ($rev == 0 && !defined $msg); return { revision => $rev, date => "+0000 $Y-$m-$d $H:$M:$S", author => $author, msg => $msg."\n", parents => $parents || [] } } @@ -2709,6 +2676,12 @@ sub libsvn_fetch { } else { die "Unrecognized action: $m, ($f r$rev)\n"; } + } elsif ($t == $SVN::Node::dir && $m =~ /^[AR]$/) { + my @traversed = (); + libsvn_traverse($gui, '', $f, $rev, \@traversed); + foreach (@traversed) { + push @amr, [ $m, $_ ] + } } $pool->clear; } @@ -2778,7 +2751,7 @@ sub libsvn_parse_revision { } sub libsvn_traverse { - my ($gui, $pfx, $path, $rev) = @_; + my ($gui, $pfx, $path, $rev, $files) = @_; my $cwd = "$pfx/$path"; my $pool = SVN::Pool->new; $cwd =~ s#^/+##g; @@ -2786,10 +2759,15 @@ sub libsvn_traverse { foreach my $d (keys %$dirent) { my $t = $dirent->{$d}->kind; if ($t == $SVN::Node::dir) { - libsvn_traverse($gui, $cwd, $d, $rev); + libsvn_traverse($gui, $cwd, $d, $rev, $files); } elsif ($t == $SVN::Node::file) { - print "\tA\t$cwd/$d\n" unless $_q; - libsvn_get_file($gui, "$cwd/$d", $rev); + my $file = "$cwd/$d"; + if (defined $files) { + push @$files, $file; + } else { + print "\tA\t$file\n" unless $_q; + libsvn_get_file($gui, $file, $rev); + } } } $pool->clear; @@ -2913,9 +2891,7 @@ sub libsvn_new_tree { } my ($paths, $rev, $author, $date, $msg) = @_; open my $gui, '| git-update-index -z --index-info' or croak $!; - my $pool = SVN::Pool->new; - libsvn_traverse($gui, '', $SVN_PATH, $rev, $pool); - $pool->clear; + libsvn_traverse($gui, '', $SVN_PATH, $rev); close $gui or croak $?; return libsvn_log_entry($rev, $author, $date, $msg); }