From 2d0c8accc3fa7de75d7cbe732873ce5a57379020 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Sun, 31 Aug 2008 17:05:09 +0200 Subject: git-svn: extract base blob in generate_diff We need the base blob to compute a delta to be sent to the server. Signed-off-by: Florian Weimer Acked-by: Eric Wong --- git-svn.perl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 7a1d26db8..0479f41b5 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3380,11 +3380,12 @@ sub generate_diff { while (<$diff_fh>) { chomp $_; # this gets rid of the trailing "\0" if ($state eq 'meta' && /^:(\d{6})\s(\d{6})\s - $::sha1\s($::sha1)\s + ($::sha1)\s($::sha1)\s ([MTCRAD])\d*$/xo) { push @mods, { mode_a => $1, mode_b => $2, - sha1_b => $3, chg => $4 }; - if ($4 =~ /^(?:C|R)$/) { + sha1_a => $3, sha1_b => $4, + chg => $5 }; + if ($5 =~ /^(?:C|R)$/) { $state = 'file_a'; } else { $state = 'file_b'; -- cgit v1.2.1 From 214a34d22ec59ec7e1166772f06ecf8799f96c96 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Sun, 31 Aug 2008 17:45:04 +0200 Subject: git-svn: Introduce SVN::Git::Editor::_chg_file_get_blob Signed-off-by: Florian Weimer Acked-by: Eric Wong --- git-svn.perl | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 0479f41b5..2c3e13f23 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3663,28 +3663,35 @@ sub change_file_prop { $self->SUPER::change_file_prop($fbat, $pname, $pval, $self->{pool}); } -sub chg_file { - my ($self, $fbat, $m) = @_; - if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) { - $self->change_file_prop($fbat,'svn:executable','*'); - } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) { - $self->change_file_prop($fbat,'svn:executable',undef); - } - my $fh = Git::temp_acquire('git_blob'); - if ($m->{mode_b} =~ /^120/) { +sub _chg_file_get_blob ($$$$) { + my ($self, $fbat, $m, $which) = @_; + my $fh = Git::temp_acquire("git_blob_$which"); + if ($m->{"mode_$which"} =~ /^120/) { print $fh 'link ' or croak $!; $self->change_file_prop($fbat,'svn:special','*'); - } elsif ($m->{mode_a} =~ /^120/ && $m->{mode_b} !~ /^120/) { + } elsif ($m->{mode_a} =~ /^120/ && $m->{"mode_$which"} !~ /^120/) { $self->change_file_prop($fbat,'svn:special',undef); } - my $size = $::_repository->cat_blob($m->{sha1_b}, $fh); - croak "Failed to read object $m->{sha1_b}" if ($size < 0); + my $blob = $m->{"sha1_$which"}; + return ($fh,) if ($blob =~ /^0{40}$/); + my $size = $::_repository->cat_blob($blob, $fh); + croak "Failed to read object $blob" if ($size < 0); $fh->flush == 0 or croak $!; seek $fh, 0, 0 or croak $!; my $exp = ::md5sum($fh); seek $fh, 0, 0 or croak $!; + return ($fh, $exp); +} +sub chg_file { + my ($self, $fbat, $m) = @_; + if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) { + $self->change_file_prop($fbat,'svn:executable','*'); + } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) { + $self->change_file_prop($fbat,'svn:executable',undef); + } + my ($fh, $exp) = _chg_file_get_blob $self, $fbat, $m, 'b'; my $pool = SVN::Pool->new; my $atd = $self->apply_textdelta($fbat, undef, $pool); my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool); -- cgit v1.2.1 From 8598db935b653c638109aecab3e345c45d53af07 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Sun, 31 Aug 2008 17:47:09 +0200 Subject: git-svn: Send deltas during commits Signed-off-by: Florian Weimer Acked-by: Eric Wong --- git-svn.perl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 2c3e13f23..fdf4e4a45 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3691,12 +3691,20 @@ sub chg_file { } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) { $self->change_file_prop($fbat,'svn:executable',undef); } - my ($fh, $exp) = _chg_file_get_blob $self, $fbat, $m, 'b'; + my ($fh_a, $exp_a) = _chg_file_get_blob $self, $fbat, $m, 'a'; + my ($fh_b, $exp_b) = _chg_file_get_blob $self, $fbat, $m, 'b'; my $pool = SVN::Pool->new; - my $atd = $self->apply_textdelta($fbat, undef, $pool); - my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool); - die "Checksum mismatch\nexpected: $exp\ngot: $got\n" if ($got ne $exp); - Git::temp_release($fh, 1); + my $atd = $self->apply_textdelta($fbat, $exp_a, $pool); + if (-s $fh_a) { + my $txstream = SVN::TxDelta::new ($fh_a, $fh_b, $pool); + SVN::TxDelta::send_txstream($txstream, @$atd, $pool); + } else { + my $got = SVN::TxDelta::send_stream($fh_b, @$atd, $pool); + die "Checksum mismatch\nexpected: $exp_b\ngot: $got\n" + if ($got ne $exp_b); + } + Git::temp_release($fh_b, 1); + Git::temp_release($fh_a, 1); $pool->clear; } -- cgit v1.2.1 From 991255c634500fe51a70aae6a8e7c8d7b73db0cc Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 31 Aug 2008 19:45:07 -0700 Subject: git-svn: check error code of send_txstream Not checking the error code of a function used to transform and send data makes me nervous. It currently returns "undef" on success; so die if we get any result other than "undef" because it's likely something went wrong somewhere. I really wish this function returned an MD5 like send_stream (or better yet, SHA1) for verification. Signed-off-by: Eric Wong --- git-svn.perl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index fdf4e4a45..2d355c183 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3697,7 +3697,11 @@ sub chg_file { my $atd = $self->apply_textdelta($fbat, $exp_a, $pool); if (-s $fh_a) { my $txstream = SVN::TxDelta::new ($fh_a, $fh_b, $pool); - SVN::TxDelta::send_txstream($txstream, @$atd, $pool); + my $res = SVN::TxDelta::send_txstream($txstream, @$atd, $pool); + if (defined $res) { + die "Unexpected result from send_txstream: $res\n", + "(SVN::Core::VERSION: $SVN::Core::VERSION)\n"; + } } else { my $got = SVN::TxDelta::send_stream($fh_b, @$atd, $pool); die "Checksum mismatch\nexpected: $exp_b\ngot: $got\n" -- cgit v1.2.1 From 2cb611054a9597a00e9387c77e75d82e78982e60 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sun, 31 Aug 2008 15:50:59 +0200 Subject: git svn: catch lack of upstream info for dcommit earlier Since 711521e 'git svn dcommit' attempts to use the upstream information to determine the SVN URL, before it verifies that it even found an upstream. Move up the corresponding check. Signed-off-by: Thomas Rast Acked-by: Eric Wong --- git-svn.perl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 2d355c183..484b4ab0d 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -421,15 +421,15 @@ sub cmd_dcommit { $head ||= 'HEAD'; my @refs; my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs); + unless ($gs) { + die "Unable to determine upstream SVN information from ", + "$head history.\nPerhaps the repository is empty."; + } $url = defined $_commit_url ? $_commit_url : $gs->full_url; my $last_rev = $_revision if defined $_revision; if ($url) { print "Committing to $url ...\n"; } - unless ($gs) { - die "Unable to determine upstream SVN information from ", - "$head history.\nPerhaps the repository is empty."; - } my ($linear_refs, $parents) = linearize_history($gs, \@refs); if ($_no_rebase && scalar(@$linear_refs) > 1) { warn "Attempting to commit more than one change while ", -- cgit v1.2.1 From edde9112abd1ef5f4565468e8a9a500e0c03f900 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Tue, 26 Aug 2008 21:32:36 +0200 Subject: git svn info: make info relative to the current directory Previously 'git svn info ' would always treat the as relative to the working directory root, with a default of ".". This does not match the behaviour of 'svn info'. Prepend $(git rev-parse --show-prefix) to the path used inside cmd_info to make it relative to the current working directory. Signed-off-by: Thomas Rast Acked-by: Eric Wong --- git-svn.perl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 484b4ab0d..5e61dd9c1 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -805,6 +805,7 @@ sub cmd_commit_diff { sub cmd_info { my $path = canonicalize_path(defined($_[0]) ? $_[0] : "."); + my $fullpath = canonicalize_path($cmd_dir_prefix . $path); if (exists $_[1]) { die "Too many arguments specified\n"; } @@ -825,7 +826,7 @@ sub cmd_info { # canonicalize_path() will return "" to make libsvn 1.5.x happy, $path = "." if $path eq ""; - my $full_url = $url . ($path eq "." ? "" : "/$path"); + my $full_url = $url . ($fullpath eq "" ? "" : "/$fullpath"); if ($_url) { print $full_url, "\n"; @@ -861,7 +862,7 @@ sub cmd_info { } my ($lc_author, $lc_rev, $lc_date_utc); - my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path); + my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $fullpath); my $log = command_output_pipe(@args); my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/; while (<$log>) { -- cgit v1.2.1 From 05427b91f0b5e45688cbea21faf0f2d79ec07b21 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Tue, 26 Aug 2008 21:32:37 +0200 Subject: git svn info: always quote URLs in 'info' output Changes 'git svn info' to always URL-escape the 'URL' and 'Repository' fields and --url output, like SVN (at least 1.5) does. Note that reusing the escape_url() further down in Git::SVN::Ra is not possible because it only triggers for http(s) URLs. I did not know whether extending it to all schemes would break SVN access anywhere, so I made a new one that quotes in all schemes. Signed-off-by: Thomas Rast Acked-by: Eric Wong --- git-svn.perl | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 5e61dd9c1..42d067981 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -803,6 +803,25 @@ sub cmd_commit_diff { } } +sub escape_uri_only { + my ($uri) = @_; + my @tmp; + foreach (split m{/}, $uri) { + s/([^\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg; + push @tmp, $_; + } + join('/', @tmp); +} + +sub escape_url { + my ($url) = @_; + if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) { + my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3)); + $url = "$scheme://$domain$uri"; + } + $url; +} + sub cmd_info { my $path = canonicalize_path(defined($_[0]) ? $_[0] : "."); my $fullpath = canonicalize_path($cmd_dir_prefix . $path); @@ -829,18 +848,18 @@ sub cmd_info { my $full_url = $url . ($fullpath eq "" ? "" : "/$fullpath"); if ($_url) { - print $full_url, "\n"; + print escape_url($full_url), "\n"; return; } my $result = "Path: $path\n"; $result .= "Name: " . basename($path) . "\n" if $file_type ne "dir"; - $result .= "URL: " . $full_url . "\n"; + $result .= "URL: " . escape_url($full_url) . "\n"; eval { my $repos_root = $gs->repos_root; Git::SVN::remove_username($repos_root); - $result .= "Repository Root: $repos_root\n"; + $result .= "Repository Root: " . escape_url($repos_root) . "\n"; }; if ($@) { $result .= "Repository Root: (offline)\n"; -- cgit v1.2.1 From 2cf3e3ac02c42cf0ba9299589db644beb395c4c5 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Fri, 29 Aug 2008 15:42:48 +0200 Subject: git-svn: match SVN 1.5 behaviour of info' on unknown item Previously 'git svn info unknown-file' only announced its failure (in the SVN 1.4 style, "not a versioned resource"), and exited successfully. It is desirable to actually exit with failure, so change the code to exit(1) under this condition. Since that is already halfway SVN 1.5 compatibility, also change the error output to match 1.5. Signed-off-by: Thomas Rast Acked-by: Eric Wong --- git-svn.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 42d067981..2cc64876b 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -832,8 +832,8 @@ sub cmd_info { my ($file_type, $diff_status) = find_file_type_and_diff_status($path); if (!$file_type && !$diff_status) { - print STDERR "$path: (Not a versioned resource)\n\n"; - return; + print STDERR "svn: '$path' is not under version control\n"; + exit 1; } my ($url, $rev, $uuid, $gs) = working_head_info('HEAD'); -- cgit v1.2.1 From 7c4d0219cf9ab6a7738a09ad7fec72d5e9f2ac67 Mon Sep 17 00:00:00 2001 From: Paul Talacko Date: Sat, 6 Sep 2008 18:50:38 -0700 Subject: git-svn: set auto_props when renaming files Patch-by: Paul Talacko : > Hello, > > There's an issue in git-svn as autoprops are not applied to > renamed files, only to added files. > > This patch fixes the bug. [ew: added test case] Signed-off-by: Eric Wong --- git-svn.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-svn.perl') diff --git a/git-svn.perl b/git-svn.perl index 2cc64876b..ee3f5edb6 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3657,6 +3657,7 @@ sub R { my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat, $self->url_path($m->{file_a}), $self->{r}); print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q; + $self->apply_autoprops($file, $fbat); $self->chg_file($fbat, $m); $self->close_file($fbat,undef,$self->{pool}); -- cgit v1.2.1