svnimport: Convert the svn:ignore property

Put the value of the svn:ignore property in a regular file when
converting a Subversion repository to GIT. The Subversion and GIT
ignore syntaxes are similar enough that it often just works to set the
filename to .gitignore and do nothing else.

Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Karl Hasselström
2006-02-26 06:11:29 +01:00
committed by Junio C Hamano
parent 4802426ddb
commit c55f3fff35
2 changed files with 64 additions and 4 deletions

View File

@ -13,7 +13,7 @@ SYNOPSIS
[ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev] [ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]
[ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ] [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]
[ -s start_chg ] [ -m ] [ -r ] [ -M regex ] [ -s start_chg ] [ -m ] [ -r ] [ -M regex ]
<SVN_repository_URL> [ <path> ] [ -I <ignorefile_name> ] <SVN_repository_URL> [ <path> ]
DESCRIPTION DESCRIPTION
@ -65,6 +65,12 @@ When importing incrementally, you might need to edit the .git/svn2git file.
Prepend 'rX: ' to commit messages, where X is the imported Prepend 'rX: ' to commit messages, where X is the imported
subversion revision. subversion revision.
-I <ignorefile_name>::
Import the svn:ignore directory property to files with this
name in each directory. (The Subversion and GIT ignore
syntaxes are similar enough that using the Subversion patterns
directly with "-I .gitignore" will almost always just work.)
-m:: -m::
Attempt to detect merges based on the commit message. This option Attempt to detect merges based on the commit message. This option
will enable default regexes that try to capture the name source will enable default regexes that try to capture the name source

View File

@ -29,19 +29,21 @@ die "Need SVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1";
$SIG{'PIPE'}="IGNORE"; $SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC"; $ENV{'TZ'}="UTC";
our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,$opt_b,$opt_r,$opt_s,$opt_l,$opt_d,$opt_D); our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,
$opt_b,$opt_r,$opt_I,$opt_s,$opt_l,$opt_d,$opt_D);
sub usage() { sub usage() {
print STDERR <<END; print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from SVN Usage: ${\basename $0} # fetch/update GIT from SVN
[-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-o branch-for-HEAD] [-h] [-v] [-l max_rev]
[-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname] [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
[-d|-D] [-i] [-u] [-r] [-s start_chg] [-m] [-M regex] [SVN_URL] [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
[-m] [-M regex] [SVN_URL]
END END
exit(1); exit(1);
} }
getopts("b:C:dDhil:mM:o:rs:t:T:uv") or usage(); getopts("b:C:dDhiI:l:mM:o:rs:t:T:uv") or usage();
usage if $opt_h; usage if $opt_h;
my $tag_name = $opt_t || "tags"; my $tag_name = $opt_t || "tags";
@ -130,6 +132,24 @@ sub file {
return ($name, $mode); return ($name, $mode);
} }
sub ignore {
my($self,$path,$rev) = @_;
print "... $rev $path ...\n" if $opt_v;
my (undef,undef,$properties)
= $self->{'svn'}->get_dir($path,$rev,undef);
if (exists $properties->{'svn:ignore'}) {
my ($fh, $name) = tempfile('gitsvn.XXXXXX',
DIR => File::Spec->tmpdir(),
UNLINK => 1);
print $fh $properties->{'svn:ignore'};
close($fh);
return $name;
} else {
return undef;
}
}
package main; package main;
use URI; use URI;
@ -341,6 +361,34 @@ sub get_file($$$) {
return [$mode, $sha, $path]; return [$mode, $sha, $path];
} }
sub get_ignore($$$$$) {
my($new,$old,$rev,$branch,$path) = @_;
return unless $opt_I;
my $svnpath = revert_split_path($branch,$path);
my $name = $svn->ignore("$svnpath",$rev);
if ($path eq '/') {
$path = $opt_I;
} else {
$path = File::Spec->catfile($path,$opt_I);
}
if (defined $name) {
my $pid = open(my $F, '-|');
die $! unless defined $pid;
if (!$pid) {
exec("git-hash-object", "-w", $name)
or die "Cannot create object: $!\n";
}
my $sha = <$F>;
chomp $sha;
close $F;
unlink $name;
push(@$new,['0644',$sha,$path]);
} else {
push(@$old,$path);
}
}
sub split_path($$) { sub split_path($$) {
my($rev,$path) = @_; my($rev,$path) = @_;
my $branch; my $branch;
@ -546,6 +594,9 @@ sub commit {
my $opath = $action->[3]; my $opath = $action->[3];
print STDERR "$revision: $branch: could not fetch '$opath'\n"; print STDERR "$revision: $branch: could not fetch '$opath'\n";
} }
} elsif ($node_kind eq $SVN::Node::dir) {
get_ignore(\@new, \@old, $revision,
$branch,$path);
} }
} elsif ($action->[0] eq "D") { } elsif ($action->[0] eq "D") {
push(@old,$path); push(@old,$path);
@ -554,6 +605,9 @@ sub commit {
if ($node_kind eq $SVN::Node::file) { if ($node_kind eq $SVN::Node::file) {
my $f = get_file($revision,$branch,$path); my $f = get_file($revision,$branch,$path);
push(@new,$f) if $f; push(@new,$f) if $f;
} elsif ($node_kind eq $SVN::Node::dir) {
get_ignore(\@new, \@old, $revision,
$branch,$path);
} }
} else { } else {
die "$revision: unknown action '".$action->[0]."' for $path\n"; die "$revision: unknown action '".$action->[0]."' for $path\n";