Skip to content

Commit

Permalink
git-svn: Add per-svn-remote ignore-paths config
Browse files Browse the repository at this point in the history
The --ignore-paths option to fetch is very useful for working on a subset
of a SVN repository.  For proper operation, every command that causes a
fetch (explicit or implied) must include a matching --ignore-paths option.

This patch adds a persistent svn-remote.$repo_id.ignore-paths config by
promoting Fetcher::is_path_ignored to a member function and initializing
$self->{ignore_regex} in Fetcher::new.  Command line --ignore-paths is
still recognized and acts in addition to the config value.

Signed-off-by: Ben Jackson <ben@ben.com>
Acked-by: Eric Wong <normalperson@yhbt.net>
  • Loading branch information
Ben Jackson authored and Eric Wong committed Apr 12, 2009
1 parent 6ea4203 commit 0d8bee7
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 21 deletions.
22 changes: 15 additions & 7 deletions Documentation/git-svn.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,25 @@ repository, either don't use this option or you should both use it in
the same local timezone.

--ignore-paths=<regex>;;
This allows one to specify Perl regular expression that will
This allows one to specify a Perl regular expression that will
cause skipping of all matching paths from checkout from SVN.
Examples:
The '--ignore-paths' option should match for every 'fetch'
(including automatic fetches due to 'clone', 'dcommit',
'rebase', etc) on a given repository.

--ignore-paths="^doc" - skip "doc*" directory for every fetch.
config key: svn-remote.<name>.ignore-paths

--ignore-paths="^[^/]+/(?:branches|tags)" - skip "branches"
and "tags" of first level directories.
If the ignore-paths config key is set and the command
line option is also given, both regular expressions
will be used.

Regular expression is not persistent, you should specify
it every time when fetching.
Examples:

--ignore-paths="^doc" - skip "doc*" directory for every
fetch.

--ignore-paths="^[^/]+/(?:branches|tags)" - skip
"branches" and "tags" of first level directories.

