@matheusbsbs / matheus-bagliano / commits / edc662f929
Fork 0

git-svn: add --ignore-paths option for fetching

This will be useful when somebody want to checkout something partially from repository with some non-standart layout or exclude some files from it. Example: repository has structure /module-{a,b,c}/{trunk,branches,tags}/... Modules are interdependent, and you want it to be single repostory (to commit to all modules simultaneously and view complete history), but do not want branches and tags be checked out into working copy. Other use case is excluding some large blobs. The quirk for now is that user must specify this option every fetch/rebase; in other case he may get extra files or "file not found" errors. It may be will be resolved by adding regular expression to .git/config into [svn-remote ...] to make it persistent. Signed-off-by: Vitaly "_Vi" Shukela <public_vi@tut.by> Acked-by: Eric Wong <normalperson@yhbt.net> [ew: replaced 4-space indent with tabs] [ew: prefixed $ignore_regex with an underscore to be consistent with other globals in git-svn] [ew: rearranged functions to minimize diff and removed prototype usage to be consistent with the rest of git-svn (and other Perl code in git (and they're ugly to me)]

Vitaly \"_Vi\" Shukela committed Jan 26, 2009 at 00:21 UTC edc662f929e1a2be3e350bf362cc9aed95f5250a
1 file changed +22 -11
git-svn.perl
+22 -11
@@ -70,7 +70,8 @@ my ($_stdin, $_help, $_edit,
70 $Git::SVN::_follow_parent = 1;
71 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
72 '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 );
75 my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
76 'authors-file|A=s' => \$_authors,
77 'repack:i' => \$Git::SVN::_repack,
@@ -3245,6 +3246,7 @@ use warnings;
3246 use Carp qw/croak/;
3247 use File::Temp qw/tempfile/;
3248 use IO::File qw//;
3249 +use vars qw/$_ignore_regex/;
3250
3251 # file baton members: path, mode_a, mode_b, pool, fh, blob, base
3252 sub new {
@@ -3297,6 +3299,15 @@ sub in_dot_git {
3299 $_[0] =~ m{(?:^|/)\.git(?:/|$)};
3300 }
3301
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 +
3311 sub set_path_strip {
3312 my ($self, $path) = @_;
3313 $self->{path_strip} = qr/^\Q$path\E(\/|$)/ if length $path;
@@ -3322,7 +3333,7 @@ sub git_path {
3333
3334 sub delete_entry {
3335 my ($self, $path, $rev, $pb) = @_;
3325 - return undef if in_dot_git($path);
3336 + return undef if is_path_ignored($path);
3337
3338 my $gpath = $self->git_path($path);
3339 return undef if ($gpath eq '');
@@ -3352,7 +3363,7 @@ sub open_file {
3363 my ($self, $path, $pb, $rev) = @_;
3364 my ($mode, $blob);
3365
3355 - goto out if in_dot_git($path);
3366 + goto out if is_path_ignored($path);
3367
3368 my $gpath = $self->git_path($path);
3369 ($mode, $blob) = (command('ls-tree', $self->{c}, '--', $gpath)
@@ -3372,7 +3383,7 @@ sub add_file {
3383 my ($self, $path, $pb, $cp_path, $cp_rev) = @_;
3384 my $mode;
3385
3375 - if (!in_dot_git($path)) {
3386 + if (!is_path_ignored($path)) {
3387 my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#);
3388 delete $self->{empty}->{$dir};
3389 $mode = '100644';
@@ -3383,7 +3394,7 @@ sub add_file {
3394
3395 sub add_directory {
3396 my ($self, $path, $cp_path, $cp_rev) = @_;
3386 - goto out if in_dot_git($path);
3397 + goto out if is_path_ignored($path);
3398 my $gpath = $self->git_path($path);
3399 if ($gpath eq '') {
3400 my ($ls, $ctx) = command_output_pipe(qw/ls-tree
@@ -3407,7 +3418,7 @@ out:
3418
3419 sub change_dir_prop {
3420 my ($self, $db, $prop, $value) = @_;
3410 - return undef if in_dot_git($db->{path});
3421 + return undef if is_path_ignored($db->{path});
3422 $self->{dir_prop}->{$db->{path}} ||= {};
3423 $self->{dir_prop}->{$db->{path}}->{$prop} = $value;
3424 undef;
@@ -3415,7 +3426,7 @@ sub change_dir_prop {
3426
3427 sub absent_directory {
3428 my ($self, $path, $pb) = @_;
3418 - return undef if in_dot_git($pb->{path});
3429 + return undef if is_path_ignored($path);
3430 $self->{absent_dir}->{$pb->{path}} ||= [];
3431 push @{$self->{absent_dir}->{$pb->{path}}}, $path;
3432 undef;
@@ -3423,7 +3434,7 @@ sub absent_directory {
3434
3435 sub absent_file {
3436 my ($self, $path, $pb) = @_;
3426 - return undef if in_dot_git($pb->{path});
3437 + return undef if is_path_ignored($path);
3438 $self->{absent_file}->{$pb->{path}} ||= [];
3439 push @{$self->{absent_file}->{$pb->{path}}}, $path;
3440 undef;
@@ -3431,7 +3442,7 @@ sub absent_file {
3442
3443 sub change_file_prop {
3444 my ($self, $fb, $prop, $value) = @_;
3434 - return undef if in_dot_git($fb->{path});
3445 + return undef if is_path_ignored($fb->{path});
3446 if ($prop eq 'svn:executable') {
3447 if ($fb->{mode_b} != 120000) {
3448 $fb->{mode_b} = defined $value ? 100755 : 100644;
@@ -3447,7 +3458,7 @@ sub change_file_prop {
3458
3459 sub apply_textdelta {
3460 my ($self, $fb, $exp) = @_;
3450 - return undef if (in_dot_git($fb->{path}));
3461 + return undef if is_path_ignored($fb->{path});
3462 my $fh = $::_repository->temp_acquire('svn_delta');
3463 # $fh gets auto-closed() by SVN::TxDelta::apply(),
3464 # (but $base does not,) so dup() it for reading in close_file
@@ -3494,7 +3505,7 @@ sub apply_textdelta {
3505
3506 sub close_file {
3507 my ($self, $fb, $exp) = @_;
3497 - return undef if (in_dot_git($fb->{path}));
3508 + return undef if is_path_ignored($fb->{path});
3509
3510 my $hash;
3511 my $path = $self->git_path($fb->{path});