Skip to content

Commit 9a4a941

Browse files
committed
Merge branch 'ss/svn-prompt' into maint
The way "git svn" asked for password using SSH_ASKPASS and GIT_ASKPASS was not in line with the rest of the system. * ss/svn-prompt: git-svn, perl/Git.pm: extend and use Git->prompt method for querying users perl/Git.pm: Honor SSH_ASKPASS as fallback if GIT_ASKPASS is not set git-svn, perl/Git.pm: add central method for prompting passwords
2 parents bf7c3f7 + e9263e4 commit 9a4a941

File tree

2 files changed

+60
-28
lines changed

2 files changed

+60
-28
lines changed

perl/Git.pm

Lines changed: 53 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,58 @@ C<git --html-path>). Useful mostly only internally.
511511

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

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 {
526+
my ($prompt, $isPassword) = @_;
527+
my $ret;
528+
if (exists $ENV{'GIT_ASKPASS'}) {
529+
$ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
530+
}
531+
if (!defined $ret && exists $ENV{'SSH_ASKPASS'}) {
532+
$ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt);
533+
}
534+
if (!defined $ret) {
535+
print STDERR $prompt;
536+
STDERR->flush;
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+
}
551+
}
552+
return $ret;
553+
}
554+
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>;
562+
$ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
563+
close ($fh);
564+
return $ret;
565+
}
514566

515567
=item repo_path ()
516568

perl/Git/SVN/Prompt.pm

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ sub ssl_server_trust {
6262
issuer_dname fingerprint);
6363
my $choice;
6464
prompt:
65-
print STDERR $may_save ?
65+
my $options = $may_save ?
6666
"(R)eject, accept (t)emporarily or accept (p)ermanently? " :
6767
"(R)eject or accept (t)emporarily? ";
6868
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') {
7171
$cred->may_save(undef);
72-
} elsif ($choice =~ /^r$/i) {
72+
} elsif ($choice eq 'r') {
7373
return -1;
74-
} elsif ($may_save && $choice =~ /^p$/i) {
74+
} elsif ($may_save && $choice eq 'p') {
7575
$cred->may_save($may_save);
7676
} else {
7777
goto prompt;
@@ -109,9 +109,7 @@ sub username {
109109
if (defined $_username) {
110110
$username = $_username;
111111
} else {
112-
print STDERR "Username: ";
113-
STDERR->flush;
114-
chomp($username = <STDIN>);
112+
$username = Git::prompt("Username: ");
115113
}
116114
$cred->username($username);
117115
$cred->may_save($may_save);
@@ -120,25 +118,7 @@ sub username {
120118

121119
sub _read_password {
122120
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-
}
121+
my $password = Git::prompt($prompt, 1);
142122
$password;
143123
}
144124

0 commit comments

Comments
 (0)