Browse Source

Merge git://git.bogomips.org/git-svn

* git://git.bogomips.org/git-svn:
  test case for regression caused by git-svn empty symlink fix
  git-svn: fix broken symlink workaround when switching branches
  git-svn: Print revision while searching for earliest use of path
  git-svn: abstract out a block into new method other_gs()
  git-svn: allow disabling expensive broken symlink checks
maint
Junio C Hamano 16 years ago
parent
commit
7b73d828f0
  1. 8
      Documentation/git-svn.txt
  2. 74
      git-svn.perl
  3. 10
      t/t9131-git-svn-empty-symlink.sh
  4. 16
      t/t9135-git-svn-moved-branch-empty-file.sh
  5. 192
      t/t9135/svn.dump

8
Documentation/git-svn.txt

@ -499,6 +499,14 @@ svn-remote.<name>.rewriteRoot:: @@ -499,6 +499,14 @@ svn-remote.<name>.rewriteRoot::
the repository with a public http:// or svn:// URL in the
metadata so users of it will see the public URL.

svn.brokenSymlinkWorkaround::
This disables potentially expensive checks to workaround broken symlinks
checked into SVN by broken clients. Set this option to "false" if you
track a SVN repository with many empty blobs that are not symlinks.
This option may be changed while "git-svn" is running and take effect on
the next revision fetched. If unset, git-svn assumes this option to be
"true".

--

Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps

74
git-svn.perl

