git-svn: add a generic tree traversal to fetch SVN properties
* git-svn.perl (&traverse_ignore): Remove. (&prop_walk): New. (&cmd_show_ignore): Use prop_walk. [ew: This will ease the implementation of the `create-ignore', `propget', and `proplist' commands] Signed-off-by: Benoit Sigoure <tsuna@lrde.epita.fr> Acked-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
ca5e949560
commit
01bdab84e3
63
git-svn.perl
63
git-svn.perl
@ -488,7 +488,15 @@ sub cmd_show_ignore {
|
||||
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
|
||||
$gs ||= Git::SVN->new;
|
||||
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
|
||||
$gs->traverse_ignore(\*STDOUT, $gs->{path}, $r);
|
||||
$gs->prop_walk($gs->{path}, $r, sub {
|
||||
my ($gs, $path, $props) = @_;
|
||||
print STDOUT "\n# $path\n";
|
||||
my $s = $props->{'svn:ignore'} or return;
|
||||
$s =~ s/[\r\n]+/\n/g;
|
||||
chomp $s;
|
||||
$s =~ s#^#$path#gm;
|
||||
print STDOUT "$s\n";
|
||||
});
|
||||
}
|
||||
|
||||
sub cmd_multi_init {
|
||||
@ -1480,28 +1488,45 @@ sub rel_path {
|
||||
$url;
|
||||
}
|
||||
|
||||
sub traverse_ignore {
|
||||
my ($self, $fh, $path, $r) = @_;
|
||||
$path =~ s#^/+##g;
|
||||
my $ra = $self->ra;
|
||||
my ($dirent, undef, $props) = $ra->get_dir($path, $r);
|
||||
# prop_walk(PATH, REV, SUB)
|
||||
# -------------------------
|
||||
# Recursively traverse PATH at revision REV and invoke SUB for each
|
||||
# directory that contains a SVN property. SUB will be invoked as
|
||||
# follows: &SUB(gs, path, props); where `gs' is this instance of
|
||||
# Git::SVN, `path' the path to the directory where the properties
|
||||
# `props' were found. The `path' will be relative to point of checkout,
|
||||
# that is, if url://repo/trunk is the current Git branch, and that
|
||||
# directory contains a sub-directory `d', SUB will be invoked with `/d/'
|
||||
# as `path' (note the trailing `/').
|
||||
sub prop_walk {
|
||||
my ($self, $path, $rev, $sub) = @_;
|
||||
|
||||
my ($dirent, undef, $props) = $self->ra->get_dir($path, $rev);
|
||||
$path =~ s#^/*#/#g;
|
||||
my $p = $path;
|
||||
$p =~ s#^\Q$self->{path}\E(/|$)##;
|
||||
print $fh length $p ? "\n# $p\n" : "\n# /\n";
|
||||
if (my $s = $props->{'svn:ignore'}) {
|
||||
$s =~ s/[\r\n]+/\n/g;
|
||||
chomp $s;
|
||||
if (length $p == 0) {
|
||||
$s =~ s#\n#\n/$p#g;
|
||||
print $fh "/$s\n";
|
||||
} else {
|
||||
$s =~ s#\n#\n/$p/#g;
|
||||
print $fh "/$p/$s\n";
|
||||
}
|
||||
# Strip the irrelevant part of the path.
|
||||
$p =~ s#^/+\Q$self->{path}\E(/|$)#/#;
|
||||
# Ensure the path is terminated by a `/'.
|
||||
$p =~ s#/*$#/#;
|
||||
|
||||
# The properties contain all the internal SVN stuff nobody
|
||||
# (usually) cares about.
|
||||
my $interesting_props = 0;
|
||||
foreach (keys %{$props}) {
|
||||
# If it doesn't start with `svn:', it must be a
|
||||
# user-defined property.
|
||||
++$interesting_props and next if $_ !~ /^svn:/;
|
||||
# FIXME: Fragile, if SVN adds new public properties,
|
||||
# this needs to be updated.
|
||||
++$interesting_props if /^svn:(?:ignore|keywords|executable
|
||||
|eol-style|mime-type
|
||||
|externals|needs-lock)$/x;
|
||||
}
|
||||
&$sub($self, $p, $props) if $interesting_props;
|
||||
|
||||
foreach (sort keys %$dirent) {
|
||||
next if $dirent->{$_}->{kind} != $SVN::Node::dir;
|
||||
$self->traverse_ignore($fh, "$path/$_", $r);
|
||||
$self->prop_walk($path . '/' . $_, $rev, $sub);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user