Merge branch 'ag/git-svn-global-ignores'

"git svn" has been taught about svn:global-ignores property
recent versions of Subversion has.

* ag/git-svn-global-ignores:
  git-svn: mention `svn:global-ignores` in help+docs
  git-svn: use `svn:global-ignores` to create .gitignore
  git-svn: add public property `svn:global-ignores`
maint
Junio C Hamano 2024-08-21 12:02:23 -07:00
commit d97956b8bd
3 changed files with 42 additions and 25 deletions

View File

@ -431,14 +431,14 @@ Any other arguments are passed directly to 'git log'
independently of 'git svn' functions. independently of 'git svn' functions.


'create-ignore':: 'create-ignore'::
Recursively finds the svn:ignore property on directories and Recursively finds the svn:ignore and svn:global-ignores properties
creates matching .gitignore files. The resulting files are staged to on directories and creates matching .gitignore files. The resulting
be committed, but are not committed. Use -r/--revision to refer to a files are staged to be committed, but are not committed. Use
specific revision. -r/--revision to refer to a specific revision.


'show-ignore':: 'show-ignore'::
Recursively finds and lists the svn:ignore property on Recursively finds and lists the svn:ignore and svn:global-ignores
directories. The output is suitable for appending to properties on directories. The output is suitable for appending to
the $GIT_DIR/info/exclude file. the $GIT_DIR/info/exclude file.


'mkdirs':: 'mkdirs'::
@ -871,7 +871,7 @@ Tracking and contributing to the trunk of a Subversion-managed project
# Now commit your changes (that were committed previously using Git) to SVN, # Now commit your changes (that were committed previously using Git) to SVN,
# as well as automatically updating your working HEAD: # as well as automatically updating your working HEAD:
git svn dcommit git svn dcommit
# Append svn:ignore settings to the default Git exclude file: # Append svn:ignore and svn:global-ignores settings to the default Git exclude file:
git svn show-ignore >> .git/info/exclude git svn show-ignore >> .git/info/exclude
------------------------------------------------------------------------ ------------------------------------------------------------------------



View File

@ -219,11 +219,11 @@ my %cmd = (
"Set an SVN repository to a git tree-ish", "Set an SVN repository to a git tree-ish",
{ 'stdin' => \$_stdin, %cmt_opts, %fc_opts, } ], { 'stdin' => \$_stdin, %cmt_opts, %fc_opts, } ],
'create-ignore' => [ \&cmd_create_ignore, 'create-ignore' => [ \&cmd_create_ignore,
'Create a .gitignore per svn:ignore', "Create a .gitignore per directory with SVN ignore properties",
{ 'revision|r=i' => \$_revision { 'revision|r=i' => \$_revision
} ], } ],
'mkdirs' => [ \&cmd_mkdirs , 'mkdirs' => [ \&cmd_mkdirs ,
"recreate empty directories after a checkout", "Recreate empty directories after a checkout",
{ 'revision|r=i' => \$_revision } ], { 'revision|r=i' => \$_revision } ],
'propget' => [ \&cmd_propget, 'propget' => [ \&cmd_propget,
'Print the value of a property on a file or directory', 'Print the value of a property on a file or directory',
@ -234,7 +234,7 @@ my %cmd = (
'proplist' => [ \&cmd_proplist, 'proplist' => [ \&cmd_proplist,
'List all properties of a file or directory', 'List all properties of a file or directory',
{ 'revision|r=i' => \$_revision } ], { 'revision|r=i' => \$_revision } ],
'show-ignore' => [ \&cmd_show_ignore, "Show svn:ignore listings", 'show-ignore' => [ \&cmd_show_ignore, "Show .gitignore patterns from SVN ignore properties",
{ 'revision|r=i' => \$_revision { 'revision|r=i' => \$_revision
} ], } ],
'show-externals' => [ \&cmd_show_externals, "Show svn:externals listings", 'show-externals' => [ \&cmd_show_externals, "Show svn:externals listings",
@ -1279,12 +1279,20 @@ sub cmd_show_ignore {
$gs->prop_walk($gs->path, $r, sub { $gs->prop_walk($gs->path, $r, sub {
my ($gs, $path, $props) = @_; my ($gs, $path, $props) = @_;
print STDOUT "\n# $path\n"; print STDOUT "\n# $path\n";
my $s = $props->{'svn:ignore'} or return; if (my $s = $props->{'svn:ignore'}) {
$s =~ s/[\r\n]+/\n/g; $s =~ s/[\r\n]+/\n/g;
$s =~ s/^\n+//; $s =~ s/^\n+//;
chomp $s; chomp $s;
$s =~ s#^#$path#gm; $s =~ s#^#$path#gm;
print STDOUT "$s\n"; print STDOUT "$s\n";
}
if (my $s = $props->{'svn:global-ignores'}) {
$s =~ s/[\r\n]+/\n/g;
$s =~ s/^\n+//;
chomp $s;
$s =~ s#^#$path**/#gm;
print STDOUT "$s\n";
}
}); });
} }


@ -1315,16 +1323,25 @@ sub cmd_create_ignore {
# which git won't track # which git won't track
mkpath([$path]) unless -d $path; mkpath([$path]) unless -d $path;
my $ignore = $path . '.gitignore'; my $ignore = $path . '.gitignore';
my $s = $props->{'svn:ignore'} or return;
open(GITIGNORE, '>', $ignore) open(GITIGNORE, '>', $ignore)
or fatal("Failed to open `$ignore' for writing: $!"); or fatal("Failed to open `$ignore' for writing: $!");
$s =~ s/[\r\n]+/\n/g; if (my $s = $props->{'svn:ignore'}) {
$s =~ s/^\n+//; $s =~ s/[\r\n]+/\n/g;
chomp $s; $s =~ s/^\n+//;
# Prefix all patterns so that the ignore doesn't apply chomp $s;
# to sub-directories. # Prefix all patterns so that the ignore doesn't apply
$s =~ s#^#/#gm; # to sub-directories.
print GITIGNORE "$s\n"; $s =~ s#^#/#gm;
print GITIGNORE "$s\n";
}
if (my $s = $props->{'svn:global-ignores'}) {
$s =~ s/[\r\n]+/\n/g;
$s =~ s/^\n+//;
chomp $s;
# Global ignores apply to sub-directories, so they are
# not prefixed.
print GITIGNORE "$s\n";
}
close(GITIGNORE) close(GITIGNORE)
or fatal("Failed to close `$ignore': $!"); or fatal("Failed to close `$ignore': $!");
command_noisy('add', '-f', $ignore); command_noisy('add', '-f', $ignore);

View File

@ -763,7 +763,7 @@ sub prop_walk {
# this needs to be updated. # this needs to be updated.
++$interesting_props if /^svn:(?:ignore|keywords|executable ++$interesting_props if /^svn:(?:ignore|keywords|executable
|eol-style|mime-type |eol-style|mime-type
|externals|needs-lock)$/x; |externals|needs-lock|global-ignores)$/x;
} }
&$sub($self, $p, $props) if $interesting_props; &$sub($self, $p, $props) if $interesting_props;