X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-svn.perl;h=ad01e182df8abbeac7efa3db0d84d55ab1563e40;hb=8b75d31c945c9361331db8cd554f25a8ea6abc4a;hp=5702b100f17d32c4d370d2b29374390ad0f03520;hpb=4deca329f5da1552c8d087975dd5107519cabef7;p=git.git diff --git a/git-svn.perl b/git-svn.perl index 5702b100f..ad01e182d 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -223,11 +223,13 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) { "but it is not a directory\n"; } my $git_dir = delete $ENV{GIT_DIR}; - chomp(my $cdup = command_oneline(qw/rev-parse --show-cdup/)); - unless (length $cdup) { - die "Already at toplevel, but $git_dir ", - "not found '$cdup'\n"; - } + my $cdup = undef; + git_cmd_try { + $cdup = command_oneline(qw/rev-parse --show-cdup/); + $git_dir = '.' unless ($cdup); + chomp $cdup if ($cdup); + $cdup = "." unless ($cdup && length $cdup); + } "Already at toplevel, but $git_dir not found\n"; chdir $cdup or die "Unable to chdir up to '$cdup'\n"; unless (-d $git_dir) { die "$git_dir still not found after going to ", @@ -556,7 +558,7 @@ sub cmd_branch { my ($src, $rev, undef, $gs) = working_head_info($head); - my $remote = Git::SVN::read_all_remotes()->{svn}; + my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}}; my $glob = $remote->{ $_tag ? 'tags' : 'branches' }; my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/}; my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ()); @@ -852,7 +854,7 @@ sub escape_uri_only { my ($uri) = @_; my @tmp; foreach (split m{/}, $uri) { - s/([^\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg; + s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg; push @tmp, $_; } join('/', @tmp); @@ -1136,9 +1138,19 @@ sub get_commit_entry { system($editor, $commit_editmsg); } rename $commit_editmsg, $commit_msg or croak $!; - open $log_fh, '<', $commit_msg or croak $!; - { local $/; chomp($log_entry{log} = <$log_fh>); } - close $log_fh or croak $!; + { + # SVN requires messages to be UTF-8 when entering the repo + local $/; + open $log_fh, '<', $commit_msg or croak $!; + binmode $log_fh; + chomp($log_entry{log} = <$log_fh>); + + if (my $enc = Git::config('i18n.commitencoding')) { + require Encode; + Encode::from_to($log_entry{log}, $enc, 'UTF-8'); + } + close $log_fh or croak $!; + } unlink $commit_msg; \%log_entry; } @@ -2273,6 +2285,14 @@ sub do_git_commit { } defined(my $pid = open3(my $msg_fh, my $out_fh, '>&STDERR', @exec)) or croak $!; + binmode $msg_fh; + + # we always get UTF-8 from SVN, but we may want our commits in + # a different encoding. + if (my $enc = Git::config('i18n.commitencoding')) { + require Encode; + Encode::from_to($log_entry->{log}, 'UTF-8', $enc); + } print $msg_fh $log_entry->{log} or croak $!; restore_commit_header_env($old_env); unless ($self->no_metadata) { @@ -2383,12 +2403,20 @@ sub find_parent_branch { $gs = Git::SVN->init($u, $p, $repo_id, $ref_id, 1); } my ($r0, $parent) = $gs->find_rev_before($r, 1); - if (!defined $r0 || !defined $parent) { - my ($base, $head) = parse_revision_argument(0, $r); - if ($base <= $r) { + { + my ($base, $head); + if (!defined $r0 || !defined $parent) { + ($base, $head) = parse_revision_argument(0, $r); + } else { + if ($r0 < $r) { + $gs->ra->get_log([$gs->{path}], $r0 + 1, $r, 1, + 0, 1, sub { $base = $_[1] - 1 }); + } + } + if (defined $base && $base <= $r) { $gs->fetch($base, $r); } - ($r0, $parent) = $gs->last_rev_commit; + ($r0, $parent) = $gs->find_rev_before($r, 1); } if (defined $r0 && defined $parent) { print STDERR "Found branch parent: ($self->{ref_id}) $parent\n"; @@ -3312,11 +3340,11 @@ sub change_file_prop { sub apply_textdelta { my ($self, $fb, $exp) = @_; - my $fh = Git::temp_acquire('svn_delta'); + my $fh = $::_repository->temp_acquire('svn_delta'); # $fh gets auto-closed() by SVN::TxDelta::apply(), # (but $base does not,) so dup() it for reading in close_file open my $dup, '<&', $fh or croak $!; - my $base = Git::temp_acquire('git_blob'); + my $base = $::_repository->temp_acquire('git_blob'); if ($fb->{blob}) { print $base 'link ' if ($fb->{mode_a} == 120000); my $size = $::_repository->cat_blob($fb->{blob}, $base); @@ -3357,7 +3385,8 @@ sub close_file { warn "$path has mode 120000", " but is not a link\n"; } else { - my $tmp_fh = Git::temp_acquire('svn_hash'); + my $tmp_fh = $::_repository->temp_acquire( + 'svn_hash'); my $res; while ($res = sysread($fh, my $str, 1024)) { my $out = syswrite($tmp_fh, $str, $res); @@ -3537,7 +3566,7 @@ sub repo_path { sub url_path { my ($self, $path) = @_; if ($self->{url} =~ m#^https?://#) { - $path =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; + $path =~ s/([^~a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; } $self->{url} . '/' . $self->repo_path($path); } @@ -3745,7 +3774,7 @@ sub change_file_prop { sub _chg_file_get_blob ($$$$) { my ($self, $fbat, $m, $which) = @_; - my $fh = Git::temp_acquire("git_blob_$which"); + my $fh = $::_repository->temp_acquire("git_blob_$which"); if ($m->{"mode_$which"} =~ /^120/) { print $fh 'link ' or croak $!; $self->change_file_prop($fbat,'svn:special','*'); @@ -3890,7 +3919,7 @@ sub escape_uri_only { my ($uri) = @_; my @tmp; foreach (split m{/}, $uri) { - s/([^\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg; + s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg; push @tmp, $_; } join('/', @tmp); @@ -4986,8 +5015,7 @@ sub minimize_connections { } } if (@emptied) { - my $file = $ENV{GIT_CONFIG} || $ENV{GIT_CONFIG_LOCAL} || - "$ENV{GIT_DIR}/config"; + my $file = $ENV{GIT_CONFIG} || "$ENV{GIT_DIR}/config"; print STDERR <