提交 0d8bee71 编写于 作者: B Ben Jackson 提交者: Eric Wong

git-svn: Add per-svn-remote ignore-paths config

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: NBen Jackson <ben@ben.com>
Acked-by: NEric Wong <normalperson@yhbt.net>
上级 6ea42032
......@@ -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
......
......@@ -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} = {};
......@@ -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;
......@@ -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 '');
......@@ -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")
......@@ -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';
......@@ -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
......@@ -3515,7 +3519,7 @@ 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;
......@@ -3523,7 +3527,7 @@ sub change_dir_prop {
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;
......@@ -3531,7 +3535,7 @@ sub absent_directory {
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;
......@@ -3539,7 +3543,7 @@ sub absent_file {
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;
......@@ -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
......@@ -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});
......
......@@ -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 &&
......@@ -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 &&
......@@ -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 &&
......@@ -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 &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册