Merge branch 'mh/git-svn-automkdirs'
authorJunio C Hamano <gitster@pobox.com>
Wed, 27 Apr 2011 18:36:41 +0000 (11:36 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 Apr 2011 18:36:41 +0000 (11:36 -0700)
* mh/git-svn-automkdirs:
git-svn: add an option to skip the creation of empty directories

1  2 
Documentation/git-svn.txt
git-svn.perl
index 30a67486d2dc9eb4169a9ba5ebd5db513a3a84f8,f470fbf82bf128511a34634ccb14208dd3ba7ac0..71fc0ae8c56320e08f995620d902c53a8a398664
@@@ -217,13 -217,6 +217,13 @@@ config key: svn.commiturl (overwrites a
  Using this option for any other purpose (don't ask) is very strongly
  discouraged.
  
 +--mergeinfo=<mergeinfo>;;
 +      Add the given merge information during the dcommit
 +      (e.g. `--mergeinfo="/branches/foo:1-10"`). All svn server versions can
 +      store this information (as a property), and svn clients starting from
 +      version 1.5 can make use of it. 'git svn' currently does not use it
 +      and does not set it automatically.
 +
  'branch'::
        Create a branch in the SVN repository.
  
@@@ -350,6 -343,8 +350,8 @@@ Any other arguments are passed directl
        Empty directories are automatically recreated when using
        "git svn clone" and "git svn rebase", so "mkdirs" is intended
        for use after commands like "git checkout" or "git reset".
+       (See the svn-remote.<name>.automkdirs config file option for
+       more information.)
  
  'commit-diff'::
        Commits the diff of two tree-ish arguments from the
@@@ -655,16 -650,6 +657,16 @@@ svn-remote.<name>.rewriteUUID:
        where the original UUID is not available via either useSvmProps
        or useSvnsyncProps.
  
 +svn-remote.<name>.pushurl::
 +
 +      Similar to git's 'remote.<name>.pushurl', this key is designed
 +      to be used in cases where 'url' points to an SVN repository
 +      via a read-only transport, to provide an alternate read/write
 +      transport. It is assumed that both keys point to the same
 +      repository. Unlike 'commiturl', 'pushurl' is a base path. If
 +      either 'commiturl' or 'pushurl' could be used, 'commiturl'
 +      takes precedence.
 +
  svn.brokenSymlinkWorkaround::
        This disables potentially expensive checks to workaround
        broken symlinks checked into SVN by broken clients.  Set this
@@@ -680,6 -665,14 +682,14 @@@ svn.pathnameencoding:
        locales to avoid corrupted file names with non-ASCII characters.
        Valid encodings are the ones supported by Perl's Encode module.
  
+ svn-remote.<name>.automkdirs::
+       Normally, the "git svn clone" and "git svn rebase" commands
+       attempt to recreate empty directories that are in the
+       Subversion repository.  If this option is set to "false", then
+       empty directories will only be created if the "git svn mkdirs"
+       command is run explicitly.  If unset, 'git svn' assumes this
+       option to be "true".
  Since the noMetadata, rewriteRoot, rewriteUUID, useSvnsyncProps and useSvmProps
  options all affect the metadata generated and used by 'git svn'; they
  *must* be set in the configuration file before any history is imported
diff --combined git-svn.perl
index bf0451b46835357af7811096538e9e7d75311166,9a9b0949f539f6cd475d449352d0004a0cc16400..0fd2fd2188b93fe15bda901f512bd55ad3a5034a
@@@ -59,7 -59,6 +59,7 @@@ use File::Find
  use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
  use IPC::Open3;
  use Git;
 +use Memoize;  # core since 5.8.0, Jul 2002
  
  BEGIN {
        # import functions from Git into our packages, en masse
@@@ -73,8 -72,6 +73,8 @@@
                        *{"${package}::$_"} = \&{"Git::$_"};
                }
        }
 +      Memoize::memoize 'Git::config';
 +      Memoize::memoize 'Git::config_bool';
  }
  
  my ($SVN);
@@@ -531,7 -528,7 +531,7 @@@ sub cmd_dcommit 
                $url = eval { command_oneline('config', '--get',
                              "svn-remote.$gs->{repo_id}.commiturl") };
                if (!$url) {
 -                      $url = $gs->full_url
 +                      $url = $gs->full_pushurl
                }
        }
  
