* Florian Weimer: >> It's been too long since I've looked at the SVN TxDelta API, but I >> thought SVN::TxDelta::apply would take care of the delta computation for >> us... > > SVN::Git::Editor::M does not seem to make use of the base text. Here's an attempt at delta generation. I don't know if it is entirely correct, but it does work in the sense that it passes "make test" and the test cases I reported eariler. Sorry for the format. Has anybody got some Emacs code to submit diffs using Gnus? commit c94c8b36b41bac20ebf952244675507d2fb927cb Author: Florian Weimer <fw@xxxxxxxxxxxxx> Date: Sun Aug 31 17:05:09 2008 +0200 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 <fw@xxxxxxxxxxxxx> diff --git a/git-svn.perl b/git-svn.perl index 7a1d26d..0479f41 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'; commit 020f941b8b606ed3dc2d323194ab11e019380b03 Author: Florian Weimer <fw@xxxxxxxxxxxxx> Date: Sun Aug 31 17:45:04 2008 +0200 git-svn: Introduce SVN::Git::Editor::_chg_file_get_blob Signed-off-by: Florian Weimer <fw@xxxxxxxxxxxxx> diff --git a/git-svn.perl b/git-svn.perl index 0479f41..2c3e13f 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); commit 846d32cbe8283ffdf4ad5ddb2905dfbc30eace27 Author: Florian Weimer <fw@xxxxxxxxxxxxx> Date: Sun Aug 31 17:47:09 2008 +0200 git-svn: Send deltas during commits Signed-off-by: Florian Weimer <fw@xxxxxxxxxxxxx> diff --git a/git-svn.perl b/git-svn.perl index 2c3e13f..fdf4e4a 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; } -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html