@ -2389,22 +2389,8 @@ sub find_parent_branch { @@ -2389,22 +2389,8 @@ sub find_parent_branch {
print STDERR "Found possible branch point: ",
"$new_url => ", $self->full_url, ", $r\n";
$branch_from =~ s#^/##;
my $gs = Git::SVN->find_by_url($new_url, $repos_root, $branch_from);
unless ($gs) {
my $ref_id = $self->{ref_id};
$ref_id =~ s/\@\d+$//;
$ref_id .= "\@$r";
# just grow a tail if we're not unique enough :x
$ref_id .= '-' while find_ref($ref_id);
print STDERR "Initializing parent: $ref_id\n";
my ($u, $p, $repo_id) = ($new_url, '', $ref_id);
if ($u =~ s#^\Q$url\E(/|$)##) {
$p = $u;
$u = $url;
$repo_id = $self->{repo_id};
}
$gs = Git::SVN->init($u, $p, $repo_id, $ref_id, 1);
}
my $gs = $self->other_gs($new_url, $url, $repos_root,
$branch_from, $r, $self->{ref_id});
my ($r0, $parent) = $gs->find_rev_before($r, 1);
{
my ($base, $head);
@ -2431,7 +2417,7 @@ sub find_parent_branch { @@ -2431,7 +2417,7 @@ sub find_parent_branch {
# is not included with SVN 1.4.3 (the latest version
# at the moment), so we can't rely on it
$self->{last_commit} = $parent;
$ed = SVN::Git::Fetcher->new($self);
$ed = SVN::Git::Fetcher->new($self, $gs->{path});
$gs->ra->gs_do_switch($r0, $rev, $gs,
$self->full_url, $ed)
or die "SVN connection failed somewhere...\n";
@ -2586,6 +2572,28 @@ sub parse_svn_date { @@ -2586,6 +2572,28 @@ sub parse_svn_date {
return $parsed_date;
}

sub other_gs {
my ($self, $new_url, $url, $repos_root,
$branch_from, $r, $old_ref_id) = @_;
my $gs = Git::SVN->find_by_url($new_url, $repos_root, $branch_from);
unless ($gs) {
my $ref_id = $old_ref_id;
$ref_id =~ s/\@\d+$//;
$ref_id .= "\@$r";
# just grow a tail if we're not unique enough :x
$ref_id .= '-' while find_ref($ref_id);
print STDERR "Initializing parent: $ref_id\n";
my ($u, $p, $repo_id) = ($new_url, '', $ref_id);
if ($u =~ s#^\Q$url\E(/|$)##) {
$p = $u;
$u = $url;
$repo_id = $self->{repo_id};
}
$gs = Git::SVN->init($u, $p, $repo_id, $ref_id, 1);
}
$gs
}

sub check_author {
my ($author) = @_;
if (!defined $author || length $author == 0) {
@ -3250,12 +3258,13 @@ use vars qw/$_ignore_regex/; @@ -3250,12 +3258,13 @@ use vars qw/$_ignore_regex/;

# file baton members: path, mode_a, mode_b, pool, fh, blob, base
sub new {
my ($class, $git_svn) = @_;
my ($class, $git_svn, $switch_path) = @_;
my $self = SVN::Delta::Editor->new;
bless $self, $class;
if (exists $git_svn->{last_commit}) {
$self->{c} = $git_svn->{last_commit};
$self->{empty_symlinks} = _mark_empty_symlinks($git_svn);
$self->{empty_symlinks} =
_mark_empty_symlinks($git_svn, $switch_path);
}
$self->{empty} = {};
$self->{dir_prop} = {};
@ -3270,19 +3279,39 @@ sub new { @@ -3270,19 +3279,39 @@ sub new {
# not inside them (when the Git::SVN::Fetcher object is passed) to
# do_{switch,update}
sub _mark_empty_symlinks {
my ($git_svn) = @_;
my ($git_svn, $switch_path) = @_;
my $bool = Git::config_bool('svn.brokenSymlinkWorkaround');
return {} if (defined($bool) && ! $bool);

my %ret;
my ($rev, $cmt) = $git_svn->last_rev_commit;
return {} unless ($rev && $cmt);

# allow the warning to be printed for each revision we fetch to
# ensure the user sees it. The user can also disable the workaround
# on the repository even while git svn is running and the next
# revision fetched will skip this expensive function.
my $printed_warning;
chomp(my $empty_blob = `git hash-object -t blob --stdin < /dev/null`);
my ($ls, $ctx) = command_output_pipe(qw/ls-tree -r -z/, $cmt);
local $/ = "\0";
my $pfx = $git_svn->{path};
my $pfx = defined($switch_path) ? $switch_path : $git_svn->{path};
$pfx .= '/' if length($pfx);
while (<$ls>) {
chomp;
s/\A100644 blob $empty_blob\t//o or next;
unless ($printed_warning) {
print STDERR "Scanning for empty symlinks, ",
"this may take a while if you have ",
"many empty files\n",
"You may disable this with `",
"git config svn.brokenSymlinkWorkaround ",
"false'.\n",
"This may be done in a different ",
"terminal without restarting ",
"git svn\n";
$printed_warning = 1;
}
my $path = $_;
my (undef, $props) =
$git_svn->ra->get_file($pfx.$path, $rev, undef);
@ -4348,6 +4377,9 @@ sub gs_fetch_loop_common { @@ -4348,6 +4377,9 @@ sub gs_fetch_loop_common {
}
$self->get_log([$longest_path], $min, $max, 0, 1, 1,
sub { $revs{$_[1]} = _cb(@_) });
if ($err) {
print "Checked through r$max\r";
}
if ($err && $max >= $head) {
print STDERR "Path '$longest_path' ",
"was probably deleted:\n",

10
t/t9131-git-svn-empty-symlink.sh

@ -87,4 +87,14 @@ test_expect_success '"bar" is an empty file' 'test -f x/bar && ! test -s x/bar' @@ -87,4 +87,14 @@ test_expect_success '"bar" is an empty file' 'test -f x/bar && ! test -s x/bar'
test_expect_success 'get "bar" => symlink fix from svn' \
'(cd x && git svn rebase)'
test_expect_success '"bar" becomes a symlink' 'test -L x/bar'


test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" y'
test_expect_success 'disable broken symlink workaround' \
'(cd y && git config svn.brokenSymlinkWorkaround false)'
test_expect_success '"bar" is an empty file' 'test -f y/bar && ! test -s y/bar'
test_expect_success 'get "bar" => symlink fix from svn' \
'(cd y && git svn rebase)'
test_expect_success '"bar" does not become a symlink' '! test -L y/bar'

test_done

16
t/t9135-git-svn-moved-branch-empty-file.sh

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
#!/bin/sh

test_description='test moved svn branch with missing empty files'

. ./lib-git-svn.sh
test_expect_success 'load svn dumpfile' '
svnadmin load "$rawsvnrepo" < "${TEST_DIRECTORY}/t9135/svn.dump"
'

test_expect_success 'clone using git svn' 'git svn clone -s "$svnrepo" x'

test_expect_success 'test that b1 exists and is empty' '
(cd x && test -f b1 && ! test -s b1)
'

test_done

192
t/t9135/svn.dump

@ -0,0 +1,192 @@ @@ -0,0 +1,192 @@
SVN-fs-dump-format-version: 2

UUID: 1f80e919-e9e3-4d80-a3ae-d9f21095e27b

Revision-number: 0
Prop-content-length: 56
Content-length: 56

K 8
svn:date
V 27
2009-02-10T19:23:16.424027Z
PROPS-END

Revision-number: 1
Prop-content-length: 123
Content-length: 123

K 7
svn:log
V 20
init standard layout
K 10
svn:author
V 8
john.doe
K 8
svn:date
V 27
2009-02-10T19:23:17.195072Z
PROPS-END

Node-path: branches
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10

PROPS-END


Node-path: trunk
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10

PROPS-END


Revision-number: 2
Prop-content-length: 121
Content-length: 121

K 7
svn:log
V 18
branch-b off trunk
K 10
svn:author
V 8
john.doe
K 8
svn:date
V 27
2009-02-10T19:23:19.160095Z
PROPS-END

Node-path: branches/branch-b
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 1
Node-copyfrom-path: trunk
Prop-content-length: 34
Content-length: 34

K 13
svn:mergeinfo
V 0

PROPS-END


Revision-number: 3
Prop-content-length: 120
Content-length: 120

K 7
svn:log
V 17
add empty file b1
K 10
svn:author
V 8
john.doe
K 8
svn:date
V 27
2009-02-10T19:23:20.194568Z
PROPS-END

Node-path: branches/branch-b/b1
Node-kind: file
Node-action: add
Prop-content-length: 10
Text-content-length: 0
Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
Content-length: 10

PROPS-END


Revision-number: 4
Prop-content-length: 110
Content-length: 110

K 7
svn:log
V 8
branch-c
K 10
svn:author
V 8
john.doe
K 8
svn:date
V 27
2009-02-10T19:23:21.169100Z
PROPS-END

Node-path: branches/branch-c
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 3
Node-copyfrom-path: trunk


Revision-number: 5
Prop-content-length: 126
Content-length: 126

K 7
svn:log
V 23
oops, wrong branchpoint
K 10
svn:author
V 8
john.doe
K 8
svn:date
V 27
2009-02-10T19:23:21.253557Z
PROPS-END

Node-path: branches/branch-c
Node-action: delete


Revision-number: 6
Prop-content-length: 127
Content-length: 127

K 7
svn:log
V 24
branch-c off of branch-b
K 10
svn:author
V 8
john.doe
K 8
svn:date
V 27
2009-02-10T19:23:21.314659Z
PROPS-END

Node-path: branches/branch-c
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 5
Node-copyfrom-path: branches/branch-b
Prop-content-length: 34
Content-length: 34

K 13
svn:mergeinfo
V 0

PROPS-END


Loading…
Cancel
Save