Code

Merge branch 'master' into db/fetch-pack
[git.git] / git-svn.perl
index 288d32cb160fcf1b7fdb8bbce9d800d971ced345..2c8a1580f8495b0f158802f8513a5df50aca3a02 100755 (executable)
@@ -1847,6 +1847,16 @@ sub find_parent_branch {
                        $gs->ra->gs_do_switch($r0, $rev, $gs,
                                              $self->full_url, $ed)
                          or die "SVN connection failed somewhere...\n";
+               } elsif ($self->ra->trees_match($new_url, $r0,
+                                               $self->full_url, $rev)) {
+                       print STDERR "Trees match:\n",
+                                    "  $new_url\@$r0\n",
+                                    "  ${\$self->full_url}\@$rev\n",
+                                    "Following parent with no changes\n";
+                       $self->tmp_index_do(sub {
+                           command_noisy('read-tree', $parent);
+                       });
+                       $self->{last_commit} = $parent;
                } else {
                        print STDERR "Following parent with do_update\n";
                        $ed = SVN::Git::Fetcher->new($self);
@@ -3027,30 +3037,57 @@ BEGIN {
        }
 }
 
+sub _auth_providers () {
+       [
+         SVN::Client::get_simple_provider(),
+         SVN::Client::get_ssl_server_trust_file_provider(),
+         SVN::Client::get_simple_prompt_provider(
+           \&Git::SVN::Prompt::simple, 2),
+         SVN::Client::get_ssl_client_cert_file_provider(),
+         SVN::Client::get_ssl_client_cert_prompt_provider(
+           \&Git::SVN::Prompt::ssl_client_cert, 2),
+         SVN::Client::get_ssl_client_cert_pw_prompt_provider(
+           \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
+         SVN::Client::get_username_provider(),
+         SVN::Client::get_ssl_server_trust_prompt_provider(
+           \&Git::SVN::Prompt::ssl_server_trust),
+         SVN::Client::get_username_prompt_provider(
+           \&Git::SVN::Prompt::username, 2)
+       ]
+}
+
 sub new {
        my ($class, $url) = @_;
        $url =~ s!/+$!!;
        return $RA if ($RA && $RA->{url} eq $url);
 
        SVN::_Core::svn_config_ensure($config_dir, undef);
-       my ($baton, $callbacks) = SVN::Core::auth_open_helper([
-           SVN::Client::get_simple_provider(),
-           SVN::Client::get_ssl_server_trust_file_provider(),
-           SVN::Client::get_simple_prompt_provider(
-             \&Git::SVN::Prompt::simple, 2),
-           SVN::Client::get_ssl_client_cert_file_provider(),
-           SVN::Client::get_ssl_client_cert_prompt_provider(
-             \&Git::SVN::Prompt::ssl_client_cert, 2),
-           SVN::Client::get_ssl_client_cert_pw_prompt_provider(
-             \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
-           SVN::Client::get_username_provider(),
-           SVN::Client::get_ssl_server_trust_prompt_provider(
-             \&Git::SVN::Prompt::ssl_server_trust),
-           SVN::Client::get_username_prompt_provider(
-             \&Git::SVN::Prompt::username, 2),
-         ]);
+       my ($baton, $callbacks) = SVN::Core::auth_open_helper(_auth_providers);
        my $config = SVN::Core::config_get_config($config_dir);
        $RA = undef;
+       my $dont_store_passwords = 1;
+       my $conf_t = ${$config}{'config'};
+       {
+               # The usage of $SVN::_Core::SVN_CONFIG_* variables
+               # produces warnings that variables are used only once.
+               # I had not found the better way to shut them up, so
+               # warnings are disabled in this block.
+               no warnings;
+               if (SVN::_Core::svn_config_get_bool($conf_t,
+                   $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
+                   $SVN::_Core::SVN_CONFIG_OPTION_STORE_PASSWORDS,
+                   1) == 0) {
+                       SVN::_Core::svn_auth_set_parameter($baton,
+                           $SVN::_Core::SVN_AUTH_PARAM_DONT_STORE_PASSWORDS,
+                           bless (\$dont_store_passwords, "_p_void"));
+               }
+               if (SVN::_Core::svn_config_get_bool($conf_t,
+                   $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
+                   $SVN::_Core::SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
+                   1) == 0) {
+                       $Git::SVN::Prompt::_no_auth_cache = 1;
+               }
+       }
        my $self = SVN::Ra->new(url => $url, auth => $baton,
                              config => $config,
                              pool => SVN::Pool->new,
@@ -3112,6 +3149,24 @@ sub get_log {
        $ret;
 }
 
+sub trees_match {
+       my ($self, $url1, $rev1, $url2, $rev2) = @_;
+       my $ctx = SVN::Client->new(auth => _auth_providers);
+       my $out = IO::File->new_tmpfile;
+
+       # older SVN (1.1.x) doesn't take $pool as the last parameter for
+       # $ctx->diff(), so we'll create a default one
+       my $pool = SVN::Pool->new_default_sub;
+
+       $ra_invalid = 1; # this will open a new SVN::Ra connection to $url1
+       $ctx->diff([], $url1, $rev1, $url2, $rev2, 1, 1, 0, $out, $out);
+       $out->flush;
+       my $ret = (($out->stat)[7] == 0);
+       close $out or croak $!;
+
+       $ret;
+}
+
 sub get_commit_editor {
        my ($self, $log, $cb, $pool) = @_;
        my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
@@ -3578,7 +3633,7 @@ sub config_pager {
 }
 
 sub run_pager {
-       return unless -t *STDOUT;
+       return unless -t *STDOUT && defined $pager;
        pipe my $rfd, my $wfd or return;
        defined(my $pid = fork) or ::fatal "Can't fork: $!\n";
        if (!$pid) {