'clone'::
Runs 'init' and 'fetch'. It will automatically create a
Expand Down
26 changes: 15 additions & 11 deletions git-svn.perl
Original file line number Diff line number Diff line change
Expand Up @@ -3331,6 +3331,8 @@ sub new {
$self->{empty_symlinks} =
_mark_empty_symlinks($git_svn, $switch_path);
}
$self->{ignore_regex} = eval { command_oneline('config', '--get',
"svn-remote.$git_svn->{repo_id}.ignore-paths") };
$self->{empty} = {};
$self->{dir_prop} = {};
$self->{file_prop} = {};
Expand Down Expand Up @@ -3395,8 +3397,10 @@ sub in_dot_git {

# return value: 0 -- don't ignore, 1 -- ignore
sub is_path_ignored {
my ($path) = @_;
my ($self, $path) = @_;
return 1 if in_dot_git($path);
return 1 if defined($self->{ignore_regex}) &&
$path =~ m!$self->{ignore_regex}!;
return 0 unless defined($_ignore_regex);
return 1 if $path =~ m!$_ignore_regex!o;
return 0;
Expand Down Expand Up @@ -3427,7 +3431,7 @@ sub git_path {

sub delete_entry {
my ($self, $path, $rev, $pb) = @_;
return undef if is_path_ignored($path);
return undef if $self->is_path_ignored($path);

my $gpath = $self->git_path($path);
return undef if ($gpath eq '');
Expand Down Expand Up @@ -3460,7 +3464,7 @@ sub open_file {
my ($self, $path, $pb, $rev) = @_;
my ($mode, $blob);

goto out if is_path_ignored($path);
goto out if $self->is_path_ignored($path);

my $gpath = $self->git_path($path);
($mode, $blob) = (command('ls-tree', '-z', $self->{c}, "./$gpath")
Expand All @@ -3480,7 +3484,7 @@ sub add_file {
my ($self, $path, $pb, $cp_path, $cp_rev) = @_;
my $mode;

if (!is_path_ignored($path)) {
if (!$self->is_path_ignored($path)) {
my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#);
delete $self->{empty}->{$dir};
$mode = '100644';
Expand All @@ -3491,7 +3495,7 @@ sub add_file {

sub add_directory {
my ($self, $path, $cp_path, $cp_rev) = @_;
goto out if is_path_ignored($path);
goto out if $self->is_path_ignored($path);
my $gpath = $self->git_path($path);
if ($gpath eq '') {
my ($ls, $ctx) = command_output_pipe(qw/ls-tree
Expand All @@ -3515,31 +3519,31 @@ sub add_directory {

sub change_dir_prop {
my ($self, $db, $prop, $value) = @_;
return undef if is_path_ignored($db->{path});
return undef if $self->is_path_ignored($db->{path});
$self->{dir_prop}->{$db->{path}} ||= {};
$self->{dir_prop}->{$db->{path}}->{$prop} = $value;
undef;
}

sub absent_directory {
my ($self, $path, $pb) = @_;
return undef if is_path_ignored($path);
return undef if $self->is_path_ignored($path);
$self->{absent_dir}->{$pb->{path}} ||= [];
push @{$self->{absent_dir}->{$pb->{path}}}, $path;
undef;
}

sub absent_file {
my ($self, $path, $pb) = @_;
return undef if is_path_ignored($path);
return undef if $self->is_path_ignored($path);
$self->{absent_file}->{$pb->{path}} ||= [];
push @{$self->{absent_file}->{$pb->{path}}}, $path;
undef;
}

sub change_file_prop {
my ($self, $fb, $prop, $value) = @_;
return undef if is_path_ignored($fb->{path});
return undef if $self->is_path_ignored($fb->{path});
if ($prop eq 'svn:executable') {
if ($fb->{mode_b} != 120000) {
$fb->{mode_b} = defined $value ? 100755 : 100644;
Expand All @@ -3555,7 +3559,7 @@ sub change_file_prop {

sub apply_textdelta {
my ($self, $fb, $exp) = @_;
return undef if is_path_ignored($fb->{path});
return undef if $self->is_path_ignored($fb->{path});
my $fh = $::_repository->temp_acquire('svn_delta');
# $fh gets auto-closed() by SVN::TxDelta::apply(),
# (but $base does not,) so dup() it for reading in close_file
Expand Down Expand Up @@ -3602,7 +3606,7 @@ sub apply_textdelta {

sub close_file {
my ($self, $fb, $exp) = @_;
return undef if is_path_ignored($fb->{path});
return undef if $self->is_path_ignored($fb->{path});

my $hash;
my $path = $self->git_path($fb->{path});
Expand Down
55 changes: 52 additions & 3 deletions t/t9134-git-svn-ignore-paths.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ test_expect_success 'clone an SVN repository with ignored www directory' '
test_cmp expect expect2
'

test_expect_success 'init+fetch an SVN repository with ignored www directory' '
git svn init "$svnrepo" c &&
( cd c && git svn fetch --ignore-paths="^www" ) &&
rm expect2 &&
echo test_qqq > expect &&
for i in c/*/*.txt; do cat $i >> expect2; done &&
test_cmp expect expect2
'

test_expect_success 'set persistent ignore-paths config' '
(
cd g &&
git config svn-remote.svn.ignore-paths "^www"
)
'

test_expect_success 'SVN-side change outside of www' '
(
cd s &&
Expand All @@ -41,9 +57,20 @@ test_expect_success 'SVN-side change outside of www' '
)
'

test_expect_success 'update git svn-cloned repo' '
test_expect_success 'update git svn-cloned repo (config ignore)' '
(
cd g &&
git svn rebase &&
printf "test_qqq\nb\n" > expect &&
for i in */*.txt; do cat $i >> expect2; done &&
test_cmp expect2 expect &&
rm expect expect2
)
'

test_expect_success 'update git svn-cloned repo (option ignore)' '
(
cd c &&
git svn rebase --ignore-paths="^www" &&
printf "test_qqq\nb\n" > expect &&
for i in */*.txt; do cat $i >> expect2; done &&
Expand All @@ -62,9 +89,20 @@ test_expect_success 'SVN-side change inside of ignored www' '
)
'

test_expect_success 'update git svn-cloned repo' '
test_expect_success 'update git svn-cloned repo (config ignore)' '
(
cd g &&
git svn rebase &&
printf "test_qqq\nb\n" > expect &&
for i in */*.txt; do cat $i >> expect2; done &&
test_cmp expect2 expect &&
rm expect expect2
)
'

test_expect_success 'update git svn-cloned repo (option ignore)' '
(
cd c &&
git svn rebase --ignore-paths="^www" &&
printf "test_qqq\nb\n" > expect &&
for i in */*.txt; do cat $i >> expect2; done &&
Expand All @@ -84,9 +122,20 @@ test_expect_success 'SVN-side change in and out of ignored www' '
)
'

test_expect_success 'update git svn-cloned repo again' '
test_expect_success 'update git svn-cloned repo again (config ignore)' '
(
cd g &&
git svn rebase &&
printf "test_qqq\nb\nygg\n" > expect &&
for i in */*.txt; do cat $i >> expect2; done &&
test_cmp expect2 expect &&
rm expect expect2
)
'

test_expect_success 'update git svn-cloned repo again (option ignore)' '
(
cd c &&
git svn rebase --ignore-paths="^www" &&
printf "test_qqq\nb\nygg\n" > expect &&
for i in */*.txt; do cat $i >> expect2; done &&
Expand Down

0 comments on commit 0d8bee7

Please sign in to comment.