Skip to content

Commit 38ecf3a

Browse files
Sven Strickrothgitster
authored andcommitted
git-svn, perl/Git.pm: add central method for prompting passwords
git-svn reads passwords from an interactive terminal or by using GIT_ASKPASS helper tool. 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). Commit 56a853b also 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, a reusable prompt() method is introduced in this commit. Signed-off-by: Sven Strickroth <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bdd478d commit 38ecf3a

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

perl/Git.pm

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ require Exporter;
5858
command_output_pipe command_input_pipe command_close_pipe
5959
command_bidi_pipe command_close_bidi_pipe
6060
version exec_path html_path hash_object git_cmd_try
61-
remote_refs
61+
remote_refs prompt
6262
temp_acquire temp_release temp_reset temp_path);
6363

6464

@@ -511,6 +511,49 @@ C<git --html-path>). Useful mostly only internally.
511511

512512
sub html_path { command_oneline('--html-path') }
513513

514+
=item prompt ( PROMPT )
515+
516+
Query user C<PROMPT> and return answer from user.
517+
518+
Honours GIT_ASKPASS environment variable for querying
519+
the user. If no GIT_ASKPASS variable is set or an error occoured,
520+
the terminal is tried as a fallback.
521+
522+
=cut
523+
524+
sub prompt {
525+
my ($prompt) = @_;
526+
my $ret;
527+
if (exists $ENV{'GIT_ASKPASS'}) {
528+
$ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
529+
}
530+
if (!defined $ret) {
531+
print STDERR $prompt;
532+
STDERR->flush;
533+
require Term::ReadKey;
534+
Term::ReadKey::ReadMode('noecho');
535+
$ret = '';
536+
while (defined(my $key = Term::ReadKey::ReadKey(0))) {
537+
last if $key =~ /[\012\015]/; # \n\r
538+
$ret .= $key;
539+
}
540+
Term::ReadKey::ReadMode('restore');
541+
print STDERR "\n";
542+
STDERR->flush;
543+
}
544+
return $ret;
545+
}
546+
547+
sub _prompt {
548+
my ($askpass, $prompt) = @_;
549+
return unless length $askpass;
550+
my $ret;
551+
open my $fh, "-|", $askpass, $prompt or return;
552+
$ret = <$fh>;
553+
$ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
554+
close ($fh);
555+
return $ret;
556+
}
514557

515558
=item repo_path ()
516559

perl/Git/SVN/Prompt.pm

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -120,25 +120,7 @@ sub username {
120120

121121
sub _read_password {
122122
my ($prompt, $realm) = @_;
123-
my $password = '';
124-
if (exists $ENV{GIT_ASKPASS}) {
125-
open(PH, "-|", $ENV{GIT_ASKPASS}, $prompt);
126-
$password = <PH>;
127-
$password =~ s/[\012\015]//; # \n\r
128-
close(PH);
129-
} else {
130-
print STDERR $prompt;
131-
STDERR->flush;
132-
require Term::ReadKey;
133-
Term::ReadKey::ReadMode('noecho');
134-
while (defined(my $key = Term::ReadKey::ReadKey(0))) {
135-
last if $key =~ /[\012\015]/; # \n\r
136-
$password .= $key;
137-
}
138-
Term::ReadKey::ReadMode('restore');
139-
print STDERR "\n";
140-
STDERR->flush;
141-
}
123+
my $password = Git::prompt($prompt);
142124
$password;
143125
}
144126

0 commit comments

Comments
 (0)