Skip to content

Commit afc7274

Browse files
committed
Merge git://git.bogomips.org/git-svn
* git://git.bogomips.org/git-svn: git-svn: Add test for --ignore-paths parameter git-svn: documented --ignore-paths git-svn: add --ignore-paths option for fetching git-svn: fix memory leak when checking for empty symlinks
2 parents 277d7e9 + 242522d commit afc7274

File tree

3 files changed

+135
-12
lines changed

3 files changed

+135
-12
lines changed

Documentation/git-svn.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@ repository to be able to interoperate with someone else's local Git
103103
repository, either don't use this option or you should both use it in
104104
the same local timezone.
105105

106+
--ignore-paths=<regex>;;
107+
This allows one to specify Perl regular expression that will
108+
cause skipping of all matching paths from checkout from SVN.
109+
Examples:
110+
111+
--ignore-paths="^doc" - skip "doc*" directory for every fetch.
112+
113+
--ignore-paths="^[^/]+/(?:branches|tags)" - skip "branches"
114+
and "tags" of first level directories.
115+
116+
Regular expression is not persistent, you should specify
117+
it every time when fetching.
118+
106119
'clone'::
107120
Runs 'init' and 'fetch'. It will automatically create a
108121
directory based on the basename of the URL passed to it;

git-svn.perl

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ BEGIN
7070
$Git::SVN::_follow_parent = 1;
7171
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
7272
'config-dir=s' => \$Git::SVN::Ra::config_dir,
73-
'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache );
73+
'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
74+
'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
7475
my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
7576
'authors-file|A=s' => \$_authors,
7677
'repack:i' => \$Git::SVN::_repack,
@@ -3245,6 +3246,7 @@ package SVN::Git::Fetcher;
32453246
use Carp qw/croak/;
32463247
use File::Temp qw/tempfile/;
32473248
use IO::File qw//;
3249+
use vars qw/$_ignore_regex/;
32483250

