git/prompt.c
Patrick Steinhardt 673af418d0 environment: guard state depending on a repository
In "environment.h" we have quite a lot of functions and variables that
either explicitly or implicitly depend on `the_repository`.

The implicit set of stateful declarations includes for example variables
which get populated when parsing a repository's Git configuration. This
set of variables is broken by design, as their state often depends on
the last repository config that has been parsed. So they may or may not
represent the state of `the_repository`.

Fixing that is quite a big undertaking, and later patches in this series
will demonstrate a solution for a first small set of those variables. So
for now, let's guard these with `USE_THE_REPOSITORY_VARIABLE` so that
callers are aware of the implicit dependency.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-12 10:15:42 -07:00

89 lines
1.7 KiB
C

#define USE_THE_REPOSITORY_VARIABLE
#include "git-compat-util.h"
#include "parse.h"
#include "environment.h"
#include "run-command.h"
#include "strbuf.h"
#include "prompt.h"
#include "compat/terminal.h"
static char *do_askpass(const char *cmd, const char *prompt)
{
struct child_process pass = CHILD_PROCESS_INIT;
static struct strbuf buffer = STRBUF_INIT;
int err = 0;
strvec_push(&pass.args, cmd);
strvec_push(&pass.args, prompt);
pass.out = -1;
if (start_command(&pass))
return NULL;
strbuf_reset(&buffer);
if (strbuf_read(&buffer, pass.out, 20) < 0)
err = 1;
close(pass.out);
if (finish_command(&pass))
err = 1;
if (err) {
error("unable to read askpass response from '%s'", cmd);
strbuf_release(&buffer);
return NULL;
}
strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
return buffer.buf;
}
char *git_prompt(const char *prompt, int flags)
{
char *r = NULL;
if (flags & PROMPT_ASKPASS) {
const char *askpass;
askpass = getenv("GIT_ASKPASS");
if (!askpass)
askpass = askpass_program;
if (!askpass)
askpass = getenv("SSH_ASKPASS");
if (askpass && *askpass)
r = do_askpass(askpass, prompt);
}
if (!r) {
const char *err;
if (git_env_bool("GIT_TERMINAL_PROMPT", 1)) {
r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
err = strerror(errno);
} else {
err = "terminal prompts disabled";
}
if (!r) {
/* prompts already contain ": " at the end */
die("could not read %s%s", prompt, err);
}
}
return r;
}
int git_read_line_interactively(struct strbuf *line)
{
int ret;
fflush(stdout);
ret = strbuf_getline_lf(line, stdin);
if (ret != EOF)
strbuf_trim_trailing_newline(line);
return ret;
}