git-svn, perl/Git.pm: extend and use Git->prompt method for querying users

git-svn reads usernames and other user queries from an interactive terminal. 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). This change extends the Git::prompt helper, so that it can also be used for non password queries, and makes use of it instead of using hand-rolled prompt-response code that only works with the interactive terminal. Signed-off-by: Sven Strickroth <email@cs-ware.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Sven Strickroth committed Dec 18, 2012 at 01:28 UTC e9263e458055ab361a7292adc800d3e62b47b39f
2 files changed +24 -20
perl/Git.pm
+17 -11
@@ -511,18 +511,19 @@ C<git --html-path>). Useful mostly only internally.
511
512 sub html_path { command_oneline('--html-path') }
513
514 -=item prompt ( PROMPT )
514 +=item prompt ( PROMPT , ISPASSWORD )
515
516 Query user C<PROMPT> and return answer from user.
517
518 Honours GIT_ASKPASS and SSH_ASKPASS environment variables for querying
519 the user. If no *_ASKPASS variable is set or an error occoured,
520 the terminal is tried as a fallback.
521 +If C<ISPASSWORD> is set and true, the terminal disables echo.
522
523 =cut
524
525 sub prompt {
525 - my ($prompt) = @_;
526 + my ($prompt, $isPassword) = @_;
527 my $ret;
528 if (exists $ENV{'GIT_ASKPASS'}) {
529 $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
@@ -533,16 +534,20 @@ sub prompt {
534 if (!defined $ret) {
535 print STDERR $prompt;
536 STDERR->flush;
536 - require Term::ReadKey;
537 - Term::ReadKey::ReadMode('noecho');
538 - $ret = '';
539 - while (defined(my $key = Term::ReadKey::ReadKey(0))) {
540 - last if $key =~ /[\012\015]/; # \n\r
541 - $ret .= $key;
537 + if (defined $isPassword && $isPassword) {
538 + require Term::ReadKey;
539 + Term::ReadKey::ReadMode('noecho');
540 + $ret = '';
541 + while (defined(my $key = Term::ReadKey::ReadKey(0))) {
542 + last if $key =~ /[\012\015]/; # \n\r
543 + $ret .= $key;
544 + }
545 + Term::ReadKey::ReadMode('restore');
546 + print STDERR "\n";
547 + STDERR->flush;
548 + } else {
549 + chomp($ret = <STDIN>);
550 }
543 - Term::ReadKey::ReadMode('restore');
544 - print STDERR "\n";
545 - STDERR->flush;
551 }
552 return $ret;
553 }
@@ -550,6 +555,7 @@ sub prompt {
555 sub _prompt {
556 my ($askpass, $prompt) = @_;
557 return unless length $askpass;
558 + $prompt =~ s/\n/ /g;
559 my $ret;
560 open my $fh, "-|", $askpass, $prompt or return;
561 $ret = <$fh>;
perl/Git/SVN/Prompt.pm
+7 -9
@@ -62,16 +62,16 @@ sub ssl_server_trust {
62 issuer_dname fingerprint);
63 my $choice;
64 prompt:
65 - print STDERR $may_save ?
65 + my $options = $may_save ?
66 "(R)eject, accept (t)emporarily or accept (p)ermanently? " :
67 "(R)eject or accept (t)emporarily? ";
68 STDERR->flush;
69 - $choice = lc(substr(<STDIN> || 'R', 0, 1));
70 - if ($choice =~ /^t$/i) {
69 + $choice = lc(substr(Git::prompt("Certificate problem.\n" . $options) || 'R', 0, 1));
70 + if ($choice eq 't') {
71 $cred->may_save(undef);
72 - } elsif ($choice =~ /^r$/i) {
72 + } elsif ($choice eq 'r') {
73 return -1;
74 - } elsif ($may_save && $choice =~ /^p$/i) {
74 + } elsif ($may_save && $choice eq 'p') {
75 $cred->may_save($may_save);
76 } else {
77 goto prompt;
@@ -109,9 +109,7 @@ sub username {
109 if (defined $_username) {
110 $username = $_username;
111 } else {
112 - print STDERR "Username: ";
113 - STDERR->flush;
114 - chomp($username = <STDIN>);
112 + $username = Git::prompt("Username: ");
113 }
114 $cred->username($username);
115 $cred->may_save($may_save);
@@ -120,7 +118,7 @@ sub username {
118
119 sub _read_password {
120 my ($prompt, $realm) = @_;
123 - my $password = Git::prompt($prompt);
121 + my $password = Git::prompt($prompt, 1);
122 $password;
123 }
124