environment: move askpass_program into repo_config_values

The global variable 'askpass_program' stores the path to the program used to prompt the user for credentials. Move it into repo_config_values to continue the libification effort. While it is uncommon for a single process to require different askpass programs for different repositories, maintaining this value as a mutable global string is a blocker for libification. Global heap-allocated strings introduce thread-safety issues in a multi-repo environment. Move 'askpass_program' into 'struct repo_config_values' to eliminate this global state. The memory is now safely managed and freed via 'repo_config_values_clear()'. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com> Mentored-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Tian Yuchen <cat@malon.dev> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Tian Yuchen committed Jul 14, 2026 at 11:25 UTC 48cbe400794bd055d259143a01024da71da5fe1a
3 files changed +7 -6
environment.c
+4 -3
@@ -55,7 +55,6 @@ int fsync_object_files = -1;
55 int use_fsync = -1;
56 enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;
57 enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;
58 -char *askpass_program;
58 enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
59 enum eol core_eol = EOL_UNSET;
60 int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
@@ -464,8 +463,8 @@ int git_default_core_config(const char *var, const char *value,
463 }
464
465 if (!strcmp(var, "core.askpass")) {
467 - FREE_AND_NULL(askpass_program);
468 - return git_config_string(&askpass_program, var, value);
466 + FREE_AND_NULL(cfg->askpass_program);
467 + return git_config_string(&cfg->askpass_program, var, value);
468 }
469
470 if (!strcmp(var, "core.excludesfile")) {
@@ -726,6 +725,7 @@ void repo_config_values_init(struct repo_config_values *cfg)
725 cfg->excludes_file = NULL;
726 cfg->editor_program = NULL;
727 cfg->pager_program = NULL;
728 + cfg->askpass_program = NULL;
729 cfg->apply_sparse_checkout = 0;
730 cfg->branch_track = BRANCH_TRACK_REMOTE;
731 cfg->trust_ctime = 1;
@@ -744,4 +744,5 @@ void repo_config_values_clear(struct repo_config_values *cfg)
744 FREE_AND_NULL(cfg->excludes_file);
745 FREE_AND_NULL(cfg->editor_program);
746 FREE_AND_NULL(cfg->pager_program);
747 + FREE_AND_NULL(cfg->askpass_program);
748 }
environment.h
+1 -2
@@ -93,6 +93,7 @@ struct repo_config_values {
93 char *excludes_file;
94 char *editor_program;
95 char *pager_program;
96 + char *askpass_program;
97 int apply_sparse_checkout;
98 int trust_ctime;
99 int check_stat;
@@ -220,8 +221,6 @@ const char *get_commit_output_encoding(void);
221 extern char *git_commit_encoding;
222 extern char *git_log_output_encoding;
223
223 -extern char *askpass_program;
224 -
224 /*
225 * The character that begins a commented line in user-editable file
226 * that is subject to stripspace.
prompt.c
+2 -1
@@ -3,6 +3,7 @@
3 #include "git-compat-util.h"
4 #include "parse.h"
5 #include "environment.h"
6 +#include "repository.h"
7 #include "run-command.h"
8 #include "strbuf.h"
9 #include "prompt.h"
@@ -51,7 +52,7 @@ char *git_prompt(const char *prompt, int flags)
52
53 askpass = getenv("GIT_ASKPASS");
54 if (!askpass)
54 - askpass = askpass_program;
55 + askpass = repo_config_values(the_repository)->askpass_program;
56 if (!askpass)
57 askpass = getenv("SSH_ASKPASS");
58 if (askpass && *askpass)