From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, Derrick Stolee <stolee@gmail.com>,
Derrick Stolee <stolee@gmail.com>
Subject: [PATCH 07/11] config: extract location structs from builtin
Date: Wed, 04 Feb 2026 14:19:59 +0000 [thread overview]
Message-ID: <4be089a4dda63fdc0ea2db00acb47b33befe07ef.1770214803.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2033.git.1770214803.gitgitgadget@gmail.com>
From: Derrick Stolee <stolee@gmail.com>
Before reusing these concepts in builtin/config-batch.c, extract the
config_location_options struct from builtin/config.c to config.h with
implementation in config.c.
The only modification in this conversion is the use of a repository
parameter instead of the_repository.
Signed-off-by: Derrick Stolee <stolee@gmail.com>
---
builtin/config.c | 117 ++++-------------------------------------------
config.c | 89 +++++++++++++++++++++++++++++++++++
config.h | 20 ++++++++
3 files changed, 117 insertions(+), 109 deletions(-)
diff --git a/builtin/config.c b/builtin/config.c
index 288ebdfdaa..d129b1204d 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -71,20 +71,6 @@ static const char *const builtin_config_edit_usage[] = {
OPT_STRING('f', "file", &opts.source.file, N_("file"), N_("use given config file")), \
OPT_STRING(0, "blob", &opts.source.blob, N_("blob-id"), N_("read config from given blob object"))
-struct config_location_options {
- struct git_config_source source;
- struct config_options options;
- char *file_to_free;
- int use_global_config;
- int use_system_config;
- int use_local_config;
- int use_worktree_config;
- int respect_includes_opt;
-};
-#define CONFIG_LOCATION_OPTIONS_INIT { \
- .respect_includes_opt = -1, \
-}
-
#define CONFIG_TYPE_OPTIONS(type) \
OPT_GROUP(N_("Type")), \
OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type), \
@@ -772,93 +758,6 @@ static char *default_user_config(void)
return strbuf_detach(&buf, NULL);
}
-static void location_options_init(struct config_location_options *opts,
- const char *prefix)
-{
- if (!opts->source.file)
- opts->source.file = opts->file_to_free =
- xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
-
- if (opts->use_global_config + opts->use_system_config +
- opts->use_local_config + opts->use_worktree_config +
- !!opts->source.file + !!opts->source.blob > 1) {
- error(_("only one config file at a time"));
- exit(129);
- }
-
- if (!startup_info->have_repository) {
- if (opts->use_local_config)
- die(_("--local can only be used inside a git repository"));
- if (opts->source.blob)
- die(_("--blob can only be used inside a git repository"));
- if (opts->use_worktree_config)
- die(_("--worktree can only be used inside a git repository"));
- }
-
- if (opts->source.file &&
- !strcmp(opts->source.file, "-")) {
- opts->source.file = NULL;
- opts->source.use_stdin = 1;
- opts->source.scope = CONFIG_SCOPE_COMMAND;
- }
-
- if (opts->use_global_config) {
- opts->source.file = opts->file_to_free = git_global_config();
- if (!opts->source.file)
- /*
- * It is unknown if HOME/.gitconfig exists, so
- * we do not know if we should write to XDG
- * location; error out even if XDG_CONFIG_HOME
- * is set and points at a sane location.
- */
- die(_("$HOME not set"));
- opts->source.scope = CONFIG_SCOPE_GLOBAL;
- } else if (opts->use_system_config) {
- opts->source.file = opts->file_to_free = git_system_config();
- opts->source.scope = CONFIG_SCOPE_SYSTEM;
- } else if (opts->use_local_config) {
- opts->source.file = opts->file_to_free = repo_git_path(the_repository, "config");
- opts->source.scope = CONFIG_SCOPE_LOCAL;
- } else if (opts->use_worktree_config) {
- struct worktree **worktrees = get_worktrees();
- if (the_repository->repository_format_worktree_config)
- opts->source.file = opts->file_to_free =
- repo_git_path(the_repository, "config.worktree");
- else if (worktrees[0] && worktrees[1])
- die(_("--worktree cannot be used with multiple "
- "working trees unless the config\n"
- "extension worktreeConfig is enabled. "
- "Please read \"CONFIGURATION FILE\"\n"
- "section in \"git help worktree\" for details"));
- else
- opts->source.file = opts->file_to_free =
- repo_git_path(the_repository, "config");
- opts->source.scope = CONFIG_SCOPE_LOCAL;
- free_worktrees(worktrees);
- } else if (opts->source.file) {
- if (!is_absolute_path(opts->source.file) && prefix)
- opts->source.file = opts->file_to_free =
- prefix_filename(prefix, opts->source.file);
- opts->source.scope = CONFIG_SCOPE_COMMAND;
- } else if (opts->source.blob) {
- opts->source.scope = CONFIG_SCOPE_COMMAND;
- }
-
- if (opts->respect_includes_opt == -1)
- opts->options.respect_includes = !opts->source.file;
- else
- opts->options.respect_includes = opts->respect_includes_opt;
- if (startup_info->have_repository) {
- opts->options.commondir = repo_get_common_dir(the_repository);
- opts->options.git_dir = repo_get_git_dir(the_repository);
- }
-}
-
-static void location_options_release(struct config_location_options *opts)
-{
- free(opts->file_to_free);
-}
-
static void display_options_init(struct config_display_options *opts)
{
if (opts->end_nul) {
@@ -885,7 +784,7 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix,
argc = parse_options(argc, argv, prefix, opts, builtin_config_list_usage, 0);
check_argc(argc, 0, 0);
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
display_options_init(&display_opts);
setup_auto_pager("config", 1);
@@ -944,7 +843,7 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix,
value_pattern))
die(_("--url= cannot be used with --all, --regexp or --value"));
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
display_options_init(&display_opts);
if (display_opts.type != TYPE_COLOR)
@@ -998,7 +897,7 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix,
comment = git_config_prepare_comment_string(comment_arg);
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
check_write(&location_opts.source);
value = normalize_value(argv[0], argv[1], type, &default_kvi);
@@ -1044,7 +943,7 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix,
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
die(_("--fixed-value only applies with 'value-pattern'"));
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
check_write(&location_opts.source);
if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern)
@@ -1073,7 +972,7 @@ static int cmd_config_rename_section(int argc, const char **argv, const char *pr
PARSE_OPT_STOP_AT_NON_OPTION);
check_argc(argc, 2, 2);
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
check_write(&location_opts.source);
ret = repo_config_rename_section_in_file(the_repository, location_opts.source.file,
@@ -1103,7 +1002,7 @@ static int cmd_config_remove_section(int argc, const char **argv, const char *pr
PARSE_OPT_STOP_AT_NON_OPTION);
check_argc(argc, 1, 1);
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
check_write(&location_opts.source);
ret = repo_config_rename_section_in_file(the_repository, location_opts.source.file,
@@ -1163,7 +1062,7 @@ static int cmd_config_edit(int argc, const char **argv, const char *prefix,
argc = parse_options(argc, argv, prefix, opts, builtin_config_edit_usage, 0);
check_argc(argc, 0, 0);
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
check_write(&location_opts.source);
ret = show_editor(&location_opts);
@@ -1231,7 +1130,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
builtin_config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
- location_options_init(&location_opts, prefix);
+ location_options_init(the_repository, &location_opts, prefix);
display_options_init(&display_opts);
if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && display_opts.type) {
diff --git a/config.c b/config.c
index 7f6d53b473..9f1a7b45cf 100644
--- a/config.c
+++ b/config.c
@@ -35,6 +35,7 @@
#include "strvec.h"
#include "trace2.h"
#include "wildmatch.h"
+#include "worktree.h"
#include "write-or-die.h"
struct config_source {
@@ -3592,3 +3593,91 @@ int lookup_config(const char **mapping, int nr_mapping, const char *var)
}
return -1;
}
+
+void location_options_init(struct repository *repo,
+ struct config_location_options *opts,
+ const char *prefix)
+{
+ if (!opts->source.file)
+ opts->source.file = opts->file_to_free =
+ xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
+
+ if (opts->use_global_config + opts->use_system_config +
+ opts->use_local_config + opts->use_worktree_config +
+ !!opts->source.file + !!opts->source.blob > 1) {
+ error(_("only one config file at a time"));
+ exit(129);
+ }
+
+ if (!startup_info->have_repository) {
+ if (opts->use_local_config)
+ die(_("--local can only be used inside a git repository"));
+ if (opts->source.blob)
+ die(_("--blob can only be used inside a git repository"));
+ if (opts->use_worktree_config)
+ die(_("--worktree can only be used inside a git repository"));
+ }
+
+ if (opts->source.file &&
+ !strcmp(opts->source.file, "-")) {
+ opts->source.file = NULL;
+ opts->source.use_stdin = 1;
+ opts->source.scope = CONFIG_SCOPE_COMMAND;
+ }
+
+ if (opts->use_global_config) {
+ opts->source.file = opts->file_to_free = git_global_config();
+ if (!opts->source.file)
+ /*
+ * It is unknown if HOME/.gitconfig exists, so
+ * we do not know if we should write to XDG
+ * location; error out even if XDG_CONFIG_HOME
+ * is set and points at a sane location.
+ */
+ die(_("$HOME not set"));
+ opts->source.scope = CONFIG_SCOPE_GLOBAL;
+ } else if (opts->use_system_config) {
+ opts->source.file = opts->file_to_free = git_system_config();
+ opts->source.scope = CONFIG_SCOPE_SYSTEM;
+ } else if (opts->use_local_config) {
+ opts->source.file = opts->file_to_free = repo_git_path(repo, "config");
+ opts->source.scope = CONFIG_SCOPE_LOCAL;
+ } else if (opts->use_worktree_config) {
+ struct worktree **worktrees = get_worktrees();
+ if (repo->repository_format_worktree_config)
+ opts->source.file = opts->file_to_free =
+ repo_git_path(repo, "config.worktree");
+ else if (worktrees[0] && worktrees[1])
+ die(_("--worktree cannot be used with multiple "
+ "working trees unless the config\n"
+ "extension worktreeConfig is enabled. "
+ "Please read \"CONFIGURATION FILE\"\n"
+ "section in \"git help worktree\" for details"));
+ else
+ opts->source.file = opts->file_to_free =
+ repo_git_path(repo, "config");
+ opts->source.scope = CONFIG_SCOPE_LOCAL;
+ free_worktrees(worktrees);
+ } else if (opts->source.file) {
+ if (!is_absolute_path(opts->source.file) && prefix)
+ opts->source.file = opts->file_to_free =
+ prefix_filename(prefix, opts->source.file);
+ opts->source.scope = CONFIG_SCOPE_COMMAND;
+ } else if (opts->source.blob) {
+ opts->source.scope = CONFIG_SCOPE_COMMAND;
+ }
+
+ if (opts->respect_includes_opt == -1)
+ opts->options.respect_includes = !opts->source.file;
+ else
+ opts->options.respect_includes = opts->respect_includes_opt;
+ if (startup_info->have_repository) {
+ opts->options.commondir = repo_get_common_dir(repo);
+ opts->options.git_dir = repo_get_git_dir(repo);
+ }
+}
+
+void location_options_release(struct config_location_options *opts)
+{
+ free(opts->file_to_free);
+}
diff --git a/config.h b/config.h
index 966a228f0e..6663964977 100644
--- a/config.h
+++ b/config.h
@@ -166,6 +166,26 @@ struct config_context {
typedef int (*config_fn_t)(const char *, const char *,
const struct config_context *, void *);
+struct config_location_options {
+ struct git_config_source source;
+ struct config_options options;
+ char *file_to_free;
+ int use_global_config;
+ int use_system_config;
+ int use_local_config;
+ int use_worktree_config;
+ int respect_includes_opt;
+};
+#define CONFIG_LOCATION_OPTIONS_INIT { \
+ .respect_includes_opt = -1, \
+}
+
+void location_options_init(struct repository *repo,
+ struct config_location_options *opts,
+ const char *prefix);
+
+void location_options_release(struct config_location_options *opts);
+
/**
* Read a specific file in git-config format.
* This function takes the same callback and data parameters as `repo_config`.
--
gitgitgadget
next prev parent reply other threads:[~2026-02-04 14:20 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-04 14:19 [PATCH 00/11] [RFC] config-batch: a new builtin for tools querying config Derrick Stolee via GitGitGadget
2026-02-04 14:19 ` [PATCH 01/11] config-batch: basic boilerplate of new builtin Derrick Stolee via GitGitGadget
2026-02-04 23:23 ` Junio C Hamano
2026-02-05 14:17 ` Derrick Stolee
2026-02-05 17:26 ` Kristoffer Haugsbakk
2026-02-05 17:29 ` Kristoffer Haugsbakk
2026-02-06 4:11 ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 02/11] config-batch: create parse loop and unknown command Derrick Stolee via GitGitGadget
2026-02-04 23:26 ` Junio C Hamano
2026-02-05 17:30 ` Kristoffer Haugsbakk
2026-02-06 4:15 ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 03/11] config-batch: implement get v1 Derrick Stolee via GitGitGadget
2026-02-06 4:41 ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 04/11] config-batch: create 'help' command Derrick Stolee via GitGitGadget
2026-02-06 4:49 ` Jean-Noël Avila
2026-02-10 4:20 ` Derrick Stolee
2026-02-04 14:19 ` [PATCH 05/11] config-batch: add NUL-terminated I/O format Derrick Stolee via GitGitGadget
2026-02-05 17:44 ` Kristoffer Haugsbakk
2026-02-06 4:58 ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 06/11] docs: add design doc for config-batch Derrick Stolee via GitGitGadget
2026-02-05 17:38 ` Kristoffer Haugsbakk
2026-02-10 4:22 ` Derrick Stolee
2026-02-04 14:19 ` Derrick Stolee via GitGitGadget [this message]
2026-02-04 14:20 ` [PATCH 08/11] config-batch: pass prefix through commands Derrick Stolee via GitGitGadget
2026-02-04 14:20 ` [PATCH 09/11] config-batch: add 'set' v1 command Derrick Stolee via GitGitGadget
2026-02-05 17:21 ` Kristoffer Haugsbakk
2026-02-05 18:58 ` Kristoffer Haugsbakk
2026-02-05 19:01 ` Kristoffer Haugsbakk
2026-02-10 4:25 ` Derrick Stolee
2026-02-06 5:04 ` Jean-Noël Avila
2026-02-04 14:20 ` [PATCH 10/11] t1312: create read/write test Derrick Stolee via GitGitGadget
2026-02-04 14:20 ` [PATCH 11/11] config-batch: add unset v1 command Derrick Stolee via GitGitGadget
2026-02-05 17:36 ` Kristoffer Haugsbakk
2026-02-04 23:04 ` [PATCH 00/11] [RFC] config-batch: a new builtin for tools querying config Junio C Hamano
2026-02-05 14:10 ` Derrick Stolee
2026-02-05 0:04 ` brian m. carlson
2026-02-05 13:52 ` Derrick Stolee
2026-02-10 4:49 ` Derrick Stolee
2026-02-05 14:45 ` Phillip Wood
2026-02-05 17:20 ` Kristoffer Haugsbakk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4be089a4dda63fdc0ea2db00acb47b33befe07ef.1770214803.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=stolee@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox