diff options
author | Sven Strickroth <sven.strickroth@tu-clausthal.de> | 2011-12-28 01:11:31 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-01-03 15:36:46 -0800 |
commit | a4ad8cda8c3c68c40c22b0ef118fa03b58a17d7d (patch) | |
tree | 666266852a4719400a5b9210750ca5d42e77e3ea | |
parent | 2ce0edcd786b790fed580e7df56291619834d276 (diff) | |
download | git-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-x | git-svn.perl | 20 | ||||
-rw-r--r-- | perl/Git.pm | 51 |
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. |