summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Strickroth <sven.strickroth@tu-clausthal.de>2011-12-28 01:11:31 +0100
committerJunio C Hamano <gitster@pobox.com>2012-01-03 15:36:46 -0800
commita4ad8cda8c3c68c40c22b0ef118fa03b58a17d7d (patch)
tree666266852a4719400a5b9210750ca5d42e77e3ea
parent2ce0edcd786b790fed580e7df56291619834d276 (diff)
downloadgit-a4ad8cda8c3c68c40c22b0ef118fa03b58a17d7d.tar.gz
perl/Git.pm: "prompt" helper to honor GIT_ASKPASS and SSH_ASKPASS
git-svn reads passwords from an interactive terminal or by using GIT_ASKPASS helper tool. But if GIT_ASKPASS environment variable is not set, git-svn does not try to use SSH_ASKPASS as git-core does. This cause GUIs (w/o STDIN connected) to hang waiting forever for git-svn to complete (http://code.google.com/p/tortoisegit/issues/detail?id=967). Earlier, 56a853b (git-svn: Support retrieving passwords with GIT_ASKPASS, 2010-03-02) tried to solve this issue, but was incomplete as described above. Instead of using hand-rolled prompt-response code that only works with the interactive terminal and uses GIT_ASKPASS, introduce prompt() helper function in Git.pm library that also pays attention to SSH_ASKPASS as a fallback, and use it in git-svn. The result mimics the behaviour of the core git better. Signed-off-by: Sven Strickroth <email@cs-ware.de> Helped-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-xgit-svn.perl20
-rw-r--r--perl/Git.pm51
2 files changed, 51 insertions, 20 deletions
diff --git a/git-svn.perl b/git-svn.perl
index e30df22d89..6a0117640d 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -4415,25 +4415,7 @@ sub username {
sub _read_password {
my ($prompt, $realm) = @_;
- my $password = '';
- if (exists $ENV{GIT_ASKPASS}) {
- open(PH, "-|", $ENV{GIT_ASKPASS}, $prompt);
- $password = <PH>;
- $password =~ s/[\012\015]//; # \n\r
- close(PH);
- } else {
- print STDERR $prompt;
- STDERR->flush;
- require Term::ReadKey;
- Term::ReadKey::ReadMode('noecho');
- while (defined(my $key = Term::ReadKey::ReadKey(0))) {
- last if $key =~ /[\012\015]/; # \n\r
- $password .= $key;
- }
- Term::ReadKey::ReadMode('restore');
- print STDERR "\n";
- STDERR->flush;
- }
+ my $password = Git::prompt($prompt);
$password;
}
diff --git a/perl/Git.pm b/perl/Git.pm
index f7ce511bbb..46f11a89de 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -58,7 +58,7 @@ require Exporter;
command_output_pipe command_input_pipe command_close_pipe
command_bidi_pipe command_close_bidi_pipe
version exec_path html_path hash_object git_cmd_try
- remote_refs
+ remote_refs prompt
temp_acquire temp_release temp_reset temp_path);
@@ -512,6 +512,55 @@ C<git --html-path>). Useful mostly only internally.
sub html_path { command_oneline('--html-path') }
+=item prompt ( PROMPT )
+
+Query user C<PROMPT> and return answer from user.
+
+If an external helper is specified via GIT_ASKPASS or SSH_ASKPASS, it
+is used to interact with the user; otherwise the prompt is given to
+and the answer is read from the terminal.
+
+=cut
+
+sub prompt {
+ my ($prompt) = @_;
+ my $ret;
+ if (!defined $ret) {
+ $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
+ }
+ if (!defined $ret) {
+ $ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt);
+ }
+ if (!defined $ret) {
+ $ret = '';
+ print STDERR $prompt;
+ STDERR->flush;
+ require Term::ReadKey;
+ Term::ReadKey::ReadMode('noecho');
+ while (defined(my $key = Term::ReadKey::ReadKey(0))) {
+ last if $key =~ /[\012\015]/; # \n\r
+ $ret .= $key;
+ }
+ Term::ReadKey::ReadMode('restore');
+ print STDERR "\n";
+ STDERR->flush;
+ }
+ return $ret;
+}
+
+sub _prompt {
+ my ($askpass, $prompt) = @_;
+ return unless ($askpass);
+
+ open my $fh, "-|", $askpass, $prompt
+ or return;
+ my $ret = <$fh>;
+ $ret =~ s/[\012\015]//g; # \n\r
+ close ($fh);
+ return $ret;
+}
+
+
=item repo_path ()
Return path to the git repository. Must be called on a repository instance.