diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-01-11 16:51:11 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-01-18 15:38:28 -0800 |
commit | baf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e (patch) | |
tree | ca0b0c411bc9859e95649d15019f8588396935a5 /git-svn.perl | |
parent | dbc6c74d0858d77e61e092a48d467e725211f8e9 (diff) | |
download | git-baf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e.tar.gz git-baf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e.tar.xz |
git-svn: better attempt to handle broken symlink updates
This is a followup to 7fc35e0e94782bbbefb920875813519038659930,
(workaround a for broken symlinks in SVN).
Since broken SVN clients can commit svn:special files without
the magic "link " prefix, this can affect delta application
when we update the broken svn:special file. So now we fall
back and retry the delta application on symlinks if having
a "link " prefix fails.
Our behavior differs from svn(1) (v1.5.1) slightly:
When a svn:special file is created w/o a "link " prefix, svn
will create a regular file (mode 100644 to git) with the
contents of the blob as-is.
Our behavior is to continue creating the symlink (mode 120000
to git) with the contents of the blob as-is. While this
differs from current svn(1) behavior, this is easier and more
efficient to implement (and the correctness of the svn(1) is
debatable, since it's a workaround for a bug in the first
place).
More information on this SVN bug is described here:
http://subversion.tigris.org/issues/show_bug.cgi?id=2692
Signed-off-by: Eric Wong <normalperson@yhbt.net>
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-x | git-svn.perl | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/git-svn.perl b/git-svn.perl index 1b87a6529..b0e3d7c79 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3380,19 +3380,35 @@ sub apply_textdelta { open my $dup, '<&', $fh or croak $!; my $base = $::_repository->temp_acquire('git_blob'); if ($fb->{blob}) { + my ($base_is_link, $size); + if ($fb->{mode_a} eq '120000' && ! $self->{empty_symlinks}->{$fb->{path}}) { print $base 'link ' or die "print $!\n"; + $base_is_link = 1; } - my $size = $::_repository->cat_blob($fb->{blob}, $base); + retry: + $size = $::_repository->cat_blob($fb->{blob}, $base); die "Failed to read object $fb->{blob}" if ($size < 0); if (defined $exp) { seek $base, 0, 0 or croak $!; my $got = ::md5sum($base); - die "Checksum mismatch: $fb->{path} $fb->{blob}\n", - "expected: $exp\n", - " got: $got\n" if ($got ne $exp); + if ($got ne $exp) { + my $err = "Checksum mismatch: ". + "$fb->{path} $fb->{blob}\n" . + "expected: $exp\n" . + " got: $got\n"; + if ($base_is_link) { + warn $err, + "Retrying... (possibly ", + "a bad symlink from SVN)\n"; + $::_repository->temp_reset($base); + $base_is_link = 0; + goto retry; + } + die $err; + } } } seek $base, 0, 0 or croak $!; |