summaryrefslogtreecommitdiff
path: root/git-svn.perl
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-01-12 00:51:11 (GMT)
committerEric Wong <normalperson@yhbt.net>2009-01-18 23:38:28 (GMT)
commitbaf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e (patch)
treeca0b0c411bc9859e95649d15019f8588396935a5 /git-svn.perl
parentdbc6c74d0858d77e61e092a48d467e725211f8e9 (diff)
downloadgit-baf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e.zip
git-baf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e.tar.gz
git-baf5fa8a7fdefc696fb1d79c95ae15a4cc779c1e.tar.bz2
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-xgit-svn.perl24
1 files changed, 20 insertions, 4 deletions
diff --git a/git-svn.perl b/git-svn.perl
index 1b87a65..b0e3d7c 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 $!;