@@@ -679,7 -676,7 +679,7 @@@ sub cmd_branch 
        $head ||= 'HEAD';
  
        my (undef, $rev, undef, $gs) = working_head_info($head);
 -      my $src = $gs->full_url;
 +      my $src = $gs->full_pushurl;
  
        my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}};
        my $allglobs = $remote->{ $_tag ? 'tags' : 'branches' };
                $url = eval { command_oneline('config', '--get',
                        "svn-remote.$gs->{repo_id}.commiturl") };
                if (!$url) {
 -                      $url = $remote->{url};
 +                      $url = $remote->{pushurl} || $remote->{url};
                }
        }
        my $dst = join '/', $url, $lft, $branch_name, ($rgt || ());
@@@ -784,6 -781,15 +784,15 @@@ sub cmd_find_rev 
        print "$result\n" if $result;
  }
  
+ sub auto_create_empty_directories {
+       my ($gs) = @_;
+       my $var = eval { command_oneline('config', '--get', '--bool',
+                                        "svn-remote.$gs->{repo_id}.automkdirs") };
+       # By default, create empty directories by consulting the unhandled log,
+       # but allow setting it to 'false' to skip it.
+       return !($var && $var eq 'false');
+ }
  sub cmd_rebase {
        command_noisy(qw/update-index --refresh/);
        my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
                $_fetch_all ? $gs->fetch_all : $gs->fetch;
        }
        command_noisy(rebase_cmd(), $gs->refname);
-       $gs->mkemptydirs;
+       if (auto_create_empty_directories($gs)) {
+               $gs->mkemptydirs;
+       }
  }
  
  sub cmd_show_ignore {
@@@ -1245,7 -1253,9 +1256,9 @@@ sub post_fetch_checkout 
        command_noisy(qw/read-tree -m -u -v HEAD HEAD/);
        print STDERR "Checked out HEAD:\n  ",
                     $gs->full_url, " r", $gs->last_rev, "\n";
-       $gs->mkemptydirs($gs->last_rev);
+       if (auto_create_empty_directories($gs)) {
+               $gs->mkemptydirs($gs->last_rev);
+       }
  }
  
  sub complete_svn_url {
@@@ -1834,8 -1844,6 +1847,8 @@@ sub read_all_remotes 
                        $r->{$1}->{svm} = {};
                } elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
                        $r->{$1}->{url} = $2;
 +              } elsif (m!^(.+)\.pushurl=\s*(.*)\s*$!) {
 +                      $r->{$1}->{pushurl} = $2;
                } elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
                        my ($remote, $t, $local_ref, $remote_ref) =
                                                             ($1, $2, $3, $4);
@@@ -2073,8 -2081,6 +2086,8 @@@ sub new 
        $self->{url} = command_oneline('config', '--get',
                                       "svn-remote.$repo_id.url") or
                    die "Failed to read \"svn-remote.$repo_id.url\" in config\n";
 +      $self->{pushurl} = eval { command_oneline('config', '--get',
 +                                "svn-remote.$repo_id.pushurl") };
        $self->rebuild;
        $self;
  }
@@@ -2552,15 -2558,6 +2565,15 @@@ sub full_url 
        $self->{url} . (length $self->{path} ? '/' . $self->{path} : '');
  }
  
 +sub full_pushurl {
 +      my ($self) = @_;
 +      if ($self->{pushurl}) {
 +              return $self->{pushurl} . (length $self->{path} ? '/' .
 +                     $self->{path} : '');
 +      } else {
 +              return $self->full_url;
 +      }
 +}
  
  sub set_commit_header_env {
        my ($log_entry) = @_;
@@@ -3213,8 -3210,6 +3226,8 @@@ sub has_no_changes 
                Memoize::unmemoize 'check_cherry_pick';
                Memoize::unmemoize 'has_no_changes';
        }
 +
 +      Memoize::memoize 'Git::SVN::repos_root';
  }
  
  END {