diff options
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-x | git-svn.perl | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/git-svn.perl b/git-svn.perl index b6e2186cef..fa5f253065 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -11,14 +11,10 @@ $AUTHOR = 'Eric Wong <normalperson@yhbt.net>'; $VERSION = '@@GIT_VERSION@@'; use Carp qw/croak/; -use Digest::MD5; -use IO::File qw//; use File::Basename qw/dirname basename/; use File::Path qw/mkpath/; use File::Spec; -use File::Find; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/; -use IPC::Open3; use Memoize; use Git::SVN; @@ -115,7 +111,7 @@ my ($_stdin, $_help, $_edit, $_before, $_after, $_merge, $_strategy, $_preserve_merges, $_dry_run, $_parents, $_local, $_prefix, $_no_checkout, $_url, $_verbose, - $_commit_url, $_tag, $_merge_info, $_interactive); + $_commit_url, $_tag, $_merge_info, $_interactive, $_set_svn_props); # This is a refactoring artifact so Git::SVN can get at this git-svn switch. sub opt_prefix { return $_prefix || '' } @@ -193,6 +189,7 @@ my %cmd = ( 'dry-run|n' => \$_dry_run, 'fetch-all|all' => \$_fetch_all, 'commit-url=s' => \$_commit_url, + 'set-svn-props=s' => \$_set_svn_props, 'revision|r=i' => \$_revision, 'no-rebase' => \$_no_rebase, 'mergeinfo=s' => \$_merge_info, @@ -228,6 +225,9 @@ my %cmd = ( 'propget' => [ \&cmd_propget, 'Print the value of a property on a file or directory', { 'revision|r=i' => \$_revision } ], + 'propset' => [ \&cmd_propset, + 'Set the value of a property on a file or directory - will be set on commit', + {} ], 'proplist' => [ \&cmd_proplist, 'List all properties of a file or directory', { 'revision|r=i' => \$_revision } ], @@ -294,7 +294,6 @@ my %cmd = ( {} ], ); -use Term::ReadLine; package FakeTerm; sub new { my ($class, $reason) = @_; @@ -309,6 +308,7 @@ package main; my $term; sub term_init { $term = eval { + require Term::ReadLine; $ENV{"GIT_SVN_NOTTY"} ? new Term::ReadLine 'git-svn', \*STDIN, \*STDOUT : new Term::ReadLine 'git-svn'; @@ -333,6 +333,12 @@ for (my $i = 0; $i < @ARGV; $i++) { # make sure we're always running at the top-level working directory if ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) { $ENV{GIT_DIR} ||= ".git"; + # catch the submodule case + if (-f $ENV{GIT_DIR}) { + open(my $fh, '<', $ENV{GIT_DIR}) or + die "failed to open $ENV{GIT_DIR}: $!\n"; + $ENV{GIT_DIR} = $1 if <$fh> =~ /^gitdir: (.+)$/; + } } else { my ($git_dir, $cdup); git_cmd_try { @@ -1163,6 +1169,7 @@ sub cmd_branch { } ::_req_svn(); + require SVN::Client; my $ctx = SVN::Client->new( config => SVN::Core::config_get_config( @@ -1376,6 +1383,49 @@ sub cmd_propget { print $props->{$prop} . "\n"; } +# cmd_propset (PROPNAME, PROPVAL, PATH) +# ------------------------ +# Adjust the SVN property PROPNAME to PROPVAL for PATH. +sub cmd_propset { + my ($propname, $propval, $path) = @_; + $path = '.' if not defined $path; + $path = $cmd_dir_prefix . $path; + usage(1) if not defined $propname; + usage(1) if not defined $propval; + my $file = basename($path); + my $dn = dirname($path); + my $cur_props = Git::SVN::Editor::check_attr( "svn-properties", $path ); + my @new_props; + if (!$cur_props || $cur_props eq "unset" || $cur_props eq "" || $cur_props eq "set") { + push @new_props, "$propname=$propval"; + } else { + # TODO: handle combining properties better + my @props = split(/;/, $cur_props); + my $replaced_prop; + foreach my $prop (@props) { + # Parse 'name=value' syntax and set the property. + if ($prop =~ /([^=]+)=(.*)/) { + my ($n,$v) = ($1,$2); + if ($n eq $propname) { + $v = $propval; + $replaced_prop = 1; + } + push @new_props, "$n=$v"; + } + } + if (!$replaced_prop) { + push @new_props, "$propname=$propval"; + } + } + my $attrfile = "$dn/.gitattributes"; + open my $attrfh, '>>', $attrfile or die "Can't open $attrfile: $!\n"; + # TODO: don't simply append here if $file already has svn-properties + my $new_props = join(';', @new_props); + print $attrfh "$file svn-properties=$new_props\n" or + die "write to $attrfile: $!\n"; + close $attrfh or die "close $attrfile: $!\n"; +} + # cmd_proplist (PATH) # ------------------- # Print the list of SVN properties for PATH. @@ -1640,11 +1690,13 @@ sub cmd_reset { } sub cmd_gc { + require File::Find; if (!can_compress()) { warn "Compress::Zlib could not be found; unhandled.log " . "files will not be compressed.\n"; } - find({ wanted => \&gc_directory, no_chdir => 1}, "$ENV{GIT_DIR}/svn"); + File::Find::find({ wanted => \&gc_directory, no_chdir => 1}, + "$ENV{GIT_DIR}/svn"); } ########################### utility functions ######################### @@ -1872,7 +1924,7 @@ sub load_authors { my $log = $cmd eq 'log'; while (<$authors>) { chomp; - next unless /^(.+?|\(no author\))\s*=\s*(.+?)\s*<(.+)>\s*$/; + next unless /^(.+?|\(no author\))\s*=\s*(.+?)\s*<(.*)>\s*$/; my ($user, $name, $email) = ($1, $2, $3); if ($log) { $Git::SVN::Log::rusers{"$name <$email>"} = $user; @@ -2069,6 +2121,7 @@ sub find_file_type_and_diff_status { sub md5sum { my $arg = shift; my $ref = ref $arg; + require Digest::MD5; my $md5 = Digest::MD5->new(); if ($ref eq 'GLOB' || $ref eq 'IO::File' || $ref eq 'File::Temp') { $md5->addfile($arg) or croak $!; @@ -2095,6 +2148,7 @@ sub gc_directory { $gz->gzwrite($str) or die "Unable to write: ".$gz->gzerror()."!\n"; } + no warnings 'once'; # $File::Find::name would warn unlink $_ or die "unlink $File::Find::name: $!\n"; } elsif (-f $_ && basename($_) eq "index") { unlink $_ or die "unlink $_: $!\n"; |