32493251
# file baton members: path, mode_a, mode_b, pool, fh, blob, base
32503252
sub new {
@@ -3297,6 +3299,15 @@ sub in_dot_git {
32973299
$_[0] =~ m{(?:^|/)\.git(?:/|$)};
32983300
}
32993301

3302+
# return value: 0 -- don't ignore, 1 -- ignore
3303+
sub is_path_ignored {
3304+
my ($path) = @_;
3305+
return 1 if in_dot_git($path);
3306+
return 0 unless defined($_ignore_regex);
3307+
return 1 if $path =~ m!$_ignore_regex!o;
3308+
return 0;
3309+
}
3310+
33003311
sub set_path_strip {
33013312
my ($self, $path) = @_;
33023313
$self->{path_strip} = qr/^\Q$path\E(\/|$)/ if length $path;
@@ -3322,7 +3333,7 @@ sub git_path {
33223333

33233334
sub delete_entry {
33243335
my ($self, $path, $rev, $pb) = @_;
3325-
return undef if in_dot_git($path);
3336+
return undef if is_path_ignored($path);
33263337

33273338
my $gpath = $self->git_path($path);
33283339
return undef if ($gpath eq '');
@@ -3352,7 +3363,7 @@ sub open_file {
33523363
my ($self, $path, $pb, $rev) = @_;
33533364
my ($mode, $blob);
33543365

3355-
goto out if in_dot_git($path);
3366+
goto out if is_path_ignored($path);
33563367

33573368
my $gpath = $self->git_path($path);
33583369
($mode, $blob) = (command('ls-tree', $self->{c}, '--', $gpath)
@@ -3372,7 +3383,7 @@ sub add_file {
33723383
my ($self, $path, $pb, $cp_path, $cp_rev) = @_;
33733384
my $mode;
33743385

3375-
if (!in_dot_git($path)) {
3386+
if (!is_path_ignored($path)) {
33763387
my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#);
33773388
delete $self->{empty}->{$dir};
33783389
$mode = '100644';
@@ -3383,7 +3394,7 @@ sub add_file {
33833394

33843395
sub add_directory {
33853396
my ($self, $path, $cp_path, $cp_rev) = @_;
3386-
goto out if in_dot_git($path);
3397+
goto out if is_path_ignored($path);
33873398
my $gpath = $self->git_path($path);
33883399
if ($gpath eq '') {
33893400
my ($ls, $ctx) = command_output_pipe(qw/ls-tree
@@ -3407,31 +3418,31 @@ sub add_directory {
34073418

34083419
sub change_dir_prop {
34093420
my ($self, $db, $prop, $value) = @_;
3410-
return undef if in_dot_git($db->{path});
3421+
return undef if is_path_ignored($db->{path});
34113422
$self->{dir_prop}->{$db->{path}} ||= {};
34123423
$self->{dir_prop}->{$db->{path}}->{$prop} = $value;
34133424
undef;
34143425
}
34153426

34163427
sub absent_directory {
34173428
my ($self, $path, $pb) = @_;
3418-
return undef if in_dot_git($pb->{path});
3429+
return undef if is_path_ignored($path);
34193430
$self->{absent_dir}->{$pb->{path}} ||= [];
34203431
push @{$self->{absent_dir}->{$pb->{path}}}, $path;
34213432
undef;
34223433
}
34233434

34243435
sub absent_file {
34253436
my ($self, $path, $pb) = @_;
3426-
return undef if in_dot_git($pb->{path});
3437+
return undef if is_path_ignored($path);
34273438
$self->{absent_file}->{$pb->{path}} ||= [];
34283439
push @{$self->{absent_file}->{$pb->{path}}}, $path;
34293440
undef;
34303441
}
34313442

34323443
sub change_file_prop {
34333444
my ($self, $fb, $prop, $value) = @_;
3434-
return undef if in_dot_git($fb->{path});
3445+
return undef if is_path_ignored($fb->{path});
34353446
if ($prop eq 'svn:executable') {
34363447
if ($fb->{mode_b} != 120000) {
34373448
$fb->{mode_b} = defined $value ? 100755 : 100644;
@@ -3447,7 +3458,7 @@ sub change_file_prop {
34473458

34483459
sub apply_textdelta {
34493460
my ($self, $fb, $exp) = @_;
3450-
return undef if (in_dot_git($fb->{path}));
3461+
return undef if is_path_ignored($fb->{path});
34513462
my $fh = $::_repository->temp_acquire('svn_delta');
34523463
# $fh gets auto-closed() by SVN::TxDelta::apply(),
34533464
# (but $base does not,) so dup() it for reading in close_file
@@ -3494,7 +3505,7 @@ sub apply_textdelta {
34943505

34953506
sub close_file {
34963507
my ($self, $fb, $exp) = @_;
3497-
return undef if (in_dot_git($fb->{path}));
3508+
return undef if is_path_ignored($fb->{path});
34983509

34993510
my $hash;
35003511
my $path = $self->git_path($fb->{path});
@@ -4021,7 +4032,8 @@ package Git::SVN::Ra;
40214032
BEGIN {
40224033
# enforce temporary pool usage for some simple functions
40234034
no strict 'refs';
4024-
for my $f (qw/rev_proplist get_latest_revnum get_uuid get_repos_root/) {
4035+
for my $f (qw/rev_proplist get_latest_revnum get_uuid get_repos_root
4036+
get_file/) {
40254037
my $SUPER = "SUPER::$f";
40264038
*$f = sub {
40274039
my $self = shift;

t/t9134-git-svn-ignore-paths.sh

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2009 Vitaly Shukela
4+
# Copyright (c) 2009 Eric Wong
5+
#
6+
7+
test_description='git svn property tests'
8+
. ./lib-git-svn.sh
9+
10+
test_expect_success 'setup test repository' '
11+
svn co "$svnrepo" s &&
12+
(
13+
cd s &&
14+
mkdir qqq www &&
15+
echo test_qqq > qqq/test_qqq.txt &&
16+
echo test_www > www/test_www.txt &&
17+
svn add qqq &&
18+
svn add www &&
19+
svn commit -m "create some files" &&
20+
svn up &&
21+
echo hi >> www/test_www.txt &&
22+
svn commit -m "modify www/test_www.txt" &&
23+
svn up
24+
)
25+
'
26+
27+
test_expect_success 'clone an SVN repository with ignored www directory' '
28+
git svn clone --ignore-paths="^www" "$svnrepo" g &&
29+
echo test_qqq > expect &&
30+
for i in g/*/*.txt; do cat $i >> expect2; done &&
31+
test_cmp expect expect2
32+
'
33+
34+
test_expect_success 'SVN-side change outside of www' '
35+
(
36+
cd s &&
37+
echo b >> qqq/test_qqq.txt &&
38+
svn commit -m "SVN-side change outside of www" &&
39+
svn up &&
40+
svn log -v | fgrep "SVN-side change outside of www"
41+
)
42+
'
43+
44+
test_expect_success 'update git svn-cloned repo' '
45+
(
46+
cd g &&
47+
git svn rebase --ignore-paths="^www" &&
48+
printf "test_qqq\nb\n" > expect &&
49+
for i in */*.txt; do cat $i >> expect2; done &&
50+
test_cmp expect2 expect &&
51+
rm expect expect2
52+
)
53+
'
54+
55+
test_expect_success 'SVN-side change inside of ignored www' '
56+
(
57+
cd s &&
58+
echo zaq >> www/test_www.txt
59+
svn commit -m "SVN-side change inside of www/test_www.txt" &&
60+
svn up &&
61+
svn log -v | fgrep "SVN-side change inside of www/test_www.txt"
62+
)
63+
'
64+
65+
test_expect_success 'update git svn-cloned repo' '
66+
(
67+
cd g &&
68+
git svn rebase --ignore-paths="^www" &&
69+
printf "test_qqq\nb\n" > expect &&
70+
for i in */*.txt; do cat $i >> expect2; done &&
71+
test_cmp expect2 expect &&
72+
rm expect expect2
73+
)
74+
'
75+
76+
test_expect_success 'SVN-side change in and out of ignored www' '
77+
(
78+
cd s &&
79+
echo cvf >> www/test_www.txt
80+
echo ygg >> qqq/test_qqq.txt
81+
svn commit -m "SVN-side change in and out of ignored www" &&
82+
svn up &&
83+
svn log -v | fgrep "SVN-side change in and out of ignored www"
84+
)
85+
'
86+
87+
test_expect_success 'update git svn-cloned repo again' '
88+
(
89+
cd g &&
90+
git svn rebase --ignore-paths="^www" &&
91+
printf "test_qqq\nb\nygg\n" > expect &&
92+
for i in */*.txt; do cat $i >> expect2; done &&
93+
test_cmp expect2 expect &&
94+
rm expect expect2
95+
)
96+
'
97+
98+
test_done

0 commit comments

Comments
 (0)