Skip to content

Commit

Permalink
git-svn: add --ignore-paths option for fetching
Browse files Browse the repository at this point in the history
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)]
  • Loading branch information
Vitaly \"_Vi\" Shukela authored and Eric Wong committed Jan 26, 2009
1 parent bf8a40b commit edc662f
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions git-svn.perl
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ BEGIN
$Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir,
'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache );
'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
'authors-file|A=s' => \$_authors,
'repack:i' => \$Git::SVN::_repack,
Expand Down Expand Up @@ -3245,6 +3246,7 @@ package SVN::Git::Fetcher;
use Carp qw/croak/;
use File::Temp qw/tempfile/;
use IO::File qw//;
use vars qw/$_ignore_regex/;

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

# return value: 0 -- don't ignore, 1 -- ignore
sub is_path_ignored {
my ($path) = @_;
return 1 if in_dot_git($path);
return 0 unless defined($_ignore_regex);
return 1 if $path =~ m!$_ignore_regex!o;
return 0;
}

sub set_path_strip {
my ($self, $path) = @_;
$self->{path_strip} = qr/^\Q$path\E(\/|$)/ if length $path;
Expand All @@ -3322,7 +3333,7 @@ sub git_path {

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

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

goto out if in_dot_git($path);
goto out if is_path_ignored($path);

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

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

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

sub change_dir_prop {
my ($self, $db, $prop, $value) = @_;
return undef if in_dot_git($db->{path});
return undef if 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 in_dot_git($pb->{path});
return undef if 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 in_dot_git($pb->{path});
return undef if 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 in_dot_git($fb->{path});
return undef if is_path_ignored($fb->{path});
if ($prop eq 'svn:executable') {
if ($fb->{mode_b} != 120000) {
$fb->{mode_b} = defined $value ? 100755 : 100644;
Expand All @@ -3447,7 +3458,7 @@ sub change_file_prop {

sub apply_textdelta {
my ($self, $fb, $exp) = @_;
return undef if (in_dot_git($fb->{path}));
return undef if 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 @@ -3494,7 +3505,7 @@ sub apply_textdelta {

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

my $hash;
my $path = $self->git_path($fb->{path});
Expand Down

0 comments on commit edc662f

Please sign in to comment.