summaryrefslogtreecommitdiff
path: root/git-svn.perl
diff options
context:
space:
mode:
authorBenoit Sigoure <tsuna@lrde.epita.fr>2007-10-16 14:36:48 (GMT)
committerShawn O. Pearce <spearce@spearce.org>2007-10-17 06:47:36 (GMT)
commit01bdab84e31763a98206c31cf99b9dc3cb221356 (patch)
tree1ddbd604045e4e2b89753fec95cd4ec6209c405b /git-svn.perl
parentca5e9495607c2abb4b665b75d3d96a457fa4c5dd (diff)
downloadgit-01bdab84e31763a98206c31cf99b9dc3cb221356.zip
git-01bdab84e31763a98206c31cf99b9dc3cb221356.tar.gz
git-01bdab84e31763a98206c31cf99b9dc3cb221356.tar.bz2
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>
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-xgit-svn.perl65
1 files changed, 45 insertions, 20 deletions
diff --git a/git-svn.perl b/git-svn.perl
index 1130a09..e217cdf 100755
--- a/git-svn.perl
+++ b/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);
}
}