From 26ef8872f1ccb095ef7d263edac1e844d6516bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Brandst=C3=B6tter?= Date: Tue, 22 Jul 2025 21:09:22 +0200 Subject: [PATCH 01/47] t7510: add test cases for non-absolute gpg program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These cases cover scenarios where `gpg.program` is set as a program in `$PATH` or as a path relative to the user's home directory. Signed-off-by: Jonas Brandstötter Signed-off-by: Junio C Hamano --- t/t7510-signed-commit.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 39677e859ab311..95d2ebe27793f0 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -449,7 +449,17 @@ test_expect_success 'custom `gpg.program`' ' test_must_fail env LET_GPG_PROGRAM_FAIL=1 \ git commit -S --allow-empty -m must-fail 2>err && - grep zOMG err + grep zOMG err && + + # `gpg.program` starts with `~`, the path should be interpreted to be relative to `$HOME` + test_config gpg.program "~/fake-gpg" && + env HOME="$(pwd)" \ + git commit -S --allow-empty -m signed-commit && + + # `gpg.program` does not specify an absolute path, it should find a program in `$PATH` + test_config gpg.program "fake-gpg" && + env PATH="$(pwd):$PATH" \ + git commit -S --allow-empty -m signed-commit ' test_done From 9ce196e86b455fa2552812802c58f30c090c94af Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:22 +0200 Subject: [PATCH 02/47] config: drop `git_config()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config()`. All callsites are adjusted so that they use `repo_config(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- Documentation/user-manual.adoc | 2 +- apply.c | 2 +- archive-tar.c | 2 +- archive-zip.c | 2 +- archive.c | 2 +- builtin/am.c | 2 +- builtin/blame.c | 2 +- builtin/branch.c | 2 +- builtin/cat-file.c | 2 +- builtin/check-attr.c | 2 +- builtin/check-ignore.c | 2 +- builtin/check-mailmap.c | 2 +- builtin/checkout--worker.c | 2 +- builtin/checkout.c | 2 +- builtin/clean.c | 2 +- builtin/clone.c | 4 ++-- builtin/column.c | 4 ++-- builtin/commit-graph.c | 4 ++-- builtin/commit-tree.c | 2 +- builtin/commit.c | 4 ++-- builtin/config.c | 2 +- builtin/count-objects.c | 2 +- builtin/credential.c | 2 +- builtin/describe.c | 2 +- builtin/diff-files.c | 2 +- builtin/diff-index.c | 2 +- builtin/diff-tree.c | 2 +- builtin/diff.c | 2 +- builtin/fast-export.c | 2 +- builtin/fast-import.c | 2 +- builtin/fetch.c | 4 ++-- builtin/fmt-merge-msg.c | 2 +- builtin/fsck.c | 2 +- builtin/fsmonitor--daemon.c | 2 +- builtin/gc.c | 2 +- builtin/grep.c | 2 +- builtin/hash-object.c | 2 +- builtin/help.c | 4 ++-- builtin/hook.c | 2 +- builtin/index-pack.c | 2 +- builtin/interpret-trailers.c | 2 +- builtin/log.c | 20 +++++++++---------- builtin/ls-tree.c | 2 +- builtin/merge-base.c | 2 +- builtin/merge-file.c | 2 +- builtin/merge-tree.c | 2 +- builtin/merge.c | 2 +- builtin/mktag.c | 2 +- builtin/multi-pack-index.c | 4 ++-- builtin/mv.c | 2 +- builtin/name-rev.c | 2 +- builtin/notes.c | 2 +- builtin/pack-objects.c | 2 +- builtin/patch-id.c | 2 +- builtin/pull.c | 2 +- builtin/push.c | 2 +- builtin/range-diff.c | 2 +- builtin/read-tree.c | 2 +- builtin/rebase.c | 2 +- builtin/receive-pack.c | 2 +- builtin/reflog.c | 2 +- builtin/refs.c | 2 +- builtin/remote.c | 6 +++--- builtin/repack.c | 2 +- builtin/replace.c | 2 +- builtin/rerere.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 2 +- builtin/rev-parse.c | 4 ++-- builtin/rm.c | 2 +- builtin/shortlog.c | 2 +- builtin/show-branch.c | 2 +- builtin/show-ref.c | 2 +- builtin/sparse-checkout.c | 2 +- builtin/stash.c | 4 ++-- builtin/stripspace.c | 2 +- builtin/submodule--helper.c | 8 ++++---- builtin/symbolic-ref.c | 2 +- builtin/tag.c | 2 +- builtin/unpack-file.c | 2 +- builtin/unpack-objects.c | 2 +- builtin/update-index.c | 2 +- builtin/update-ref.c | 2 +- builtin/var.c | 4 ++-- builtin/verify-pack.c | 2 +- builtin/worktree.c | 2 +- builtin/write-tree.c | 2 +- config.h | 5 ----- connect.c | 2 +- .../coccinelle/config_fn_ctx.pending.cocci | 2 +- convert.c | 2 +- fetch-pack.c | 2 +- fsck.h | 2 +- gpg-interface.c | 2 +- help.c | 4 ++-- http-fetch.c | 2 +- http.c | 2 +- imap-send.c | 2 +- ls-refs.c | 2 +- merge-ll.c | 2 +- merge-ort.c | 2 +- notes-utils.c | 2 +- notes.c | 2 +- pretty.c | 2 +- refs/reftable-backend.c | 2 +- rerere.c | 4 ++-- revision.c | 2 +- scalar.c | 2 +- sequencer.c | 2 +- setup.c | 4 ++-- t/helper/test-advise.c | 2 +- t/helper/test-config.c | 8 ++++---- t/helper/test-read-cache.c | 2 +- t/helper/test-userdiff.c | 2 +- t/t4256/1/mailinfo.c | 2 +- t/t4256/1/mailinfo.c.orig | 2 +- trailer.c | 4 ++-- transport.c | 2 +- 118 files changed, 148 insertions(+), 153 deletions(-) diff --git a/Documentation/user-manual.adoc b/Documentation/user-manual.adoc index 8d00a9e8229b9c..76969871176e58 100644 --- a/Documentation/user-manual.adoc +++ b/Documentation/user-manual.adoc @@ -4270,7 +4270,7 @@ So, look into `builtin/cat-file.c`, search for `cmd_cat_file()` and look what it does. ------------------------------------------------------------------ - git_config(git_default_config); + repo_config(the_repository, git_default_config); if (argc != 3) usage("git cat-file [-t|-s|-e|-p|] "); if (get_sha1(argv[2], sha1)) diff --git a/apply.c b/apply.c index a3804316fbd11f..d2381a157c0a83 100644 --- a/apply.c +++ b/apply.c @@ -50,7 +50,7 @@ static void git_apply_config(void) { git_config_get_string("apply.whitespace", &apply_default_whitespace); git_config_get_string("apply.ignorewhitespace", &apply_default_ignorewhitespace); - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); } static int parse_whitespace_option(struct apply_state *state, const char *option) diff --git a/archive-tar.c b/archive-tar.c index 249164ea77dc04..73b63ddc41bad6 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -537,7 +537,7 @@ void init_tar_archiver(void) tar_filter_config("tar.tgz.remote", "true", NULL); tar_filter_config("tar.tar.gz.command", internal_gzip_command, NULL); tar_filter_config("tar.tar.gz.remote", "true", NULL); - git_config(git_tar_config, NULL); + repo_config(the_repository, git_tar_config, NULL); for (i = 0; i < nr_tar_filters; i++) { /* omit any filters that never had a command configured */ if (tar_filters[i]->filter_command) diff --git a/archive-zip.c b/archive-zip.c index df8866d5bae28a..dbd90d9c3d4b32 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -632,7 +632,7 @@ static int write_zip_archive(const struct archiver *ar UNUSED, { int err; - git_config(archive_zip_config, NULL); + repo_config(the_repository, archive_zip_config, NULL); dos_time(&args->time, &zip_date, &zip_time); diff --git a/archive.c b/archive.c index f5a9d45c8d3e24..2dd306a07a7290 100644 --- a/archive.c +++ b/archive.c @@ -761,7 +761,7 @@ int write_archive(int argc, const char **argv, const char *prefix, int rc; git_config_get_bool("uploadarchive.allowunreachable", &remote_allow_unreachable); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); describe_status.max_invocations = 1; ctx.date_mode.type = DATE_NORMAL; diff --git a/builtin/am.c b/builtin/am.c index c9d925f7b96071..a7e7cf1465aa19 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -2445,7 +2445,7 @@ int cmd_am(int argc, show_usage_with_options_if_asked(argc, argv, usage, options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); am_state_init(&state); diff --git a/builtin/blame.c b/builtin/blame.c index 91586e6852b09e..71efeb7c7e6ad7 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -947,7 +947,7 @@ int cmd_blame(int argc, const char *const *opt_usage = cmd_is_annotate ? annotate_opt_usage : blame_opt_usage; setup_default_color_by_age(); - git_config(git_blame_config, &output_option); + repo_config(the_repository, git_blame_config, &output_option); repo_init_revisions(the_repository, &revs, NULL); revs.date_mode = blame_date_mode; revs.diffopt.flags.allow_textconv = 1; diff --git a/builtin/branch.c b/builtin/branch.c index c150131bd9f122..08e50bf77b3f54 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -791,7 +791,7 @@ int cmd_branch(int argc, * Try to set sort keys from config. If config does not set any, * fall back on default (refname) sorting. */ - git_config(git_branch_config, &sorting_options); + repo_config(the_repository, git_branch_config, &sorting_options); if (!sorting_options.nr) string_list_append(&sorting_options, "refname"); diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 2492a0b6f39ac3..b9eb2bb3b923ac 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -1095,7 +1095,7 @@ int cmd_cat_file(int argc, OPT_END() }; - git_config(git_cat_file_config, NULL); + repo_config(the_repository, git_cat_file_config, NULL); batch.buffer_output = -1; diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 7cf275b8937958..51ed48ce4370c3 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -119,7 +119,7 @@ int cmd_check_attr(int argc, if (!is_bare_repository()) setup_work_tree(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, check_attr_options, check_attr_usage, PARSE_OPT_KEEP_DASHDASH); diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 7b7831d13a85ff..03033499cb0832 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -159,7 +159,7 @@ int cmd_check_ignore(int argc, int num_ignored; struct dir_struct dir = DIR_INIT; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, check_ignore_options, check_ignore_usage, 0); diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index be2cebe12152e3..634626c672848f 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -56,7 +56,7 @@ int cmd_check_mailmap(int argc, int i; struct string_list mailmap = STRING_LIST_INIT_NODUP; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, check_mailmap_options, check_mailmap_usage, 0); if (argc == 0 && !use_stdin) diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index da9345a44b84de..27a7d4f0409893 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -132,7 +132,7 @@ int cmd_checkout__worker(int argc, checkout_worker_usage, checkout_worker_options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, checkout_worker_options, checkout_worker_usage, 0); if (argc > 0) diff --git a/builtin/checkout.c b/builtin/checkout.c index 0a90b86a72913f..948ff7bdda7c17 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1764,7 +1764,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix, opts->prefix = prefix; opts->show_progress = -1; - git_config(git_checkout_config, opts); + repo_config(the_repository, git_checkout_config, opts); if (the_repository->gitdir) { prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/clean.c b/builtin/clean.c index 053c94fc6bd12a..5ee147c4acc053 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -949,7 +949,7 @@ int cmd_clean(int argc, OPT_END() }; - git_config(git_clean_config, NULL); + repo_config(the_repository, git_clean_config, NULL); argc = parse_options(argc, argv, prefix, options, builtin_clean_usage, 0); diff --git a/builtin/clone.c b/builtin/clone.c index 6d08abed37c4ce..3c6d8529b6c3a3 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1001,7 +1001,7 @@ int cmd_clone(int argc, packet_trace_identity("clone"); - git_config(git_clone_config, NULL); + repo_config(the_repository, git_clone_config, NULL); argc = parse_options(argc, argv, prefix, builtin_clone_options, builtin_clone_usage, 0); @@ -1242,7 +1242,7 @@ int cmd_clone(int argc, * re-read config after init_db and write_config to pick up any config * injected by --template and --config, respectively. */ - git_config(git_clone_config, NULL); + repo_config(the_repository, git_clone_config, NULL); /* * If option_reject_shallow is specified from CLI option, diff --git a/builtin/column.c b/builtin/column.c index ce6443d5fac84d..87dce3c6e53a19 100644 --- a/builtin/column.c +++ b/builtin/column.c @@ -42,9 +42,9 @@ int cmd_column(int argc, /* This one is special and must be the first one */ if (argc > 1 && starts_with(argv[1], "--command=")) { command = argv[1] + 10; - git_config(column_config, (void *)command); + repo_config(the_repository, column_config, (void *)command); } else - git_config(column_config, NULL); + repo_config(the_repository, column_config, NULL); memset(&copts, 0, sizeof(copts)); copts.padding = 1; diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 25018a0b9df464..c5cc601844cce5 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -265,7 +265,7 @@ static int graph_write(int argc, const char **argv, const char *prefix, trace2_cmd_mode("write"); - git_config(git_commit_graph_write_config, &opts); + repo_config(the_repository, git_commit_graph_write_config, &opts); argc = parse_options(argc, argv, prefix, options, @@ -347,7 +347,7 @@ int cmd_commit_graph(int argc, }; struct option *options = parse_options_concat(builtin_commit_graph_options, common_opts); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); disable_replace_refs(); save_commit_buffer = 0; diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 31cfd9bd15d615..2f1df28d41394d 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -125,7 +125,7 @@ int cmd_commit_tree(int argc, }; int ret; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); show_usage_with_options_if_asked(argc, argv, commit_tree_usage, options); diff --git a/builtin/commit.c b/builtin/commit.c index fba0dded64a718..fcd829e04ec2ba 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -207,9 +207,9 @@ static void status_init_config(struct wt_status *s, config_fn_t fn) { wt_status_prepare(the_repository, s); init_diff_ui_defaults(); - git_config(fn, s); + repo_config(the_repository, fn, s); determine_whence(s); - s->hints = advice_enabled(ADVICE_STATUS_HINTS); /* must come after git_config() */ + s->hints = advice_enabled(ADVICE_STATUS_HINTS); /* must come after repo_config() */ } static void rollback_index_files(void) diff --git a/builtin/config.c b/builtin/config.c index 5efe2730106c99..af5d79eadc0804 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -1091,7 +1091,7 @@ static int show_editor(struct config_location_options *opts) die(_("editing stdin is not supported")); if (opts->source.blob) die(_("editing blobs is not supported")); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); config_file = opts->source.file ? xstrdup(opts->source.file) : repo_git_path(the_repository, "config"); diff --git a/builtin/count-objects.c b/builtin/count-objects.c index f687647931e0e2..433daff805abf9 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -106,7 +106,7 @@ int cmd_count_objects(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, opts, count_objects_usage, 0); /* we do not take arguments other than flags for now */ diff --git a/builtin/credential.c b/builtin/credential.c index 2e11b15dde3e85..52f172e80cb496 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -16,7 +16,7 @@ int cmd_credential(int argc, const char *op; struct credential c = CREDENTIAL_INIT; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); show_usage_if_asked(argc, argv, usage_msg); if (argc != 2) diff --git a/builtin/describe.c b/builtin/describe.c index fbf305d7624487..d7dd8139dec4b6 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -623,7 +623,7 @@ int cmd_describe(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, describe_usage, 0); if (abbrev < 0) abbrev = DEFAULT_ABBREV; diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 99b1749723bc67..ea91347ce23beb 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -31,7 +31,7 @@ int cmd_diff_files(int argc, show_usage_if_asked(argc, argv, diff_files_usage); - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(the_repository, git_diff_basic_config, NULL); /* no "diff" UI options */ prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 81c0bc8ed7c6be..522dacfc4cf097 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -28,7 +28,7 @@ int cmd_diff_index(int argc, show_usage_if_asked(argc, argv, diff_cache_usage); - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(the_repository, git_diff_basic_config, NULL); /* no "diff" UI options */ prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index e31cc797fe1e6e..49dd4d00ebf1bc 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -124,7 +124,7 @@ int cmd_diff_tree(int argc, show_usage_if_asked(argc, argv, diff_tree_usage); - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(the_repository, git_diff_basic_config, NULL); /* no "diff" UI options */ prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/diff.c b/builtin/diff.c index eebffe36ccfb08..9a89e25a982abb 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -486,7 +486,7 @@ int cmd_diff(int argc, repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT); init_diff_ui_defaults(); - git_config(git_diff_ui_config, NULL); + repo_config(the_repository, git_diff_ui_config, NULL); prefix = precompose_argv_prefix(argc, argv, prefix); repo_init_revisions(the_repository, &rev, prefix); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 6a3a17a8cd9132..17027b859e0caf 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -1327,7 +1327,7 @@ int cmd_fast_export(int argc, usage_with_options (fast_export_usage, options); /* we handle encodings */ - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); repo_init_revisions(the_repository, &revs, prefix); init_revision_sources(&revision_sources); diff --git a/builtin/fast-import.c b/builtin/fast-import.c index b1389c59211a48..607441e921b38a 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -3541,7 +3541,7 @@ static void git_pack_config(void) else if (!git_config_get_int("transfer.unpacklimit", &limit)) unpack_limit = limit; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } static const char fast_import_usage[] = diff --git a/builtin/fetch.c b/builtin/fetch.c index 87a0cca7994ff3..ea447c453d148a 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1995,7 +1995,7 @@ static int add_remote_or_group(const char *name, struct string_list *list) struct remote_group_data g; g.name = name; g.list = list; - git_config(get_remote_group, &g); + repo_config(the_repository, get_remote_group, &g); if (list->nr == prev_nr) { struct remote *remote = remote_get(name); if (!remote_is_configured(remote, 0)) @@ -2417,7 +2417,7 @@ int cmd_fetch(int argc, free(anon); } - git_config(git_fetch_config, &config); + repo_config(the_repository, git_fetch_config, &config); if (the_repository->gitdir) { prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 3b6aac2cf7faab..edb93c0b3a31e3 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -53,7 +53,7 @@ int cmd_fmt_merge_msg(int argc, int ret; struct fmt_merge_msg_opts opts; - git_config(fmt_merge_msg_config, NULL); + repo_config(the_repository, fmt_merge_msg_config, NULL); argc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage, 0); if (argc > 0) diff --git a/builtin/fsck.c b/builtin/fsck.c index 0084cf7400bd46..0ec6ca06e3b083 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -987,7 +987,7 @@ int cmd_fsck(int argc, if (name_objects) fsck_enable_object_names(&fsck_walk_options); - git_config(git_fsck_config, &fsck_obj_options); + repo_config(the_repository, git_fsck_config, &fsck_obj_options); prepare_repo_settings(the_repository); if (check_references) diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 0820e524f1a517..469c62b555bcde 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1547,7 +1547,7 @@ int cmd_fsmonitor__daemon(int argc, OPT_END() }; - git_config(fsmonitor_config, NULL); + repo_config(the_repository, fsmonitor_config, NULL); argc = parse_options(argc, argv, prefix, options, builtin_fsmonitor__daemon_usage, 0); diff --git a/builtin/gc.c b/builtin/gc.c index fab8f4dd4f7b6c..d9e3b9d2ec3632 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -228,7 +228,7 @@ static void gc_config(struct gc_config *cfg) cfg->repack_filter_to = owned; } - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } enum schedule_priority { diff --git a/builtin/grep.c b/builtin/grep.c index 39273d9c0fd47d..7982dda9a3b682 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -1035,7 +1035,7 @@ int cmd_grep(int argc, grep_prefix = prefix; grep_init(&opt, the_repository); - git_config(grep_cmd_config, &opt); + repo_config(the_repository, grep_cmd_config, &opt); /* * If there is no -- then the paths must exist in the working diff --git a/builtin/hash-object.c b/builtin/hash-object.c index ddf281413a652e..c3ad1e91c96fd9 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -111,7 +111,7 @@ int cmd_hash_object(int argc, vpath = vpath_free; } - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); if (stdin_paths) { if (hashstdin) diff --git a/builtin/help.c b/builtin/help.c index c257079cebc3c0..d79ecd946a640c 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -210,7 +210,7 @@ static enum help_format parse_help_format(const char *format) if (!strcmp(format, "web") || !strcmp(format, "html")) return HELP_FORMAT_WEB; /* - * Please update _git_config() in git-completion.bash when you + * Please update _repo_config() in git-completion.bash when you * add new help formats. */ die(_("unrecognized help format '%s'"), format); @@ -706,7 +706,7 @@ int cmd_help(int argc, } setup_git_directory_gently(&nongit); - git_config(git_help_config, NULL); + repo_config(the_repository, git_help_config, NULL); if (parsed_help_format != HELP_FORMAT_NONE) help_format = parsed_help_format; diff --git a/builtin/hook.c b/builtin/hook.c index 672d2e37e845a2..044c27aa95dba6 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -55,7 +55,7 @@ static int run(int argc, const char **argv, const char *prefix, strvec_push(&opt.args, argv[i]); /* Need to take into account core.hooksPath */ - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); hook_name = argv[0]; if (!ignore_missing) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 0a5c8a1ac858f7..53f1a7cd71ec96 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1917,7 +1917,7 @@ int cmd_index_pack(int argc, reset_pack_idx_option(&opts); opts.flags |= WRITE_REV; - git_config(git_index_pack_config, &opts); + repo_config(the_repository, git_index_pack_config, &opts); if (prefix && chdir(prefix)) die(_("Cannot come back to cwd")); diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 44d8ccddc9d8de..3141c37b853ff0 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -220,7 +220,7 @@ int cmd_interpret_trailers(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_interpret_trailers_usage, 0); diff --git a/builtin/log.c b/builtin/log.c index 24a57c20a410e4..1bedc4ef3551e9 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -659,10 +659,10 @@ int cmd_whatchanged(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.diff = 1; rev.simplify_history = 0; @@ -790,7 +790,7 @@ int cmd_show(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); if (the_repository->gitdir) { prepare_repo_settings(the_repository); @@ -799,7 +799,7 @@ int cmd_show(int argc, memset(&match_all, 0, sizeof(match_all)); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.diff = 1; rev.always_show_header = 1; @@ -907,11 +907,11 @@ int cmd_log_reflog(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); init_reflog_walk(&rev.reflog_info); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.verbose_header = 1; memset(&opt, 0, sizeof(opt)); @@ -952,10 +952,10 @@ int cmd_log(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.always_show_header = 1; memset(&opt, 0, sizeof(opt)); @@ -2158,9 +2158,9 @@ int cmd_format_patch(int argc, format_config_init(&cfg); init_diff_ui_defaults(); init_display_notes(&cfg.notes_opt); - git_config(git_format_config, &cfg); + repo_config(the_repository, git_format_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.show_notes = cfg.show_notes; memcpy(&rev.notes_opt, &cfg.notes_opt, sizeof(cfg.notes_opt)); diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 4d616dd52827d9..4ba84e519672d3 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -375,7 +375,7 @@ int cmd_ls_tree(int argc, struct object_context obj_context = {0}; int ret; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, ls_tree_options, ls_tree_usage, 0); diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 123c81515e1f5f..8fde35c1751ee1 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -167,7 +167,7 @@ int cmd_merge_base(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); if (cmdmode == 'a') { diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 9464f2756299ec..3da4ca2c8cfe59 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -97,7 +97,7 @@ int cmd_merge_file(int argc, if (startup_info->have_repository) { /* Read the configuration file */ - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); if (0 <= git_xmerge_style) xmp.style = git_xmerge_style; } diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index cf8b06cadc7d50..99a6495fd52f79 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -683,7 +683,7 @@ int cmd_merge_tree(int argc, if (argc != expected_remaining_argc) usage_with_options(merge_tree_usage, mt_options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); /* Do the relevant type of merge */ if (o.mode == MODE_REAL) diff --git a/builtin/merge.c b/builtin/merge.c index 18b22c0a26d633..dc4cb8fb14dbf3 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1392,7 +1392,7 @@ int cmd_merge(int argc, skip_prefix(branch, "refs/heads/", &branch); init_diff_ui_defaults(); - git_config(git_merge_config, NULL); + repo_config(the_repository, git_merge_config, NULL); if (!branch || is_null_oid(&head_oid)) head_commit = NULL; diff --git a/builtin/mktag.c b/builtin/mktag.c index 27e649736cf48c..e078c97d032d95 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -98,7 +98,7 @@ int cmd_mktag(int argc, fsck_set_msg_type_from_ids(&fsck_options, FSCK_MSG_EXTRA_HEADER_ENTRY, FSCK_WARN); /* config might set fsck.extraHeaderEntry=* again */ - git_config(git_fsck_config, &fsck_options); + repo_config(the_repository, git_fsck_config, &fsck_options); if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options, &tagged_oid, &tagged_type)) die(_("tag on stdin did not pass our strict fsck check")); diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index aa25b06f9d0f89..9a113f0f1f33ce 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -143,7 +143,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; - git_config(git_multi_pack_index_write_config, NULL); + repo_config(the_repository, git_multi_pack_index_write_config, NULL); options = add_common_options(builtin_multi_pack_index_write_options); @@ -290,7 +290,7 @@ int cmd_multi_pack_index(int argc, disable_replace_refs(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); if (the_repository && the_repository->objects && diff --git a/builtin/mv.c b/builtin/mv.c index 07548fe96aeb49..d43925097b420f 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -239,7 +239,7 @@ int cmd_mv(int argc, struct strbuf pathbuf = STRBUF_INIT; int ret; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, builtin_mv_options, builtin_mv_usage, 0); diff --git a/builtin/name-rev.c b/builtin/name-rev.c index ff199638deebf7..74512e54a38c45 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -600,7 +600,7 @@ int cmd_name_rev(int argc, mem_pool_init(&string_pool, 0); init_commit_rev_name(&rev_names); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0); #ifndef WITH_BREAKING_CHANGES diff --git a/builtin/notes.c b/builtin/notes.c index a9529b1696ae14..17004cdb10eb75 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -1145,7 +1145,7 @@ int cmd_notes(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_notes_usage, PARSE_OPT_SUBCOMMAND_OPTIONAL); if (!fn) { diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 5781dec9808273..8c86ec2d89fddb 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -4924,7 +4924,7 @@ int cmd_pack_objects(int argc, reset_pack_idx_option(&pack_idx_opts); pack_idx_opts.flags |= WRITE_REV; - git_config(git_pack_config, NULL); + repo_config(the_repository, git_pack_config, NULL); if (git_env_bool(GIT_TEST_NO_WRITE_REV_INDEX, 0)) pack_idx_opts.flags &= ~WRITE_REV; diff --git a/builtin/patch-id.c b/builtin/patch-id.c index 26f04b0335da7e..a659f00531a0f4 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -235,7 +235,7 @@ int cmd_patch_id(int argc, OPT_END() }; - git_config(git_patch_id_config, &config); + repo_config(the_repository, git_patch_id_config, &config); /* verbatim implies stable */ if (config.verbatim) diff --git a/builtin/pull.c b/builtin/pull.c index c593f324fe7f1d..d13ed9b5176c24 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -999,7 +999,7 @@ int cmd_pull(int argc, if (!getenv("GIT_REFLOG_ACTION")) set_reflog_message(argc, argv); - git_config(git_pull_config, NULL); + repo_config(the_repository, git_pull_config, NULL); if (the_repository->gitdir) { prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/push.c b/builtin/push.c index 92d530e5c4dff0..d0794b7b305c87 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -598,7 +598,7 @@ int cmd_push(int argc, }; packet_trace_identity("push"); - git_config(git_push_config, &flags); + repo_config(the_repository, git_push_config, &flags); argc = parse_options(argc, argv, prefix, options, push_usage, 0); push_options = (push_options_cmdline.nr ? &push_options_cmdline diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 32ddb6613fb443..a563abff5fee9b 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -54,7 +54,7 @@ int cmd_range_diff(int argc, struct object_id oid; const char *three_dots = NULL; - git_config(git_diff_ui_config, NULL); + repo_config(the_repository, git_diff_ui_config, NULL); repo_diff_setup(the_repository, &diffopt); diff --git a/builtin/read-tree.c b/builtin/read-tree.c index a8f352f7cd9b10..00eef756e67b0c 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -168,7 +168,7 @@ int cmd_read_tree(int argc, opts.src_index = the_repository->index; opts.dst_index = the_repository->index; - git_config(git_read_tree_config, NULL); + repo_config(the_repository, git_read_tree_config, NULL); argc = parse_options(argc, argv, cmd_prefix, read_tree_options, read_tree_usage, 0); diff --git a/builtin/rebase.c b/builtin/rebase.c index e90562a3b8a84e..0c3daa4b8140d8 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1245,7 +1245,7 @@ int cmd_rebase(int argc, prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - git_config(rebase_config, &options); + repo_config(the_repository, rebase_config, &options); /* options.gpg_sign_opt will be either "-S" or NULL */ gpg_sign = options.gpg_sign_opt ? "" : NULL; FREE_AND_NULL(options.gpg_sign_opt); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 7974d157eb9240..82d516a42c46b6 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2613,7 +2613,7 @@ int cmd_receive_pack(int argc, if (!enter_repo(service_dir, 0)) die("'%s' does not appear to be a git repository", service_dir); - git_config(receive_pack_config, NULL); + repo_config(the_repository, receive_pack_config, NULL); if (cert_nonce_seed) push_cert_nonce = prepare_push_cert_nonce(service_dir, time(NULL)); diff --git a/builtin/reflog.c b/builtin/reflog.c index 3acaf3e32c2714..4312f3d34c93f8 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -202,7 +202,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix, OPT_END() }; - git_config(reflog_expire_config, &opts); + repo_config(the_repository, reflog_expire_config, &opts); save_commit_buffer = 0; do_all = status = 0; diff --git a/builtin/refs.c b/builtin/refs.c index 998d2a2c1cc4e3..c7ad0a2963a3d1 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -88,7 +88,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix, if (argc) usage(_("'git refs verify' takes no arguments")); - git_config(git_fsck_config, &fsck_refs_options); + repo_config(the_repository, git_fsck_config, &fsck_refs_options); prepare_repo_settings(the_repository); worktrees = get_worktrees_without_reading_head(); diff --git a/builtin/remote.c b/builtin/remote.c index 18843b6bf6ccb5..ebd70bea3a186d 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -353,7 +353,7 @@ static void read_branches(void) { if (branch_list.nr) return; - git_config(config_read_branches, NULL); + repo_config(the_repository, config_read_branches, NULL); } struct ref_states { @@ -690,7 +690,7 @@ static void handle_push_default(const char* old_name, const char* new_name) .origin = STRBUF_INIT, .linenr = -1, }; - git_config(config_read_push_default, &push_default); + repo_config(the_repository, config_read_push_default, &push_default); if (push_default.scope >= CONFIG_SCOPE_COMMAND) ; /* pass */ else if (push_default.scope >= CONFIG_SCOPE_LOCAL) { @@ -1620,7 +1620,7 @@ static int update(int argc, const char **argv, const char *prefix, strvec_push(&cmd.args, argv[i]); if (strcmp(cmd.args.v[cmd.args.nr-1], "default") == 0) { - git_config(get_remote_default, &default_defined); + repo_config(the_repository, get_remote_default, &default_defined); if (!default_defined) { strvec_pop(&cmd.args); strvec_push(&cmd.args, "--all"); diff --git a/builtin/repack.c b/builtin/repack.c index b05ffe4623981e..dd1db282dacf27 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -1230,7 +1230,7 @@ int cmd_repack(int argc, list_objects_filter_init(&po_args.filter_options); - git_config(repack_config, &cruft_po_args); + repo_config(the_repository, repack_config, &cruft_po_args); argc = parse_options(argc, argv, prefix, builtin_repack_options, git_repack_usage, 0); diff --git a/builtin/replace.c b/builtin/replace.c index 5ff2ab723cbd58..3fe39e9df731df 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -574,7 +574,7 @@ int cmd_replace(int argc, }; disable_replace_refs(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0); diff --git a/builtin/rerere.c b/builtin/rerere.c index 1312e79d89f38e..a056cb791b4c80 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -66,7 +66,7 @@ int cmd_rerere(int argc, argc = parse_options(argc, argv, prefix, options, rerere_usage, 0); - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); if (autoupdate == 1) flags = RERERE_AUTOUPDATE; diff --git a/builtin/reset.c b/builtin/reset.c index dc50ffc1ac59e8..00492c19b06025 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -377,7 +377,7 @@ int cmd_reset(int argc, OPT_END() }; - git_config(git_reset_config, NULL); + repo_config(the_repository, git_reset_config, NULL); argc = parse_options(argc, argv, prefix, options, git_reset_usage, PARSE_OPT_KEEP_DASHDASH); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 4d0c460f1862db..034ea0a558acab 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -636,7 +636,7 @@ int cmd_rev_list(int argc, show_usage_if_asked(argc, argv, rev_list_usage); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); repo_init_revisions(the_repository, &revs, prefix); revs.abbrev = DEFAULT_ABBREV; revs.commit_format = CMIT_FMT_UNSPECIFIED; diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 490da33beccf72..44ff1b8342acae 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -734,7 +734,7 @@ int cmd_rev_parse(int argc, /* No options; just report on whether we're in a git repo or not. */ if (argc == 1) { setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); return 0; } @@ -769,7 +769,7 @@ int cmd_rev_parse(int argc, /* The rest of the options require a git repository. */ if (!did_repo_setup) { prefix = setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); did_repo_setup = 1; prepare_repo_settings(the_repository); diff --git a/builtin/rm.c b/builtin/rm.c index a6565a69cfca87..8c0da7a3ce7a66 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -271,7 +271,7 @@ int cmd_rm(int argc, struct pathspec pathspec; char *seen; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, builtin_rm_options, builtin_rm_usage, 0); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 60adc5e7a568f9..b91acf45c8fe59 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -421,7 +421,7 @@ int cmd_shortlog(int argc, if (nongit && !the_hash_algo) repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); shortlog_init(&log); repo_init_revisions(the_repository, &rev, prefix); parse_options_start(&ctx, argc, argv, prefix, options, diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 525b231d87e1d9..1ab7db9d2ca8cf 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -710,7 +710,7 @@ int cmd_show_branch(int ac, init_commit_name_slab(&name_slab); - git_config(git_show_branch_config, NULL); + repo_config(the_repository, git_show_branch_config, NULL); /* If nothing is specified, try the default first */ if (ac == 1 && default_args.nr) { diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 117709cb076ab3..414e55b92d5fef 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -324,7 +324,7 @@ struct repository *repo UNUSED) OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 1bf01591b27523..8c333b3e2e145b 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -1082,7 +1082,7 @@ int cmd_sparse_checkout(int argc, builtin_sparse_checkout_options, builtin_sparse_checkout_usage, 0); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/stash.c b/builtin/stash.c index e2f95cc2ebc219..821b58a14e578c 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -979,7 +979,7 @@ static int show_stash(int argc, const char **argv, const char *prefix, int do_usage = 0; init_diff_ui_defaults(); - git_config(git_diff_ui_config, NULL); + repo_config(the_repository, git_diff_ui_config, NULL); repo_init_revisions(the_repository, &rev, prefix); argc = parse_options(argc, argv, prefix, options, git_stash_show_usage, @@ -2358,7 +2358,7 @@ int cmd_stash(int argc, const char **args_copy; int ret; - git_config(git_stash_config, NULL); + repo_config(the_repository, git_stash_config, NULL); argc = parse_options(argc, argv, prefix, options, git_stash_usage, PARSE_OPT_SUBCOMMAND_OPTIONAL | diff --git a/builtin/stripspace.c b/builtin/stripspace.c index e147f3ff92c37a..4a566cbc5de672 100644 --- a/builtin/stripspace.c +++ b/builtin/stripspace.c @@ -55,7 +55,7 @@ int cmd_stripspace(int argc, if (mode == STRIP_COMMENTS || mode == COMMENT_LINES) { setup_git_directory_gently(&nongit); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } if (strbuf_read(&buf, 0, 1024) < 0) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index d8a6fa47e59214..89ee09abea6f5d 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -649,7 +649,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, "--ignore-submodules=dirty", "--quiet", "--", path, NULL); - git_config(git_diff_basic_config, NULL); + repo_config(the_repository, git_diff_basic_config, NULL); repo_init_revisions(the_repository, &rev, NULL); rev.abbrev = 0; @@ -1108,7 +1108,7 @@ static int compute_summary_module_list(struct object_id *head_oid, if (info->argc) strvec_pushv(&diff_args, info->argv); - git_config(git_diff_basic_config, NULL); + repo_config(the_repository, git_diff_basic_config, NULL); repo_init_revisions(the_repository, &rev, info->prefix); rev.abbrev = 0; precompose_argv_prefix(diff_args.nr, diff_args.v, NULL); @@ -2830,7 +2830,7 @@ static int module_update(int argc, const char **argv, const char *prefix, }; update_clone_config_from_gitmodules(&opt.max_jobs); - git_config(git_update_clone_config, &opt.max_jobs); + repo_config(the_repository, git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_options, git_submodule_helper_usage, 0); @@ -3128,7 +3128,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix, NULL }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); track = git_branch_track; argc = parse_options(argc, argv, prefix, options, usage, 0); diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 299d23d76a83f3..5c4623067c5372 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -59,7 +59,7 @@ int cmd_symbolic_ref(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_symbolic_ref_usage, 0); if (msg && !*msg) diff --git a/builtin/tag.c b/builtin/tag.c index 46cbf892e34224..25f30e3f9beb1d 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -546,7 +546,7 @@ int cmd_tag(int argc, * Try to set sort keys from config. If config does not set any, * fall back on default (refname) sorting. */ - git_config(git_tag_config, &sorting_options); + repo_config(the_repository, git_tag_config, &sorting_options); if (!sorting_options.nr) string_list_append(&sorting_options, "refname"); diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index 4360872ae07026..ae871adc909074 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -43,7 +43,7 @@ int cmd_unpack_file(int argc, if (repo_get_oid(the_repository, argv[1], &oid)) die("Not a valid object name %s", argv[1]); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); puts(create_temp_file(&oid)); return 0; diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index a69d59eb50c902..26aa885da92c85 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -621,7 +621,7 @@ int cmd_unpack_objects(int argc, disable_replace_refs(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); quiet = !isatty(2); diff --git a/builtin/update-index.c b/builtin/update-index.c index 0c1d4ed55beb08..2380f3ccd68c8c 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -1103,7 +1103,7 @@ int cmd_update_index(int argc, show_usage_with_options_if_asked(argc, argv, update_index_usage, options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); prepare_repo_settings(r); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 1e6131e04ad745..cb936643243088 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -769,7 +769,7 @@ int cmd_update_ref(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_update_ref_usage, 0); if (msg && !*msg) diff --git a/builtin/var.c b/builtin/var.c index ada642a9fe5257..beeac12dccf3ea 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -226,11 +226,11 @@ int cmd_var(int argc, usage(var_usage); if (strcmp(argv[1], "-l") == 0) { - git_config(show_config, NULL); + repo_config(the_repository, show_config, NULL); list_vars(); return 0; } - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); git_var = get_git_var(argv[1]); if (!git_var) diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index 34e4ed715f3e8e..d9f66f5e767776 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -81,7 +81,7 @@ int cmd_verify_pack(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, verify_pack_options, verify_pack_usage, 0); if (argc < 1) diff --git a/builtin/worktree.c b/builtin/worktree.c index 2dceeeed8bd03c..b1306248dec80b 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -1448,7 +1448,7 @@ int cmd_worktree(int ac, OPT_END() }; - git_config(git_worktree_config, NULL); + repo_config(the_repository, git_worktree_config, NULL); if (!prefix) prefix = ""; diff --git a/builtin/write-tree.c b/builtin/write-tree.c index cfec044710a56a..3465c70a48a7eb 100644 --- a/builtin/write-tree.c +++ b/builtin/write-tree.c @@ -43,7 +43,7 @@ int cmd_write_tree(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, cmd_prefix, write_tree_options, write_tree_usage, 0); diff --git a/config.h b/config.h index 29a027748375f1..6b729fc6bbfb2e 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline void git_config(config_fn_t fn, void *data) -{ - repo_config(the_repository, fn, data); -} - static inline void git_config_clear(void) { repo_config_clear(the_repository); diff --git a/connect.c b/connect.c index e77287f426cdfd..4b1dc65e5cef1b 100644 --- a/connect.c +++ b/connect.c @@ -1028,7 +1028,7 @@ static int git_proxy_command_options(const char *var, const char *value, static int git_use_proxy(const char *host) { git_proxy_command = getenv("GIT_PROXY_COMMAND"); - git_config(git_proxy_command_options, (void*)host); + repo_config(the_repository, git_proxy_command_options, (void*)host); return (git_proxy_command && *git_proxy_command); } diff --git a/contrib/coccinelle/config_fn_ctx.pending.cocci b/contrib/coccinelle/config_fn_ctx.pending.cocci index 6d3d1000a9657d..54f09fcbcde486 100644 --- a/contrib/coccinelle/config_fn_ctx.pending.cocci +++ b/contrib/coccinelle/config_fn_ctx.pending.cocci @@ -83,7 +83,7 @@ int fn(const char *C1, const char *C2, // The previous rules don't catch all callbacks, especially if they're defined -// in a separate file from the git_config() call. Fix these manually. +// in a separate file from the repo_config() call. Fix these manually. @@ identifier C1, C2, D; attribute name UNUSED; diff --git a/convert.c b/convert.c index b5f7cf6306c3c3..c7d6a85c226db7 100644 --- a/convert.c +++ b/convert.c @@ -1326,7 +1326,7 @@ void convert_attrs(struct index_state *istate, "eol", "text", "working-tree-encoding", NULL); user_convert_tail = &user_convert; - git_config(read_convert_config, NULL); + repo_config(the_repository, read_convert_config, NULL); } git_check_attr(istate, path, check); diff --git a/fetch-pack.c b/fetch-pack.c index 01d3699c4b7fbe..11344206f73ce8 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1916,7 +1916,7 @@ static void fetch_pack_config(void) } } - git_config(fetch_pack_config_cb, NULL); + repo_config(the_repository, fetch_pack_config_cb, NULL); } static void fetch_pack_setup(void) diff --git a/fsck.h b/fsck.h index 0c5869ac34e216..dd7df3d5b3651b 100644 --- a/fsck.h +++ b/fsck.h @@ -287,7 +287,7 @@ const char *fsck_describe_object(struct fsck_options *options, struct key_value_info; /* - * git_config() callback for use by fsck-y tools that want to support + * repo_config() callback for use by fsck-y tools that want to support * fsck. fsck.skipList etc. */ int git_fsck_config(const char *var, const char *value, diff --git a/gpg-interface.c b/gpg-interface.c index bdcc8c2a2ed683..bc0c21ebab1712 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -25,7 +25,7 @@ static void gpg_interface_lazy_init(void) if (done) return; done = 1; - git_config(git_gpg_config, NULL); + repo_config(the_repository, git_gpg_config, NULL); } static char *configured_signing_key; diff --git a/help.c b/help.c index 652efebf00c309..db62cda44426e6 100644 --- a/help.c +++ b/help.c @@ -332,7 +332,7 @@ static int get_colopts(const char *var, const char *value, void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds) { unsigned int colopts = 0; - git_config(get_colopts, &colopts); + repo_config(the_repository, get_colopts, &colopts); if (main_cmds->cnt) { const char *exec_path = git_exec_path(); @@ -502,7 +502,7 @@ static void list_all_cmds_help_aliases(int longest) struct cmdname_help *aliases; int i; - git_config(get_alias, &alias_list); + repo_config(the_repository, get_alias, &alias_list); string_list_sort(&alias_list); for (i = 0; i < alias_list.nr; i++) { diff --git a/http-fetch.c b/http-fetch.c index 02ab80533f0e34..17b9fe4ff8c7a2 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -150,7 +150,7 @@ int cmd_main(int argc, const char **argv) trace2_cmd_name("http-fetch"); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); if (packfile) { if (!index_pack_args.nr) diff --git a/http.c b/http.c index 9b62f627dc576e..d94e8f63b57380 100644 --- a/http.c +++ b/http.c @@ -1315,7 +1315,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) http_is_verbose = 0; normalized_url = url_normalize(url, &config.url); - git_config(urlmatch_config_entry, &config); + repo_config(the_repository, urlmatch_config_entry, &config); free(normalized_url); string_list_clear(&config.vars, 1); diff --git a/imap-send.c b/imap-send.c index f5a656ac71dc2d..9b26c669c01558 100644 --- a/imap-send.c +++ b/imap-send.c @@ -1776,7 +1776,7 @@ int cmd_main(int argc, const char **argv) int ret; setup_git_directory_gently(&nongit_ok); - git_config(git_imap_config, &server); + repo_config(the_repository, git_imap_config, &server); argc = parse_options(argc, (const char **)argv, "", imap_send_options, imap_send_usage, 0); diff --git a/ls-refs.c b/ls-refs.c index e28c841375861d..c47acde07f335b 100644 --- a/ls-refs.c +++ b/ls-refs.c @@ -159,7 +159,7 @@ int ls_refs(struct repository *r, struct packet_reader *request) strbuf_init(&data.buf, 0); strvec_init(&data.hidden_refs); - git_config(ls_refs_config, &data); + repo_config(the_repository, ls_refs_config, &data); while (packet_reader_read(request) == PACKET_READ_NORMAL) { const char *arg = request->line; diff --git a/merge-ll.c b/merge-ll.c index b2dc26da4fe92d..fafe2c91971856 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -357,7 +357,7 @@ static void initialize_ll_merge(void) if (ll_user_merge_tail) return; ll_user_merge_tail = &ll_user_merge; - git_config(read_merge_config, NULL); + repo_config(the_repository, read_merge_config, NULL); } static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr) diff --git a/merge-ort.c b/merge-ort.c index 473ff61e36e9f7..49aa37a8f236bd 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -5387,7 +5387,7 @@ static void merge_recursive_config(struct merge_options *opt, int ui) free(value); } } - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); } static void init_merge_options(struct merge_options *opt, diff --git a/notes-utils.c b/notes-utils.c index ac66b82dd31082..6a50c6d56466d5 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -162,7 +162,7 @@ struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd) c->refs_from_env = 1; string_list_add_refs_from_colon_sep(c->refs, rewrite_refs_env); } - git_config(notes_rewrite_config, c); + repo_config(the_repository, notes_rewrite_config, c); if (!c->enabled || !c->refs->nr) { string_list_clear(c->refs, 0); free(c->refs); diff --git a/notes.c b/notes.c index 97b995f3f2da6f..49393fbfd8d860 100644 --- a/notes.c +++ b/notes.c @@ -1123,7 +1123,7 @@ void load_display_notes(struct display_notes_opt *opt) load_config_refs = 1; } - git_config(notes_display_config, &load_config_refs); + repo_config(the_repository, notes_display_config, &load_config_refs); if (opt) { struct string_list_item *item; diff --git a/pretty.c b/pretty.c index 0bc8ad8a9a8bc1..cee96b9d94dd0a 100644 --- a/pretty.c +++ b/pretty.c @@ -141,7 +141,7 @@ static void setup_commit_formats(void) COPY_ARRAY(commit_formats, builtin_formats, ARRAY_SIZE(builtin_formats)); - git_config(git_pretty_formats_config, NULL); + repo_config(the_repository, git_pretty_formats_config, NULL); } static struct cmt_fmt_map *find_commit_format_recursive(const char *sought, diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 4c3817f4ec1a88..5134781d52d7f7 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -386,7 +386,7 @@ static struct ref_store *reftable_be_init(struct repository *repo, refs->write_options.lock_timeout_ms = 100; refs->write_options.fsync = reftable_be_fsync; - git_config(reftable_be_config, &refs->write_options); + repo_config(the_repository, reftable_be_config, &refs->write_options); /* * It is somewhat unfortunate that we have to mirror the default block diff --git a/rerere.c b/rerere.c index 8bb97c98229bdd..1ac2075144c97c 100644 --- a/rerere.c +++ b/rerere.c @@ -879,7 +879,7 @@ static void git_rerere_config(void) { git_config_get_bool("rerere.enabled", &rerere_enabled); git_config_get_bool("rerere.autoupdate", &rerere_autoupdate); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } static GIT_PATH_FUNC(git_path_rr_cache, "rr-cache") @@ -1247,7 +1247,7 @@ void rerere_gc(struct repository *r, struct string_list *rr) &cutoff_resolve, now); repo_config_get_expiry_in_days(the_repository, "gc.rerereunresolved", &cutoff_noresolve, now); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); dir = opendir(repo_git_path_replace(the_repository, &buf, "rr-cache")); if (!dir) die_errno(_("unable to open rr-cache directory")); diff --git a/revision.c b/revision.c index 0ca6a297a6b09c..ad63c100eb936e 100644 --- a/revision.c +++ b/revision.c @@ -1636,7 +1636,7 @@ void exclude_hidden_refs(struct ref_exclusions *exclusions, const char *section) cb.exclusions = exclusions; cb.section = section; - git_config(hide_refs_config, &cb); + repo_config(the_repository, hide_refs_config, &cb); } struct all_refs_cb { diff --git a/scalar.c b/scalar.c index 0dc79fa9fb07a5..3b713abca3c289 100644 --- a/scalar.c +++ b/scalar.c @@ -713,7 +713,7 @@ static int cmd_reconfigure(int argc, const char **argv) maintenance_str); } - git_config(get_scalar_repos, &scalar_repos); + repo_config(the_repository, get_scalar_repos, &scalar_repos); for (size_t i = 0; i < scalar_repos.nr; i++) { int succeeded = 0; diff --git a/sequencer.c b/sequencer.c index 67e4310edcff5a..df207f33e07bb7 100644 --- a/sequencer.c +++ b/sequencer.c @@ -327,7 +327,7 @@ static int git_sequencer_config(const char *k, const char *v, void sequencer_init_config(struct replay_opts *opts) { opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_NONE; - git_config(git_sequencer_config, opts); + repo_config(the_repository, git_sequencer_config, opts); } static inline int is_rebase_i(const struct replay_opts *opts) diff --git a/setup.c b/setup.c index 6f52dab64cacb6..91a3affdd8f551 100644 --- a/setup.c +++ b/setup.c @@ -2339,7 +2339,7 @@ static int create_default_files(const char *template_path, copy_templates(template_path); git_config_clear(); repo_settings_reset_shared_repository(the_repository); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); reinit = is_reinit(); @@ -2610,7 +2610,7 @@ int init_db(const char *git_dir, const char *real_git_dir, * have set up the repository format such that we can evaluate * includeIf conditions correctly in the case of re-initialization. */ - git_config(platform_core_config, NULL); + repo_config(the_repository, platform_core_config, NULL); safe_create_dir(the_repository, git_dir, 0); diff --git a/t/helper/test-advise.c b/t/helper/test-advise.c index 6967c8e25c6860..77c15a46cfa07d 100644 --- a/t/helper/test-advise.c +++ b/t/helper/test-advise.c @@ -11,7 +11,7 @@ int cmd__advise_if_enabled(int argc, const char **argv) die("usage: %s ", argv[0]); setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); /* * Any advice type can be used for testing, but NESTED_TAG was diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 75e028ab2a0449..41ba864790014e 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -32,10 +32,10 @@ * ascending order of priority from a config_set * constructed from files entered as arguments. * - * iterate -> iterate over all values using git_config(), and print some + * iterate -> iterate over all values using repo_config(), and print some * data for each * - * git_config_int -> iterate over all values using git_config() and print the + * git_config_int -> iterate over all values using repo_config() and print the * integer value for the entered key or die * * Examples: @@ -218,10 +218,10 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (!strcmp(argv[1], "iterate")) { - git_config(iterate_cb, NULL); + repo_config(the_repository, iterate_cb, NULL); goto exit0; } else if (argc == 3 && !strcmp(argv[1], "git_config_int")) { - git_config(parse_int_cb, (void *) argv[2]); + repo_config(the_repository, parse_int_cb, (void *) argv[2]); goto exit0; } diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c index e277dde8e7107a..b2da48eda05185 100644 --- a/t/helper/test-read-cache.c +++ b/t/helper/test-read-cache.c @@ -19,7 +19,7 @@ int cmd__read_cache(int argc, const char **argv) if (argc == 2) cnt = strtol(argv[1], NULL, 0); setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); for (i = 0; i < cnt; i++) { repo_read_index(the_repository); diff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c index 94c48ababbefd0..aa3a9894d257ef 100644 --- a/t/helper/test-userdiff.c +++ b/t/helper/test-userdiff.c @@ -41,7 +41,7 @@ int cmd__userdiff(int argc, const char **argv) if (want & USERDIFF_DRIVER_TYPE_CUSTOM) { setup_git_directory(); - git_config(cmd__userdiff_config, NULL); + repo_config(the_repository, cmd__userdiff_config, NULL); } for_each_userdiff_driver(driver_cb, &want); diff --git a/t/t4256/1/mailinfo.c b/t/t4256/1/mailinfo.c index b395adbdf2a405..39caeba865391c 100644 --- a/t/t4256/1/mailinfo.c +++ b/t/t4256/1/mailinfo.c @@ -1214,7 +1214,7 @@ void setup_mailinfo(struct mailinfo *mi) mi->header_stage = 1; mi->use_inbody_headers = 1; mi->content_top = mi->content; - git_config(git_mailinfo_config, mi); + repo_config(the_repository, git_mailinfo_config, mi); } void clear_mailinfo(struct mailinfo *mi) diff --git a/t/t4256/1/mailinfo.c.orig b/t/t4256/1/mailinfo.c.orig index 3281a37d51830a..b76eb866aae801 100644 --- a/t/t4256/1/mailinfo.c.orig +++ b/t/t4256/1/mailinfo.c.orig @@ -1154,7 +1154,7 @@ void setup_mailinfo(struct mailinfo *mi) mi->header_stage = 1; mi->use_inbody_headers = 1; mi->content_top = mi->content; - git_config(git_mailinfo_config, mi); + repo_config(the_repository, git_mailinfo_config, mi); } void clear_mailinfo(struct mailinfo *mi) diff --git a/trailer.c b/trailer.c index 310cf582dc3703..911a81ed993ec6 100644 --- a/trailer.c +++ b/trailer.c @@ -595,8 +595,8 @@ void trailer_config_init(void) default_conf_info.where = WHERE_END; default_conf_info.if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR; default_conf_info.if_missing = MISSING_ADD; - git_config(git_trailer_default_config, NULL); - git_config(git_trailer_config, NULL); + repo_config(the_repository, git_trailer_default_config, NULL); + repo_config(the_repository, git_trailer_config, NULL); configured = 1; } diff --git a/transport.c b/transport.c index c123ac1e38b815..a246afd09fa5d5 100644 --- a/transport.c +++ b/transport.c @@ -202,7 +202,7 @@ static int fetch_refs_from_bundle(struct transport *transport, if (!data->get_refs_from_bundle_called) get_refs_from_bundle_inner(transport); - git_config(fetch_fsck_config_cb, &msg_types); + repo_config(the_repository, fetch_fsck_config_cb, &msg_types); opts.fsck_msg_types = msg_types.buf; ret = unbundle(the_repository, &data->header, data->fd, From 83bd9e03eddffbec034b8c79f46bfd360f0ea267 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:23 +0200 Subject: [PATCH 03/47] config: drop `git_config_clear()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_clear()`. All callsites are adjusted so that they use `repo_config_clear(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- config.h | 5 ----- scalar.c | 2 +- setup.c | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/config.h b/config.h index 6b729fc6bbfb2e..4eea99e9b9561b 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline void git_config_clear(void) -{ - repo_config_clear(the_repository); -} - static inline int git_config_get(const char *key) { return repo_config_get(the_repository, key); diff --git a/scalar.c b/scalar.c index 3b713abca3c289..2aaff5aa109585 100644 --- a/scalar.c +++ b/scalar.c @@ -763,7 +763,7 @@ static int cmd_reconfigure(int argc, const char **argv) break; } - git_config_clear(); + repo_config_clear(the_repository); if (repo_init(&r, gitdir.buf, commondir.buf)) goto loop_end; diff --git a/setup.c b/setup.c index 91a3affdd8f551..9661c5d5d5d7aa 100644 --- a/setup.c +++ b/setup.c @@ -1741,7 +1741,7 @@ const char *setup_git_directory_gently(int *nongit_ok) * configuration (including the per-repo config file that we * ignored previously). */ - git_config_clear(); + repo_config_clear(the_repository); /* * Let's assume that we are in a git repository. @@ -2337,7 +2337,7 @@ static int create_default_files(const char *template_path, * disk). */ copy_templates(template_path); - git_config_clear(); + repo_config_clear(the_repository); repo_settings_reset_shared_repository(the_repository); repo_config(the_repository, git_default_config, NULL); From 7807051e9b58628b09e77cca396306c9022b90c0 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:24 +0200 Subject: [PATCH 04/47] config: drop `git_config_get()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get()`. All callsites are adjusted so that they use `repo_config_get(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/gc.c | 2 +- builtin/submodule--helper.c | 6 +++--- config.h | 5 ----- t/helper/test-config.c | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index d9e3b9d2ec3632..e5c3d082edaed5 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1916,7 +1916,7 @@ static int maintenance_register(int argc, const char **argv, const char *prefix, git_config_set("maintenance.auto", "false"); /* Set maintenance strategy, if unset */ - if (git_config_get("maintenance.strategy")) + if (repo_config_get(the_repository, "maintenance.strategy")) git_config_set("maintenance.strategy", "incremental"); if (!git_config_get_string_multi(key, &list)) { diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 89ee09abea6f5d..6bcc741a6ac894 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -549,7 +549,7 @@ static int module_init(int argc, const char **argv, const char *prefix, * If there are no path args and submodule.active is set then, * by default, only initialize 'active' modules. */ - if (!argc && !git_config_get("submodule.active")) + if (!argc && !repo_config_get(the_repository, "submodule.active")) module_list_active(&list); info.prefix = prefix; @@ -2878,7 +2878,7 @@ static int module_update(int argc, const char **argv, const char *prefix, * If there are no path args and submodule.active is set then, * by default, only initialize 'active' modules. */ - if (!argc && !git_config_get("submodule.active")) + if (!argc && !repo_config_get(the_repository, "submodule.active")) module_list_active(&list); info.prefix = opt.prefix; @@ -3349,7 +3349,7 @@ static void configure_added_submodule(struct add_data *add_data) * is_submodule_active(), since that function needs to find * out the value of "submodule.active" again anyway. */ - if (!git_config_get("submodule.active")) { + if (!repo_config_get(the_repository, "submodule.active")) { /* * If the submodule being added isn't already covered by the * current configured pathspec, set the submodule's active flag diff --git a/config.h b/config.h index 4eea99e9b9561b..9261ed0f8d7f05 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get(const char *key) -{ - return repo_config_get(the_repository, key); -} - static inline int git_config_get_value(const char *key, const char **value) { return repo_config_get_value(the_repository, key, value); diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 41ba864790014e..cacf6f306b1484 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -137,7 +137,7 @@ int cmd__config(int argc, const char **argv) } else if (argc == 3 && !strcmp(argv[1], "get")) { int ret; - if (!(ret = git_config_get(argv[2]))) + if (!(ret = repo_config_get(the_repository, argv[2]))) goto exit0; else if (ret == 1) printf("Value not found for \"%s\"\n", argv[2]); From 2f1242567ebe48f7f61df138f37b226256b7c4c6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:25 +0200 Subject: [PATCH 05/47] config: drop `git_config_get_value()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_value()`. All callsites are adjusted so that they use `repo_config_get_value(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/gc.c | 4 ++-- builtin/pull.c | 6 +++--- config.h | 5 ----- rebase-interactive.c | 2 +- t/helper/test-config.c | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index e5c3d082edaed5..e94931ff48f08c 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -114,7 +114,7 @@ static int gc_config_is_timestamp_never(const char *var) const char *value; timestamp_t expire; - if (!git_config_get_value(var, &value) && value) { + if (!repo_config_get_value(the_repository, var, &value) && value) { if (parse_expiry_date(value, &expire)) die(_("failed to parse '%s' value '%s'"), var, value); return expire == 0; @@ -178,7 +178,7 @@ static void gc_config(struct gc_config *cfg) char *owned = NULL; unsigned long ulongval; - if (!git_config_get_value("gc.packrefs", &value)) { + if (!repo_config_get_value(the_repository, "gc.packrefs", &value)) { if (value && !strcmp(value, "notbare")) cfg->pack_refs = -1; else diff --git a/builtin/pull.c b/builtin/pull.c index d13ed9b5176c24..5ea51c31f5878b 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -312,7 +312,7 @@ static const char *config_get_ff(void) { const char *value; - if (git_config_get_value("pull.ff", &value)) + if (repo_config_get_value(the_repository, "pull.ff", &value)) return NULL; switch (git_parse_maybe_bool(value)) { @@ -343,7 +343,7 @@ static enum rebase_type config_get_rebase(int *rebase_unspecified) if (curr_branch) { char *key = xstrfmt("branch.%s.rebase", curr_branch->name); - if (!git_config_get_value(key, &value)) { + if (!repo_config_get_value(the_repository, key, &value)) { enum rebase_type ret = parse_config_rebase(key, value, 1); free(key); return ret; @@ -352,7 +352,7 @@ static enum rebase_type config_get_rebase(int *rebase_unspecified) free(key); } - if (!git_config_get_value("pull.rebase", &value)) + if (!repo_config_get_value(the_repository, "pull.rebase", &value)) return parse_config_rebase("pull.rebase", value, 1); *rebase_unspecified = 1; diff --git a/config.h b/config.h index 9261ed0f8d7f05..5dc330b88b1ab9 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_value(const char *key, const char **value) -{ - return repo_config_get_value(the_repository, key, value); -} - static inline int git_config_get_value_multi(const char *key, const struct string_list **dest) { return repo_config_get_value_multi(the_repository, key, dest); diff --git a/rebase-interactive.c b/rebase-interactive.c index cbeb8641477106..809f76a87b8c77 100644 --- a/rebase-interactive.c +++ b/rebase-interactive.c @@ -30,7 +30,7 @@ static enum missing_commit_check_level get_missing_commit_check_level(void) { const char *value; - if (git_config_get_value("rebase.missingcommitscheck", &value) || + if (repo_config_get_value(the_repository, "rebase.missingcommitscheck", &value) || !strcasecmp("ignore", value)) return MISSING_COMMIT_CHECK_IGNORE; if (!strcasecmp("warn", value)) diff --git a/t/helper/test-config.c b/t/helper/test-config.c index cacf6f306b1484..99c91512173dfd 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -110,7 +110,7 @@ int cmd__config(int argc, const char **argv) fprintf(stderr, "Please, provide a command name on the command-line\n"); goto exit1; } else if (argc == 3 && !strcmp(argv[1], "get_value")) { - if (!git_config_get_value(argv[2], &v)) { + if (!repo_config_get_value(the_repository, argv[2], &v)) { if (!v) printf("(NULL)\n"); else From 8e7110d50cee1ca557d1d79066a2e192b46a1d48 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:26 +0200 Subject: [PATCH 06/47] config: drop `git_config_get_value()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_value()`. All callsites are adjusted so that they use `repo_config_get_value(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- config.h | 5 ----- t/helper/test-config.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/config.h b/config.h index 5dc330b88b1ab9..e90c1c4d33587f 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_value_multi(const char *key, const struct string_list **dest) -{ - return repo_config_get_value_multi(the_repository, key, dest); -} - static inline int git_config_get_string_multi(const char *key, const struct string_list **dest) { diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 99c91512173dfd..1953ab846e455a 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -121,7 +121,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) { - if (!git_config_get_value_multi(argv[2], &strptr)) { + if (!repo_config_get_value_multi(the_repository, argv[2], &strptr)) { for (i = 0; i < strptr->nr; i++) { v = strptr->items[i].string; if (!v) From 4f5ba823b879bbe0f06ceb6246755f39e793769f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:27 +0200 Subject: [PATCH 07/47] config: drop `git_config_get_string_multi()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_string_multi()`. All callsites are adjusted so that they use `repo_config_get_string_multi(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/gc.c | 4 ++-- builtin/log.c | 2 +- config.h | 6 ------ reachable.c | 2 +- versioncmp.c | 4 ++-- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index e94931ff48f08c..f395cc57a15762 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1919,7 +1919,7 @@ static int maintenance_register(int argc, const char **argv, const char *prefix, if (repo_config_get(the_repository, "maintenance.strategy")) git_config_set("maintenance.strategy", "incremental"); - if (!git_config_get_string_multi(key, &list)) { + if (!repo_config_get_string_multi(the_repository, key, &list)) { for_each_string_list_item(item, list) { if (!strcmp(maintpath, item->string)) { found = 1; @@ -1988,7 +1988,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi } if (!(config_file ? git_configset_get_string_multi(&cs, key, &list) - : git_config_get_string_multi(key, &list))) { + : repo_config_get_string_multi(the_repository, key, &list))) { for_each_string_list_item(item, list) { if (!strcmp(maintpath, item->string)) { found = 1; diff --git a/builtin/log.c b/builtin/log.c index 1bedc4ef3551e9..b512f12e8058a3 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -221,7 +221,7 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f struct string_list *include = decoration_filter->include_ref_pattern; const struct string_list *config_exclude; - if (!git_config_get_string_multi("log.excludeDecoration", + if (!repo_config_get_string_multi(the_repository, "log.excludeDecoration", &config_exclude)) { struct string_list_item *item; for_each_string_list_item(item, config_exclude) diff --git a/config.h b/config.h index e90c1c4d33587f..f6635e48c2342b 100644 --- a/config.h +++ b/config.h @@ -719,12 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_string_multi(const char *key, - const struct string_list **dest) -{ - return repo_config_get_string_multi(the_repository, key, dest); -} - static inline int git_config_get_string(const char *key, char **dest) { return repo_config_get_string(the_repository, key, dest); diff --git a/reachable.c b/reachable.c index e984b68a0c41e1..8330a14fa82b96 100644 --- a/reachable.c +++ b/reachable.c @@ -170,7 +170,7 @@ static void load_gc_recent_objects(struct recent_data *data) data->extra_recent_oids_loaded = 1; - if (git_config_get_string_multi("gc.recentobjectshook", &programs)) + if (repo_config_get_string_multi(the_repository, "gc.recentobjectshook", &programs)) return; for (i = 0; i < programs->nr; i++) { diff --git a/versioncmp.c b/versioncmp.c index b6eebdb989c042..3a81b17bc1b8d1 100644 --- a/versioncmp.c +++ b/versioncmp.c @@ -167,8 +167,8 @@ int versioncmp(const char *s1, const char *s2) const char *const oldk = "versionsort.prereleasesuffix"; const struct string_list *newl; const struct string_list *oldl; - int new = git_config_get_string_multi(newk, &newl); - int old = git_config_get_string_multi(oldk, &oldl); + int new = repo_config_get_string_multi(the_repository, newk, &newl); + int old = repo_config_get_string_multi(the_repository, oldk, &oldl); if (!new && !old) warning("ignoring %s because %s is set", oldk, newk); From 627d08cca769999a7a9419b8aeaba26f61f551f5 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:28 +0200 Subject: [PATCH 08/47] config: drop `git_config_get_string()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_string()`. All callsites are adjusted so that they use `repo_config_get_string(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- apply.c | 4 ++-- branch.c | 2 +- builtin/gc.c | 4 ++-- builtin/log.c | 2 +- builtin/notes.c | 2 +- builtin/submodule--helper.c | 12 ++++++------ config.h | 5 ----- fetch-pack.c | 2 +- merge-ort.c | 8 ++++---- scalar.c | 4 ++-- sequencer.c | 2 +- transport.c | 8 ++++---- 12 files changed, 25 insertions(+), 30 deletions(-) diff --git a/apply.c b/apply.c index d2381a157c0a83..45eb790d1334cc 100644 --- a/apply.c +++ b/apply.c @@ -48,8 +48,8 @@ struct gitdiff_data { static void git_apply_config(void) { - git_config_get_string("apply.whitespace", &apply_default_whitespace); - git_config_get_string("apply.ignorewhitespace", &apply_default_ignorewhitespace); + repo_config_get_string(the_repository, "apply.whitespace", &apply_default_whitespace); + repo_config_get_string(the_repository, "apply.ignorewhitespace", &apply_default_ignorewhitespace); repo_config(the_repository, git_xmerge_config, NULL); } diff --git a/branch.c b/branch.c index 93f5b4e8dd9fe5..b4811671fc741c 100644 --- a/branch.c +++ b/branch.c @@ -355,7 +355,7 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name) char *v = NULL; struct strbuf name = STRBUF_INIT; strbuf_addf(&name, "branch.%s.description", branch_name); - if (git_config_get_string(name.buf, &v)) { + if (repo_config_get_string(the_repository, name.buf, &v)) { strbuf_release(&name); return -1; } diff --git a/builtin/gc.c b/builtin/gc.c index f395cc57a15762..d8f7a1858cb22e 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -218,12 +218,12 @@ static void gc_config(struct gc_config *cfg) if (!git_config_get_ulong("core.deltabasecachelimit", &ulongval)) cfg->delta_base_cache_limit = ulongval; - if (!git_config_get_string("gc.repackfilter", &owned)) { + if (!repo_config_get_string(the_repository, "gc.repackfilter", &owned)) { free(cfg->repack_filter); cfg->repack_filter = owned; } - if (!git_config_get_string("gc.repackfilterto", &owned)) { + if (!repo_config_get_string(the_repository, "gc.repackfilterto", &owned)) { free(cfg->repack_filter_to); cfg->repack_filter_to = owned; } diff --git a/builtin/log.c b/builtin/log.c index b512f12e8058a3..a9969ad00a0362 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -235,7 +235,7 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f * since the command-line takes precedent. */ if (use_default_decoration_filter && - !git_config_get_string("log.initialdecorationset", &value) && + !repo_config_get_string(the_repository, "log.initialdecorationset", &value) && !strcmp("all", value)) use_default_decoration_filter = 0; free(value); diff --git a/builtin/notes.c b/builtin/notes.c index 17004cdb10eb75..d2252cf5346b81 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -873,7 +873,7 @@ static int git_config_get_notes_strategy(const char *key, { char *value; - if (git_config_get_string(key, &value)) + if (repo_config_get_string(the_repository, key, &value)) return 1; if (parse_notes_merge_strategy(value, strategy)) git_die_config(the_repository, key, _("unknown notes merge strategy %s"), value); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 6bcc741a6ac894..18aa69f0cae6fd 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -53,7 +53,7 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int struct strbuf remotesb = STRBUF_INIT; strbuf_addf(&remotesb, "remote.%s.url", remote); - if (git_config_get_string(remotesb.buf, &remoteurl)) { + if (repo_config_get_string(the_repository, remotesb.buf, &remoteurl)) { if (!quiet) warning(_("could not look up configuration '%s'. " "Assuming this repository is its own " @@ -468,7 +468,7 @@ static void init_submodule(const char *path, const char *prefix, * .gitmodules, so look it up directly. */ strbuf_addf(&sb, "submodule.%s.url", sub->name); - if (git_config_get_string(sb.buf, &url)) { + if (repo_config_get_string(the_repository, sb.buf, &url)) { if (!sub->url) die(_("No url found for submodule path '%s' in .gitmodules"), displaypath); @@ -1623,11 +1623,11 @@ static void prepare_possible_alternates(const char *sm_name, char *sm_alternate = NULL, *error_strategy = NULL; struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT; - git_config_get_string("submodule.alternateLocation", &sm_alternate); + repo_config_get_string(the_repository, "submodule.alternateLocation", &sm_alternate); if (!sm_alternate) return; - git_config_get_string("submodule.alternateErrorStrategy", &error_strategy); + repo_config_get_string(the_repository, "submodule.alternateErrorStrategy", &error_strategy); if (!error_strategy) error_strategy = xstrdup("die"); @@ -1808,11 +1808,11 @@ static int clone_submodule(const struct module_clone_data *clone_data, die(_("could not get submodule directory for '%s'"), clone_data_path); /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */ - git_config_get_string("submodule.alternateLocation", &sm_alternate); + repo_config_get_string(the_repository, "submodule.alternateLocation", &sm_alternate); if (sm_alternate) git_config_set_in_file(p, "submodule.alternateLocation", sm_alternate); - git_config_get_string("submodule.alternateErrorStrategy", &error_strategy); + repo_config_get_string(the_repository, "submodule.alternateErrorStrategy", &error_strategy); if (error_strategy) git_config_set_in_file(p, "submodule.alternateErrorStrategy", error_strategy); diff --git a/config.h b/config.h index f6635e48c2342b..8887ebf62eadae 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_string(const char *key, char **dest) -{ - return repo_config_get_string(the_repository, key, dest); -} - static inline int git_config_get_string_tmp(const char *key, const char **dest) { return repo_config_get_string_tmp(the_repository, key, dest); diff --git a/fetch-pack.c b/fetch-pack.c index 11344206f73ce8..04768087879ad0 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1910,7 +1910,7 @@ static void fetch_pack_config(void) if (!uri_protocols.nr) { char *str; - if (!git_config_get_string("fetch.uriprotocols", &str) && str) { + if (!repo_config_get_string(the_repository, "fetch.uriprotocols", &str) && str) { string_list_split(&uri_protocols, str, ',', -1); free(str); } diff --git a/merge-ort.c b/merge-ort.c index 49aa37a8f236bd..29789579c9b122 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -5358,15 +5358,15 @@ static void merge_recursive_config(struct merge_options *opt, int ui) git_config_get_int("merge.renamelimit", &opt->rename_limit); git_config_get_bool("merge.renormalize", &renormalize); opt->renormalize = renormalize; - if (!git_config_get_string("diff.renames", &value)) { + if (!repo_config_get_string(the_repository, "diff.renames", &value)) { opt->detect_renames = git_config_rename("diff.renames", value); free(value); } - if (!git_config_get_string("merge.renames", &value)) { + if (!repo_config_get_string(the_repository, "merge.renames", &value)) { opt->detect_renames = git_config_rename("merge.renames", value); free(value); } - if (!git_config_get_string("merge.directoryrenames", &value)) { + if (!repo_config_get_string(the_repository, "merge.directoryrenames", &value)) { int boolval = git_parse_maybe_bool(value); if (0 <= boolval) { opt->detect_directory_renames = boolval ? @@ -5379,7 +5379,7 @@ static void merge_recursive_config(struct merge_options *opt, int ui) free(value); } if (ui) { - if (!git_config_get_string("diff.algorithm", &value)) { + if (!repo_config_get_string(the_repository, "diff.algorithm", &value)) { long diff_algorithm = parse_algorithm_value(value); if (diff_algorithm < 0) die(_("unknown value for config '%s': %s"), "diff.algorithm", value); diff --git a/scalar.c b/scalar.c index 2aaff5aa109585..07f855c9913985 100644 --- a/scalar.c +++ b/scalar.c @@ -101,7 +101,7 @@ static int set_scalar_config(const struct scalar_config *config, int reconfigure int res; if ((reconfigure && config->overwrite_on_reconfigure) || - git_config_get_string(config->key, &value)) { + repo_config_get_string(the_repository, config->key, &value)) { trace2_data_string("scalar", the_repository, config->key, "created"); res = git_config_set_gently(config->key, config->value); } else { @@ -193,7 +193,7 @@ static int set_recommended_config(int reconfigure) * The `log.excludeDecoration` setting is special because it allows * for multiple values. */ - if (git_config_get_string("log.excludeDecoration", &value)) { + if (repo_config_get_string(the_repository, "log.excludeDecoration", &value)) { trace2_data_string("scalar", the_repository, "log.excludeDecoration", "created"); if (git_config_set_multivar_gently("log.excludeDecoration", diff --git a/sequencer.c b/sequencer.c index df207f33e07bb7..f3bada39b4075b 100644 --- a/sequencer.c +++ b/sequencer.c @@ -6089,7 +6089,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, revs.topo_order = 1; revs.pretty_given = 1; - git_config_get_string("rebase.instructionFormat", &format); + repo_config_get_string(the_repository, "rebase.instructionFormat", &format); if (!format || !*format) { free(format); format = xstrdup("# %s"); diff --git a/transport.c b/transport.c index a246afd09fa5d5..89e6297ce222bb 100644 --- a/transport.c +++ b/transport.c @@ -54,14 +54,14 @@ static int transport_color_config(void) return 0; initialized = 1; - if (!git_config_get_string(key, &value)) + if (!repo_config_get_string(the_repository, key, &value)) transport_use_color = git_config_colorbool(key, value); if (!want_color_stderr(transport_use_color)) return 0; for (size_t i = 0; i < ARRAY_SIZE(keys); i++) - if (!git_config_get_string(keys[i], &value)) { + if (!repo_config_get_string(the_repository, keys[i], &value)) { if (!value) return config_error_nonbool(keys[i]); if (color_parse(value, transport_colors[i]) < 0) @@ -1078,7 +1078,7 @@ static enum protocol_allow_config get_protocol_config(const char *type) char *value; /* first check the per-protocol config */ - if (!git_config_get_string(key, &value)) { + if (!repo_config_get_string(the_repository, key, &value)) { enum protocol_allow_config ret = parse_protocol_config(key, value); free(key); @@ -1088,7 +1088,7 @@ static enum protocol_allow_config get_protocol_config(const char *type) free(key); /* if defined, fallback to user-defined default for unknown protocols */ - if (!git_config_get_string("protocol.allow", &value)) { + if (!repo_config_get_string(the_repository, "protocol.allow", &value)) { enum protocol_allow_config ret = parse_protocol_config("protocol.allow", value); free(value); From cba3c02591b820fdb812cb2c2ebb5dbd98761ba8 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:29 +0200 Subject: [PATCH 09/47] config: drop `git_config_get_string()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_string()`. All callsites are adjusted so that they use `repo_config_get_string(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/fetch.c | 2 +- builtin/gc.c | 4 ++-- builtin/remote.c | 2 +- builtin/submodule--helper.c | 4 ++-- checkout.c | 2 +- config.h | 5 ----- connect.c | 4 ++-- editor.c | 2 +- help.c | 2 +- promisor-remote.c | 4 ++-- protocol.c | 2 +- remote.c | 2 +- sideband.c | 6 +++--- t/helper/test-config.c | 2 +- 14 files changed, 19 insertions(+), 24 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index ea447c453d148a..52eae4b972ddce 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -2508,7 +2508,7 @@ int cmd_fetch(int argc, if (!max_jobs) max_jobs = online_cpus(); - if (!git_config_get_string_tmp("fetch.bundleuri", &bundle_uri) && + if (!repo_config_get_string_tmp(the_repository, "fetch.bundleuri", &bundle_uri) && fetch_bundle_uri(the_repository, bundle_uri, NULL)) warning(_("failed to fetch bundles from '%s'"), bundle_uri); diff --git a/builtin/gc.c b/builtin/gc.c index d8f7a1858cb22e..a2b8fbc9f3d87c 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1765,7 +1765,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts, if (opts->schedule) { strategy = none_strategy; - if (!git_config_get_string_tmp("maintenance.strategy", &config_str)) { + if (!repo_config_get_string_tmp(the_repository, "maintenance.strategy", &config_str)) { if (!strcasecmp(config_str, "incremental")) strategy = incremental_strategy; } @@ -1788,7 +1788,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts, strbuf_reset(&config_name); strbuf_addf(&config_name, "maintenance.%s.schedule", tasks[i].name); - if (!git_config_get_string_tmp(config_name.buf, &config_str)) + if (!repo_config_get_string_tmp(the_repository, config_name.buf, &config_str)) strategy.tasks[i].schedule = parse_schedule(config_str); if (strategy.tasks[i].schedule < opts->schedule) continue; diff --git a/builtin/remote.c b/builtin/remote.c index ebd70bea3a186d..826b2dcfd04a4e 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1268,7 +1268,7 @@ static int get_one_entry(struct remote *remote, void *priv) strbuf_addf(&promisor_config, "remote.%s.partialclonefilter", remote->name); strbuf_addf(&remote_info_buf, "%s (fetch)", remote->url.v[0]); - if (!git_config_get_string_tmp(promisor_config.buf, &partial_clone_filter)) + if (!repo_config_get_string_tmp(the_repository, promisor_config.buf, &partial_clone_filter)) strbuf_addf(&remote_info_buf, " [%s]", partial_clone_filter); strbuf_release(&promisor_config); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 18aa69f0cae6fd..d2ab31835b51ed 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -496,7 +496,7 @@ static void init_submodule(const char *path, const char *prefix, /* Copy "update" setting when it is not set yet */ strbuf_addf(&sb, "submodule.%s.update", sub->name); - if (git_config_get_string_tmp(sb.buf, &upd) && + if (repo_config_get_string_tmp(the_repository, sb.buf, &upd) && sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) { if (sub->update_strategy.type == SM_UPDATE_COMMAND) { fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"), @@ -1034,7 +1034,7 @@ static void prepare_submodule_summary(struct summary_cb *info, config_key = xstrfmt("submodule.%s.ignore", sub->name); - if (!git_config_get_string_tmp(config_key, &value)) + if (!repo_config_get_string_tmp(the_repository, config_key, &value)) ignore_all = !strcmp(value, "all"); else if (sub->ignore) ignore_all = !strcmp(sub->ignore, "all"); diff --git a/checkout.c b/checkout.c index 0b1cf8b40b7846..1588b116eedf06 100644 --- a/checkout.c +++ b/checkout.c @@ -52,7 +52,7 @@ char *unique_tracking_name(const char *name, struct object_id *oid, { struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT; const char *default_remote = NULL; - if (!git_config_get_string_tmp("checkout.defaultremote", &default_remote)) + if (!repo_config_get_string_tmp(the_repository, "checkout.defaultremote", &default_remote)) cb_data.default_remote = default_remote; cb_data.src_ref = xstrfmt("refs/heads/%s", name); cb_data.dst_oid = oid; diff --git a/config.h b/config.h index 8887ebf62eadae..89739bee9b048f 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_string_tmp(const char *key, const char **dest) -{ - return repo_config_get_string_tmp(the_repository, key, dest); -} - static inline int git_config_get_int(const char *key, int *dest) { return repo_config_get_int(the_repository, key, dest); diff --git a/connect.c b/connect.c index 4b1dc65e5cef1b..34cac24d54c638 100644 --- a/connect.c +++ b/connect.c @@ -1154,7 +1154,7 @@ static const char *get_ssh_command(void) if ((ssh = getenv("GIT_SSH_COMMAND"))) return ssh; - if (!git_config_get_string_tmp("core.sshcommand", &ssh)) + if (!repo_config_get_string_tmp(the_repository, "core.sshcommand", &ssh)) return ssh; return NULL; @@ -1173,7 +1173,7 @@ static void override_ssh_variant(enum ssh_variant *ssh_variant) { const char *variant = getenv("GIT_SSH_VARIANT"); - if (!variant && git_config_get_string_tmp("ssh.variant", &variant)) + if (!variant && repo_config_get_string_tmp(the_repository, "ssh.variant", &variant)) return; if (!strcmp(variant, "auto")) diff --git a/editor.c b/editor.c index b79d97b0e721c2..fd174e6a034f1c 100644 --- a/editor.c +++ b/editor.c @@ -50,7 +50,7 @@ const char *git_sequence_editor(void) const char *editor = getenv("GIT_SEQUENCE_EDITOR"); if (!editor) - git_config_get_string_tmp("sequence.editor", &editor); + repo_config_get_string_tmp(the_repository, "sequence.editor", &editor); if (!editor) editor = git_editor(); diff --git a/help.c b/help.c index db62cda44426e6..bb20498cfd0f15 100644 --- a/help.c +++ b/help.c @@ -417,7 +417,7 @@ void list_cmds_by_config(struct string_list *list) { const char *cmd_list; - if (git_config_get_string_tmp("completion.commands", &cmd_list)) + if (repo_config_get_string_tmp(the_repository, "completion.commands", &cmd_list)) return; string_list_sort(list); diff --git a/promisor-remote.c b/promisor-remote.c index be6f82d12f847a..a9c877d9cfa30f 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -327,7 +327,7 @@ static void promisor_info_vecs(struct repository *repo, char *url_key = xstrfmt("remote.%s.url", r->name); /* Only add remotes with a non empty URL */ - if (!git_config_get_string_tmp(url_key, &url) && *url) { + if (!repo_config_get_string_tmp(the_repository, url_key, &url) && *url) { strvec_push(names, r->name); strvec_push(urls, url); } @@ -433,7 +433,7 @@ static void filter_promisor_remote(struct repository *repo, struct strvec names = STRVEC_INIT; struct strvec urls = STRVEC_INIT; - if (!git_config_get_string_tmp("promisor.acceptfromserver", &accept_str)) { + if (!repo_config_get_string_tmp(the_repository, "promisor.acceptfromserver", &accept_str)) { if (!*accept_str || !strcasecmp("None", accept_str)) accept = ACCEPT_NONE; else if (!strcasecmp("KnownUrl", accept_str)) diff --git a/protocol.c b/protocol.c index bae7226ff4074f..65f66217021609 100644 --- a/protocol.c +++ b/protocol.c @@ -24,7 +24,7 @@ enum protocol_version get_protocol_version_config(void) const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION"; const char *git_test_v; - if (!git_config_get_string_tmp("protocol.version", &value)) { + if (!repo_config_get_string_tmp(the_repository, "protocol.version", &value)) { enum protocol_version version = parse_protocol_version(value); if (version == protocol_unknown_version) diff --git a/remote.c b/remote.c index e965f022f12b78..88f991795b2683 100644 --- a/remote.c +++ b/remote.c @@ -734,7 +734,7 @@ static void validate_remote_url(struct remote *remote) struct strbuf redacted = STRBUF_INIT; int warn_not_die; - if (git_config_get_string_tmp("transfer.credentialsinurl", &value)) + if (repo_config_get_string_tmp(the_repository, "transfer.credentialsinurl", &value)) return; if (!strcmp("warn", value)) diff --git a/sideband.c b/sideband.c index 251e9615ed0239..8f15b98a65444f 100644 --- a/sideband.c +++ b/sideband.c @@ -39,9 +39,9 @@ static int use_sideband_colors(void) if (use_sideband_colors_cached >= 0) return use_sideband_colors_cached; - if (!git_config_get_string_tmp(key, &value)) + if (!repo_config_get_string_tmp(the_repository, key, &value)) use_sideband_colors_cached = git_config_colorbool(key, value); - else if (!git_config_get_string_tmp("color.ui", &value)) + else if (!repo_config_get_string_tmp(the_repository, "color.ui", &value)) use_sideband_colors_cached = git_config_colorbool("color.ui", value); else use_sideband_colors_cached = GIT_COLOR_AUTO; @@ -49,7 +49,7 @@ static int use_sideband_colors(void) for (i = 0; i < ARRAY_SIZE(keywords); i++) { strbuf_reset(&sb); strbuf_addf(&sb, "%s.%s", key, keywords[i].keyword); - if (git_config_get_string_tmp(sb.buf, &value)) + if (repo_config_get_string_tmp(the_repository, sb.buf, &value)) continue; color_parse(value, keywords[i].color); } diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 1953ab846e455a..30e70f1a6c2310 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -171,7 +171,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_string")) { - if (!git_config_get_string_tmp(argv[2], &v)) { + if (!repo_config_get_string_tmp(the_repository, argv[2], &v)) { printf("%s\n", v); goto exit0; } else { From 3fda14d86d91c665e3d7c50da242cc4ddd63eea5 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:30 +0200 Subject: [PATCH 10/47] config: drop `git_config_get_int()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_int()`. All callsites are adjusted so that they use `repo_config_get_int(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/credential-store.c | 2 +- builtin/fast-import.c | 6 +++--- builtin/fetch.c | 4 ++-- builtin/gc.c | 26 +++++++++++++------------- config.h | 5 ----- fetch-pack.c | 4 ++-- fsmonitor.c | 2 +- merge-ort.c | 6 +++--- parallel-checkout.c | 4 ++-- refs.c | 2 +- refs/packed-backend.c | 2 +- sequencer.c | 2 +- t/helper/test-config.c | 2 +- 13 files changed, 31 insertions(+), 36 deletions(-) diff --git a/builtin/credential-store.c b/builtin/credential-store.c index e669e99dbfb9a7..b74e06cc93d9cd 100644 --- a/builtin/credential-store.c +++ b/builtin/credential-store.c @@ -66,7 +66,7 @@ static void rewrite_credential_file(const char *fn, struct credential *c, { int timeout_ms = 1000; - git_config_get_int("credentialstore.locktimeoutms", &timeout_ms); + repo_config_get_int(the_repository, "credentialstore.locktimeoutms", &timeout_ms); if (hold_lock_file_for_update_timeout(&credential_lock, fn, 0, timeout_ms) < 0) die_errno(_("unable to get credential storage lock in %d ms"), timeout_ms); if (extra) diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 607441e921b38a..9b0ae437148678 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -3527,7 +3527,7 @@ static void git_pack_config(void) if (max_depth > MAX_DEPTH) max_depth = MAX_DEPTH; } - if (!git_config_get_int("pack.indexversion", &indexversion_value)) { + if (!repo_config_get_int(the_repository, "pack.indexversion", &indexversion_value)) { pack_idx_opts.version = indexversion_value; if (pack_idx_opts.version > 2) git_die_config(the_repository, "pack.indexversion", @@ -3536,9 +3536,9 @@ static void git_pack_config(void) if (!git_config_get_ulong("pack.packsizelimit", &packsizelimit_value)) max_packsize = packsizelimit_value; - if (!git_config_get_int("fastimport.unpacklimit", &limit)) + if (!repo_config_get_int(the_repository, "fastimport.unpacklimit", &limit)) unpack_limit = limit; - else if (!git_config_get_int("transfer.unpacklimit", &limit)) + else if (!repo_config_get_int(the_repository, "transfer.unpacklimit", &limit)) unpack_limit = limit; repo_config(the_repository, git_default_config, NULL); diff --git a/builtin/fetch.c b/builtin/fetch.c index 52eae4b972ddce..24645c465335de 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -2683,12 +2683,12 @@ int cmd_fetch(int argc, * but respect config settings disabling it. */ int opt_val; - if (git_config_get_int("gc.autopacklimit", &opt_val)) + if (repo_config_get_int(the_repository, "gc.autopacklimit", &opt_val)) opt_val = -1; if (opt_val != 0) git_config_push_parameter("gc.autoPackLimit=1"); - if (git_config_get_int("maintenance.incremental-repack.auto", &opt_val)) + if (repo_config_get_int(the_repository, "maintenance.incremental-repack.auto", &opt_val)) opt_val = -1; if (opt_val != 0) git_config_push_parameter("maintenance.incremental-repack.auto=-1"); diff --git a/builtin/gc.c b/builtin/gc.c index a2b8fbc9f3d87c..cf175b8f1b7610 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -189,10 +189,10 @@ static void gc_config(struct gc_config *cfg) gc_config_is_timestamp_never("gc.reflogexpireunreachable")) cfg->prune_reflogs = 0; - git_config_get_int("gc.aggressivewindow", &cfg->aggressive_window); - git_config_get_int("gc.aggressivedepth", &cfg->aggressive_depth); - git_config_get_int("gc.auto", &cfg->gc_auto_threshold); - git_config_get_int("gc.autopacklimit", &cfg->gc_auto_pack_limit); + repo_config_get_int(the_repository, "gc.aggressivewindow", &cfg->aggressive_window); + repo_config_get_int(the_repository, "gc.aggressivedepth", &cfg->aggressive_depth); + repo_config_get_int(the_repository, "gc.auto", &cfg->gc_auto_threshold); + repo_config_get_int(the_repository, "gc.autopacklimit", &cfg->gc_auto_pack_limit); git_config_get_bool("gc.autodetach", &cfg->detach_auto); git_config_get_bool("gc.cruftpacks", &cfg->cruft_packs); git_config_get_ulong("gc.maxcruftsize", &cfg->max_cruft_size); @@ -332,7 +332,7 @@ static int reflog_expire_condition(struct gc_config *cfg UNUSED) }; int limit = 100; - git_config_get_int("maintenance.reflog-expire.auto", &limit); + repo_config_get_int(the_repository, "maintenance.reflog-expire.auto", &limit); if (!limit) return 0; if (limit < 0) @@ -378,7 +378,7 @@ static int worktree_prune_condition(struct gc_config *cfg) struct dirent *d; DIR *dir = NULL; - git_config_get_int("maintenance.worktree-prune.auto", &limit); + repo_config_get_int(the_repository, "maintenance.worktree-prune.auto", &limit); if (limit <= 0) { should_prune = limit < 0; goto out; @@ -423,7 +423,7 @@ static int rerere_gc_condition(struct gc_config *cfg UNUSED) int should_gc = 0, limit = 1; DIR *dir = NULL; - git_config_get_int("maintenance.rerere-gc.auto", &limit); + repo_config_get_int(the_repository, "maintenance.rerere-gc.auto", &limit); if (limit <= 0) { should_gc = limit < 0; goto out; @@ -1161,8 +1161,8 @@ static int should_write_commit_graph(struct gc_config *cfg UNUSED) data.num_not_in_graph = 0; data.limit = 100; - git_config_get_int("maintenance.commit-graph.auto", - &data.limit); + repo_config_get_int(the_repository, "maintenance.commit-graph.auto", + &data.limit); if (!data.limit) return 0; @@ -1300,8 +1300,8 @@ static int loose_object_auto_condition(struct gc_config *cfg UNUSED) { int count = 0; - git_config_get_int("maintenance.loose-objects.auto", - &loose_object_auto_limit); + repo_config_get_int(the_repository, "maintenance.loose-objects.auto", + &loose_object_auto_limit); if (!loose_object_auto_limit) return 0; @@ -1415,8 +1415,8 @@ static int incremental_repack_auto_condition(struct gc_config *cfg UNUSED) if (!the_repository->settings.core_multi_pack_index) return 0; - git_config_get_int("maintenance.incremental-repack.auto", - &incremental_repack_auto_limit); + repo_config_get_int(the_repository, "maintenance.incremental-repack.auto", + &incremental_repack_auto_limit); if (!incremental_repack_auto_limit) return 0; diff --git a/config.h b/config.h index 89739bee9b048f..2490c47daaff8e 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_int(const char *key, int *dest) -{ - return repo_config_get_int(the_repository, key, dest); -} - static inline int git_config_get_ulong(const char *key, unsigned long *dest) { return repo_config_get_ulong(the_repository, key, dest); diff --git a/fetch-pack.c b/fetch-pack.c index 04768087879ad0..1f184efb3c9c60 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1901,8 +1901,8 @@ static int fetch_pack_config_cb(const char *var, const char *value, static void fetch_pack_config(void) { - git_config_get_int("fetch.unpacklimit", &fetch_unpack_limit); - git_config_get_int("transfer.unpacklimit", &transfer_unpack_limit); + repo_config_get_int(the_repository, "fetch.unpacklimit", &fetch_unpack_limit); + repo_config_get_int(the_repository, "transfer.unpacklimit", &transfer_unpack_limit); git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta); git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects); git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects); diff --git a/fsmonitor.c b/fsmonitor.c index 98b2b476f08684..d07dc18967ae33 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -43,7 +43,7 @@ static int fsmonitor_hook_version(void) { int hook_version; - if (git_config_get_int("core.fsmonitorhookversion", &hook_version)) + if (repo_config_get_int(the_repository, "core.fsmonitorhookversion", &hook_version)) return -1; if (hook_version == HOOK_INTERFACE_VERSION1 || diff --git a/merge-ort.c b/merge-ort.c index 29789579c9b122..45fd41f8dfdd2d 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -5353,9 +5353,9 @@ static void merge_recursive_config(struct merge_options *opt, int ui) { char *value = NULL; int renormalize = 0; - git_config_get_int("merge.verbosity", &opt->verbosity); - git_config_get_int("diff.renamelimit", &opt->rename_limit); - git_config_get_int("merge.renamelimit", &opt->rename_limit); + repo_config_get_int(the_repository, "merge.verbosity", &opt->verbosity); + repo_config_get_int(the_repository, "diff.renamelimit", &opt->rename_limit); + repo_config_get_int(the_repository, "merge.renamelimit", &opt->rename_limit); git_config_get_bool("merge.renormalize", &renormalize); opt->renormalize = renormalize; if (!repo_config_get_string(the_repository, "diff.renames", &value)) { diff --git a/parallel-checkout.c b/parallel-checkout.c index 57c2dcaa8f60a1..fba6aa65a6e852 100644 --- a/parallel-checkout.c +++ b/parallel-checkout.c @@ -57,12 +57,12 @@ void get_parallel_checkout_configs(int *num_workers, int *threshold) return; } - if (git_config_get_int("checkout.workers", num_workers)) + if (repo_config_get_int(the_repository, "checkout.workers", num_workers)) *num_workers = DEFAULT_NUM_WORKERS; else if (*num_workers < 1) *num_workers = online_cpus(); - if (git_config_get_int("checkout.thresholdForParallelism", threshold)) + if (repo_config_get_int(the_repository, "checkout.thresholdForParallelism", threshold)) *threshold = DEFAULT_THRESHOLD_FOR_PARALLELISM; } diff --git a/refs.c b/refs.c index 73913b6627be95..777cbd34ebcb39 100644 --- a/refs.c +++ b/refs.c @@ -945,7 +945,7 @@ long get_files_ref_lock_timeout_ms(void) static int timeout_ms = 100; if (!configured) { - git_config_get_int("core.filesreflocktimeout", &timeout_ms); + repo_config_get_int(the_repository, "core.filesreflocktimeout", &timeout_ms); configured = 1; } diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 7fd73a0e6da3b5..7dd26726b1e987 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1228,7 +1228,7 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) static int timeout_value = 1000; if (!timeout_configured) { - git_config_get_int("core.packedrefstimeout", &timeout_value); + repo_config_get_int(the_repository, "core.packedrefstimeout", &timeout_value); timeout_configured = 1; } diff --git a/sequencer.c b/sequencer.c index f3bada39b4075b..f8d9bb69df8263 100644 --- a/sequencer.c +++ b/sequencer.c @@ -5834,7 +5834,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, *cmd_reset = abbr ? "t" : "reset", *cmd_merge = abbr ? "m" : "merge"; - git_config_get_int("rebase.maxlabellength", &state.max_label_length); + repo_config_get_int(the_repository, "rebase.maxlabellength", &state.max_label_length); oidmap_init(&commit2todo, 0); oidmap_init(&state.commit2label, 0); diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 30e70f1a6c2310..ce1e333051676e 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -155,7 +155,7 @@ int cmd__config(int argc, const char **argv) BUG("Key \"%s\" has unknown return %d", argv[2], ret); goto exit1; } else if (argc == 3 && !strcmp(argv[1], "get_int")) { - if (!git_config_get_int(argv[2], &val)) { + if (!repo_config_get_int(the_repository, argv[2], &val)) { printf("%d\n", val); goto exit0; } else { From d57f078e37c94616654137411e80d6fb9dfa8bbe Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:31 +0200 Subject: [PATCH 11/47] config: drop `git_config_get_ulong()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_ulong()`. All callsites are adjusted so that they use `repo_config_get_ulong(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/fast-import.c | 4 ++-- builtin/gc.c | 10 +++++----- config.h | 5 ----- http-backend.c | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 9b0ae437148678..a3f7f14f4fe5bb 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -3523,7 +3523,7 @@ static void git_pack_config(void) int limit; unsigned long packsizelimit_value; - if (!git_config_get_ulong("pack.depth", &max_depth)) { + if (!repo_config_get_ulong(the_repository, "pack.depth", &max_depth)) { if (max_depth > MAX_DEPTH) max_depth = MAX_DEPTH; } @@ -3533,7 +3533,7 @@ static void git_pack_config(void) git_die_config(the_repository, "pack.indexversion", "bad pack.indexVersion=%"PRIu32, pack_idx_opts.version); } - if (!git_config_get_ulong("pack.packsizelimit", &packsizelimit_value)) + if (!repo_config_get_ulong(the_repository, "pack.packsizelimit", &packsizelimit_value)) max_packsize = packsizelimit_value; if (!repo_config_get_int(the_repository, "fastimport.unpacklimit", &limit)) diff --git a/builtin/gc.c b/builtin/gc.c index cf175b8f1b7610..d15daf59625597 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -195,7 +195,7 @@ static void gc_config(struct gc_config *cfg) repo_config_get_int(the_repository, "gc.autopacklimit", &cfg->gc_auto_pack_limit); git_config_get_bool("gc.autodetach", &cfg->detach_auto); git_config_get_bool("gc.cruftpacks", &cfg->cruft_packs); - git_config_get_ulong("gc.maxcruftsize", &cfg->max_cruft_size); + repo_config_get_ulong(the_repository, "gc.maxcruftsize", &cfg->max_cruft_size); if (!repo_config_get_expiry(the_repository, "gc.pruneexpire", &owned)) { free(cfg->prune_expire); @@ -212,10 +212,10 @@ static void gc_config(struct gc_config *cfg) cfg->gc_log_expire = owned; } - git_config_get_ulong("gc.bigpackthreshold", &cfg->big_pack_threshold); - git_config_get_ulong("pack.deltacachesize", &cfg->max_delta_cache_size); + repo_config_get_ulong(the_repository, "gc.bigpackthreshold", &cfg->big_pack_threshold); + repo_config_get_ulong(the_repository, "pack.deltacachesize", &cfg->max_delta_cache_size); - if (!git_config_get_ulong("core.deltabasecachelimit", &ulongval)) + if (!repo_config_get_ulong(the_repository, "core.deltabasecachelimit", &ulongval)) cfg->delta_base_cache_limit = ulongval; if (!repo_config_get_string(the_repository, "gc.repackfilter", &owned)) { @@ -2344,7 +2344,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit die(_("failed to create directories for '%s'"), filename); if ((long)lock_file_timeout_ms < 0 && - git_config_get_ulong("gc.launchctlplistlocktimeoutms", + repo_config_get_ulong(the_repository, "gc.launchctlplistlocktimeoutms", &lock_file_timeout_ms)) lock_file_timeout_ms = 150; diff --git a/config.h b/config.h index 2490c47daaff8e..e22c07a4488bfa 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_ulong(const char *key, unsigned long *dest) -{ - return repo_config_get_ulong(the_repository, key, dest); -} - static inline int git_config_get_bool(const char *key, int *dest) { return repo_config_get_bool(the_repository, key, dest); diff --git a/http-backend.c b/http-backend.c index ad8c4037493057..3d5d5a84646ebc 100644 --- a/http-backend.c +++ b/http-backend.c @@ -247,7 +247,7 @@ static void http_config(void) struct strbuf var = STRBUF_INIT; git_config_get_bool("http.getanyfile", &getanyfile); - git_config_get_ulong("http.maxrequestbuffer", &max_request_buffer); + repo_config_get_ulong(the_repository, "http.maxrequestbuffer", &max_request_buffer); for (i = 0; i < ARRAY_SIZE(rpc_service); i++) { struct rpc_service *svc = &rpc_service[i]; From 5d215a7b3eb0a9a69c0cb9aa43dcae956a0aa03e Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:32 +0200 Subject: [PATCH 12/47] config: drop `git_config_get_bool()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_bool()`. All callsites are adjusted so that they use `repo_config_get_bool(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- archive.c | 2 +- builtin/am.c | 8 ++++---- builtin/checkout.c | 2 +- builtin/clone.c | 2 +- builtin/credential-cache--daemon.c | 2 +- builtin/gc.c | 6 +++--- builtin/grep.c | 2 +- builtin/rebase.c | 2 +- compat/precompose_utf8.c | 2 +- config.h | 5 ----- daemon.c | 2 +- fetch-pack.c | 8 ++++---- http-backend.c | 4 ++-- merge-ort.c | 2 +- promisor-remote.c | 4 ++-- read-cache.c | 4 ++-- rerere.c | 4 ++-- run-command.c | 6 +++--- setup.c | 2 +- t/helper/test-config.c | 2 +- transport.c | 2 +- 21 files changed, 34 insertions(+), 39 deletions(-) diff --git a/archive.c b/archive.c index 2dd306a07a7290..310672b479a19f 100644 --- a/archive.c +++ b/archive.c @@ -760,7 +760,7 @@ int write_archive(int argc, const char **argv, const char *prefix, const char **argv_copy; int rc; - git_config_get_bool("uploadarchive.allowunreachable", &remote_allow_unreachable); + repo_config_get_bool(the_repository, "uploadarchive.allowunreachable", &remote_allow_unreachable); repo_config(the_repository, git_default_config, NULL); describe_status.max_invocations = 1; diff --git a/builtin/am.c b/builtin/am.c index a7e7cf1465aa19..6073d64ae9798e 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -162,18 +162,18 @@ static void am_state_init(struct am_state *state) state->prec = 4; - git_config_get_bool("am.threeway", &state->threeway); + repo_config_get_bool(the_repository, "am.threeway", &state->threeway); state->utf8 = 1; - git_config_get_bool("am.messageid", &state->message_id); + repo_config_get_bool(the_repository, "am.messageid", &state->message_id); state->scissors = SCISSORS_UNSET; state->quoted_cr = quoted_cr_unset; strvec_init(&state->git_apply_opts); - if (!git_config_get_bool("commit.gpgsign", &gpgsign)) + if (!repo_config_get_bool(the_repository, "commit.gpgsign", &gpgsign)) state->sign_commit = gpgsign ? "" : NULL; } @@ -965,7 +965,7 @@ static int split_mail(struct am_state *state, enum patch_format patch_format, { if (keep_cr < 0) { keep_cr = 0; - git_config_get_bool("am.keepcr", &keep_cr); + repo_config_get_bool(the_repository, "am.keepcr", &keep_cr); } switch (patch_format) { diff --git a/builtin/checkout.c b/builtin/checkout.c index 948ff7bdda7c17..37efde59898093 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -291,7 +291,7 @@ static int checkout_merged(int pos, const struct checkout *state, read_mmblob(&ours, &threeway[1]); read_mmblob(&theirs, &threeway[2]); - git_config_get_bool("merge.renormalize", &renormalize); + repo_config_get_bool(the_repository, "merge.renormalize", &renormalize); ll_opts.renormalize = renormalize; ll_opts.conflict_style = conflict_style; merge_status = ll_merge(&result_buf, path, &ancestor, "base", diff --git a/builtin/clone.c b/builtin/clone.c index 3c6d8529b6c3a3..34eea11db4d9ca 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1150,7 +1150,7 @@ int cmd_clone(int argc, strbuf_reset(&sb); } - if (!git_config_get_bool("submodule.stickyRecursiveClone", &val) && + if (!repo_config_get_bool(the_repository, "submodule.stickyRecursiveClone", &val) && val) string_list_append(&option_config, "submodule.recurse=true"); diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 5065ff4660bec9..65cc619bec2869 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -307,7 +307,7 @@ int cmd_credential_cache_daemon(int argc, OPT_END() }; - git_config_get_bool("credentialcache.ignoresighup", &ignore_sighup); + repo_config_get_bool(the_repository, "credentialcache.ignoresighup", &ignore_sighup); argc = parse_options(argc, argv, prefix, options, usage, 0); socket_path = argv[0]; diff --git a/builtin/gc.c b/builtin/gc.c index d15daf59625597..fa62e4f262720c 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -193,8 +193,8 @@ static void gc_config(struct gc_config *cfg) repo_config_get_int(the_repository, "gc.aggressivedepth", &cfg->aggressive_depth); repo_config_get_int(the_repository, "gc.auto", &cfg->gc_auto_threshold); repo_config_get_int(the_repository, "gc.autopacklimit", &cfg->gc_auto_pack_limit); - git_config_get_bool("gc.autodetach", &cfg->detach_auto); - git_config_get_bool("gc.cruftpacks", &cfg->cruft_packs); + repo_config_get_bool(the_repository, "gc.autodetach", &cfg->detach_auto); + repo_config_get_bool(the_repository, "gc.cruftpacks", &cfg->cruft_packs); repo_config_get_ulong(the_repository, "gc.maxcruftsize", &cfg->max_cruft_size); if (!repo_config_get_expiry(the_repository, "gc.pruneexpire", &owned)) { @@ -1779,7 +1779,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts, strbuf_reset(&config_name); strbuf_addf(&config_name, "maintenance.%s.enabled", tasks[i].name); - if (!git_config_get_bool(config_name.buf, &config_value)) + if (!repo_config_get_bool(the_repository, config_name.buf, &config_value)) strategy.tasks[i].enabled = config_value; if (!strategy.tasks[i].enabled) continue; diff --git a/builtin/grep.c b/builtin/grep.c index 7982dda9a3b682..8fcb69dbf2cba5 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -1058,7 +1058,7 @@ int cmd_grep(int argc, if (use_index && !startup_info->have_repository) { int fallback = 0; - git_config_get_bool("grep.fallbacktonoindex", &fallback); + repo_config_get_bool(the_repository, "grep.fallbacktonoindex", &fallback); if (fallback) use_index = 0; else diff --git a/builtin/rebase.c b/builtin/rebase.c index 0c3daa4b8140d8..72a52bdfb9872e 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -340,7 +340,7 @@ static int run_sequencer_rebase(struct rebase_options *opts) unsigned flags = 0; int abbreviate_commands = 0, ret = 0; - git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands); + repo_config_get_bool(the_repository, "rebase.abbreviatecommands", &abbreviate_commands); flags |= opts->keep_empty ? TODO_LIST_KEEP_EMPTY : 0; flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0; diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 12e38e0ea3c570..3985ed108eb458 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -75,7 +75,7 @@ const char *precompose_string_if_needed(const char *in) iconv_t ic_prec; char *out; if (precomposed_unicode < 0) - git_config_get_bool("core.precomposeunicode", &precomposed_unicode); + repo_config_get_bool(the_repository, "core.precomposeunicode", &precomposed_unicode); if (precomposed_unicode != 1) return in; ic_prec = iconv_open(repo_encoding, path_encoding); diff --git a/config.h b/config.h index e22c07a4488bfa..c9f582c7c55d7c 100644 --- a/config.h +++ b/config.h @@ -719,11 +719,6 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l int lookup_config(const char **mapping, int nr_mapping, const char *var); # ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_bool(const char *key, int *dest) -{ - return repo_config_get_bool(the_repository, key, dest); -} - static inline int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest) { return repo_config_get_bool_or_int(the_repository, key, is_bool, dest); diff --git a/daemon.c b/daemon.c index 61cd50f7200f99..cb209235557355 100644 --- a/daemon.c +++ b/daemon.c @@ -402,7 +402,7 @@ static int run_service(const char *dir, struct daemon_service *service, if (service->overridable) { strbuf_addf(&var, "daemon.%s", service->config_name); - git_config_get_bool(var.buf, &enabled); + repo_config_get_bool(the_repository, var.buf, &enabled); strbuf_release(&var); } if (!enabled) { diff --git a/fetch-pack.c b/fetch-pack.c index 1f184efb3c9c60..94b1436c5c267a 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1903,10 +1903,10 @@ static void fetch_pack_config(void) { repo_config_get_int(the_repository, "fetch.unpacklimit", &fetch_unpack_limit); repo_config_get_int(the_repository, "transfer.unpacklimit", &transfer_unpack_limit); - git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta); - git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects); - git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects); - git_config_get_bool("transfer.advertisesid", &advertise_sid); + repo_config_get_bool(the_repository, "repack.usedeltabaseoffset", &prefer_ofs_delta); + repo_config_get_bool(the_repository, "fetch.fsckobjects", &fetch_fsck_objects); + repo_config_get_bool(the_repository, "transfer.fsckobjects", &transfer_fsck_objects); + repo_config_get_bool(the_repository, "transfer.advertisesid", &advertise_sid); if (!uri_protocols.nr) { char *str; diff --git a/http-backend.c b/http-backend.c index 3d5d5a84646ebc..d5dfe762bb5178 100644 --- a/http-backend.c +++ b/http-backend.c @@ -246,13 +246,13 @@ static void http_config(void) int i, value = 0; struct strbuf var = STRBUF_INIT; - git_config_get_bool("http.getanyfile", &getanyfile); + repo_config_get_bool(the_repository, "http.getanyfile", &getanyfile); repo_config_get_ulong(the_repository, "http.maxrequestbuffer", &max_request_buffer); for (i = 0; i < ARRAY_SIZE(rpc_service); i++) { struct rpc_service *svc = &rpc_service[i]; strbuf_addf(&var, "http.%s", svc->config_name); - if (!git_config_get_bool(var.buf, &value)) + if (!repo_config_get_bool(the_repository, var.buf, &value)) svc->enabled = value; strbuf_reset(&var); } diff --git a/merge-ort.c b/merge-ort.c index 45fd41f8dfdd2d..86896ff11b014d 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -5356,7 +5356,7 @@ static void merge_recursive_config(struct merge_options *opt, int ui) repo_config_get_int(the_repository, "merge.verbosity", &opt->verbosity); repo_config_get_int(the_repository, "diff.renamelimit", &opt->rename_limit); repo_config_get_int(the_repository, "merge.renamelimit", &opt->rename_limit); - git_config_get_bool("merge.renormalize", &renormalize); + repo_config_get_bool(the_repository, "merge.renormalize", &renormalize); opt->renormalize = renormalize; if (!repo_config_get_string(the_repository, "diff.renames", &value)) { opt->detect_renames = git_config_rename("diff.renames", value); diff --git a/promisor-remote.c b/promisor-remote.c index a9c877d9cfa30f..08b0da896227c8 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -46,7 +46,7 @@ static int fetch_objects(struct repository *repo, "fetch", remote_name, "--no-tags", "--no-write-fetch-head", "--recurse-submodules=no", "--filter=blob:none", "--stdin", NULL); - if (!git_config_get_bool("promisor.quiet", &quiet) && quiet) + if (!repo_config_get_bool(the_repository, "promisor.quiet", &quiet) && quiet) strvec_push(&child.args, "--quiet"); if (start_command(&child)) die(_("promisor-remote: unable to fork off fetch subprocess")); @@ -343,7 +343,7 @@ char *promisor_remote_info(struct repository *repo) struct strvec names = STRVEC_INIT; struct strvec urls = STRVEC_INIT; - git_config_get_bool("promisor.advertise", &advertise_promisors); + repo_config_get_bool(the_repository, "promisor.advertise", &advertise_promisors); if (!advertise_promisors) return NULL; diff --git a/read-cache.c b/read-cache.c index 5cf41b81f1fd8b..4fdde758d1bf6a 100644 --- a/read-cache.c +++ b/read-cache.c @@ -2755,7 +2755,7 @@ static int record_eoie(void) { int val; - if (!git_config_get_bool("index.recordendofindexentries", &val)) + if (!repo_config_get_bool(the_repository, "index.recordendofindexentries", &val)) return val; /* @@ -2770,7 +2770,7 @@ static int record_ieot(void) { int val; - if (!git_config_get_bool("index.recordoffsettable", &val)) + if (!repo_config_get_bool(the_repository, "index.recordoffsettable", &val)) return val; /* diff --git a/rerere.c b/rerere.c index 1ac2075144c97c..c7c3e535ce5045 100644 --- a/rerere.c +++ b/rerere.c @@ -877,8 +877,8 @@ static int do_plain_rerere(struct repository *r, static void git_rerere_config(void) { - git_config_get_bool("rerere.enabled", &rerere_enabled); - git_config_get_bool("rerere.autoupdate", &rerere_autoupdate); + repo_config_get_bool(the_repository, "rerere.enabled", &rerere_enabled); + repo_config_get_bool(the_repository, "rerere.autoupdate", &rerere_autoupdate); repo_config(the_repository, git_default_config, NULL); } diff --git a/run-command.c b/run-command.c index 8833b2336785d9..ed9575bd6a8cbb 100644 --- a/run-command.c +++ b/run-command.c @@ -1817,7 +1817,7 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) { int enabled, auto_detach; - if (!git_config_get_bool("maintenance.auto", &enabled) && + if (!repo_config_get_bool(the_repository, "maintenance.auto", &enabled) && !enabled) return 0; @@ -1826,8 +1826,8 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) * honoring `gc.autoDetach`. This is somewhat weird, but required to * retain behaviour from when we used to run git-gc(1) here. */ - if (git_config_get_bool("maintenance.autodetach", &auto_detach) && - git_config_get_bool("gc.autodetach", &auto_detach)) + if (repo_config_get_bool(the_repository, "maintenance.autodetach", &auto_detach) && + repo_config_get_bool(the_repository, "gc.autodetach", &auto_detach)) auto_detach = 1; maint->git_cmd = 1; diff --git a/setup.c b/setup.c index 9661c5d5d5d7aa..a06bb921b3a99c 100644 --- a/setup.c +++ b/setup.c @@ -1877,7 +1877,7 @@ const char *setup_git_directory_gently(int *nongit_ok) * the core.precomposeunicode configuration, this * has to happen after the above block that finds * out where the repository is, i.e. a preparation - * for calling git_config_get_bool(). + * for calling repo_config_get_bool(). */ if (prefix) { prefix = precompose_string_if_needed(prefix); diff --git a/t/helper/test-config.c b/t/helper/test-config.c index ce1e333051676e..9f8cca7c48cfe3 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -163,7 +163,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_bool")) { - if (!git_config_get_bool(argv[2], &val)) { + if (!repo_config_get_bool(the_repository, argv[2], &val)) { printf("%d\n", val); goto exit0; } else { diff --git a/transport.c b/transport.c index 89e6297ce222bb..e305d6bd228b45 100644 --- a/transport.c +++ b/transport.c @@ -1602,7 +1602,7 @@ int transport_get_remote_bundle_uri(struct transport *transport) * Don't request bundle-uri from the server unless configured to * do so by the transfer.bundleURI=true config option. */ - if (git_config_get_bool("transfer.bundleuri", &value) || !value) + if (repo_config_get_bool(the_repository, "transfer.bundleuri", &value) || !value) return 0; if (!transport->bundles->baseURI) From 122e38c92f19054b0da2212ed3dcbc35c221a375 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:33 +0200 Subject: [PATCH 13/47] config: drop `git_config_set_in_file()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_set_in_file()`. All callsites are adjusted so that they use `repo_config_set_in_file(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/submodule--helper.c | 10 +++++----- config.h | 6 ------ dir.c | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index d2ab31835b51ed..0be737ac4ffa47 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1810,12 +1810,12 @@ static int clone_submodule(const struct module_clone_data *clone_data, /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */ repo_config_get_string(the_repository, "submodule.alternateLocation", &sm_alternate); if (sm_alternate) - git_config_set_in_file(p, "submodule.alternateLocation", - sm_alternate); + repo_config_set_in_file(the_repository, p, "submodule.alternateLocation", + sm_alternate); repo_config_get_string(the_repository, "submodule.alternateErrorStrategy", &error_strategy); if (error_strategy) - git_config_set_in_file(p, "submodule.alternateErrorStrategy", - error_strategy); + repo_config_set_in_file(the_repository, p, "submodule.alternateErrorStrategy", + error_strategy); free(sm_alternate); free(error_strategy); @@ -2522,7 +2522,7 @@ static int ensure_core_worktree(const char *path) abs_path = absolute_pathdup(path); rel_path = relative_path(abs_path, subrepo.gitdir, &sb); - git_config_set_in_file(cfg_file, "core.worktree", rel_path); + repo_config_set_in_file(the_repository, cfg_file, "core.worktree", rel_path); free(cfg_file); free(abs_path); diff --git a/config.h b/config.h index c9f582c7c55d7c..b4f79d4d4cc5cf 100644 --- a/config.h +++ b/config.h @@ -734,12 +734,6 @@ static inline int git_config_get_pathname(const char *key, char **dest) return repo_config_get_pathname(the_repository, key, dest); } -static inline void git_config_set_in_file(const char *config_filename, - const char *key, const char *value) -{ - repo_config_set_in_file(the_repository, config_filename, key, value); -} - static inline int git_config_set_gently(const char *key, const char *value) { return repo_config_set_gently(the_repository, key, value); diff --git a/dir.c b/dir.c index 02873f59ea6e8c..dfb4d40103fb4a 100644 --- a/dir.c +++ b/dir.c @@ -4091,8 +4091,8 @@ void connect_work_tree_and_git_dir(const char *work_tree_, write_file(gitfile_sb.buf, "gitdir: %s", relative_path(git_dir, work_tree, &rel_path)); /* Update core.worktree setting */ - git_config_set_in_file(cfg_sb.buf, "core.worktree", - relative_path(work_tree, git_dir, &rel_path)); + repo_config_set_in_file(the_repository, cfg_sb.buf, "core.worktree", + relative_path(work_tree, git_dir, &rel_path)); strbuf_release(&gitfile_sb); strbuf_release(&cfg_sb); From b1659e63e2c647455e877cee0aff64e089d9e2ae Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:34 +0200 Subject: [PATCH 14/47] config: drop `git_config_set_gently()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_set_gently()`. All callsites are adjusted so that they use `repo_config_set_gently(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- branch.c | 6 +++--- builtin/clone.c | 2 +- builtin/remote.c | 8 ++++---- builtin/submodule--helper.c | 14 +++++++------- config.h | 5 ----- scalar.c | 4 ++-- setup.c | 4 ++-- worktree.c | 4 ++-- 8 files changed, 21 insertions(+), 26 deletions(-) diff --git a/branch.c b/branch.c index b4811671fc741c..3dc237adf6c8bc 100644 --- a/branch.c +++ b/branch.c @@ -116,7 +116,7 @@ static int install_branch_config_multiple_remotes(int flag, const char *local, } strbuf_addf(&key, "branch.%s.remote", local); - if (git_config_set_gently(key.buf, origin ? origin : ".") < 0) + if (repo_config_set_gently(the_repository, key.buf, origin ? origin : ".") < 0) goto out_err; strbuf_reset(&key); @@ -127,7 +127,7 @@ static int install_branch_config_multiple_remotes(int flag, const char *local, * more than one is provided, use CONFIG_REGEX_NONE to preserve what * we've written so far. */ - if (git_config_set_gently(key.buf, NULL) < 0) + if (repo_config_set_gently(the_repository, key.buf, NULL) < 0) goto out_err; for_each_string_list_item(item, remotes) if (git_config_set_multivar_gently(key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0) @@ -136,7 +136,7 @@ static int install_branch_config_multiple_remotes(int flag, const char *local, if (rebasing) { strbuf_reset(&key); strbuf_addf(&key, "branch.%s.rebase", local); - if (git_config_set_gently(key.buf, "true") < 0) + if (repo_config_set_gently(the_repository, key.buf, "true") < 0) goto out_err; } strbuf_release(&key); diff --git a/builtin/clone.c b/builtin/clone.c index 34eea11db4d9ca..0d7dd5e8ec9be3 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1467,7 +1467,7 @@ int cmd_clone(int argc, warning(_("failed to fetch objects from bundle URI '%s'"), bundle_uri); else if (has_heuristic) - git_config_set_gently("fetch.bundleuri", bundle_uri); + repo_config_set_gently(the_repository, "fetch.bundleuri", bundle_uri); remote_state_clear(the_repository->remote_state); free(the_repository->remote_state); diff --git a/builtin/remote.c b/builtin/remote.c index 826b2dcfd04a4e..5c4dfc98afa966 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -694,8 +694,8 @@ static void handle_push_default(const char* old_name, const char* new_name) if (push_default.scope >= CONFIG_SCOPE_COMMAND) ; /* pass */ else if (push_default.scope >= CONFIG_SCOPE_LOCAL) { - int result = git_config_set_gently("remote.pushDefault", - new_name); + int result = repo_config_set_gently(the_repository, "remote.pushDefault", + new_name); if (new_name && result && result != CONFIG_NOTHING_SET) die(_("could not set '%s'"), "remote.pushDefault"); else if (!new_name && result && result != CONFIG_NOTHING_SET) @@ -934,7 +934,7 @@ static int rm(int argc, const char **argv, const char *prefix, strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.%s", item->string, *k); - result = git_config_set_gently(buf.buf, NULL); + result = repo_config_set_gently(the_repository, buf.buf, NULL); if (result && result != CONFIG_NOTHING_SET) die(_("could not unset '%s'"), buf.buf); } @@ -942,7 +942,7 @@ static int rm(int argc, const char **argv, const char *prefix, if (info->push_remote_name && !strcmp(info->push_remote_name, remote->name)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.pushremote", item->string); - result = git_config_set_gently(buf.buf, NULL); + result = repo_config_set_gently(the_repository, buf.buf, NULL); if (result && result != CONFIG_NOTHING_SET) die(_("could not unset '%s'"), buf.buf); } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0be737ac4ffa47..710a2a2004ebc3 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -458,7 +458,7 @@ static void init_submodule(const char *path, const char *prefix, */ if (!is_submodule_active(the_repository, path)) { strbuf_addf(&sb, "submodule.%s.active", sub->name); - git_config_set_gently(sb.buf, "true"); + repo_config_set_gently(the_repository, sb.buf, "true"); strbuf_reset(&sb); } @@ -484,7 +484,7 @@ static void init_submodule(const char *path, const char *prefix, free(oldurl); } - if (git_config_set_gently(sb.buf, url)) + if (repo_config_set_gently(the_repository, sb.buf, url)) die(_("Failed to register url for submodule path '%s'"), displaypath); if (!(flags & OPT_QUIET)) @@ -506,7 +506,7 @@ static void init_submodule(const char *path, const char *prefix, upd = submodule_update_type_to_string(sub->update_strategy.type); } - if (git_config_set_gently(sb.buf, upd)) + if (repo_config_set_gently(the_repository, sb.buf, upd)) die(_("Failed to register update mode for submodule path '%s'"), displaypath); } strbuf_release(&sb); @@ -1262,7 +1262,7 @@ static void sync_submodule(const char *path, const char *prefix, strbuf_reset(&sb); strbuf_addf(&sb, "submodule.%s.url", sub->name); - if (git_config_set_gently(sb.buf, super_config_url)) + if (repo_config_set_gently(the_repository, sb.buf, super_config_url)) die(_("failed to register url for submodule path '%s'"), displaypath); @@ -3309,7 +3309,7 @@ static void configure_added_submodule(struct add_data *add_data) struct child_process add_gitmodules = CHILD_PROCESS_INIT; key = xstrfmt("submodule.%s.url", add_data->sm_name); - git_config_set_gently(key, add_data->realrepo); + repo_config_set_gently(the_repository, key, add_data->realrepo); free(key); add_submod.git_cmd = 1; @@ -3356,12 +3356,12 @@ static void configure_added_submodule(struct add_data *add_data) */ if (!is_submodule_active(the_repository, add_data->sm_path)) { key = xstrfmt("submodule.%s.active", add_data->sm_name); - git_config_set_gently(key, "true"); + repo_config_set_gently(the_repository, key, "true"); free(key); } } else { key = xstrfmt("submodule.%s.active", add_data->sm_name); - git_config_set_gently(key, "true"); + repo_config_set_gently(the_repository, key, "true"); free(key); } } diff --git a/config.h b/config.h index b4f79d4d4cc5cf..90977441c3bbd5 100644 --- a/config.h +++ b/config.h @@ -734,11 +734,6 @@ static inline int git_config_get_pathname(const char *key, char **dest) return repo_config_get_pathname(the_repository, key, dest); } -static inline int git_config_set_gently(const char *key, const char *value) -{ - return repo_config_set_gently(the_repository, key, value); -} - static inline void git_config_set(const char *key, const char *value) { repo_config_set(the_repository, key, value); diff --git a/scalar.c b/scalar.c index 07f855c9913985..c09c5ca194eab1 100644 --- a/scalar.c +++ b/scalar.c @@ -103,7 +103,7 @@ static int set_scalar_config(const struct scalar_config *config, int reconfigure if ((reconfigure && config->overwrite_on_reconfigure) || repo_config_get_string(the_repository, config->key, &value)) { trace2_data_string("scalar", the_repository, config->key, "created"); - res = git_config_set_gently(config->key, config->value); + res = repo_config_set_gently(the_repository, config->key, config->value); } else { trace2_data_string("scalar", the_repository, config->key, "exists"); res = 0; @@ -322,7 +322,7 @@ static int set_config(const char *fmt, ...) value = strchr(buf.buf, '='); if (value) *(value++) = '\0'; - res = git_config_set_gently(buf.buf, value); + res = repo_config_set_gently(the_repository, buf.buf, value); strbuf_release(&buf); return res; diff --git a/setup.c b/setup.c index a06bb921b3a99c..a05c348dcdf8fe 100644 --- a/setup.c +++ b/setup.c @@ -2236,13 +2236,13 @@ void initialize_repository_version(int hash_algo, git_config_set("extensions.objectformat", hash_algos[hash_algo].name); else if (reinit) - git_config_set_gently("extensions.objectformat", NULL); + repo_config_set_gently(the_repository, "extensions.objectformat", NULL); if (ref_storage_format != REF_STORAGE_FORMAT_FILES) git_config_set("extensions.refstorage", ref_storage_format_to_name(ref_storage_format)); else if (reinit) - git_config_set_gently("extensions.refstorage", NULL); + repo_config_set_gently(the_repository, "extensions.refstorage", NULL); if (reinit) { struct strbuf config = STRBUF_INIT; diff --git a/worktree.c b/worktree.c index c34b9eb74e595a..981a2713374ff8 100644 --- a/worktree.c +++ b/worktree.c @@ -1013,7 +1013,7 @@ int init_worktree_config(struct repository *r) */ if (r->repository_format_worktree_config) return 0; - if ((res = git_config_set_gently("extensions.worktreeConfig", "true"))) + if ((res = repo_config_set_gently(the_repository, "extensions.worktreeConfig", "true"))) return error(_("failed to set extensions.worktreeConfig setting")); common_config_file = xstrfmt("%s/config", r->commondir); @@ -1077,7 +1077,7 @@ void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir, if (use_relative_paths && !the_repository->repository_format_relative_worktrees) { if (upgrade_repository_format(1) < 0) die(_("unable to upgrade repository format to support relative worktrees")); - if (git_config_set_gently("extensions.relativeWorktrees", "true")) + if (repo_config_set_gently(the_repository, "extensions.relativeWorktrees", "true")) die(_("unable to set extensions.relativeWorktrees setting")); the_repository->repository_format_relative_worktrees = 1; } From e957ed2b275b3fd44475bacaf3955cf451a976c4 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:35 +0200 Subject: [PATCH 15/47] config: drop `git_config_set()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_set()`. All callsites are adjusted so that they use `repo_config_set(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- builtin/clone.c | 8 ++++---- builtin/gc.c | 4 ++-- builtin/remote.c | 16 ++++++++-------- compat/precompose_utf8.c | 4 ++-- config.c | 2 +- config.h | 5 ----- list-objects-filter-options.c | 6 +++--- setup.c | 30 +++++++++++++++--------------- 9 files changed, 36 insertions(+), 41 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 08e50bf77b3f54..5de0691d18d4ac 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -699,7 +699,7 @@ static int edit_branch_description(const char *branch_name) strbuf_addf(&name, "branch.%s.description", branch_name); if (buf.len || exists) - git_config_set(name.buf, buf.len ? buf.buf : NULL); + repo_config_set(the_repository, name.buf, buf.len ? buf.buf : NULL); strbuf_release(&name); strbuf_release(&buf); diff --git a/builtin/clone.c b/builtin/clone.c index 0d7dd5e8ec9be3..f025a8f19e08d2 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -827,7 +827,7 @@ static void write_refspec_config(const char *src_ref_prefix, if (option_mirror) { strbuf_addf(&key, "remote.%s.mirror", remote_name); - git_config_set(key.buf, "true"); + repo_config_set(the_repository, key.buf, "true"); strbuf_reset(&key); } } @@ -1294,18 +1294,18 @@ int cmd_clone(int argc, src_ref_prefix = "refs/"; strbuf_addstr(&branch_top, src_ref_prefix); - git_config_set("core.bare", "true"); + repo_config_set(the_repository, "core.bare", "true"); } else if (!option_rev) { strbuf_addf(&branch_top, "refs/remotes/%s/", remote_name); } strbuf_addf(&key, "remote.%s.url", remote_name); - git_config_set(key.buf, repo); + repo_config_set(the_repository, key.buf, repo); strbuf_reset(&key); if (!option_tags) { strbuf_addf(&key, "remote.%s.tagOpt", remote_name); - git_config_set(key.buf, "--no-tags"); + repo_config_set(the_repository, key.buf, "--no-tags"); strbuf_reset(&key); } diff --git a/builtin/gc.c b/builtin/gc.c index fa62e4f262720c..c0fe4e73087731 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1913,11 +1913,11 @@ static int maintenance_register(int argc, const char **argv, const char *prefix, options); /* Disable foreground maintenance */ - git_config_set("maintenance.auto", "false"); + repo_config_set(the_repository, "maintenance.auto", "false"); /* Set maintenance strategy, if unset */ if (repo_config_get(the_repository, "maintenance.strategy")) - git_config_set("maintenance.strategy", "incremental"); + repo_config_set(the_repository, "maintenance.strategy", "incremental"); if (!repo_config_get_string_multi(the_repository, key, &list)) { for_each_string_list_item(item, list) { diff --git a/builtin/remote.c b/builtin/remote.c index 5c4dfc98afa966..827639e0398636 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -209,7 +209,7 @@ static int add(int argc, const char **argv, const char *prefix, die(_("'%s' is not a valid remote name"), name); strbuf_addf(&buf, "remote.%s.url", name); - git_config_set(buf.buf, url); + repo_config_set(the_repository, buf.buf, url); if (!mirror || mirror & MIRROR_FETCH) { strbuf_reset(&buf); @@ -225,14 +225,14 @@ static int add(int argc, const char **argv, const char *prefix, if (mirror & MIRROR_PUSH) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.mirror", name); - git_config_set(buf.buf, "true"); + repo_config_set(the_repository, buf.buf, "true"); } if (fetch_tags != TAGS_DEFAULT) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.tagOpt", name); - git_config_set(buf.buf, - fetch_tags == TAGS_SET ? "--tags" : "--no-tags"); + repo_config_set(the_repository, buf.buf, + fetch_tags == TAGS_SET ? "--tags" : "--no-tags"); } if (fetch && fetch_remote(name)) { @@ -802,12 +802,12 @@ static int mv(int argc, const char **argv, const char *prefix, if (info->remote_name && !strcmp(info->remote_name, rename.old_name)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.remote", item->string); - git_config_set(buf.buf, rename.new_name); + repo_config_set(the_repository, buf.buf, rename.new_name); } if (info->push_remote_name && !strcmp(info->push_remote_name, rename.old_name)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.pushRemote", item->string); - git_config_set(buf.buf, rename.new_name); + repo_config_set(the_repository, buf.buf, rename.new_name); } } @@ -1503,7 +1503,7 @@ static int set_head(int argc, const char **argv, const char *prefix, struct strbuf config_name = STRBUF_INIT; strbuf_addf(&config_name, "remote.%s.followremotehead", remote->name); - git_config_set(config_name.buf, "warn"); + repo_config_set(the_repository, config_name.buf, "warn"); strbuf_release(&config_name); } @@ -1793,7 +1793,7 @@ static int set_url(int argc, const char **argv, const char *prefix, git_config_set_multivar(name_buf.buf, newurl, "^$", 0); else - git_config_set(name_buf.buf, newurl); + repo_config_set(the_repository, name_buf.buf, newurl); goto out; } diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 3985ed108eb458..43b3be011439ef 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -56,8 +56,8 @@ void probe_utf8_pathname_composition(void) close(output_fd); repo_git_path_replace(the_repository, &path, "%s", auml_nfd); precomposed_unicode = access(path.buf, R_OK) ? 0 : 1; - git_config_set("core.precomposeunicode", - precomposed_unicode ? "true" : "false"); + repo_config_set(the_repository, "core.precomposeunicode", + precomposed_unicode ? "true" : "false"); repo_git_path_replace(the_repository, &path, "%s", auml_nfc); if (unlink(path.buf)) die_errno(_("failed to unlink '%s'"), path.buf); diff --git a/config.c b/config.c index 095a17bd4299eb..285cab0ce2a6a2 100644 --- a/config.c +++ b/config.c @@ -2748,7 +2748,7 @@ void git_die_config(struct repository *r, const char *key, const char *err, ...) } /* - * Find all the stuff for git_config_set() below. + * Find all the stuff for repo_config_set() below. */ struct config_store_data { diff --git a/config.h b/config.h index 90977441c3bbd5..43d06c279e3ebb 100644 --- a/config.h +++ b/config.h @@ -734,11 +734,6 @@ static inline int git_config_get_pathname(const char *key, char **dest) return repo_config_get_pathname(the_repository, key, dest); } -static inline void git_config_set(const char *key, const char *value) -{ - repo_config_set(the_repository, key, value); -} - static inline int git_config_set_in_file_gently( const char *config_filename, const char *key, diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 948376d42d06af..7420bf81fe0103 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -350,7 +350,7 @@ void partial_clone_register( /* Add promisor config for the remote */ cfg_name = xstrfmt("remote.%s.promisor", remote); - git_config_set(cfg_name, "true"); + repo_config_set(the_repository, cfg_name, "true"); free(cfg_name); } @@ -360,8 +360,8 @@ void partial_clone_register( */ filter_name = xstrfmt("remote.%s.partialclonefilter", remote); /* NEEDSWORK: 'expand' result leaking??? */ - git_config_set(filter_name, - expand_list_objects_filter_spec(filter_options)); + repo_config_set(the_repository, filter_name, + expand_list_objects_filter_spec(filter_options)); free(filter_name); /* Make sure the config info are reset */ diff --git a/setup.c b/setup.c index a05c348dcdf8fe..98ddbf377f923b 100644 --- a/setup.c +++ b/setup.c @@ -815,7 +815,7 @@ int upgrade_repository_format(int target_version) } strbuf_addf(&repo_version, "%d", target_version); - git_config_set("core.repositoryformatversion", repo_version.buf); + repo_config_set(the_repository, "core.repositoryformatversion", repo_version.buf); ret = 1; @@ -2233,14 +2233,14 @@ void initialize_repository_version(int hash_algo, target_version = GIT_REPO_VERSION_READ; if (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN) - git_config_set("extensions.objectformat", - hash_algos[hash_algo].name); + repo_config_set(the_repository, "extensions.objectformat", + hash_algos[hash_algo].name); else if (reinit) repo_config_set_gently(the_repository, "extensions.objectformat", NULL); if (ref_storage_format != REF_STORAGE_FORMAT_FILES) - git_config_set("extensions.refstorage", - ref_storage_format_to_name(ref_storage_format)); + repo_config_set(the_repository, "extensions.refstorage", + ref_storage_format_to_name(ref_storage_format)); else if (reinit) repo_config_set_gently(the_repository, "extensions.refstorage", NULL); @@ -2259,7 +2259,7 @@ void initialize_repository_version(int hash_algo, } strbuf_addf(&repo_version, "%d", target_version); - git_config_set("core.repositoryformatversion", repo_version.buf); + repo_config_set(the_repository, "core.repositoryformatversion", repo_version.buf); strbuf_release(&repo_version); } @@ -2375,17 +2375,17 @@ static int create_default_files(const char *template_path, if (filemode && !reinit && (st1.st_mode & S_IXUSR)) filemode = 0; } - git_config_set("core.filemode", filemode ? "true" : "false"); + repo_config_set(the_repository, "core.filemode", filemode ? "true" : "false"); if (is_bare_repository()) - git_config_set("core.bare", "true"); + repo_config_set(the_repository, "core.bare", "true"); else { - git_config_set("core.bare", "false"); + repo_config_set(the_repository, "core.bare", "false"); /* allow template config file to override the default */ if (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET) - git_config_set("core.logallrefupdates", "true"); + repo_config_set(the_repository, "core.logallrefupdates", "true"); if (needs_work_tree_config(original_git_dir, work_tree)) - git_config_set("core.worktree", work_tree); + repo_config_set(the_repository, "core.worktree", work_tree); } if (!reinit) { @@ -2398,12 +2398,12 @@ static int create_default_files(const char *template_path, S_ISLNK(st1.st_mode)) unlink(path.buf); /* good */ else - git_config_set("core.symlinks", "false"); + repo_config_set(the_repository, "core.symlinks", "false"); /* Check if the filesystem is case-insensitive */ repo_git_path_replace(the_repository, &path, "CoNfIg"); if (!access(path.buf, F_OK)) - git_config_set("core.ignorecase", "true"); + repo_config_set(the_repository, "core.ignorecase", "true"); probe_utf8_pathname_composition(); } @@ -2639,8 +2639,8 @@ int init_db(const char *git_dir, const char *real_git_dir, xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY); else BUG("invalid value for shared_repository"); - git_config_set("core.sharedrepository", buf); - git_config_set("receive.denyNonFastforwards", "true"); + repo_config_set(the_repository, "core.sharedrepository", buf); + repo_config_set(the_repository, "receive.denyNonFastforwards", "true"); } if (!(flags & INIT_DB_QUIET)) { From 62c1ed3e9d03b7434fd86c257fa04abe47e7b626 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:36 +0200 Subject: [PATCH 16/47] config: drop `git_config_set_in_file_gently()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_set_in_file_gently()`. All callsites are adjusted so that they use `repo_config_set_in_file_gently(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/config.c | 14 +++++++------- builtin/submodule--helper.c | 2 +- builtin/worktree.c | 4 ++-- config.h | 10 ---------- sequencer.c | 28 ++++++++++++++-------------- submodule-config.c | 2 +- submodule.c | 2 +- worktree.c | 4 ++-- 8 files changed, 28 insertions(+), 38 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index af5d79eadc0804..f7e718c67025c5 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -970,8 +970,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix, argv[0], value, value_pattern, comment, flags); } else { - ret = git_config_set_in_file_gently(location_opts.source.file, - argv[0], comment, value); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, + argv[0], comment, value); if (ret == CONFIG_NOTHING_SET) error(_("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s."), argv[0]); @@ -1014,8 +1014,8 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix, argv[0], NULL, value_pattern, NULL, flags); else - ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], - NULL, NULL); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], + NULL, NULL); location_options_release(&location_opts); return ret; @@ -1296,7 +1296,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) check_write(&location_opts.source); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], comment, value); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], comment, value); if (ret == CONFIG_NOTHING_SET) error(_("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s."), argv[0]); @@ -1354,8 +1354,8 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) argv[0], NULL, argv[1], NULL, flags); else - ret = git_config_set_in_file_gently(location_opts.source.file, - argv[0], NULL, NULL); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, NULL); } else if (actions == ACTION_UNSET_ALL) { check_write(&location_opts.source); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 710a2a2004ebc3..28f34f7bc183d2 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1280,7 +1280,7 @@ static void sync_submodule(const char *path, const char *prefix, submodule_to_gitdir(the_repository, &sb, path); strbuf_addstr(&sb, "/config"); - if (git_config_set_in_file_gently(sb.buf, remote_key, NULL, sub_origin_url)) + if (repo_config_set_in_file_gently(the_repository, sb.buf, remote_key, NULL, sub_origin_url)) die(_("failed to update remote for submodule '%s'"), path); diff --git a/builtin/worktree.c b/builtin/worktree.c index b1306248dec80b..fd517c82c444a4 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -384,8 +384,8 @@ static void copy_filtered_worktree_config(const char *worktree_git_dir) error(_("failed to unset '%s' in '%s'"), "core.bare", to_file); if (!git_configset_get(&cs, "core.worktree") && - git_config_set_in_file_gently(to_file, - "core.worktree", NULL, NULL)) + repo_config_set_in_file_gently(the_repository, to_file, + "core.worktree", NULL, NULL)) error(_("failed to unset '%s' in '%s'"), "core.worktree", to_file); diff --git a/config.h b/config.h index 43d06c279e3ebb..4e658e47f0a25a 100644 --- a/config.h +++ b/config.h @@ -734,16 +734,6 @@ static inline int git_config_get_pathname(const char *key, char **dest) return repo_config_get_pathname(the_repository, key, dest); } -static inline int git_config_set_in_file_gently( - const char *config_filename, - const char *key, - const char *comment, - const char *value) -{ - return repo_config_set_in_file_gently(the_repository, config_filename, - key, comment, value); -} - static inline int git_config_set_multivar_in_file_gently( const char *config_filename, const char *key, const char *value, diff --git a/sequencer.c b/sequencer.c index f8d9bb69df8263..8acb699f4f2f60 100644 --- a/sequencer.c +++ b/sequencer.c @@ -3650,57 +3650,57 @@ static int save_opts(struct replay_opts *opts) int res = 0; if (opts->no_commit) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.no-commit", NULL, "true"); if (opts->edit >= 0) - res |= git_config_set_in_file_gently(opts_file, "options.edit", NULL, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.edit", NULL, opts->edit ? "true" : "false"); if (opts->allow_empty) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-empty", NULL, "true"); if (opts->allow_empty_message) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-empty-message", NULL, "true"); if (opts->drop_redundant_commits) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.drop-redundant-commits", NULL, "true"); if (opts->keep_redundant_commits) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.keep-redundant-commits", NULL, "true"); if (opts->signoff) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.signoff", NULL, "true"); if (opts->record_origin) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.record-origin", NULL, "true"); if (opts->allow_ff) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-ff", NULL, "true"); if (opts->mainline) { struct strbuf buf = STRBUF_INIT; strbuf_addf(&buf, "%d", opts->mainline); - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.mainline", NULL, buf.buf); strbuf_release(&buf); } if (opts->strategy) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.strategy", NULL, opts->strategy); if (opts->gpg_sign) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.gpg-sign", NULL, opts->gpg_sign); for (size_t i = 0; i < opts->xopts.nr; i++) res |= git_config_set_multivar_in_file_gently(opts_file, "options.strategy-option", opts->xopts.v[i], "^$", NULL, 0); if (opts->allow_rerere_auto) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-rerere-auto", NULL, opts->allow_rerere_auto == RERERE_AUTOUPDATE ? "true" : "false"); if (opts->explicit_cleanup) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.default-msg-cleanup", NULL, describe_cleanup_mode(opts->default_msg_cleanup)); return res; diff --git a/submodule-config.c b/submodule-config.c index 70324da38300f4..1f19fe207741bc 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -983,7 +983,7 @@ int config_set_in_gitmodules_file_gently(const char *key, const char *value) { int ret; - ret = git_config_set_in_file_gently(GITMODULES_FILE, key, NULL, value); + ret = repo_config_set_in_file_gently(the_repository, GITMODULES_FILE, key, NULL, value); if (ret < 0) /* Maybe the user already did that, don't error out here */ warning(_("Could not update .gitmodules entry %s"), key); diff --git a/submodule.c b/submodule.c index f8373a9ea7decf..fff3c755703163 100644 --- a/submodule.c +++ b/submodule.c @@ -2058,7 +2058,7 @@ void submodule_unset_core_worktree(const struct submodule *sub) submodule_name_to_gitdir(&config_path, the_repository, sub->name); strbuf_addstr(&config_path, "/config"); - if (git_config_set_in_file_gently(config_path.buf, "core.worktree", NULL, NULL)) + if (repo_config_set_in_file_gently(the_repository, config_path.buf, "core.worktree", NULL, NULL)) warning(_("Could not unset core.worktree setting in submodule '%s'"), sub->path); diff --git a/worktree.c b/worktree.c index 981a2713374ff8..a2a5f51f29fca2 100644 --- a/worktree.c +++ b/worktree.c @@ -991,9 +991,9 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, static int move_config_setting(const char *key, const char *value, const char *from_file, const char *to_file) { - if (git_config_set_in_file_gently(to_file, key, NULL, value)) + if (repo_config_set_in_file_gently(the_repository, to_file, key, NULL, value)) return error(_("unable to set %s in '%s'"), key, to_file); - if (git_config_set_in_file_gently(from_file, key, NULL, NULL)) + if (repo_config_set_in_file_gently(the_repository, from_file, key, NULL, NULL)) return error(_("unable to unset %s in '%s'"), key, from_file); return 0; } From adf9e5f8f222c79dee953b012b2e6196e908996d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:37 +0200 Subject: [PATCH 17/47] config: drop `git_config_set_multivar_in_file_gently()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_set_multivar_in_file_gently()`. All callsites are adjusted so that they use `repo_config_set_multivar_in_file_gently(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/config.c | 44 ++++++++++++++++++++++---------------------- builtin/gc.c | 4 ++-- builtin/worktree.c | 2 +- config.h | 12 ------------ sequencer.c | 2 +- 5 files changed, 26 insertions(+), 38 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index f7e718c67025c5..59fb113b073926 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -966,9 +966,9 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix, value = normalize_value(argv[0], argv[1], type, &default_kvi); if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) { - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, value_pattern, - comment, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, value_pattern, + comment, flags); } else { ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], comment, value); @@ -1010,9 +1010,9 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix, check_write(&location_opts.source); if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], NULL, value_pattern, - NULL, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, value_pattern, + NULL, flags); else ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], NULL, NULL); @@ -1305,26 +1305,26 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) check_write(&location_opts.source); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, argv[2], - comment, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, argv[2], + comment, flags); } else if (actions == ACTION_ADD) { check_write(&location_opts.source); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, - CONFIG_REGEX_NONE, - comment, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, + CONFIG_REGEX_NONE, + comment, flags); } else if (actions == ACTION_REPLACE_ALL) { check_write(&location_opts.source); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, argv[2], - comment, flags | CONFIG_FLAGS_MULTI_REPLACE); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, argv[2], + comment, flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_GET) { check_argc(argc, 1, 2); @@ -1350,9 +1350,9 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) check_write(&location_opts.source); check_argc(argc, 1, 2); if (argc == 2) - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], NULL, argv[1], - NULL, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, argv[1], + NULL, flags); else ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], NULL, NULL); @@ -1360,9 +1360,9 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) else if (actions == ACTION_UNSET_ALL) { check_write(&location_opts.source); check_argc(argc, 1, 2); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], NULL, argv[1], - NULL, flags | CONFIG_FLAGS_MULTI_REPLACE); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, argv[1], + NULL, flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_RENAME_SECTION) { check_write(&location_opts.source); diff --git a/builtin/gc.c b/builtin/gc.c index c0fe4e73087731..183798f0dc966e 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1938,7 +1938,7 @@ static int maintenance_register(int argc, const char **argv, const char *prefix, } if (!config_file) die(_("$HOME not set")); - rc = git_config_set_multivar_in_file_gently( + rc = repo_config_set_multivar_in_file_gently(the_repository, config_file, "maintenance.repo", maintpath, CONFIG_REGEX_NONE, NULL, 0); free(global_config_file); @@ -2007,7 +2007,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi } if (!config_file) die(_("$HOME not set")); - rc = git_config_set_multivar_in_file_gently( + rc = repo_config_set_multivar_in_file_gently(the_repository, config_file, key, NULL, maintpath, NULL, CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE); free(global_config_file); diff --git a/builtin/worktree.c b/builtin/worktree.c index fd517c82c444a4..812774a5ca992c 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -379,7 +379,7 @@ static void copy_filtered_worktree_config(const char *worktree_git_dir) if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare && - git_config_set_multivar_in_file_gently( + repo_config_set_multivar_in_file_gently(the_repository, to_file, "core.bare", NULL, "true", NULL, 0)) error(_("failed to unset '%s' in '%s'"), "core.bare", to_file); diff --git a/config.h b/config.h index 4e658e47f0a25a..e69592ada15c68 100644 --- a/config.h +++ b/config.h @@ -734,18 +734,6 @@ static inline int git_config_get_pathname(const char *key, char **dest) return repo_config_get_pathname(the_repository, key, dest); } -static inline int git_config_set_multivar_in_file_gently( - const char *config_filename, - const char *key, const char *value, - const char *value_pattern, - const char *comment, - unsigned flags) -{ - return repo_config_set_multivar_in_file_gently(the_repository, config_filename, - key, value, value_pattern, - comment, flags); -} - static inline void git_config_set_multivar_in_file( const char *config_filename, const char *key, diff --git a/sequencer.c b/sequencer.c index 8acb699f4f2f60..aaf2e4df64ed0b 100644 --- a/sequencer.c +++ b/sequencer.c @@ -3690,7 +3690,7 @@ static int save_opts(struct replay_opts *opts) res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.gpg-sign", NULL, opts->gpg_sign); for (size_t i = 0; i < opts->xopts.nr; i++) - res |= git_config_set_multivar_in_file_gently(opts_file, + res |= repo_config_set_multivar_in_file_gently(the_repository, opts_file, "options.strategy-option", opts->xopts.v[i], "^$", NULL, 0); if (opts->allow_rerere_auto) From 1bb3e41027ba65446407068a09c4855b7556fe4d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:38 +0200 Subject: [PATCH 18/47] config: drop `git_config_get_multivar_gently()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_get_multivar_gently()`. All callsites are adjusted so that they use `repo_config_get_multivar_gently(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- branch.c | 2 +- builtin/clone.c | 8 ++++---- builtin/remote.c | 4 ++-- config.h | 7 ------- scalar.c | 6 +++--- 5 files changed, 10 insertions(+), 17 deletions(-) diff --git a/branch.c b/branch.c index 3dc237adf6c8bc..26be35834718f2 100644 --- a/branch.c +++ b/branch.c @@ -130,7 +130,7 @@ static int install_branch_config_multiple_remotes(int flag, const char *local, if (repo_config_set_gently(the_repository, key.buf, NULL) < 0) goto out_err; for_each_string_list_item(item, remotes) - if (git_config_set_multivar_gently(key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0) + if (repo_config_set_multivar_gently(the_repository, key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0) goto out_err; if (rebasing) { diff --git a/builtin/clone.c b/builtin/clone.c index f025a8f19e08d2..183297787cb9e3 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -762,16 +762,16 @@ static int write_one_config(const char *key, const char *value, { /* * give git_clone_config a chance to write config values back to the - * environment, since git_config_set_multivar_gently only deals with + * environment, since repo_config_set_multivar_gently only deals with * config-file writes */ int apply_failed = git_clone_config(key, value, ctx, data); if (apply_failed) return apply_failed; - return git_config_set_multivar_gently(key, - value ? value : "true", - CONFIG_REGEX_NONE, 0); + return repo_config_set_multivar_gently(the_repository, key, + value ? value : "true", + CONFIG_REGEX_NONE, 0); } static void write_config(struct string_list *config) diff --git a/builtin/remote.c b/builtin/remote.c index 827639e0398636..dd340a332592cb 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1633,8 +1633,8 @@ static int update(int argc, const char **argv, const char *prefix, static int remove_all_fetch_refspecs(const char *key) { - return git_config_set_multivar_gently(key, NULL, NULL, - CONFIG_FLAGS_MULTI_REPLACE); + return repo_config_set_multivar_gently(the_repository, key, NULL, NULL, + CONFIG_FLAGS_MULTI_REPLACE); } static void add_branches(struct remote *remote, const char **branches, diff --git a/config.h b/config.h index e69592ada15c68..a90b814292c7e0 100644 --- a/config.h +++ b/config.h @@ -745,13 +745,6 @@ static inline void git_config_set_multivar_in_file( key, value, value_pattern, flags); } -static inline int git_config_set_multivar_gently(const char *key, const char *value, - const char *value_pattern, unsigned flags) -{ - return repo_config_set_multivar_gently(the_repository, key, value, - value_pattern, flags); -} - static inline void git_config_set_multivar(const char *key, const char *value, const char *value_pattern, unsigned flags) { diff --git a/scalar.c b/scalar.c index c09c5ca194eab1..4a373c133d8562 100644 --- a/scalar.c +++ b/scalar.c @@ -196,9 +196,9 @@ static int set_recommended_config(int reconfigure) if (repo_config_get_string(the_repository, "log.excludeDecoration", &value)) { trace2_data_string("scalar", the_repository, "log.excludeDecoration", "created"); - if (git_config_set_multivar_gently("log.excludeDecoration", - "refs/prefetch/*", - CONFIG_REGEX_NONE, 0)) + if (repo_config_set_multivar_gently(the_repository, "log.excludeDecoration", + "refs/prefetch/*", + CONFIG_REGEX_NONE, 0)) return error(_("could not configure " "log.excludeDecoration")); } else { From a538250d97ca751f489ce4fa864648f8f4c8cd29 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:39 +0200 Subject: [PATCH 19/47] config: drop `git_config_set_multivar()` wrapper In 036876a1067 (config: hide functions using `the_repository` by default, 2024-08-13) we have moved around a bunch of functions in the config subsystem that depend on `the_repository`. Those function have been converted into mere wrappers around their equivalent function that takes in a repository as parameter, and the intent was that we'll eventually remove those wrappers to make the dependency on the global repository variable explicit at the callsite. Follow through with that intent and remove `git_config_set_multivar()`. All callsites are adjusted so that they use `repo_config_set_multivar(the_repository, ...)` instead. While some callsites might already have a repository available, this mechanical conversion is the exact same as the current situation and thus cannot cause any regression. Those sites should eventually be cleaned up in a later patch series. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/branch.c | 4 ++-- builtin/clone.c | 2 +- builtin/remote.c | 20 ++++++++++---------- config.h | 7 ------- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 5de0691d18d4ac..fa5ced452e5bb3 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -987,10 +987,10 @@ int cmd_branch(int argc, strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.remote", branch->name); - git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.merge", branch->name); - git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); strbuf_release(&buf); } else if (!noncreate_actions && argc > 0 && argc <= 2) { const char *branch_name = argv[0]; diff --git a/builtin/clone.c b/builtin/clone.c index 183297787cb9e3..c990f398ef6f37 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -822,7 +822,7 @@ static void write_refspec_config(const char *src_ref_prefix, /* Configure the remote */ if (value.len) { strbuf_addf(&key, "remote.%s.fetch", remote_name); - git_config_set_multivar(key.buf, value.buf, "^$", 0); + repo_config_set_multivar(the_repository, key.buf, value.buf, "^$", 0); strbuf_reset(&key); if (option_mirror) { diff --git a/builtin/remote.c b/builtin/remote.c index dd340a332592cb..4c63a8bb5760da 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -132,7 +132,7 @@ static void add_branch(const char *key, const char *branchname, else strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s", branchname, remotename, branchname); - git_config_set_multivar(key, tmp->buf, "^$", 0); + repo_config_set_multivar(the_repository, key, tmp->buf, "^$", 0); } static const char mirror_advice[] = @@ -634,15 +634,15 @@ static int migrate_file(struct remote *remote) strbuf_addf(&buf, "remote.%s.url", remote->name); for (i = 0; i < remote->url.nr; i++) - git_config_set_multivar(buf.buf, remote->url.v[i], "^$", 0); + repo_config_set_multivar(the_repository, buf.buf, remote->url.v[i], "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.push", remote->name); for (i = 0; i < remote->push.nr; i++) - git_config_set_multivar(buf.buf, remote->push.items[i].raw, "^$", 0); + repo_config_set_multivar(the_repository, buf.buf, remote->push.items[i].raw, "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", remote->name); for (i = 0; i < remote->fetch.nr; i++) - git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0); + repo_config_set_multivar(the_repository, buf.buf, remote->fetch.items[i].raw, "^$", 0); #ifndef WITH_BREAKING_CHANGES if (remote->origin == REMOTE_REMOTES) unlink_or_warn(repo_git_path_replace(the_repository, &buf, @@ -771,7 +771,7 @@ static int mv(int argc, const char **argv, const char *prefix, if (oldremote->fetch.nr) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", rename.new_name); - git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name); for (i = 0; i < oldremote->fetch.nr; i++) { char *ptr; @@ -791,7 +791,7 @@ static int mv(int argc, const char **argv, const char *prefix, "\tPlease update the configuration manually if necessary."), buf2.buf); - git_config_set_multivar(buf.buf, buf2.buf, "^$", 0); + repo_config_set_multivar(the_repository, buf.buf, buf2.buf, "^$", 0); } } @@ -1790,7 +1790,7 @@ static int set_url(int argc, const char **argv, const char *prefix, /* Special cases that add new entry. */ if ((!oldurl && !delete_mode) || add_mode) { if (add_mode) - git_config_set_multivar(name_buf.buf, newurl, + repo_config_set_multivar(the_repository, name_buf.buf, newurl, "^$", 0); else repo_config_set(the_repository, name_buf.buf, newurl); @@ -1814,10 +1814,10 @@ static int set_url(int argc, const char **argv, const char *prefix, regfree(&old_regex); if (!delete_mode) - git_config_set_multivar(name_buf.buf, newurl, oldurl, 0); + repo_config_set_multivar(the_repository, name_buf.buf, newurl, oldurl, 0); else - git_config_set_multivar(name_buf.buf, NULL, oldurl, - CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, name_buf.buf, NULL, oldurl, + CONFIG_FLAGS_MULTI_REPLACE); out: strbuf_release(&name_buf); return 0; diff --git a/config.h b/config.h index a90b814292c7e0..61774f17db33b1 100644 --- a/config.h +++ b/config.h @@ -744,13 +744,6 @@ static inline void git_config_set_multivar_in_file( repo_config_set_multivar_in_file(the_repository, config_filename, key, value, value_pattern, flags); } - -static inline void git_config_set_multivar(const char *key, const char *value, - const char *value_pattern, unsigned flags) -{ - repo_config_set_multivar(the_repository, key, value, - value_pattern, flags); -} # endif /* USE_THE_REPOSITORY_VARIABLE */ #endif /* CONFIG_H */ From 00271bb3001fd8732d8afc746f2188f807192e87 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:40 +0200 Subject: [PATCH 20/47] config: remove unused `the_repository` wrappers Remove the last couple of wrapper functions that implicitly depend on `the_repository`. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- config.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/config.h b/config.h index 61774f17db33b1..87baf8eeffe0a1 100644 --- a/config.h +++ b/config.h @@ -718,32 +718,4 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l lookup_config(mapping, ARRAY_SIZE(mapping), var) int lookup_config(const char **mapping, int nr_mapping, const char *var); -# ifdef USE_THE_REPOSITORY_VARIABLE -static inline int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest) -{ - return repo_config_get_bool_or_int(the_repository, key, is_bool, dest); -} - -static inline int git_config_get_maybe_bool(const char *key, int *dest) -{ - return repo_config_get_maybe_bool(the_repository, key, dest); -} - -static inline int git_config_get_pathname(const char *key, char **dest) -{ - return repo_config_get_pathname(the_repository, key, dest); -} - -static inline void git_config_set_multivar_in_file( - const char *config_filename, - const char *key, - const char *value, - const char *value_pattern, - unsigned flags) -{ - repo_config_set_multivar_in_file(the_repository, config_filename, - key, value, value_pattern, flags); -} -# endif /* USE_THE_REPOSITORY_VARIABLE */ - #endif /* CONFIG_H */ From 08b775864edf96b97500fd70446c55528f5cf4a6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:41 +0200 Subject: [PATCH 21/47] config: move Git config parsing into "environment.c" In "config.c" we host both the business logic to read and write config files as well as the logic to parse specific Git-related variables. On the one hand this is mixing concerns, but even more importantly it means that we cannot easily remove the dependency on `the_repository` in our config parsing logic. Move the logic into "environment.c". This file is a grab bag of all kinds of global state already, so it is quite a good fit. Furthermore, it also hosts most of the global variables that we're parsing the config values into, making this an even better fit. Note that there is one hidden change: in `parse_fsync_components()` we use an `int` to iterate through `ARRAY_SIZE(fsync_component_names)`. But as -Wsign-compare warnings are enabled in this file this causes a compiler warning. The issue is fixed by using a `size_t` instead. This change allows us to drop the `USE_THE_REPOSITORY_VARIABLE` declaration. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/add.c | 1 + builtin/check-ignore.c | 1 + builtin/check-mailmap.c | 1 + builtin/checkout--worker.c | 1 + builtin/checkout-index.c | 1 + builtin/clean.c | 1 + builtin/commit-graph.c | 1 + builtin/commit-tree.c | 1 + builtin/count-objects.c | 1 + builtin/credential.c | 1 + builtin/fast-export.c | 1 + builtin/for-each-ref.c | 1 + builtin/fsmonitor--daemon.c | 1 + builtin/grep.c | 1 + builtin/hash-object.c | 1 + builtin/help.c | 1 + builtin/hook.c | 1 + builtin/interpret-trailers.c | 1 + builtin/ls-files.c | 1 + builtin/ls-tree.c | 1 + builtin/merge-base.c | 1 + builtin/merge-tree.c | 1 + builtin/multi-pack-index.c | 1 + builtin/pack-refs.c | 1 + builtin/patch-id.c | 1 + builtin/pull.c | 1 + builtin/read-tree.c | 1 + builtin/replace.c | 1 + builtin/rm.c | 1 + builtin/send-pack.c | 1 + builtin/show-ref.c | 1 + builtin/symbolic-ref.c | 1 + builtin/unpack-file.c | 1 + builtin/update-ref.c | 1 + builtin/update-server-info.c | 1 + builtin/var.c | 1 + builtin/verify-commit.c | 1 + builtin/verify-pack.c | 1 + builtin/verify-tag.c | 1 + builtin/write-tree.c | 1 + commit-graph.c | 1 + config.c | 511 ---------------------------------- config.h | 3 - environment.c | 512 +++++++++++++++++++++++++++++++++++ environment.h | 3 + fsck.c | 1 + http-fetch.c | 1 + http.c | 1 + imap-send.c | 1 + mailinfo.c | 1 + reflog.c | 1 + rerere.c | 1 + t/helper/test-advise.c | 1 + t/helper/test-read-cache.c | 1 + xdiff-interface.c | 1 + 55 files changed, 566 insertions(+), 514 deletions(-) diff --git a/builtin/add.c b/builtin/add.c index 7c292ffdc6c2c9..88d1d330fa8fe6 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "lockfile.h" #include "editor.h" #include "dir.h" diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 03033499cb0832..644c9a414ffa1e 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "quote.h" #include "pathspec.h" diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index 634626c672848f..9cc5c598302657 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "ident.h" #include "mailmap.h" diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index 27a7d4f0409893..e0772b718b27bf 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -4,6 +4,7 @@ #include "builtin.h" #include "config.h" #include "entry.h" +#include "environment.h" #include "gettext.h" #include "parallel-checkout.h" #include "parse-options.h" diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 7f74bc702fa739..188128aebd9bc0 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "lockfile.h" #include "quote.h" diff --git a/builtin/clean.c b/builtin/clean.c index 5ee147c4acc053..a1977b92dc89dd 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -13,6 +13,7 @@ #include "abspath.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "path.h" diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index c5cc601844cce5..4992ac146e14d1 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "commit.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "parse-options.h" diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 2f1df28d41394d..5189e685a7eccd 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -6,6 +6,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 433daff805abf9..b1148a68fa826f 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "path.h" #include "parse-options.h" diff --git a/builtin/credential.c b/builtin/credential.c index 52f172e80cb496..a295c80b366b95 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "credential.h" #include "builtin.h" +#include "environment.h" #include "config.h" static const char usage_msg[] = diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 17027b859e0caf..66a3a98c9384fe 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h" diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 3d2207ec7733b2..a8f7f8c7625623 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -1,6 +1,7 @@ #include "builtin.h" #include "commit.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "object.h" #include "parse-options.h" diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 469c62b555bcde..242c594646d1f5 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -5,6 +5,7 @@ #include "abspath.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h" diff --git a/builtin/grep.c b/builtin/grep.c index 8fcb69dbf2cba5..5df653733371d8 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "abspath.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "config.h" diff --git a/builtin/hash-object.c b/builtin/hash-object.c index c3ad1e91c96fd9..5d900a6b8c953e 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -8,6 +8,7 @@ #include "builtin.h" #include "abspath.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-file.h" diff --git a/builtin/help.c b/builtin/help.c index d79ecd946a640c..c09cbc8912deb6 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -6,6 +6,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "exec-cmd.h" #include "gettext.h" #include "pager.h" diff --git a/builtin/hook.c b/builtin/hook.c index 044c27aa95dba6..7afec380d2e579 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hook.h" #include "parse-options.h" diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 3141c37b853ff0..41b0750e5af324 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -6,6 +6,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "string-list.h" diff --git a/builtin/ls-files.c b/builtin/ls-files.c index ff975e7be06045..c06a6f33e41c56 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -11,6 +11,7 @@ #include "builtin.h" #include "config.h" #include "convert.h" +#include "environment.h" #include "quote.h" #include "dir.h" #include "gettext.h" diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 4ba84e519672d3..5d55731ca35b7a 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 8fde35c1751ee1..3f82781245bd27 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "config.h" #include "commit.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 99a6495fd52f79..203f0e6456a751 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" +#include "environment.h" #include "tree-walk.h" #include "xdiff-interface.h" #include "help.h" diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index 9a113f0f1f33ce..d3b9e98be37424 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "abspath.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "midx.h" diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index e47bae1c803bc8..5e28d0f9e80996 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "refs.h" diff --git a/builtin/patch-id.c b/builtin/patch-id.c index a659f00531a0f4..d26e9d0c1eae6a 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -3,6 +3,7 @@ #include "builtin.h" #include "config.h" #include "diff.h" +#include "environment.h" #include "gettext.h" #include "hash.h" #include "hex.h" diff --git a/builtin/pull.c b/builtin/pull.c index 5ea51c31f5878b..e6d3535c3b59d5 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -11,6 +11,7 @@ #include "builtin.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "merge.h" diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 00eef756e67b0c..34f7a59f38ee22 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -6,6 +6,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" diff --git a/builtin/replace.c b/builtin/replace.c index 3fe39e9df731df..19897ef927fea8 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -11,6 +11,7 @@ #include "builtin.h" #include "config.h" #include "editor.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h" diff --git a/builtin/rm.c b/builtin/rm.c index 8c0da7a3ce7a66..05d89e98c3c6b8 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "lockfile.h" #include "dir.h" #include "gettext.h" diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 28b69d26b483d2..8b81c8a84863eb 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "hex.h" #include "pkt-line.h" #include "run-command.h" diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 414e55b92d5fef..0b6f9edf86c24f 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs/refs-internal.h" diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 5c4623067c5372..231e41e715b95a 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "refs.h" #include "parse-options.h" diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index ae871adc909074..87877a9fabc6f6 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "hex.h" #include "object-file.h" #include "object-name.h" diff --git a/builtin/update-ref.c b/builtin/update-ref.c index cb936643243088..195437e7c656ff 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -3,6 +3,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hash.h" #include "hex.h" diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index ba702d30efdc17..4c12968a8360f2 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "server-info.h" diff --git a/builtin/var.c b/builtin/var.c index beeac12dccf3ea..a2d790d45320ae 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -11,6 +11,7 @@ #include "attr.h" #include "config.h" #include "editor.h" +#include "environment.h" #include "ident.h" #include "pager.h" #include "refs.h" diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index 5f749a30daf015..62398acd721060 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -7,6 +7,7 @@ */ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "object-name.h" #include "commit.h" diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index d9f66f5e767776..65fd6629a0079d 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "run-command.h" #include "parse-options.h" diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index ed1c40338fd88c..cd6bc11095d01a 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -7,6 +7,7 @@ */ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "tag.h" #include "object-name.h" diff --git a/builtin/write-tree.c b/builtin/write-tree.c index 3465c70a48a7eb..e3bd1a40dbf389 100644 --- a/builtin/write-tree.c +++ b/builtin/write-tree.c @@ -6,6 +6,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "tree.h" diff --git a/commit-graph.c b/commit-graph.c index bd7b6f5338bd9d..e0d92b816f5938 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -4,6 +4,7 @@ #include "git-compat-util.h" #include "config.h" #include "csum-file.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" diff --git a/config.c b/config.c index 285cab0ce2a6a2..947fba3d8d4404 100644 --- a/config.c +++ b/config.c @@ -6,12 +6,10 @@ * */ -#define USE_THE_REPOSITORY_VARIABLE #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" -#include "advice.h" #include "date.h" #include "branch.h" #include "config.h" @@ -20,11 +18,8 @@ #include "environment.h" #include "gettext.h" #include "git-zlib.h" -#include "ident.h" #include "repository.h" #include "lockfile.h" -#include "mailmap.h" -#include "attr.h" #include "exec-cmd.h" #include "strbuf.h" #include "quote.h" @@ -32,7 +27,6 @@ #include "string-list.h" #include "object-name.h" #include "odb.h" -#include "pager.h" #include "path.h" #include "utf8.h" #include "color.h" @@ -41,7 +35,6 @@ #include "strvec.h" #include "trace2.h" #include "wildmatch.h" -#include "ws.h" #include "write-or-die.h" struct config_source { @@ -71,9 +64,6 @@ struct config_source { }; #define CONFIG_SOURCE_INIT { 0 } -static int pack_compression_seen; -static int zlib_compression_seen; - /* * Config that comes from trusted scopes, namely: * - CONFIG_SCOPE_SYSTEM (e.g. /etc/gitconfig) @@ -1262,80 +1252,6 @@ double git_config_double(const char *name, const char *value, return ret; } -static const struct fsync_component_name { - const char *name; - enum fsync_component component_bits; -} fsync_component_names[] = { - { "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT }, - { "pack", FSYNC_COMPONENT_PACK }, - { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA }, - { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH }, - { "index", FSYNC_COMPONENT_INDEX }, - { "objects", FSYNC_COMPONENTS_OBJECTS }, - { "reference", FSYNC_COMPONENT_REFERENCE }, - { "derived-metadata", FSYNC_COMPONENTS_DERIVED_METADATA }, - { "committed", FSYNC_COMPONENTS_COMMITTED }, - { "added", FSYNC_COMPONENTS_ADDED }, - { "all", FSYNC_COMPONENTS_ALL }, -}; - -static enum fsync_component parse_fsync_components(const char *var, const char *string) -{ - enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT; - enum fsync_component positive = 0, negative = 0; - - while (string) { - int i; - size_t len; - const char *ep; - int negated = 0; - int found = 0; - - string = string + strspn(string, ", \t\n\r"); - ep = strchrnul(string, ','); - len = ep - string; - if (!strcmp(string, "none")) { - current = FSYNC_COMPONENT_NONE; - goto next_name; - } - - if (*string == '-') { - negated = 1; - string++; - len--; - if (!len) - warning(_("invalid value for variable %s"), var); - } - - if (!len) - break; - - for (i = 0; i < ARRAY_SIZE(fsync_component_names); ++i) { - const struct fsync_component_name *n = &fsync_component_names[i]; - - if (strncmp(n->name, string, len)) - continue; - - found = 1; - if (negated) - negative |= n->component_bits; - else - positive |= n->component_bits; - } - - if (!found) { - char *component = xstrndup(string, len); - warning(_("ignoring unknown core.fsync component '%s'"), component); - free(component); - } - -next_name: - string = ep; - } - - return (current & ~negative) | positive; -} - int git_config_bool_or_int(const char *name, const char *value, const struct key_value_info *kvi, int *is_bool) { @@ -1393,433 +1309,6 @@ int git_config_color(char *dest, const char *var, const char *value) return 0; } -static int git_default_core_config(const char *var, const char *value, - const struct config_context *ctx, void *cb) -{ - /* This needs a better name */ - if (!strcmp(var, "core.filemode")) { - trust_executable_bit = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.trustctime")) { - trust_ctime = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.checkstat")) { - if (!value) - return config_error_nonbool(var); - if (!strcasecmp(value, "default")) - check_stat = 1; - else if (!strcasecmp(value, "minimal")) - check_stat = 0; - else - return error(_("invalid value for '%s': '%s'"), - var, value); - } - - if (!strcmp(var, "core.quotepath")) { - quote_path_fully = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.symlinks")) { - has_symlinks = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.ignorecase")) { - ignore_case = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.attributesfile")) { - FREE_AND_NULL(git_attributes_file); - return git_config_pathname(&git_attributes_file, var, value); - } - - if (!strcmp(var, "core.bare")) { - is_bare_repository_cfg = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.ignorestat")) { - assume_unchanged = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.abbrev")) { - if (!value) - return config_error_nonbool(var); - if (!strcasecmp(value, "auto")) - default_abbrev = -1; - else if (!git_parse_maybe_bool_text(value)) - default_abbrev = GIT_MAX_HEXSZ; - else { - int abbrev = git_config_int(var, value, ctx->kvi); - if (abbrev < minimum_abbrev) - return error(_("abbrev length out of range: %d"), abbrev); - default_abbrev = abbrev; - } - return 0; - } - - if (!strcmp(var, "core.disambiguate")) - return set_disambiguate_hint_config(var, value); - - if (!strcmp(var, "core.loosecompression")) { - int level = git_config_int(var, value, ctx->kvi); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die(_("bad zlib compression level %d"), level); - zlib_compression_level = level; - zlib_compression_seen = 1; - return 0; - } - - if (!strcmp(var, "core.compression")) { - int level = git_config_int(var, value, ctx->kvi); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die(_("bad zlib compression level %d"), level); - if (!zlib_compression_seen) - zlib_compression_level = level; - if (!pack_compression_seen) - pack_compression_level = level; - return 0; - } - - if (!strcmp(var, "core.autocrlf")) { - if (value && !strcasecmp(value, "input")) { - auto_crlf = AUTO_CRLF_INPUT; - return 0; - } - auto_crlf = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.safecrlf")) { - int eol_rndtrp_die; - if (value && !strcasecmp(value, "warn")) { - global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; - return 0; - } - eol_rndtrp_die = git_config_bool(var, value); - global_conv_flags_eol = eol_rndtrp_die ? - CONV_EOL_RNDTRP_DIE : 0; - return 0; - } - - if (!strcmp(var, "core.eol")) { - if (value && !strcasecmp(value, "lf")) - core_eol = EOL_LF; - else if (value && !strcasecmp(value, "crlf")) - core_eol = EOL_CRLF; - else if (value && !strcasecmp(value, "native")) - core_eol = EOL_NATIVE; - else - core_eol = EOL_UNSET; - return 0; - } - - if (!strcmp(var, "core.checkroundtripencoding")) { - FREE_AND_NULL(check_roundtrip_encoding); - return git_config_string(&check_roundtrip_encoding, var, value); - } - - if (!strcmp(var, "core.editor")) { - FREE_AND_NULL(editor_program); - return git_config_string(&editor_program, var, value); - } - - if (!strcmp(var, "core.commentchar") || - !strcmp(var, "core.commentstring")) { - if (!value) - return config_error_nonbool(var); - else if (!strcasecmp(value, "auto")) - auto_comment_line_char = 1; - else if (value[0]) { - if (strchr(value, '\n')) - return error(_("%s cannot contain newline"), var); - comment_line_str = value; - FREE_AND_NULL(comment_line_str_to_free); - auto_comment_line_char = 0; - } else - return error(_("%s must have at least one character"), var); - return 0; - } - - if (!strcmp(var, "core.askpass")) { - FREE_AND_NULL(askpass_program); - return git_config_string(&askpass_program, var, value); - } - - if (!strcmp(var, "core.excludesfile")) { - FREE_AND_NULL(excludes_file); - return git_config_pathname(&excludes_file, var, value); - } - - if (!strcmp(var, "core.whitespace")) { - if (!value) - return config_error_nonbool(var); - whitespace_rule_cfg = parse_whitespace_rule(value); - return 0; - } - - if (!strcmp(var, "core.fsync")) { - if (!value) - return config_error_nonbool(var); - fsync_components = parse_fsync_components(var, value); - return 0; - } - - if (!strcmp(var, "core.fsyncmethod")) { - if (!value) - return config_error_nonbool(var); - if (!strcmp(value, "fsync")) - fsync_method = FSYNC_METHOD_FSYNC; - else if (!strcmp(value, "writeout-only")) - fsync_method = FSYNC_METHOD_WRITEOUT_ONLY; - else if (!strcmp(value, "batch")) - fsync_method = FSYNC_METHOD_BATCH; - else - warning(_("ignoring unknown core.fsyncMethod value '%s'"), value); - - } - - if (!strcmp(var, "core.fsyncobjectfiles")) { - if (fsync_object_files < 0) - warning(_("core.fsyncObjectFiles is deprecated; use core.fsync instead")); - fsync_object_files = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.createobject")) { - if (!value) - return config_error_nonbool(var); - if (!strcmp(value, "rename")) - object_creation_mode = OBJECT_CREATION_USES_RENAMES; - else if (!strcmp(value, "link")) - object_creation_mode = OBJECT_CREATION_USES_HARDLINKS; - else - die(_("invalid mode for object creation: %s"), value); - return 0; - } - - if (!strcmp(var, "core.sparsecheckout")) { - core_apply_sparse_checkout = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.sparsecheckoutcone")) { - core_sparse_checkout_cone = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.precomposeunicode")) { - precomposed_unicode = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.protecthfs")) { - protect_hfs = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.protectntfs")) { - protect_ntfs = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.maxtreedepth")) { - max_allowed_tree_depth = git_config_int(var, value, ctx->kvi); - return 0; - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return platform_core_config(var, value, ctx, cb); -} - -static int git_default_sparse_config(const char *var, const char *value) -{ - if (!strcmp(var, "sparse.expectfilesoutsideofpatterns")) { - sparse_expect_files_outside_of_patterns = git_config_bool(var, value); - return 0; - } - - /* Add other config variables here and to Documentation/config/sparse.adoc. */ - return 0; -} - -static int git_default_i18n_config(const char *var, const char *value) -{ - if (!strcmp(var, "i18n.commitencoding")) { - FREE_AND_NULL(git_commit_encoding); - return git_config_string(&git_commit_encoding, var, value); - } - - if (!strcmp(var, "i18n.logoutputencoding")) { - FREE_AND_NULL(git_log_output_encoding); - return git_config_string(&git_log_output_encoding, var, value); - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_branch_config(const char *var, const char *value) -{ - if (!strcmp(var, "branch.autosetupmerge")) { - if (value && !strcmp(value, "always")) { - git_branch_track = BRANCH_TRACK_ALWAYS; - return 0; - } else if (value && !strcmp(value, "inherit")) { - git_branch_track = BRANCH_TRACK_INHERIT; - return 0; - } else if (value && !strcmp(value, "simple")) { - git_branch_track = BRANCH_TRACK_SIMPLE; - return 0; - } - git_branch_track = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "branch.autosetuprebase")) { - if (!value) - return config_error_nonbool(var); - else if (!strcmp(value, "never")) - autorebase = AUTOREBASE_NEVER; - else if (!strcmp(value, "local")) - autorebase = AUTOREBASE_LOCAL; - else if (!strcmp(value, "remote")) - autorebase = AUTOREBASE_REMOTE; - else if (!strcmp(value, "always")) - autorebase = AUTOREBASE_ALWAYS; - else - return error(_("malformed value for %s"), var); - return 0; - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_push_config(const char *var, const char *value) -{ - if (!strcmp(var, "push.default")) { - if (!value) - return config_error_nonbool(var); - else if (!strcmp(value, "nothing")) - push_default = PUSH_DEFAULT_NOTHING; - else if (!strcmp(value, "matching")) - push_default = PUSH_DEFAULT_MATCHING; - else if (!strcmp(value, "simple")) - push_default = PUSH_DEFAULT_SIMPLE; - else if (!strcmp(value, "upstream")) - push_default = PUSH_DEFAULT_UPSTREAM; - else if (!strcmp(value, "tracking")) /* deprecated */ - push_default = PUSH_DEFAULT_UPSTREAM; - else if (!strcmp(value, "current")) - push_default = PUSH_DEFAULT_CURRENT; - else { - error(_("malformed value for %s: %s"), var, value); - return error(_("must be one of nothing, matching, simple, " - "upstream or current")); - } - return 0; - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_mailmap_config(const char *var, const char *value) -{ - if (!strcmp(var, "mailmap.file")) { - FREE_AND_NULL(git_mailmap_file); - return git_config_pathname(&git_mailmap_file, var, value); - } - - if (!strcmp(var, "mailmap.blob")) { - FREE_AND_NULL(git_mailmap_blob); - return git_config_string(&git_mailmap_blob, var, value); - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_attr_config(const char *var, const char *value) -{ - if (!strcmp(var, "attr.tree")) { - FREE_AND_NULL(git_attr_tree); - return git_config_string(&git_attr_tree, var, value); - } - - /* - * Add other attribute related config variables here and to - * Documentation/config/attr.adoc. - */ - return 0; -} - -int git_default_config(const char *var, const char *value, - const struct config_context *ctx, void *cb) -{ - if (starts_with(var, "core.")) - return git_default_core_config(var, value, ctx, cb); - - if (starts_with(var, "user.") || - starts_with(var, "author.") || - starts_with(var, "committer.")) - return git_ident_config(var, value, ctx, cb); - - if (starts_with(var, "i18n.")) - return git_default_i18n_config(var, value); - - if (starts_with(var, "branch.")) - return git_default_branch_config(var, value); - - if (starts_with(var, "push.")) - return git_default_push_config(var, value); - - if (starts_with(var, "mailmap.")) - return git_default_mailmap_config(var, value); - - if (starts_with(var, "attr.")) - return git_default_attr_config(var, value); - - if (starts_with(var, "advice.") || starts_with(var, "color.advice")) - return git_default_advice_config(var, value); - - if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { - pager_use_color = git_config_bool(var,value); - return 0; - } - - if (!strcmp(var, "pack.packsizelimit")) { - pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi); - return 0; - } - - if (!strcmp(var, "pack.compression")) { - int level = git_config_int(var, value, ctx->kvi); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die(_("bad pack compression level %d"), level); - pack_compression_level = level; - pack_compression_seen = 1; - return 0; - } - - if (starts_with(var, "sparse.")) - return git_default_sparse_config(var, value); - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - /* * All source specific fields in the union, die_on_error, name and the callbacks * fgetc, ungetc, ftell of top need to be initialized before calling diff --git a/config.h b/config.h index 87baf8eeffe0a1..65fc47966e6b52 100644 --- a/config.h +++ b/config.h @@ -165,9 +165,6 @@ struct config_context { typedef int (*config_fn_t)(const char *, const char *, const struct config_context *, void *); -int git_default_config(const char *, const char *, - const struct config_context *, void *); - /** * Read a specific file in git-config format. * This function takes the same callback and data parameters as `repo_config`. diff --git a/environment.c b/environment.c index 7c2480b22e5991..ae1427bb9e8e62 100644 --- a/environment.c +++ b/environment.c @@ -12,22 +12,34 @@ #include "git-compat-util.h" #include "abspath.h" +#include "advice.h" +#include "attr.h" #include "branch.h" +#include "color.h" #include "convert.h" #include "environment.h" #include "gettext.h" #include "git-zlib.h" +#include "ident.h" +#include "mailmap.h" +#include "object-name.h" #include "repository.h" #include "config.h" #include "refs.h" #include "fmt-merge-msg.h" #include "commit.h" #include "strvec.h" +#include "pager.h" #include "path.h" +#include "quote.h" #include "chdir-notify.h" #include "setup.h" +#include "ws.h" #include "write-or-die.h" +static int pack_compression_seen; +static int zlib_compression_seen; + int trust_executable_bit = 1; int trust_ctime = 1; int check_stat = 1; @@ -231,3 +243,503 @@ int print_sha1_ellipsis(void) } return cached_result; } + +static const struct fsync_component_name { + const char *name; + enum fsync_component component_bits; +} fsync_component_names[] = { + { "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT }, + { "pack", FSYNC_COMPONENT_PACK }, + { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA }, + { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH }, + { "index", FSYNC_COMPONENT_INDEX }, + { "objects", FSYNC_COMPONENTS_OBJECTS }, + { "reference", FSYNC_COMPONENT_REFERENCE }, + { "derived-metadata", FSYNC_COMPONENTS_DERIVED_METADATA }, + { "committed", FSYNC_COMPONENTS_COMMITTED }, + { "added", FSYNC_COMPONENTS_ADDED }, + { "all", FSYNC_COMPONENTS_ALL }, +}; + +static enum fsync_component parse_fsync_components(const char *var, const char *string) +{ + enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT; + enum fsync_component positive = 0, negative = 0; + + while (string) { + size_t len; + const char *ep; + int negated = 0; + int found = 0; + + string = string + strspn(string, ", \t\n\r"); + ep = strchrnul(string, ','); + len = ep - string; + if (!strcmp(string, "none")) { + current = FSYNC_COMPONENT_NONE; + goto next_name; + } + + if (*string == '-') { + negated = 1; + string++; + len--; + if (!len) + warning(_("invalid value for variable %s"), var); + } + + if (!len) + break; + + for (size_t i = 0; i < ARRAY_SIZE(fsync_component_names); ++i) { + const struct fsync_component_name *n = &fsync_component_names[i]; + + if (strncmp(n->name, string, len)) + continue; + + found = 1; + if (negated) + negative |= n->component_bits; + else + positive |= n->component_bits; + } + + if (!found) { + char *component = xstrndup(string, len); + warning(_("ignoring unknown core.fsync component '%s'"), component); + free(component); + } + +next_name: + string = ep; + } + + return (current & ~negative) | positive; +} + +static int git_default_core_config(const char *var, const char *value, + const struct config_context *ctx, void *cb) +{ + /* This needs a better name */ + if (!strcmp(var, "core.filemode")) { + trust_executable_bit = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.trustctime")) { + trust_ctime = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.checkstat")) { + if (!value) + return config_error_nonbool(var); + if (!strcasecmp(value, "default")) + check_stat = 1; + else if (!strcasecmp(value, "minimal")) + check_stat = 0; + else + return error(_("invalid value for '%s': '%s'"), + var, value); + } + + if (!strcmp(var, "core.quotepath")) { + quote_path_fully = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.symlinks")) { + has_symlinks = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.ignorecase")) { + ignore_case = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.attributesfile")) { + FREE_AND_NULL(git_attributes_file); + return git_config_pathname(&git_attributes_file, var, value); + } + + if (!strcmp(var, "core.bare")) { + is_bare_repository_cfg = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.ignorestat")) { + assume_unchanged = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.abbrev")) { + if (!value) + return config_error_nonbool(var); + if (!strcasecmp(value, "auto")) + default_abbrev = -1; + else if (!git_parse_maybe_bool_text(value)) + default_abbrev = GIT_MAX_HEXSZ; + else { + int abbrev = git_config_int(var, value, ctx->kvi); + if (abbrev < minimum_abbrev) + return error(_("abbrev length out of range: %d"), abbrev); + default_abbrev = abbrev; + } + return 0; + } + + if (!strcmp(var, "core.disambiguate")) + return set_disambiguate_hint_config(var, value); + + if (!strcmp(var, "core.loosecompression")) { + int level = git_config_int(var, value, ctx->kvi); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die(_("bad zlib compression level %d"), level); + zlib_compression_level = level; + zlib_compression_seen = 1; + return 0; + } + + if (!strcmp(var, "core.compression")) { + int level = git_config_int(var, value, ctx->kvi); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die(_("bad zlib compression level %d"), level); + if (!zlib_compression_seen) + zlib_compression_level = level; + if (!pack_compression_seen) + pack_compression_level = level; + return 0; + } + + if (!strcmp(var, "core.autocrlf")) { + if (value && !strcasecmp(value, "input")) { + auto_crlf = AUTO_CRLF_INPUT; + return 0; + } + auto_crlf = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.safecrlf")) { + int eol_rndtrp_die; + if (value && !strcasecmp(value, "warn")) { + global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; + return 0; + } + eol_rndtrp_die = git_config_bool(var, value); + global_conv_flags_eol = eol_rndtrp_die ? + CONV_EOL_RNDTRP_DIE : 0; + return 0; + } + + if (!strcmp(var, "core.eol")) { + if (value && !strcasecmp(value, "lf")) + core_eol = EOL_LF; + else if (value && !strcasecmp(value, "crlf")) + core_eol = EOL_CRLF; + else if (value && !strcasecmp(value, "native")) + core_eol = EOL_NATIVE; + else + core_eol = EOL_UNSET; + return 0; + } + + if (!strcmp(var, "core.checkroundtripencoding")) { + FREE_AND_NULL(check_roundtrip_encoding); + return git_config_string(&check_roundtrip_encoding, var, value); + } + + if (!strcmp(var, "core.editor")) { + FREE_AND_NULL(editor_program); + return git_config_string(&editor_program, var, value); + } + + if (!strcmp(var, "core.commentchar") || + !strcmp(var, "core.commentstring")) { + if (!value) + return config_error_nonbool(var); + else if (!strcasecmp(value, "auto")) + auto_comment_line_char = 1; + else if (value[0]) { + if (strchr(value, '\n')) + return error(_("%s cannot contain newline"), var); + comment_line_str = value; + FREE_AND_NULL(comment_line_str_to_free); + auto_comment_line_char = 0; + } else + return error(_("%s must have at least one character"), var); + return 0; + } + + if (!strcmp(var, "core.askpass")) { + FREE_AND_NULL(askpass_program); + return git_config_string(&askpass_program, var, value); + } + + if (!strcmp(var, "core.excludesfile")) { + FREE_AND_NULL(excludes_file); + return git_config_pathname(&excludes_file, var, value); + } + + if (!strcmp(var, "core.whitespace")) { + if (!value) + return config_error_nonbool(var); + whitespace_rule_cfg = parse_whitespace_rule(value); + return 0; + } + + if (!strcmp(var, "core.fsync")) { + if (!value) + return config_error_nonbool(var); + fsync_components = parse_fsync_components(var, value); + return 0; + } + + if (!strcmp(var, "core.fsyncmethod")) { + if (!value) + return config_error_nonbool(var); + if (!strcmp(value, "fsync")) + fsync_method = FSYNC_METHOD_FSYNC; + else if (!strcmp(value, "writeout-only")) + fsync_method = FSYNC_METHOD_WRITEOUT_ONLY; + else if (!strcmp(value, "batch")) + fsync_method = FSYNC_METHOD_BATCH; + else + warning(_("ignoring unknown core.fsyncMethod value '%s'"), value); + + } + + if (!strcmp(var, "core.fsyncobjectfiles")) { + if (fsync_object_files < 0) + warning(_("core.fsyncObjectFiles is deprecated; use core.fsync instead")); + fsync_object_files = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.createobject")) { + if (!value) + return config_error_nonbool(var); + if (!strcmp(value, "rename")) + object_creation_mode = OBJECT_CREATION_USES_RENAMES; + else if (!strcmp(value, "link")) + object_creation_mode = OBJECT_CREATION_USES_HARDLINKS; + else + die(_("invalid mode for object creation: %s"), value); + return 0; + } + + if (!strcmp(var, "core.sparsecheckout")) { + core_apply_sparse_checkout = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.sparsecheckoutcone")) { + core_sparse_checkout_cone = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.precomposeunicode")) { + precomposed_unicode = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.protecthfs")) { + protect_hfs = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.protectntfs")) { + protect_ntfs = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.maxtreedepth")) { + max_allowed_tree_depth = git_config_int(var, value, ctx->kvi); + return 0; + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return platform_core_config(var, value, ctx, cb); +} + +static int git_default_sparse_config(const char *var, const char *value) +{ + if (!strcmp(var, "sparse.expectfilesoutsideofpatterns")) { + sparse_expect_files_outside_of_patterns = git_config_bool(var, value); + return 0; + } + + /* Add other config variables here and to Documentation/config/sparse.adoc. */ + return 0; +} + +static int git_default_i18n_config(const char *var, const char *value) +{ + if (!strcmp(var, "i18n.commitencoding")) { + FREE_AND_NULL(git_commit_encoding); + return git_config_string(&git_commit_encoding, var, value); + } + + if (!strcmp(var, "i18n.logoutputencoding")) { + FREE_AND_NULL(git_log_output_encoding); + return git_config_string(&git_log_output_encoding, var, value); + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_branch_config(const char *var, const char *value) +{ + if (!strcmp(var, "branch.autosetupmerge")) { + if (value && !strcmp(value, "always")) { + git_branch_track = BRANCH_TRACK_ALWAYS; + return 0; + } else if (value && !strcmp(value, "inherit")) { + git_branch_track = BRANCH_TRACK_INHERIT; + return 0; + } else if (value && !strcmp(value, "simple")) { + git_branch_track = BRANCH_TRACK_SIMPLE; + return 0; + } + git_branch_track = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "branch.autosetuprebase")) { + if (!value) + return config_error_nonbool(var); + else if (!strcmp(value, "never")) + autorebase = AUTOREBASE_NEVER; + else if (!strcmp(value, "local")) + autorebase = AUTOREBASE_LOCAL; + else if (!strcmp(value, "remote")) + autorebase = AUTOREBASE_REMOTE; + else if (!strcmp(value, "always")) + autorebase = AUTOREBASE_ALWAYS; + else + return error(_("malformed value for %s"), var); + return 0; + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_push_config(const char *var, const char *value) +{ + if (!strcmp(var, "push.default")) { + if (!value) + return config_error_nonbool(var); + else if (!strcmp(value, "nothing")) + push_default = PUSH_DEFAULT_NOTHING; + else if (!strcmp(value, "matching")) + push_default = PUSH_DEFAULT_MATCHING; + else if (!strcmp(value, "simple")) + push_default = PUSH_DEFAULT_SIMPLE; + else if (!strcmp(value, "upstream")) + push_default = PUSH_DEFAULT_UPSTREAM; + else if (!strcmp(value, "tracking")) /* deprecated */ + push_default = PUSH_DEFAULT_UPSTREAM; + else if (!strcmp(value, "current")) + push_default = PUSH_DEFAULT_CURRENT; + else { + error(_("malformed value for %s: %s"), var, value); + return error(_("must be one of nothing, matching, simple, " + "upstream or current")); + } + return 0; + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_mailmap_config(const char *var, const char *value) +{ + if (!strcmp(var, "mailmap.file")) { + FREE_AND_NULL(git_mailmap_file); + return git_config_pathname(&git_mailmap_file, var, value); + } + + if (!strcmp(var, "mailmap.blob")) { + FREE_AND_NULL(git_mailmap_blob); + return git_config_string(&git_mailmap_blob, var, value); + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_attr_config(const char *var, const char *value) +{ + if (!strcmp(var, "attr.tree")) { + FREE_AND_NULL(git_attr_tree); + return git_config_string(&git_attr_tree, var, value); + } + + /* + * Add other attribute related config variables here and to + * Documentation/config/attr.adoc. + */ + return 0; +} + +int git_default_config(const char *var, const char *value, + const struct config_context *ctx, void *cb) +{ + if (starts_with(var, "core.")) + return git_default_core_config(var, value, ctx, cb); + + if (starts_with(var, "user.") || + starts_with(var, "author.") || + starts_with(var, "committer.")) + return git_ident_config(var, value, ctx, cb); + + if (starts_with(var, "i18n.")) + return git_default_i18n_config(var, value); + + if (starts_with(var, "branch.")) + return git_default_branch_config(var, value); + + if (starts_with(var, "push.")) + return git_default_push_config(var, value); + + if (starts_with(var, "mailmap.")) + return git_default_mailmap_config(var, value); + + if (starts_with(var, "attr.")) + return git_default_attr_config(var, value); + + if (starts_with(var, "advice.") || starts_with(var, "color.advice")) + return git_default_advice_config(var, value); + + if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { + pager_use_color = git_config_bool(var,value); + return 0; + } + + if (!strcmp(var, "pack.packsizelimit")) { + pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi); + return 0; + } + + if (!strcmp(var, "pack.compression")) { + int level = git_config_int(var, value, ctx->kvi); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die(_("bad pack compression level %d"), level); + pack_compression_level = level; + pack_compression_seen = 1; + return 0; + } + + if (starts_with(var, "sparse.")) + return git_default_sparse_config(var, value); + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} diff --git a/environment.h b/environment.h index 3d806ced6e4552..8cfce41015b3c8 100644 --- a/environment.h +++ b/environment.h @@ -104,6 +104,9 @@ int use_optional_locks(void); const char *get_git_namespace(void); const char *strip_namespace(const char *namespaced_ref); +int git_default_config(const char *, const char *, + const struct config_context *, void *); + /* * TODO: All the below state either explicitly or implicitly relies on * `the_repository`. We should eventually get rid of these and make the diff --git a/fsck.c b/fsck.c index 23965e1880fede..171b424dd57de1 100644 --- a/fsck.c +++ b/fsck.c @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "date.h" #include "dir.h" +#include "environment.h" #include "hex.h" #include "odb.h" #include "path.h" diff --git a/http-fetch.c b/http-fetch.c index 17b9fe4ff8c7a2..1922e23fcd3f97 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -2,6 +2,7 @@ #include "git-compat-util.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "http.h" diff --git a/http.c b/http.c index d94e8f63b57380..33ae9429fd81a1 100644 --- a/http.c +++ b/http.c @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "git-curl-compat.h" +#include "environment.h" #include "hex.h" #include "http.h" #include "config.h" diff --git a/imap-send.c b/imap-send.c index 9b26c669c01558..254ec83ab78179 100644 --- a/imap-send.c +++ b/imap-send.c @@ -28,6 +28,7 @@ #include "advice.h" #include "config.h" #include "credential.h" +#include "environment.h" #include "gettext.h" #include "run-command.h" #include "parse-options.h" diff --git a/mailinfo.c b/mailinfo.c index b4e815b2d8b03c..99ac596e096e70 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -2,6 +2,7 @@ #include "git-compat-util.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex-ll.h" #include "utf8.h" diff --git a/reflog.c b/reflog.c index 39c205fd26e77b..a974005134629b 100644 --- a/reflog.c +++ b/reflog.c @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "odb.h" diff --git a/rerere.c b/rerere.c index c7c3e535ce5045..6ec55964e2ae4a 100644 --- a/rerere.c +++ b/rerere.c @@ -5,6 +5,7 @@ #include "abspath.h" #include "config.h" #include "copy.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" diff --git a/t/helper/test-advise.c b/t/helper/test-advise.c index 77c15a46cfa07d..81ed93a05c9ac7 100644 --- a/t/helper/test-advise.c +++ b/t/helper/test-advise.c @@ -3,6 +3,7 @@ #include "test-tool.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "setup.h" int cmd__advise_if_enabled(int argc, const char **argv) diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c index b2da48eda05185..9ae71cefb302c9 100644 --- a/t/helper/test-read-cache.c +++ b/t/helper/test-read-cache.c @@ -2,6 +2,7 @@ #include "test-tool.h" #include "config.h" +#include "environment.h" #include "read-cache-ll.h" #include "repository.h" #include "setup.h" diff --git a/xdiff-interface.c b/xdiff-interface.c index 0e5d38c96003d3..4971f722b3e5f4 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -2,6 +2,7 @@ #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" +#include "environment.h" #include "gettext.h" #include "config.h" #include "hex.h" From b06408b817c70204542924db0c689f258f010f7e Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 23 Jul 2025 16:08:42 +0200 Subject: [PATCH 22/47] config: fix sign comparison warnings There are a couple of -Wsign-compare warnings in "config.c": - `prepare_include_condition_pattern()` is returns a signed integer, where it either returns a negative error code or the index of the last dir separator in a path. That index will always be a non-negative number, but we cannot just change the return type to a `size_t` due to it being re-used as error code. This is fixed by splitting up concerns: the return value is only used as error code, and the prefix is now returned via an out-pointer. This fixes a sign comparison warning when comparing `text.len < prefix`, - We treat `struct config_store_data::seen` as signed integer in several places even though it's unsigned. - There are multiple trivial sign comparison warnings where we use a signed loop index to iterate through an unsigned number of items. Fix all of these issues and drop the `DISABLE_SIGN_COMPARE_WARNINGS` macro. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- config.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/config.c b/config.c index 947fba3d8d4404..2fe8e52ae2aee3 100644 --- a/config.c +++ b/config.c @@ -6,8 +6,6 @@ * */ -#define DISABLE_SIGN_COMPARE_WARNINGS - #include "git-compat-util.h" #include "abspath.h" #include "date.h" @@ -198,11 +196,12 @@ static void add_trailing_starstar_for_dir(struct strbuf *pat) } static int prepare_include_condition_pattern(const struct key_value_info *kvi, - struct strbuf *pat) + struct strbuf *pat, + size_t *out) { struct strbuf path = STRBUF_INIT; char *expanded; - int prefix = 0; + size_t prefix = 0; expanded = interpolate_path(pat->buf, 1); if (expanded) { @@ -229,8 +228,10 @@ static int prepare_include_condition_pattern(const struct key_value_info *kvi, add_trailing_starstar_for_dir(pat); + *out = prefix; + strbuf_release(&path); - return prefix; + return 0; } static int include_by_gitdir(const struct key_value_info *kvi, @@ -239,7 +240,8 @@ static int include_by_gitdir(const struct key_value_info *kvi, { struct strbuf text = STRBUF_INIT; struct strbuf pattern = STRBUF_INIT; - int ret = 0, prefix; + size_t prefix; + int ret = 0; const char *git_dir; int already_tried_absolute = 0; @@ -250,12 +252,11 @@ static int include_by_gitdir(const struct key_value_info *kvi, strbuf_realpath(&text, git_dir, 1); strbuf_add(&pattern, cond, cond_len); - prefix = prepare_include_condition_pattern(kvi, &pattern); - -again: - if (prefix < 0) + ret = prepare_include_condition_pattern(kvi, &pattern, &prefix); + if (ret < 0) goto done; +again: if (prefix > 0) { /* * perform literal matching on the prefix part so that @@ -724,7 +725,6 @@ int git_config_from_parameters(config_fn_t fn, void *data) if (env) { unsigned long count; char *endp; - int i; count = strtoul(env, &endp, 10); if (*endp) { @@ -736,10 +736,10 @@ int git_config_from_parameters(config_fn_t fn, void *data) goto out; } - for (i = 0; i < count; i++) { + for (unsigned long i = 0; i < count; i++) { const char *key, *value; - strbuf_addf(&envvar, "GIT_CONFIG_KEY_%d", i); + strbuf_addf(&envvar, "GIT_CONFIG_KEY_%lu", i); key = getenv_safe(&to_free, envvar.buf); if (!key) { ret = error(_("missing config key %s"), envvar.buf); @@ -747,7 +747,7 @@ int git_config_from_parameters(config_fn_t fn, void *data) } strbuf_reset(&envvar); - strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%d", i); + strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%lu", i); value = getenv_safe(&to_free, envvar.buf); if (!value) { ret = error(_("missing config value %s"), envvar.buf); @@ -1614,13 +1614,13 @@ int config_with_options(config_fn_t fn, void *data, static void configset_iter(struct config_set *set, config_fn_t fn, void *data) { - int i, value_index; + int value_index; struct string_list *values; struct config_set_element *entry; struct configset_list *list = &set->list; struct config_context ctx = CONFIG_CONTEXT_INIT; - for (i = 0; i < list->nr; i++) { + for (size_t i = 0; i < list->nr; i++) { entry = list->items[i].e; value_index = list->items[i].value_index; values = &entry->value_list; @@ -2470,10 +2470,11 @@ static ssize_t write_pair(int fd, const char *key, const char *value, */ static void maybe_remove_section(struct config_store_data *store, size_t *begin_offset, size_t *end_offset, - int *seen_ptr) + unsigned *seen_ptr) { size_t begin; - int i, seen, section_seen = 0; + int section_seen = 0; + unsigned int i, seen; /* * First, ensure that this is the first key, and that there are no @@ -2716,7 +2717,8 @@ int repo_config_set_multivar_in_file_gently(struct repository *r, } else { struct stat st; size_t copy_begin, copy_end; - int i, new_line = 0; + unsigned i; + int new_line = 0; struct config_options opts; if (!value_pattern) From 5345ca174597e733821f0aebd8ed59fa2edd3da3 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Fri, 25 Jul 2025 18:05:36 +0200 Subject: [PATCH 23/47] t9350: redirect input to only fast-import A number of tests in "t9350-fast-export.sh" are using sub-shells to redirect content to a number of commands instead of only `git fast-import`. This is confusing and possibly error-prone, so let's change those tests so that no sub-shell is used and the content goes only to `git fast-import`. Reported-by: Elijah Newren Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- t/t9350-fast-export.sh | 215 +++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 124 deletions(-) diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 46700dbc401734..8f85c69d62f17a 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -48,12 +48,11 @@ test_expect_success 'fast-export | fast-import' ' mkdir new && git --git-dir=new/.git init && git fast-export --all >actual && - (cd new && - git fast-import && - test $MAIN = $(git rev-parse --verify refs/heads/main) && - test $REIN = $(git rev-parse --verify refs/tags/rein) && - test $WER = $(git rev-parse --verify refs/heads/wer) && - test $MUSS = $(git rev-parse --verify refs/tags/muss)) actual && - sed "s/main/partial/" actual | - (cd new && - git fast-import && - test $MAIN != $(git rev-parse --verify refs/heads/partial) && - git diff --exit-code main partial && - git diff --exit-code main^ partial^ && - test_must_fail git rev-parse partial~2) + sed "s/main/partial/" actual | git -C new fast-import && + test $MAIN != $(git -C new rev-parse --verify refs/heads/partial) && + git -C new diff --exit-code main partial && + git -C new diff --exit-code main^ partial^ && + test_must_fail git -C new rev-parse partial~2 ' @@ -102,10 +99,8 @@ test_expect_success 'fast-export --reference-excluded-parents main~2..main' ' git fast-export --reference-excluded-parents main~2..main >actual && grep commit.refs/heads/main actual >commit-count && test_line_count = 2 commit-count && - sed "s/main/rewrite/" actual | - (cd new && - git fast-import && - test $MAIN = $(git rev-parse --verify refs/heads/rewrite)) + sed "s/main/rewrite/" actual | git -C new fast-import && + test $MAIN = $(git -C new rev-parse --verify refs/heads/rewrite) ' test_expect_success 'fast-export --show-original-ids' ' @@ -133,20 +128,19 @@ test_expect_success ICONV 'reencoding iso-8859-7' ' echo rosten >file && git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && git fast-export --reencode=yes wer^..wer >iso-8859-7.fi && - sed "s/wer/i18n/" iso-8859-7.fi | - (cd new && - git fast-import && - # The commit object, if not re-encoded, would be 200 bytes plus hash. - # Removing the "encoding iso-8859-7\n" header drops 20 bytes. - # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 - # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for - # the expected size. - test $(($(test_oid hexsz) + 181)) -eq "$(git cat-file -s i18n)" && - # ...and for the expected translation of bytes. - git cat-file commit i18n >actual && - grep $(printf "\317\200") actual && - # Also make sure the commit does not have the "encoding" header - ! grep ^encoding actual) + sed "s/wer/i18n/" iso-8859-7.fi | git -C new fast-import && + + # The commit object, if not re-encoded, would be 200 bytes plus hash. + # Removing the "encoding iso-8859-7\n" header drops 20 bytes. + # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 + # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for + # the expected size. + test $(($(test_oid hexsz) + 181)) -eq "$(git -C new cat-file -s i18n)" && + # ...and for the expected translation of bytes. + git -C new cat-file commit i18n >actual && + grep $(printf "\317\200") actual && + # Also make sure the commit does not have the "encoding" header + ! grep ^encoding actual ' test_expect_success 'aborting on iso-8859-7' ' @@ -165,20 +159,19 @@ test_expect_success 'preserving iso-8859-7' ' echo rosten >file && git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && git fast-export --reencode=no wer^..wer >iso-8859-7.fi && - sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | - (cd new && - git fast-import && - # The commit object, if not re-encoded, is 200 bytes plus hash. - # Removing the "encoding iso-8859-7\n" header would drops 20 - # bytes. Re-encoding the Pi character from \xF0 (\360) in - # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. - # Check for the expected size... - test $(($(test_oid hexsz) + 200)) -eq "$(git cat-file -s i18n-no-recoding)" && - # ...as well as the expected byte. - git cat-file commit i18n-no-recoding >actual && - grep $(printf "\360") actual && - # Also make sure the commit has the "encoding" header - grep ^encoding actual) + sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | git -C new fast-import && + + # The commit object, if not re-encoded, is 200 bytes plus hash. + # Removing the "encoding iso-8859-7\n" header would drops 20 + # bytes. Re-encoding the Pi character from \xF0 (\360) in + # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. + # Check for the expected size... + test $(($(test_oid hexsz) + 200)) -eq "$(git -C new cat-file -s i18n-no-recoding)" && + # ...as well as the expected byte. + git -C new cat-file commit i18n-no-recoding >actual && + grep $(printf "\360") actual && + # Also make sure the commit has the "encoding" header + grep ^encoding actual ' test_expect_success 'encoding preserved if reencoding fails' ' @@ -188,18 +181,17 @@ test_expect_success 'encoding preserved if reencoding fails' ' echo rosten >file && git commit -s -F "$TEST_DIRECTORY/t9350/broken-iso-8859-7-commit-message.txt" file && git fast-export --reencode=yes wer^..wer >iso-8859-7.fi && - sed "s/wer/i18n-invalid/" iso-8859-7.fi | - (cd new && - git fast-import && - git cat-file commit i18n-invalid >actual && - # Make sure the commit still has the encoding header - grep ^encoding actual && - # Verify that the commit has the expected size; i.e. - # that no bytes were re-encoded to a different encoding. - test $(($(test_oid hexsz) + 212)) -eq "$(git cat-file -s i18n-invalid)" && - # ...and check for the original special bytes - grep $(printf "\360") actual && - grep $(printf "\377") actual) + sed "s/wer/i18n-invalid/" iso-8859-7.fi | git -C new fast-import && + git -C new cat-file commit i18n-invalid >actual && + + # Make sure the commit still has the encoding header + grep ^encoding actual && + # Verify that the commit has the expected size; i.e. + # that no bytes were re-encoded to a different encoding. + test $(($(test_oid hexsz) + 212)) -eq "$(git -C new cat-file -s i18n-invalid)" && + # ...and check for the original special bytes + grep $(printf "\360") actual && + grep $(printf "\377") actual ' test_expect_success 'import/export-marks' ' @@ -316,12 +308,9 @@ test_expect_success GPG 'signed-commits=verbatim' ' git fast-export --signed-commits=verbatim --reencode=no commit-signing >output && test_grep -E "^gpgsig $GIT_DEFAULT_HASH openpgp" output && grep "encoding ISO-8859-1" output && - ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-signing) && - test $COMMIT_SIGNING = $STRIPPED - ) output && ! grep ^gpgsig output && grep "^encoding ISO-8859-1" output && - sed "s/commit-signing/commit-strip-signing/" output | ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-strip-signing) && - test $COMMIT_SIGNING != $STRIPPED - ) + sed "s/commit-signing/commit-strip-signing/" output | git -C new fast-import && + STRIPPED=$(git -C new rev-parse --verify refs/heads/commit-strip-signing) && + test $COMMIT_SIGNING != $STRIPPED ' @@ -360,12 +343,9 @@ test_expect_success GPG 'signed-commits=warn-strip' ' ! grep ^gpgsig output && grep "^encoding ISO-8859-1" output && test -s err && - sed "s/commit-signing/commit-strip-signing/" output | ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-strip-signing) && - test $COMMIT_SIGNING != $STRIPPED - ) + sed "s/commit-signing/commit-strip-signing/" output | git -C new fast-import && + STRIPPED=$(git -C new rev-parse --verify refs/heads/commit-strip-signing) && + test $COMMIT_SIGNING != $STRIPPED ' @@ -386,14 +366,11 @@ test_expect_success GPGSM 'round-trip X.509 signed commit' ' git fast-export --signed-commits=verbatim x509-signing >output && test_grep -E "^gpgsig $GIT_DEFAULT_HASH x509" output && - ( - cd new && - git fast-import && - git cat-file commit refs/heads/x509-signing >actual && - grep "^gpgsig" actual && - IMPORTED=$(git rev-parse refs/heads/x509-signing) && - test $X509_COMMIT = $IMPORTED - ) actual && + grep "^gpgsig" actual && + IMPORTED=$(git -C new rev-parse refs/heads/x509-signing) && + test $X509_COMMIT = $IMPORTED ' @@ -414,14 +391,11 @@ test_expect_success GPGSSH 'round-trip SSH signed commit' ' git fast-export --signed-commits=verbatim ssh-signing >output && test_grep -E "^gpgsig $GIT_DEFAULT_HASH ssh" output && - ( - cd new && - git fast-import && - git cat-file commit refs/heads/ssh-signing >actual && - grep "^gpgsig" actual && - IMPORTED=$(git rev-parse refs/heads/ssh-signing) && - test $SSH_COMMIT = $IMPORTED - ) actual && + grep "^gpgsig" actual && + IMPORTED=$(git -C new rev-parse refs/heads/ssh-signing) && + test $SSH_COMMIT = $IMPORTED ' @@ -461,14 +435,13 @@ test_expect_success 'submodule fast-export | fast-import' ' mkdir new && git --git-dir=new/.git init && git fast-export --signed-tags=strip --all >actual && - (cd new && - git fast-import && - test "$SUBENT1" = "$(git ls-tree refs/heads/main^ sub)" && - test "$SUBENT2" = "$(git ls-tree refs/heads/main sub)" && - git checkout main && - git submodule init && - git submodule update && - cmp sub/file ../sub/file) output && grep "^C file2 file4\$" output && - cat output | - (cd new && - git fast-import && - test $ENTRY = $(git rev-parse --verify refs/heads/copy)) + git -C new fast-import output && test_grep -E "^gpgsig sha1 openpgp" output && test_grep -E "^gpgsig sha256 openpgp" output && - - ( - cd new && - git fast-import && - git cat-file commit refs/heads/dual-signed >actual && - test_grep -E "^gpgsig " actual && - test_grep -E "^gpgsig-sha256 " actual && - IMPORTED=$(git rev-parse refs/heads/dual-signed) && - if test "$GIT_DEFAULT_HASH" = "sha1" - then - test $SHA1_B = $IMPORTED - else - test $SHA256_B = $IMPORTED - fi - ) actual && + test_grep -E "^gpgsig " actual && + test_grep -E "^gpgsig-sha256 " actual && + IMPORTED=$(git -C new rev-parse refs/heads/dual-signed) && + if test "$GIT_DEFAULT_HASH" = "sha1" + then + test $SHA1_B = $IMPORTED + else + test $SHA256_B = $IMPORTED + fi ' test_done From 65855751d190d66d15bc2c7e17e93fe00d04c539 Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Mon, 28 Jul 2025 22:20:46 +0200 Subject: [PATCH 24/47] ref-cache: use 'size_t' instead of int for length The commit 090eb5336c (refs: selectively set prefix in the seek functions, 2025-07-15) modified the ref-cache iterator to support seeking to a specified marker without setting the prefix. The commit adds and uses an integer 'len' to capture the length of the seek marker to compare with the entries of a given directory. Since the type of the variable is 'int', this is met with a typecast of converting a `strlen` to 'int' so it can be assigned to the 'len' variable. This is whole operation is a bit wrong: 1. Since the 'len' variable is eventually used in a 'strncmp', it should have been of type 'size_t'. 2. This also truncates the value provided from 'strlen' to an int, which could cause a large refname to produce a negative number. Let's do the correct thing here and simply use 'size_t' for `len`. Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- refs/ref-cache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/refs/ref-cache.c b/refs/ref-cache.c index ceef3a20088267..c180e0aad74e87 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -498,13 +498,14 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator, * indexing to each level as needed. */ do { - int len, idx; + int idx; + size_t len; int cmp = 0; sort_ref_dir(dir); slash = strchr(slash, '/'); - len = slash ? slash - refname : (int)strlen(refname); + len = slash ? (size_t)(slash - refname) : strlen(refname); for (idx = 0; idx < dir->nr; idx++) { cmp = strncmp(refname, dir->entries[idx]->name, len); From a7c8a4c5f5bbe6c232c8aefc02499fe1c0b6d221 Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Mon, 28 Jul 2025 22:20:47 +0200 Subject: [PATCH 25/47] for-each-ref: fix documentation argument ordering Improve the 'git-for-each-ref(1)' documentation with two corrections: 1. Add parentheses around `--exclude=` to indicate this option can be repeated as a complete unit. 2. Move `--stdin | ...` to the end, after all flags, since `` is a positional argument that should appear last in the argument list. While here, change to using the synopsis block which will automatically format placeholders in italics and keywords in monospace. Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- Documentation/git-for-each-ref.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/git-for-each-ref.adoc b/Documentation/git-for-each-ref.adoc index ae61ba642a6389..ec3b10e14a29c2 100644 --- a/Documentation/git-for-each-ref.adoc +++ b/Documentation/git-for-each-ref.adoc @@ -7,14 +7,14 @@ git-for-each-ref - Output information on each ref SYNOPSIS -------- -[verse] -'git for-each-ref' [--count=] [--shell|--perl|--python|--tcl] +[synopsis] +git for-each-ref [--count=] [--shell|--perl|--python|--tcl] [(--sort=)...] [--format=] - [--include-root-refs] [ --stdin | ... ] - [--points-at=] + [--include-root-refs] [--points-at=] [--merged[=]] [--no-merged[=]] [--contains[=]] [--no-contains[=]] - [--exclude= ...] [--start-after=] + [(--exclude=)...] [--start-after=] + [ --stdin | ... ] DESCRIPTION ----------- From fa0f4e46f5db22d0be63e66228d5f27fa1cb7ee6 Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Mon, 28 Jul 2025 22:20:48 +0200 Subject: [PATCH 26/47] for-each-ref: reword the documentation for '--start-after' The documentation for '--start-after' states that the flag cannot be used with general pattern matching. This is a bit vague, since there is no clear understanding about what 'general' means here. Rewrite the sentence to be more specific. While here, fix a typo in the 'OPT_STRING'. Helped-by: Junio C Hamano Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- Documentation/git-for-each-ref.adoc | 3 ++- builtin/for-each-ref.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/git-for-each-ref.adoc b/Documentation/git-for-each-ref.adoc index ec3b10e14a29c2..060940904da21c 100644 --- a/Documentation/git-for-each-ref.adoc +++ b/Documentation/git-for-each-ref.adoc @@ -114,7 +114,8 @@ TAB %(refname)`. deleted, modified or added between invocations. Output will only yield those references which follow the marker lexicographically. Output begins from the first reference that would come after the marker alphabetically. Cannot be - used with general pattern matching or custom sort options. + used with `--sort=` or `--stdin` options, or the __ argument(s) + to limit the refs. FIELD NAMES ----------- diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 3f21598046a758..79a79212c927ef 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -45,7 +45,7 @@ int cmd_for_each_ref(int argc, OPT_GROUP(""), OPT_INTEGER( 0 , "count", &format.array_opts.max_count, N_("show only matched refs")), OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")), - OPT_STRING( 0 , "start-after", &filter.start_after, N_("start-start"), N_("start iteration after the provided marker")), + OPT_STRING( 0 , "start-after", &filter.start_after, N_("start-after"), N_("start iteration after the provided marker")), OPT__COLOR(&format.use_color, N_("respect format colors")), OPT_REF_FILTER_EXCLUDE(&filter), OPT_REF_SORT(&sorting_options), From ed9cc2144c97b3ad609d71b6033a95079179fc0e Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Mon, 28 Jul 2025 22:20:49 +0200 Subject: [PATCH 27/47] t6302: add test combining '--start-after' with '--exclude' The '--start-after' doesn't explicitly mention being compatible with the '--exclude' flag, generally only incompatibility is explicitly called out. However, it would be nice to test the compatibility between the two to avoid future regressions. Let's do that. Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- t/t6302-for-each-ref-filter.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index e097db6b02f0c4..9b80ea1e3b7414 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -712,6 +712,25 @@ test_expect_success 'start after, overflow specific reference path' ' test_cmp expect actual ' +test_expect_success 'start after, with exclude pattern' ' + cat >expect <<-\EOF && + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/spot \ + --exclude=refs/tags/foo >actual && + test_cmp expect actual +' + test_expect_success 'start after, last reference' ' cat >expect <<-\EOF && EOF From 444ad14e02edc59e61f7d53ae3b9f8ebe90860fd Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Mon, 28 Jul 2025 22:20:50 +0200 Subject: [PATCH 28/47] ref-filter: use REF_ITERATOR_SEEK_SET_PREFIX instead of '1' In the commit 51511d68f4 (for-each-ref: introduce a '--start-after' option, 2025-07-15), for introducing the '--start-after' flag, the `ref_iterator_seek()` was modified to also accept a flag. This was to allow the function to also set the prefix when 'REF_ITERATOR_SEEK_SET_PREFIX' was set. In `do_filter_refs()` instead of passing the flag, we pass in '1' which is the value of the flag. While this works, this is definitely hard to read and introduces inconsistency. Change it to use the flag. While here, remove the unnecessary 'if (prefix)' clause in the 'else' statement, since the block already checks for 'prefix'. Reported-by: Junio C Hamano Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- ref-filter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index c8a6b7f1aff470..62ffdcdcad7453 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -3254,8 +3254,9 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref if (filter->start_after) ret = start_ref_iterator_after(iter, filter->start_after); - else if (prefix) - ret = ref_iterator_seek(iter, prefix, 1); + else + ret = ref_iterator_seek(iter, prefix, + REF_ITERATOR_SEEK_SET_PREFIX); if (!ret) ret = do_for_each_ref_iterator(iter, fn, cb_data); From f609dc4f7a7cc8b57435696cac1cd0b056f9e8b9 Mon Sep 17 00:00:00 2001 From: Justin Tobler Date: Mon, 28 Jul 2025 14:42:18 -0500 Subject: [PATCH 29/47] builtin: unmark git-switch and git-restore as experimental In 4e43b7ff (Declare both git-switch and git-restore experimental, 2019-04-25), the newly introduced git-switch(1) and git-restore(1) commands were marked as experimental. This was done to provide time to make breaking changes to the interface. It has now been over six years since these commands were implemented and there hasn't been much change. Consequently, users have grown to rely on how these commands work and it is no longer feasible to make any breaking changes. Let's remove the experimental label for git-switch(1) and git-restore(1). Signed-off-by: Justin Tobler Signed-off-by: Junio C Hamano --- Documentation/git-restore.adoc | 2 -- Documentation/git-switch.adoc | 2 -- 2 files changed, 4 deletions(-) diff --git a/Documentation/git-restore.adoc b/Documentation/git-restore.adoc index 877b7772e66735..3763a7f4f435a4 100644 --- a/Documentation/git-restore.adoc +++ b/Documentation/git-restore.adoc @@ -28,8 +28,6 @@ otherwise from the index. Use `--source` to restore from a different commit. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. -THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. - OPTIONS ------- `-s `:: diff --git a/Documentation/git-switch.adoc b/Documentation/git-switch.adoc index 9f62abf9e2b89a..87707e92652064 100644 --- a/Documentation/git-switch.adoc +++ b/Documentation/git-switch.adoc @@ -29,8 +29,6 @@ Switching branches does not require a clean index and working tree however if the operation leads to loss of local changes, unless told otherwise with `--discard-changes` or `--merge`. -THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. - OPTIONS ------- __:: From 7e2943128e8aad1b409828e72905d6c63c9f748d Mon Sep 17 00:00:00 2001 From: Han Young Date: Mon, 28 Jul 2025 11:55:48 +0800 Subject: [PATCH 30/47] blame: remove parameter detailed in get_commit_info() The get_commit_info() function accepts a parameter that can be used to stop the commit parsing early. However, none of the callers use this feature, and testing proved that the performance gain of stopping parsing early is negligible and unmeasurable. Signed-off-by: Han Young Signed-off-by: Junio C Hamano --- builtin/blame.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index 91586e6852b09e..dc934abef40215 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -197,9 +197,7 @@ static void commit_info_destroy(struct commit_info *ci) strbuf_release(&ci->summary); } -static void get_commit_info(struct commit *commit, - struct commit_info *ret, - int detailed) +static void get_commit_info(struct commit *commit, struct commit_info *ret) { int len; const char *subject, *encoding; @@ -211,11 +209,6 @@ static void get_commit_info(struct commit *commit, &ret->author, &ret->author_mail, &ret->author_time, &ret->author_tz); - if (!detailed) { - repo_unuse_commit_buffer(the_repository, commit, message); - return; - } - get_ac_line(message, "\ncommitter ", &ret->committer, &ret->committer_mail, &ret->committer_time, &ret->committer_tz); @@ -263,7 +256,7 @@ static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat) return 0; suspect->commit->object.flags |= METAINFO_SHOWN; - get_commit_info(suspect->commit, &ci, 1); + get_commit_info(suspect->commit, &ci); printf("author %s\n", ci.author.buf); printf("author-mail %s\n", ci.author_mail.buf); printf("author-time %"PRItime"\n", ci.author_time); @@ -471,7 +464,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP); const char *default_color = NULL, *color = NULL, *reset = NULL; - get_commit_info(suspect->commit, &ci, 1); + get_commit_info(suspect->commit, &ci); oid_to_hex_r(hex, &suspect->commit->object.oid); cp = blame_nth_line(sb, ent->lno); @@ -665,7 +658,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option) if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { struct commit_info ci = COMMIT_INFO_INIT; suspect->commit->object.flags |= METAINFO_SHOWN; - get_commit_info(suspect->commit, &ci, 1); + get_commit_info(suspect->commit, &ci); if (*option & OUTPUT_SHOW_EMAIL) num = utf8_strwidth(ci.author_mail.buf); else From c26ecaf069080c6f9f98925530394a5b4c53e325 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 25 Jul 2025 01:13:09 -0400 Subject: [PATCH 31/47] t7510: use $PWD instead of $(pwd) inside PATH On Windows, $(pwd) will give us a Windows-style path like "D:/foo". Putting that into $PATH confuses anybody parsing that variable, since colon is a separator character in $PATH. Instead, we should use the Unix-style value we get from $PWD ("/d/foo"). This is similar to the cases fixed by 71dd50472d (t0021, t5615: use $PWD instead of $(pwd) in PATH-like shell variables, 2016-11-11). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t7510-signed-commit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 95d2ebe27793f0..1201c85ba62af8 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -458,7 +458,7 @@ test_expect_success 'custom `gpg.program`' ' # `gpg.program` does not specify an absolute path, it should find a program in `$PATH` test_config gpg.program "fake-gpg" && - env PATH="$(pwd):$PATH" \ + env PATH="$PWD:$PATH" \ git commit -S --allow-empty -m signed-commit ' From 5247da07b87ab16e57f67f3071db98c0263c40dd Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 29 Jul 2025 16:10:11 +0200 Subject: [PATCH 32/47] meson: ensure correct "clar-decls.h" header is used The "clar-decls.h" header gets generated by us to extract prototypes of unit test functions from our clar-based tests. This generated file is then written into "t/unit-tests/" and included via "unit-test.h". The intent of all this is that we can keep "-Wmissing-prototype" warnings enabled. If we had that warning disabled, it would be easy to miss in case any of the non-static functions had a typo in its name and thus wasn't picked up by our test case extractor. Including the file directly has a big downside though: if a source tree was built both with our Makefile and with Meson, then the Meson build would include the "clar-decls.h" file from our Makefile. And if those are out of sync we get compiler errors. We already fixed a similar issue in 4771501c0a (meson: ensure correct version-def.h is used, 2025-01-14). Let's do the same and pass the absolute path to "clar-decls.h" via a preprocessor define. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- t/meson.build | 3 +++ t/unit-tests/unit-test.h | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/t/meson.build b/t/meson.build index d052fc3e23d2ec..181b5ec1e97dd9 100644 --- a/t/meson.build +++ b/t/meson.build @@ -49,6 +49,9 @@ clar_sources += custom_target( clar_unit_tests = executable('unit-tests', sources: clar_sources + clar_test_suites, + c_args: [ + '-DGIT_CLAR_DECLS_H="' + clar_decls_h.full_path() + '"', + ], dependencies: [libgit_commonmain], ) test('unit-tests', clar_unit_tests) diff --git a/t/unit-tests/unit-test.h b/t/unit-tests/unit-test.h index 85e5d6a948acf9..39a0b72a05dec3 100644 --- a/t/unit-tests/unit-test.h +++ b/t/unit-tests/unit-test.h @@ -1,8 +1,13 @@ #include "git-compat-util.h" #include "clar/clar.h" -#include "clar-decls.h" #include "strbuf.h" +#ifndef GIT_CLAR_DECLS_H +# include "clar-decls.h" +#else +# include GIT_CLAR_DECLS_H +#endif + #define cl_failf(fmt, ...) do { \ char desc[4096]; \ snprintf(desc, sizeof(desc), fmt, __VA_ARGS__); \ From 671b28394d3d3af645752afec3e6a447ee075172 Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Tue, 29 Jul 2025 07:01:48 +0000 Subject: [PATCH 33/47] t: use test_grep in t3701 and t4055 As a preparatory clean-up, use the "test_grep" test utility instead of regular "grep" which provides better debug information if tests fail. Signed-off-by: Leon Michalak Signed-off-by: Junio C Hamano --- t/t3701-add-interactive.sh | 48 +++++++++++++++++++------------------- t/t4055-diff-context.sh | 28 +++++++++++----------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b8a05d95f3f130..b088ee141ff4d5 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -63,7 +63,7 @@ test_expect_success 'setup (initial)' ' ' test_expect_success 'status works (initial)' ' git add -i output && - grep "+1/-0 *+2/-0 file" output + test_grep "+1/-0 *+2/-0 file" output ' test_expect_success 'setup expected' ' @@ -86,7 +86,7 @@ test_expect_success 'revert works (initial)' ' git add file && test_write_lines r 1 | git add -i && git ls-files >output && - ! grep . output + test_grep ! . output ' test_expect_success 'add untracked (multiple)' ' @@ -109,7 +109,7 @@ test_expect_success 'setup (commit)' ' ' test_expect_success 'status works (commit)' ' git add -i output && - grep "+1/-0 *+2/-0 file" output + test_grep "+1/-0 *+2/-0 file" output ' test_expect_success 'update can stage deletions' ' @@ -141,7 +141,7 @@ test_expect_success 'revert works (commit)' ' git add file && test_write_lines r 1 | git add -i && git add -i output && - grep "unchanged *+3/-0 file" output + test_grep "unchanged *+3/-0 file" output ' test_expect_success 'reject multi-key input' ' @@ -185,7 +185,7 @@ test_expect_success 'setup fake editor' ' test_expect_success 'bad edit rejected' ' git reset && test_write_lines e n d | git add -p >output && - grep "hunk does not apply" output + test_grep "hunk does not apply" output ' test_expect_success 'setup patch' ' @@ -198,7 +198,7 @@ test_expect_success 'setup patch' ' test_expect_success 'garbage edit rejected' ' git reset && test_write_lines e n d | git add -p >output && - grep "hunk does not apply" output + test_grep "hunk does not apply" output ' test_expect_success 'setup patch' ' @@ -313,8 +313,8 @@ test_expect_success FILEMODE 'stage mode and hunk' ' chmod +x file && printf "y\\ny\\n" | git add -p && git diff --cached file >out && - grep "new mode" out && - grep "+content" out && + test_grep "new mode" out && + test_grep "+content" out && git diff file >out && test_must_be_empty out ' @@ -636,7 +636,7 @@ test_expect_success 'split hunk "add -p (edit)"' ' printf "%s\n" s e q n q q | EDITOR=: git add -p && git diff >actual && - ! grep "^+15" actual + test_grep ! "^+15" actual ' test_expect_success 'split hunk "add -p (no, yes, edit)"' ' @@ -648,7 +648,7 @@ test_expect_success 'split hunk "add -p (no, yes, edit)"' ' EDITOR=: git add -p 2>error && test_must_be_empty error && git diff >actual && - ! grep "^+31" actual + test_grep ! "^+31" actual ' test_expect_success 'split hunk with incomplete line at end' ' @@ -682,7 +682,7 @@ test_expect_success 'edit, adding lines to the first hunk' ' EDITOR=./fake_editor.sh git add -p 2>error && test_must_be_empty error && git diff --cached >actual && - grep "^+22" actual + test_grep "^+22" actual ' test_expect_success 'patch mode ignores unmerged entries' ' @@ -696,7 +696,7 @@ test_expect_success 'patch mode ignores unmerged entries' ' test_must_fail git merge side && echo changed >non-conflict.t && echo y | git add -p >output && - ! grep a/conflict.t output && + test_grep ! a/conflict.t output && cat >expected <<-\EOF && * Unmerged path conflict.t diff --git a/non-conflict.t b/non-conflict.t @@ -728,7 +728,7 @@ test_expect_success 'diffs can be colorized' ' # We do not want to depend on the exact coloring scheme # git uses for diffs, so just check that we saw some kind of color. - grep "$(printf "\\033")" output + test_grep "$(printf "\\033")" output ' test_expect_success 'colors can be overridden' ' @@ -743,7 +743,7 @@ test_expect_success 'colors can be overridden' ' -c color.interactive.error=blue \ add -i 2>err.raw err && - grep "Huh (trigger)?" err && + test_grep "Huh (trigger)?" err && test_write_lines help quit >input && force_color git \ @@ -863,7 +863,7 @@ test_expect_success 'colorized diffs respect diff.wsErrorHighlight' ' printf y >y && force_color git -c diff.wsErrorHighlight=all add -p >output.raw 2>&1 output && - grep "old<" output + test_grep "old<" output ' test_expect_success 'diffFilter filters diff' ' @@ -876,7 +876,7 @@ test_expect_success 'diffFilter filters diff' ' # avoid depending on the exact coloring or content of the prompts, # and just make sure we saw our diff prefixed - grep foo:.*content output + test_grep foo:.*content output ' test_expect_success 'detect bogus diffFilter output' ' @@ -886,7 +886,7 @@ test_expect_success 'detect bogus diffFilter output' ' test_config interactive.diffFilter "sed 6d" && printf y >y && force_color test_must_fail git add -p output 2>&1 && - grep "mismatched output" output + test_grep "mismatched output" output ' test_expect_success 'handle iffy colored hunk headers' ' @@ -896,7 +896,7 @@ test_expect_success 'handle iffy colored hunk headers' ' printf n >n && force_color git -c interactive.diffFilter="sed s/.*@@.*/XX/" \ add -p >output 2>&1 output && - grep dirty-head output && - grep dirty-both-ways output && - ! grep dirty-otherwise output + test_grep dirty-head output && + test_grep dirty-both-ways output && + test_grep ! dirty-otherwise output ' test_expect_success 'handle submodules' ' echo 123 >>for-submodules/dirty-otherwise/initial.t && force_color git -C for-submodules add -p dirty-otherwise >output 2>&1 && - grep "No changes" output && + test_grep "No changes" output && force_color git -C for-submodules add -p dirty-head >output 2>&1 actual && rev="$(git -C for-submodules/dirty-head rev-parse HEAD)" && - grep "$rev" actual + test_grep "$rev" actual ' test_expect_success 'set up pathological context' ' diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index ec2804eea67cf1..c66f966a3ab324 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -38,36 +38,36 @@ test_expect_success 'setup' ' test_expect_success 'the default number of context lines is 3' ' git diff >output && - ! grep "^ d" output && - grep "^ e" output && - grep "^ j" output && - ! grep "^ k" output + test_grep ! "^ d" output && + test_grep "^ e" output && + test_grep "^ j" output && + test_grep ! "^ k" output ' test_expect_success 'diff.context honored by "log"' ' git log -1 -p >output && - ! grep firstline output && + test_grep ! firstline output && git config diff.context 8 && git log -1 -p >output && - grep "^ firstline" output + test_grep "^ firstline" output ' test_expect_success 'The -U option overrides diff.context' ' git config diff.context 8 && git log -U4 -1 >output && - ! grep "^ firstline" output + test_grep ! "^ firstline" output ' test_expect_success 'diff.context honored by "diff"' ' git config diff.context 8 && git diff >output && - grep "^ firstline" output + test_grep "^ firstline" output ' test_expect_success 'plumbing not affected' ' git config diff.context 8 && git diff-files -p >output && - ! grep "^ firstline" output + test_grep ! "^ firstline" output ' test_expect_success 'non-integer config parsing' ' @@ -85,8 +85,8 @@ test_expect_success 'negative integer config parsing' ' test_expect_success '-U0 is valid, so is diff.context=0' ' git config diff.context 0 && git diff >output && - grep "^-ADDED" output && - grep "^+MODIFIED" output + test_grep "^-ADDED" output && + test_grep "^+MODIFIED" output ' test_expect_success '-U2147483647 works' ' @@ -94,9 +94,9 @@ test_expect_success '-U2147483647 works' ' test_line_count = 16 x && git diff -U2147483647 >output && test_line_count = 22 output && - grep "^-ADDED" output && - grep "^+MODIFIED" output && - grep "^+APPENDED" output + test_grep "^-ADDED" output && + test_grep "^+MODIFIED" output && + test_grep "^+APPENDED" output ' test_done From 97b99a9eb6b3fec7ff46ab68af423b9a08d5a264 Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Tue, 29 Jul 2025 07:01:49 +0000 Subject: [PATCH 34/47] t: use test_config in t4055 Use the modern "test_config" test utility instead of manual"git config" as the former provides clean up on test completion. This is a prerequisite to the commits that follow which add to this test file. Signed-off-by: Leon Michalak Signed-off-by: Junio C Hamano --- t/t4055-diff-context.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index c66f966a3ab324..1384a8195705e3 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -47,43 +47,43 @@ test_expect_success 'the default number of context lines is 3' ' test_expect_success 'diff.context honored by "log"' ' git log -1 -p >output && test_grep ! firstline output && - git config diff.context 8 && + test_config diff.context 8 && git log -1 -p >output && test_grep "^ firstline" output ' test_expect_success 'The -U option overrides diff.context' ' - git config diff.context 8 && + test_config diff.context 8 && git log -U4 -1 >output && test_grep ! "^ firstline" output ' test_expect_success 'diff.context honored by "diff"' ' - git config diff.context 8 && + test_config diff.context 8 && git diff >output && test_grep "^ firstline" output ' test_expect_success 'plumbing not affected' ' - git config diff.context 8 && + test_config diff.context 8 && git diff-files -p >output && test_grep ! "^ firstline" output ' test_expect_success 'non-integer config parsing' ' - git config diff.context no && + test_config diff.context no && test_must_fail git diff 2>output && test_grep "bad numeric config value" output ' test_expect_success 'negative integer config parsing' ' - git config diff.context -1 && + test_config diff.context -1 && test_must_fail git diff 2>output && test_grep "bad config variable" output ' test_expect_success '-U0 is valid, so is diff.context=0' ' - git config diff.context 0 && + test_config diff.context 0 && git diff >output && test_grep "^-ADDED" output && test_grep "^+MODIFIED" output From 2b0a2db2c0bf4870592656e8f50876957db8660c Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Tue, 29 Jul 2025 07:01:50 +0000 Subject: [PATCH 35/47] add-patch: respect diff.context configuration Various builtins that use add-patch infrastructure do not respect the user's diff.context and diff.interHunkContext file configurations. The user may be used to seeing their diffs with customized context size, but not in the patches "git add -p" shows them to pick from. Teach add-patch infrastructure to read these configuration variables and pass their values when spawning the underlying plumbing commands as their command line option. Signed-off-by: Leon Michalak Signed-off-by: Junio C Hamano --- add-interactive.c | 9 +++++++++ add-interactive.h | 1 + add-patch.c | 9 ++++++--- t/t3701-add-interactive.sh | 22 ++++++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/add-interactive.c b/add-interactive.c index 97ff35b6f12a32..eb3d0d3ada8427 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -41,6 +41,8 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) const char *value; s->r = r; + s->context = -1; + s->interhunkcontext = -1; if (repo_config_get_value(r, "color.interactive", &value)) s->use_color = -1; @@ -78,6 +80,13 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) repo_config_get_string(r, "diff.algorithm", &s->interactive_diff_algorithm); + if (!repo_config_get_int(r, "diff.context", &s->context)) + if (s->context < 0) + die(_("%s cannot be negative"), "diff.context"); + if (!repo_config_get_int(r, "diff.interHunkContext", &s->interhunkcontext)) + if (s->interhunkcontext < 0) + die(_("%s cannot be negative"), "diff.interHunkContext"); + repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key); if (s->use_single_key) setbuf(stdin, NULL); diff --git a/add-interactive.h b/add-interactive.h index 693f125e8e4bc6..c63f35b14be868 100644 --- a/add-interactive.h +++ b/add-interactive.h @@ -18,6 +18,7 @@ struct add_i_state { int use_single_key; char *interactive_diff_filter, *interactive_diff_algorithm; + int context, interhunkcontext; }; void init_add_i_state(struct add_i_state *s, struct repository *r); diff --git a/add-patch.c b/add-patch.c index 95c67d8c80c4f3..b0125b51ba45e0 100644 --- a/add-patch.c +++ b/add-patch.c @@ -414,7 +414,6 @@ static int normalize_marker(const char *p) static int parse_diff(struct add_p_state *s, const struct pathspec *ps) { struct strvec args = STRVEC_INIT; - const char *diff_algorithm = s->s.interactive_diff_algorithm; struct strbuf *plain = &s->plain, *colored = NULL; struct child_process cp = CHILD_PROCESS_INIT; char *p, *pend, *colored_p = NULL, *colored_pend = NULL, marker = '\0'; @@ -424,8 +423,12 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) int res; strvec_pushv(&args, s->mode->diff_cmd); - if (diff_algorithm) - strvec_pushf(&args, "--diff-algorithm=%s", diff_algorithm); + if (s->s.context != -1) + strvec_pushf(&args, "--unified=%i", s->s.context); + if (s->s.interhunkcontext != -1) + strvec_pushf(&args, "--inter-hunk-context=%i", s->s.interhunkcontext); + if (s->s.interactive_diff_algorithm) + strvec_pushf(&args, "--diff-algorithm=%s", s->s.interactive_diff_algorithm); if (s->revision) { struct object_id oid; strvec_push(&args, diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b088ee141ff4d5..18dc329ea1f697 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -1230,4 +1230,26 @@ test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' ' test_cmp expect actual ' +test_expect_success 'add -p respects diff.context' ' + test_write_lines a b c d e f g h i j k l m >file && + git add file && + test_write_lines a b c d e f G h i j k l m >file && + echo y | git -c diff.context=5 add -p >actual && + test_grep "@@ -2,11 +2,11 @@" actual +' + +test_expect_success 'add -p respects diff.interHunkContext' ' + test_write_lines a b c d e f g h i j k l m n o p q r s >file && + git add file && + test_write_lines a b c d E f g i i j k l m N o p q r s >file && + echo y | git -c diff.interhunkcontext=2 add -p >actual && + test_grep "@@ -2,16 +2,16 @@" actual +' + +test_expect_success 'add -p rejects negative diff.context' ' + test_config diff.context -1 && + test_must_fail git add -p 2>output && + test_grep "diff.context cannot be negative" output +' + test_done From 2b3ae04011c3d679ba601c7ef9e20b9dec125ebb Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Tue, 29 Jul 2025 07:01:51 +0000 Subject: [PATCH 36/47] add-patch: add diff.context command line overrides This patch compliments the previous commit, where builtins that use add-patch infrastructure now respect diff.context and diff.interHunkContext file configurations. In particular, this patch helps users who don't want to set persistent context configurations or just want a way to override them on a one-time basis, by allowing the relevant builtins to accept corresponding command line options that override the file configurations. This mimics commands such as diff and log, which allow for both context file configuration and command line overrides. Signed-off-by: Leon Michalak Signed-off-by: Junio C Hamano --- Documentation/diff-context-options.adoc | 10 +++++ Documentation/git-add.adoc | 2 + Documentation/git-checkout.adoc | 2 + Documentation/git-commit.adoc | 2 + Documentation/git-reset.adoc | 2 + Documentation/git-restore.adoc | 2 + Documentation/git-stash.adoc | 2 + add-interactive.c | 36 ++++++++++++---- add-interactive.h | 16 +++++-- add-patch.c | 5 ++- builtin/add.c | 21 ++++++++-- builtin/checkout.c | 31 ++++++++++++-- builtin/commit.c | 16 ++++++- builtin/reset.c | 17 +++++++- builtin/stash.c | 56 ++++++++++++++++++++----- commit.h | 3 +- parse-options.h | 2 + t/t3701-add-interactive.sh | 49 ++++++++++++++++++++++ t/t9902-completion.sh | 2 + 19 files changed, 241 insertions(+), 35 deletions(-) create mode 100644 Documentation/diff-context-options.adoc diff --git a/Documentation/diff-context-options.adoc b/Documentation/diff-context-options.adoc new file mode 100644 index 00000000000000..e161260358fff5 --- /dev/null +++ b/Documentation/diff-context-options.adoc @@ -0,0 +1,10 @@ +`-U`:: +`--unified=`:: + Generate diffs with __ lines of context. Defaults to `diff.context` + or 3 if the config option is unset. + +`--inter-hunk-context=`:: + Show the context between diff hunks, up to the specified __ + of lines, thereby fusing hunks that are close to each other. + Defaults to `diff.interHunkContext` or 0 if the config option + is unset. diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc index eba0b419ce508f..b7a735824d6ce0 100644 --- a/Documentation/git-add.adoc +++ b/Documentation/git-add.adoc @@ -104,6 +104,8 @@ This effectively runs `add --interactive`, but bypasses the initial command menu and directly jumps to the `patch` subcommand. See ``Interactive mode'' for details. +include::diff-context-options.adoc[] + `-e`:: `--edit`:: Open the diff vs. the index in an editor and let the user diff --git a/Documentation/git-checkout.adoc b/Documentation/git-checkout.adoc index ee83b6d9ba9a9b..40e02cfd6562ae 100644 --- a/Documentation/git-checkout.adoc +++ b/Documentation/git-checkout.adoc @@ -289,6 +289,8 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode. Note that this option uses the no overlay mode by default (see also `--overlay`), and currently doesn't support overlay mode. +include::diff-context-options.adoc[] + `--ignore-other-worktrees`:: `git checkout` refuses when the wanted branch is already checked out or otherwise in use by another worktree. This option makes diff --git a/Documentation/git-commit.adoc b/Documentation/git-commit.adoc index dc219025f1eb0b..ae988a883b5b86 100644 --- a/Documentation/git-commit.adoc +++ b/Documentation/git-commit.adoc @@ -76,6 +76,8 @@ OPTIONS which changes to commit. See linkgit:git-add[1] for details. +include::diff-context-options.adoc[] + `-C `:: `--reuse-message=`:: Take an existing __ object, and reuse the log message diff --git a/Documentation/git-reset.adoc b/Documentation/git-reset.adoc index 53ab88c5451c44..50e8a0ba6f6612 100644 --- a/Documentation/git-reset.adoc +++ b/Documentation/git-reset.adoc @@ -125,6 +125,8 @@ OPTIONS separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). +include::diff-context-options.adoc[] + `--`:: Do not interpret any more arguments as options. diff --git a/Documentation/git-restore.adoc b/Documentation/git-restore.adoc index 877b7772e66735..1dcc2bb7aea387 100644 --- a/Documentation/git-restore.adoc +++ b/Documentation/git-restore.adoc @@ -52,6 +52,8 @@ leave out at most one of ___ and __, in which case it defaults to Mode" section of linkgit:git-add[1] to learn how to operate the `--patch` mode. +include::diff-context-options.adoc[] + `-W`:: `--worktree`:: `-S`:: diff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc index 1a5177f4986ca4..0578c619c410c6 100644 --- a/Documentation/git-stash.adoc +++ b/Documentation/git-stash.adoc @@ -208,6 +208,8 @@ to learn how to operate the `--patch` mode. The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. +include::diff-context-options.adoc[] + -S:: --staged:: This option is only valid for `push` and `save` commands. diff --git a/add-interactive.c b/add-interactive.c index eb3d0d3ada8427..3e692b47eca0a3 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -36,7 +36,8 @@ static void init_color(struct repository *r, struct add_i_state *s, free(key); } -void init_add_i_state(struct add_i_state *s, struct repository *r) +void init_add_i_state(struct add_i_state *s, struct repository *r, + struct add_p_opt *add_p_opt) { const char *value; @@ -90,6 +91,17 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key); if (s->use_single_key) setbuf(stdin, NULL); + + if (add_p_opt->context != -1) { + if (add_p_opt->context < 0) + die(_("%s cannot be negative"), "--unified"); + s->context = add_p_opt->context; + } + if (add_p_opt->interhunkcontext != -1) { + if (add_p_opt->interhunkcontext < 0) + die(_("%s cannot be negative"), "--inter-hunk-context"); + s->interhunkcontext = add_p_opt->interhunkcontext; + } } void clear_add_i_state(struct add_i_state *s) @@ -978,6 +990,10 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, opts->prompt = N_("Patch update"); count = list_and_choose(s, files, opts); if (count > 0) { + struct add_p_opt add_p_opt = { + .context = s->context, + .interhunkcontext = s->interhunkcontext, + }; struct strvec args = STRVEC_INIT; struct pathspec ps_selected = { 0 }; @@ -988,7 +1004,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, parse_pathspec(&ps_selected, PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL, PATHSPEC_LITERAL_PATH, "", args.v); - res = run_add_p(s->r, ADD_P_ADD, NULL, &ps_selected); + res = run_add_p(s->r, ADD_P_ADD, &add_p_opt, NULL, &ps_selected); strvec_clear(&args); clear_pathspec(&ps_selected); } @@ -1023,10 +1039,13 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps, if (count > 0) { struct child_process cmd = CHILD_PROCESS_INIT; - strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", - oid_to_hex(!is_initial ? &oid : - s->r->hash_algo->empty_tree), - "--", NULL); + strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", NULL); + if (s->context != -1) + strvec_pushf(&cmd.args, "--unified=%i", s->context); + if (s->interhunkcontext != -1) + strvec_pushf(&cmd.args, "--inter-hunk-context=%i", s->interhunkcontext); + strvec_pushl(&cmd.args, oid_to_hex(!is_initial ? &oid : + s->r->hash_algo->empty_tree), "--", NULL); for (i = 0; i < files->items.nr; i++) if (files->selected[i]) strvec_push(&cmd.args, @@ -1119,7 +1138,8 @@ static void command_prompt_help(struct add_i_state *s) _("(empty) select nothing")); } -int run_add_i(struct repository *r, const struct pathspec *ps) +int run_add_i(struct repository *r, const struct pathspec *ps, + struct add_p_opt *add_p_opt) { struct add_i_state s = { NULL }; struct print_command_item_data data = { "[", "]" }; @@ -1162,7 +1182,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps) ->util = util; } - init_add_i_state(&s, r); + init_add_i_state(&s, r, add_p_opt); /* * When color was asked for, use the prompt color for diff --git a/add-interactive.h b/add-interactive.h index c63f35b14be868..4213dcd67b9a8e 100644 --- a/add-interactive.h +++ b/add-interactive.h @@ -3,6 +3,13 @@ #include "color.h" +struct add_p_opt { + int context; + int interhunkcontext; +}; + +#define ADD_P_OPT_INIT { .context = -1, .interhunkcontext = -1 } + struct add_i_state { struct repository *r; int use_color; @@ -21,12 +28,14 @@ struct add_i_state { int context, interhunkcontext; }; -void init_add_i_state(struct add_i_state *s, struct repository *r); +void init_add_i_state(struct add_i_state *s, struct repository *r, + struct add_p_opt *add_p_opt); void clear_add_i_state(struct add_i_state *s); struct repository; struct pathspec; -int run_add_i(struct repository *r, const struct pathspec *ps); +int run_add_i(struct repository *r, const struct pathspec *ps, + struct add_p_opt *add_p_opt); enum add_p_mode { ADD_P_ADD, @@ -37,6 +46,7 @@ enum add_p_mode { }; int run_add_p(struct repository *r, enum add_p_mode mode, - const char *revision, const struct pathspec *ps); + struct add_p_opt *o, const char *revision, + const struct pathspec *ps); #endif diff --git a/add-patch.c b/add-patch.c index b0125b51ba45e0..302e6ba7d9a353 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1763,14 +1763,15 @@ static int patch_update_file(struct add_p_state *s, } int run_add_p(struct repository *r, enum add_p_mode mode, - const char *revision, const struct pathspec *ps) + struct add_p_opt *o, const char *revision, + const struct pathspec *ps) { struct add_p_state s = { { r }, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; size_t i, binary_count = 0; - init_add_i_state(&s.s, r); + init_add_i_state(&s.s, r, o); if (mode == ADD_P_STASH) s.mode = &patch_mode_stash; diff --git a/builtin/add.c b/builtin/add.c index 7c292ffdc6c2c9..a00dab9b8fa094 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -29,6 +29,7 @@ static const char * const builtin_add_usage[] = { NULL }; static int patch_interactive, add_interactive, edit_interactive; +static struct add_p_opt add_p_opt = ADD_P_OPT_INIT; static int take_worktree_changes; static int add_renormalize; static int pathspec_file_nul; @@ -157,7 +158,7 @@ static int refresh(struct repository *repo, int verbose, const struct pathspec * int interactive_add(struct repository *repo, const char **argv, const char *prefix, - int patch) + int patch, struct add_p_opt *add_p_opt) { struct pathspec pathspec; int ret; @@ -169,9 +170,9 @@ int interactive_add(struct repository *repo, prefix, argv); if (patch) - ret = !!run_add_p(repo, ADD_P_ADD, NULL, &pathspec); + ret = !!run_add_p(repo, ADD_P_ADD, add_p_opt, NULL, &pathspec); else - ret = !!run_add_i(repo, &pathspec); + ret = !!run_add_i(repo, &pathspec, add_p_opt); clear_pathspec(&pathspec); return ret; @@ -253,6 +254,8 @@ static struct option builtin_add_options[] = { OPT_GROUP(""), OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")), OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")), OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0), OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")), @@ -394,6 +397,11 @@ int cmd_add(int argc, prepare_repo_settings(repo); repo->settings.command_requires_full_index = 0; + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + if (patch_interactive) add_interactive = 1; if (add_interactive) { @@ -401,7 +409,12 @@ int cmd_add(int argc, die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch"); if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch"); - exit(interactive_add(repo, argv + 1, prefix, patch_interactive)); + exit(interactive_add(repo, argv + 1, prefix, patch_interactive, &add_p_opt)); + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch"); } if (edit_interactive) { diff --git a/builtin/checkout.c b/builtin/checkout.c index d185982f3a6372..2dc99ec7bfae57 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -61,6 +61,8 @@ static const char * const restore_usage[] = { struct checkout_opts { int patch_mode; + int patch_context; + int patch_interhunk_context; int quiet; int merge; int force; @@ -104,7 +106,12 @@ struct checkout_opts { struct tree *source_tree; }; -#define CHECKOUT_OPTS_INIT { .conflict_style = -1, .merge = -1 } +#define CHECKOUT_OPTS_INIT { \ + .conflict_style = -1, \ + .merge = -1, \ + .patch_context = -1, \ + .patch_interhunk_context = -1, \ +} struct branch_info { char *name; /* The short name used */ @@ -539,6 +546,10 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->patch_mode) { enum add_p_mode patch_mode; + struct add_p_opt add_p_opt = { + .context = opts->patch_context, + .interhunkcontext = opts->patch_interhunk_context, + }; const char *rev = new_branch_info->name; char rev_oid[GIT_MAX_HEXSZ + 1]; @@ -564,8 +575,8 @@ static int checkout_paths(const struct checkout_opts *opts, else BUG("either flag must have been set, worktree=%d, index=%d", opts->checkout_worktree, opts->checkout_index); - return !!run_add_p(the_repository, patch_mode, rev, - &opts->pathspec); + return !!run_add_p(the_repository, patch_mode, &add_p_opt, + rev, &opts->pathspec); } repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR); @@ -1738,6 +1749,8 @@ static struct option *add_checkout_path_options(struct checkout_opts *opts, N_("checkout their version for unmerged files"), 3, PARSE_OPT_NONEG), OPT_BOOL('p', "patch", &opts->patch_mode, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&opts->patch_context), + OPT_DIFF_INTERHUNK_CONTEXT(&opts->patch_interhunk_context), OPT_BOOL(0, "ignore-skip-worktree-bits", &opts->ignore_skipworktree, N_("do not limit pathspecs to sparse entries only")), OPT_PATHSPEC_FROM_FILE(&opts->pathspec_from_file), @@ -1780,6 +1793,18 @@ static int checkout_main(int argc, const char **argv, const char *prefix, argc = parse_options(argc, argv, prefix, options, usagestr, parseopt_flags); + if (opts->patch_context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (opts->patch_interhunk_context < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + + if (!opts->patch_mode) { + if (opts->patch_context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (opts->patch_interhunk_context != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + if (opts->show_progress < 0) { if (opts->quiet) opts->show_progress = 0; diff --git a/builtin/commit.c b/builtin/commit.c index fba0dded64a718..73673bc7db9ff8 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -19,6 +19,7 @@ #include "environment.h" #include "diff.h" #include "commit.h" +#include "add-interactive.h" #include "gettext.h" #include "revision.h" #include "wt-status.h" @@ -122,6 +123,7 @@ static const char *edit_message, *use_message; static char *fixup_message, *fixup_commit, *squash_message; static const char *fixup_prefix; static int all, also, interactive, patch_interactive, only, amend, signoff; +static struct add_p_opt add_p_opt = ADD_P_OPT_INIT; static int edit_flag = -1; /* unspecified */ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; static int config_commit_verbose = -1; /* unspecified */ @@ -354,6 +356,11 @@ static const char *prepare_index(const char **argv, const char *prefix, const char *ret; char *path = NULL; + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + if (is_status) refresh_flags |= REFRESH_UNMERGED; parse_pathspec(&pathspec, 0, @@ -400,7 +407,7 @@ static const char *prepare_index(const char **argv, const char *prefix, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - if (interactive_add(the_repository, argv, prefix, patch_interactive) != 0) + if (interactive_add(the_repository, argv, prefix, patch_interactive, &add_p_opt) != 0) die(_("interactive add failed")); the_repository->index_file = old_repo_index_file; @@ -424,6 +431,11 @@ static const char *prepare_index(const char **argv, const char *prefix, commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); goto out; + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch"); } /* @@ -1722,6 +1734,8 @@ int cmd_commit(int argc, OPT_BOOL('i', "include", &also, N_("add specified files to index for commit")), OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")), OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('o', "only", &only, N_("commit only specified files")), OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit and commit-msg hooks")), OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")), diff --git a/builtin/reset.c b/builtin/reset.c index dc50ffc1ac59e8..9fb32795c9c53d 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -346,6 +346,7 @@ int cmd_reset(int argc, struct object_id oid; struct pathspec pathspec; int intent_to_add = 0; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; const struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "no-refresh", &no_refresh, @@ -370,6 +371,8 @@ int cmd_reset(int argc, PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater), OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that removed paths will be added later")), OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), @@ -420,6 +423,11 @@ int cmd_reset(int argc, oidcpy(&oid, &tree->object.oid); } + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -427,9 +435,14 @@ int cmd_reset(int argc, if (reset_type != NONE) die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}"); trace2_cmd_mode("patch-interactive"); - update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, rev, - &pathspec); + update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, + &add_p_opt, rev, &pathspec); goto cleanup; + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); } /* git reset tree [--] paths... can be used to diff --git a/builtin/stash.c b/builtin/stash.c index cfbd92852a6557..745421187cc106 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1242,7 +1242,8 @@ static int stash_staged(struct stash_info *info, struct strbuf *out_patch, } static int stash_patch(struct stash_info *info, const struct pathspec *ps, - struct strbuf *out_patch, int quiet) + struct strbuf *out_patch, int quiet, + struct add_p_opt *add_p_opt) { int ret = 0; struct child_process cp_read_tree = CHILD_PROCESS_INIT; @@ -1267,7 +1268,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - ret = !!run_add_p(the_repository, ADD_P_STASH, NULL, ps); + ret = !!run_add_p(the_repository, ADD_P_STASH, add_p_opt, NULL, ps); the_repository->index_file = old_repo_index_file; if (old_index_env && *old_index_env) @@ -1362,8 +1363,8 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps } static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_buf, - int include_untracked, int patch_mode, int only_staged, - struct stash_info *info, struct strbuf *patch, + int include_untracked, int patch_mode, struct add_p_opt *add_p_opt, + int only_staged, struct stash_info *info, struct strbuf *patch, int quiet) { int ret = 0; @@ -1439,7 +1440,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b untracked_commit_option = 1; } if (patch_mode) { - ret = stash_patch(info, ps, patch, quiet); + ret = stash_patch(info, ps, patch, quiet, add_p_opt); if (ret < 0) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " @@ -1513,7 +1514,7 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED, if (!check_changes_tracked_files(&ps)) return 0; - ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, 0, &info, + ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, NULL, 0, &info, NULL, 0); if (!ret) printf_ln("%s", oid_to_hex(&info.w_commit)); @@ -1524,7 +1525,8 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED, } static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int quiet, - int keep_index, int patch_mode, int include_untracked, int only_staged) + int keep_index, int patch_mode, struct add_p_opt *add_p_opt, + int include_untracked, int only_staged) { int ret = 0; struct stash_info info = STASH_INFO_INIT; @@ -1594,8 +1596,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q if (stash_msg) strbuf_addstr(&stash_msg_buf, stash_msg); - if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, only_staged, - &info, &patch, quiet)) { + if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, + add_p_opt, only_staged, &info, &patch, quiet)) { ret = -1; goto done; } @@ -1768,6 +1770,7 @@ static int push_stash(int argc, const char **argv, const char *prefix, const char *stash_msg = NULL; char *pathspec_from_file = NULL; struct pathspec ps; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, N_("keep index")), @@ -1775,6 +1778,8 @@ static int push_stash(int argc, const char **argv, const char *prefix, N_("stash staged changes only")), OPT_BOOL('p', "patch", &patch_mode, N_("stash in patch mode")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT__QUIET(&quiet, N_("quiet mode")), OPT_BOOL('u', "include-untracked", &include_untracked, N_("include untracked files in stash")), @@ -1826,8 +1831,20 @@ static int push_stash(int argc, const char **argv, const char *prefix, die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file"); } + if (!patch_mode) { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode, - include_untracked, only_staged); + &add_p_opt, include_untracked, only_staged); clear_pathspec(&ps); free(pathspec_from_file); @@ -1852,6 +1869,7 @@ static int save_stash(int argc, const char **argv, const char *prefix, const char *stash_msg = NULL; struct pathspec ps; struct strbuf stash_msg_buf = STRBUF_INIT; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, N_("keep index")), @@ -1859,6 +1877,8 @@ static int save_stash(int argc, const char **argv, const char *prefix, N_("stash staged changes only")), OPT_BOOL('p', "patch", &patch_mode, N_("stash in patch mode")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT__QUIET(&quiet, N_("quiet mode")), OPT_BOOL('u', "include-untracked", &include_untracked, N_("include untracked files in stash")), @@ -1877,8 +1897,22 @@ static int save_stash(int argc, const char **argv, const char *prefix, stash_msg = strbuf_join_argv(&stash_msg_buf, argc, argv, ' '); memset(&ps, 0, sizeof(ps)); + + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + + if (!patch_mode) { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, - patch_mode, include_untracked, only_staged); + patch_mode, &add_p_opt, include_untracked, + only_staged); strbuf_release(&stash_msg_buf); return ret; diff --git a/commit.h b/commit.h index 70c870dae4d4b9..7a7fedbc2f1484 100644 --- a/commit.h +++ b/commit.h @@ -2,6 +2,7 @@ #define COMMIT_H #include "object.h" +#include "add-interactive.h" struct signature_check; struct strbuf; @@ -257,7 +258,7 @@ int for_each_commit_graft(each_commit_graft_fn, void *); int interactive_add(struct repository *repo, const char **argv, const char *prefix, - int patch); + int patch, struct add_p_opt *add_p_opt); struct commit_extra_header { struct commit_extra_header *next; diff --git a/parse-options.h b/parse-options.h index 91c3e3c29b3dda..bdae8f116198d6 100644 --- a/parse-options.h +++ b/parse-options.h @@ -616,6 +616,8 @@ int parse_opt_tracking_mode(const struct option *, const char *, int); #define OPT_PATHSPEC_FROM_FILE(v) OPT_FILENAME(0, "pathspec-from-file", v, N_("read pathspec from file")) #define OPT_PATHSPEC_FILE_NUL(v) OPT_BOOL(0, "pathspec-file-nul", v, N_("with --pathspec-from-file, pathspec elements are separated with NUL character")) #define OPT_AUTOSTASH(v) OPT_BOOL(0, "autostash", v, N_("automatically stash/stash pop before and after")) +#define OPT_DIFF_UNIFIED(v) OPT_INTEGER_F('U', "unified", v, N_("generate diffs with lines context"), PARSE_OPT_NONEG) +#define OPT_DIFF_INTERHUNK_CONTEXT(v) OPT_INTEGER_F(0, "inter-hunk-context", v, N_("show context between diff hunks up to the specified number of lines"), PARSE_OPT_NONEG) #define OPT_IPVERSION(v) \ OPT_SET_INT_F('4', "ipv4", (v), N_("use IPv4 addresses only"), \ diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 18dc329ea1f697..04d2a198352531 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -1252,4 +1252,53 @@ test_expect_success 'add -p rejects negative diff.context' ' test_grep "diff.context cannot be negative" output ' +for cmd in add checkout restore 'commit -m file' +do + test_expect_success "${cmd%% *} accepts -U and --inter-hunk-context" ' + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + git add file && + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + $cmd -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual + ' +done + +test_expect_success 'reset accepts -U and --inter-hunk-context' ' + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + git commit -m file file && + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + git add file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + reset -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual +' + +test_expect_success 'stash accepts -U and --inter-hunk-context' ' + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + git commit -m file file && + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + stash -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual +' + +for cmd in add checkout commit reset restore "stash save" "stash push" +do + test_expect_success "$cmd rejects invalid context options" ' + test_must_fail git $cmd -p -U -3 2>actual && + cat actual | echo && + test_grep -e ".--unified. cannot be negative" actual && + + test_must_fail git $cmd -p --inter-hunk-context -3 2>actual && + test_grep -e ".--inter-hunk-context. cannot be negative" actual && + + test_must_fail git $cmd -U 7 2>actual && + test_grep -E ".--unified. requires .(--interactive/)?--patch." actual && + + test_must_fail git $cmd --inter-hunk-context 2 2>actual && + test_grep -E ".--inter-hunk-context. requires .(--interactive/)?--patch." actual + ' +done + test_done diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 343b8cd1912bd5..6650d33fba69c8 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -2596,6 +2596,8 @@ test_expect_success 'double dash "git checkout"' ' --merge Z --conflict=Z --patch Z + --unified=Z + --inter-hunk-context=Z --ignore-skip-worktree-bits Z --ignore-other-worktrees Z --recurse-submodules Z From 9b0781196a0fb7c7631b1fbaf5898e5f87a5f1bd Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 30 Jul 2025 16:18:16 -0700 Subject: [PATCH 37/47] test-hashmap: document why it is no longer used but still there As I ended up wasting a few dozen minutes looking for the reason why this is still here, help future developers by saving them from wasting their time by documenting why this code that apparently is not used by anybody is still here. Signed-off-by: Junio C Hamano --- t/helper/test-hashmap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c index 7782ae585e6471..16a3145c3a07b1 100644 --- a/t/helper/test-hashmap.c +++ b/t/helper/test-hashmap.c @@ -137,6 +137,11 @@ static void perf_hashmap(unsigned int method, unsigned int rounds) * Read stdin line by line and print result of commands to stdout: * * perfhashmap method rounds -> test hashmap.[ch] performance + * + * NOTE: this is not used by any of our mechanized build & test + * procedure, after 3469a236 (t: port helper/test-hashmap.c to + * unit-tests/t-hashmap.c, 2024-08-03). See the log message of that + * commit for the reason why this is still here. */ int cmd__hashmap(int argc UNUSED, const char **argv UNUSED) { From f3ef347bb2e0332872088bb00c8ba9801c578822 Mon Sep 17 00:00:00 2001 From: chenjianhu Date: Thu, 31 Jul 2025 03:49:40 +0000 Subject: [PATCH 38/47] t7450: inspect the correct path a broken code would write to Prior to 05e9cd64 (config: quote values containing CR character, 2025-05-19), a repository can trick "clone --recurse-submodules" into running a post-checkout hook shipped with the project. The test was written to make sure the trick would no longer run the hook with the fix in the commit. However, the test did not check for the path the hook would create; correct the path to the expected one if the bug were still with us. Signed-off-by: chenjianhu Signed-off-by: Junio C Hamano --- t/t7450-bad-git-dotfiles.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh index ff63c0565203d1..e8b89eba77bc6a 100755 --- a/t/t7450-bad-git-dotfiles.sh +++ b/t/t7450-bad-git-dotfiles.sh @@ -402,7 +402,7 @@ test_expect_success SYMLINKS,!WINDOWS,!MINGW 'submodule must not checkout into d git -C repo commit -m submodule && git -c protocol.file.allow=always clone --recurse-submodules repo bad-clone && - ! test -f "$PWD/foo" && + ! test -f "$PWD/bad-clone/sub/foo" && test -f $(printf "bad-clone/sub\r/post-checkout") ' From 711a20827b7e99cda7329872c0e75860ddfb08bc Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Thu, 31 Jul 2025 18:07:36 +0200 Subject: [PATCH 39/47] interactive: do strip trailing CRLF from input `git reset -p file` on a Windows CMD refuses to do anything useful with this error message: (1/5) Unstage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? n 'nly one letter is expected, got 'n The letter 'O' at the beginning of the line is overwritten by an apostrophe, so, clearly the parser sees the string "n\r". strbuf_trim_trailing_newline() removes trailing CRLF from the string. In particular, it first removes LF if present, and if that was the case, it also removes CR if present. git_read_line_interactively() clearly intends to remove CRLF as it calls strbuf_trim_trailing_newline(). However, input is gathered using strbuf_getline_lf(), which already removes the trailing LF. Now strbuf_trim_trailing_newline() does not see LF, so that it does not remove CR, either, and leaves it for the caller to process. Call strbuf_getline() instead, which removes both LF and CR. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- prompt.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/prompt.c b/prompt.c index f21c5bf1c7e42f..706fba2a5030c7 100644 --- a/prompt.c +++ b/prompt.c @@ -77,12 +77,6 @@ char *git_prompt(const char *prompt, int flags) 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; + return strbuf_getline(line, stdin); } From 4ac3302a1a77cf833fc7085a0b6a6b49024d1bc5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 1 Aug 2025 10:06:55 -0700 Subject: [PATCH 40/47] CodingGuidelines: clarify that S_release() does not reinitialize In the section for naming various API functions, the fact that S_release() only releases the resources without preparing the structure for immediate reuse becomes only apparent when you readentries for S_release() and S_clear(). Clarify the description of S_release() a bit to make the entry self sufficient. Signed-off-by: Junio C Hamano --- Documentation/CodingGuidelines | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 3263245b032370..ea6b9652e43ea7 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -610,8 +610,9 @@ For C programs: - `S_init()` initializes a structure without allocating the structure itself. - - `S_release()` releases a structure's contents without freeing the - structure. + - `S_release()` releases a structure's contents without reinitializing + the structure for immediate reuse, and without freeing the structure + itself. - `S_clear()` is equivalent to `S_release()` followed by `S_init()` such that the structure is directly usable after clearing it. When From cca758d324acb0c4b8fd64e9d8792b3ee251ff76 Mon Sep 17 00:00:00 2001 From: Kristoffer Haugsbakk Date: Fri, 1 Aug 2025 15:42:25 +0200 Subject: [PATCH 41/47] doc: fast-import: contextualize the hardware cost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6e411d20440 (Initial draft of fast-import documentation., 2007-02-05) pointed out how much time a fast-import took on some hardware with a specific cost. Let’s further point out that this experiment was done in 2007. So modern hardware should have no issues with such a repo. Also move the parenthetical to the end now that it contains four words. Signed-off-by: Kristoffer Haugsbakk Signed-off-by: Junio C Hamano --- Documentation/git-fast-import.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 8b5dd6add006d1..77c88a18c6f16d 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -182,7 +182,7 @@ amount of memory usage and processing time. Assuming the frontend is able to keep up with fast-import and feed it a constant stream of data, import times for projects holding 10+ years of history and containing 100,000+ individual commits are generally completed in just 1-2 -hours on quite modest (~$2,000 USD) hardware. +hours on quite modest hardware (~$2,000 USD in 2007). Most bottlenecks appear to be in foreign source data access (the source just cannot extract revisions fast enough) or disk IO (fast-import From 3bdd8974137d0348f599a9ba9d93f6ea9804e19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 1 Aug 2025 19:28:14 +0300 Subject: [PATCH 42/47] meson: tolerate errors from git ls-files --deduplicate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the Meson build system with versions of Git before 2.31, that does not yet know the `git ls-files --deduplicate` option, one can observe the following error: ../meson.build:697:19: ERROR: Command `/usr/bin/git -C /home/martin/code/git ls-files --deduplicate '*.h' ':!contrib' ':!compat/inet_ntop.c' ':!compat/inet_pton.c' ':!compat/nedmalloc' ':!compat/obstack.*' ':!compat/poll' ':!compat/regex' ':!sha1collisiondetection' ':!sha1dc' ':!t/unit-tests/clar' ':!t/t[0-9][0-9][0-9][0-9]*' ':!xdiff'` failed with status 129. The failing command is used to find all header files in our code base, which is required for static analysis. Static analysis is an entirely optional feature that distributors typically don't care about, and we already know to skip running the command when we are not in a Git repository. But we do not handle the above failure gracefully, even though we could. Fix this by passing `check: false` to `run_command`, which makes it tolerate failures. Then check `returncode()` manually to decide whether to inspect the output. Signed-off-by: Martin Storsjö Signed-off-by: Junio C Hamano --- meson.build | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index 596f5ac7110ebf..9b6462005652b1 100644 --- a/meson.build +++ b/meson.build @@ -694,9 +694,14 @@ third_party_excludes = [ headers_to_check = [] if git.found() and fs.exists(meson.project_source_root() / '.git') - foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_excludes, check: true).stdout().split() - headers_to_check += header - endforeach + ls_headers = run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_excludes, check: false) + if ls_headers.returncode() == 0 + foreach header : ls_headers.stdout().split() + headers_to_check += header + endforeach + else + warning('could not list headers, disabling static analysis targets') + endif endif if not get_option('breaking_changes') From 5f277fc5f25dc0fb54aa42bad62c23325bab9200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= Date: Sun, 3 Aug 2025 21:25:15 +0000 Subject: [PATCH 43/47] mingw_open_existing: handle directories better MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CreateFileW() requires FILE_FLAG_BACKUP_SEMANTICS to create a directory handle [1] and errors out with ERROR_ACCESS_DENIED without this flag. Fall back to accessing Directory handles this way. [1] https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#directories This fixes https://github.com/git-for-windows/git/issues/5068 Signed-off-by: Matthias Aßhauer Signed-off-by: Junio C Hamano --- compat/mingw.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 5d69ae32f4b946..2dd5cbcaee0d5a 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -588,13 +588,24 @@ static int mingw_open_existing(const wchar_t *filename, int oflags, ...) &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) { + DWORD attrs = GetFileAttributesW(filename); + if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) + handle = CreateFileW(filename, access, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_BACKUP_SEMANTICS, NULL); + } - /* See `mingw_open_append()` for why we have this conversion. */ - if (err == ERROR_INVALID_PARAMETER) - err = ERROR_PATH_NOT_FOUND; + if (handle == INVALID_HANDLE_VALUE) { + err = GetLastError(); - errno = err_win_to_posix(err); - return -1; + /* See `mingw_open_append()` for why we have this conversion. */ + if (err == ERROR_INVALID_PARAMETER) + err = ERROR_PATH_NOT_FOUND; + + errno = err_win_to_posix(err); + return -1; + } } fd = _open_osfhandle((intptr_t)handle, oflags | O_BINARY); From ce6ccbaf92ec41743d83c386cad4dba77f768f13 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Aug 2025 21:25:16 +0000 Subject: [PATCH 44/47] mingw: drop Windows 7-specific work-around In ac33519ddfa8 (mingw: restrict file handle inheritance only on Windows 7 and later, 2019-11-22), I introduced code to safe-guard the defense-in-depth handling that restricts handles' inheritance so that it would work with Windows 7, too. Let's revert this patch: Git for Windows dropped supporting Windows 7 (and Windows 8) directly after Git for Windows v2.46.2. For full details, see https://gitforwindows.org/requirements#windows-version. Actually, on second thought: revert only the part that makes this handle inheritance restriction logic optional and that suggests to open a bug report if it fails, but keep the fall-back to try again without said logic: There have been a few false positives over the past few years (where the warning was triggered e.g. because Defender was still accessing a file that Git wanted to overwrite), and the fall-back logic seems to have helped occasionally in such situations. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/config/core.adoc | 6 --- compat/mingw.c | 68 ++-------------------------------- 2 files changed, 4 insertions(+), 70 deletions(-) diff --git a/Documentation/config/core.adoc b/Documentation/config/core.adoc index 9fde1ab63a70ea..3fbe83eef1612c 100644 --- a/Documentation/config/core.adoc +++ b/Documentation/config/core.adoc @@ -696,12 +696,6 @@ core.unsetenvvars:: Defaults to `PERL5LIB` to account for the fact that Git for Windows insists on using its own Perl interpreter. -core.restrictinheritedhandles:: - Windows-only: override whether spawned processes inherit only standard - file handles (`stdin`, `stdout` and `stderr`) or all handles. Can be - `auto`, `true` or `false`. Defaults to `auto`, which means `true` on - Windows 7 and later, and `false` on older Windows versions. - core.createObject:: You can set this to 'link', in which case a hardlink followed by a delete of the source are used to make sure that object creation diff --git a/compat/mingw.c b/compat/mingw.c index 2dd5cbcaee0d5a..c331c3ac32a8f9 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -244,7 +244,6 @@ enum hide_dotfiles_type { HIDE_DOTFILES_DOTGITONLY }; -static int core_restrict_inherited_handles = -1; static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; static char *unset_environment_variables; @@ -268,15 +267,6 @@ int mingw_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.restrictinheritedhandles")) { - if (value && !strcasecmp(value, "auto")) - core_restrict_inherited_handles = -1; - else - core_restrict_inherited_handles = - git_config_bool(var, value); - return 0; - } - return 0; } @@ -1667,7 +1657,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen const char *dir, int prepend_cmd, int fhin, int fhout, int fherr) { - static int restrict_handle_inheritance = -1; STARTUPINFOEXW si; PROCESS_INFORMATION pi; LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL; @@ -1687,16 +1676,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen /* Make sure to override previous errors, if any */ errno = 0; - if (restrict_handle_inheritance < 0) - restrict_handle_inheritance = core_restrict_inherited_handles; - /* - * The following code to restrict which handles are inherited seems - * to work properly only on Windows 7 and later, so let's disable it - * on Windows Vista and 2008. - */ - if (restrict_handle_inheritance < 0) - restrict_handle_inheritance = GetVersion() >> 16 >= 7601; - do_unset_environment_variables(); /* Determine whether or not we are associated to a console */ @@ -1798,7 +1777,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen wenvblk = make_environment_block(deltaenv); memset(&pi, 0, sizeof(pi)); - if (restrict_handle_inheritance && stdhandles_count && + if (stdhandles_count && (InitializeProcThreadAttributeList(NULL, 1, 0, &size) || GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST) @@ -1819,52 +1798,13 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen &si.StartupInfo, &pi); /* - * On Windows 2008 R2, it seems that specifying certain types of handles - * (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an - * error. Rather than playing finicky and fragile games, let's just try - * to detect this situation and simply try again without restricting any - * handle inheritance. This is still better than failing to create - * processes. + * On the off-chance that something with the file handle restriction + * went wrong, silently fall back to trying without it. */ - if (!ret && restrict_handle_inheritance && stdhandles_count) { + if (!ret && stdhandles_count) { DWORD err = GetLastError(); struct strbuf buf = STRBUF_INIT; - if (err != ERROR_NO_SYSTEM_RESOURCES && - /* - * On Windows 7 and earlier, handles on pipes and character - * devices are inherited automatically, and cannot be - * specified in the thread handle list. Rather than trying - * to catch each and every corner case (and running the - * chance of *still* forgetting a few), let's just fall - * back to creating the process without trying to limit the - * handle inheritance. - */ - !(err == ERROR_INVALID_PARAMETER && - GetVersion() >> 16 < 9200) && - !getenv("SUPPRESS_HANDLE_INHERITANCE_WARNING")) { - DWORD fl = 0; - int i; - - setenv("SUPPRESS_HANDLE_INHERITANCE_WARNING", "1", 1); - - for (i = 0; i < stdhandles_count; i++) { - HANDLE h = stdhandles[i]; - strbuf_addf(&buf, "handle #%d: %p (type %lx, " - "handle info (%d) %lx\n", i, h, - GetFileType(h), - GetHandleInformation(h, &fl), - fl); - } - strbuf_addstr(&buf, "\nThis is a bug; please report it " - "at\nhttps://github.com/git-for-windows/" - "git/issues/new\n\n" - "To suppress this warning, please set " - "the environment variable\n\n" - "\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1" - "\n"); - } - restrict_handle_inheritance = 0; flags &= ~EXTENDED_STARTUPINFO_PRESENT; ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL, TRUE, flags, wenvblk, dir ? wdir : NULL, From 51f9b623f276806be92b4f62e061df79cdd397a3 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Aug 2025 21:25:17 +0000 Subject: [PATCH 45/47] mingw_rename: support ReFS on Windows 2022 ReFS is an alternative filesystem to NTFS. On Windows 2022, it seems not to support the rename operation using POSIX semantics that Git uses on Windows as of 391bceae4350 (compat/mingw: support POSIX semantics for atomic renames, 2024-10-27). However, Windows 2022 reports `ERROR_NOT_SUPPORTED` in this instance. This is in contrast to `ERROR_INVALID_PARAMETER` (as previous Windows versions would report that do not support POSIX semantics in renames at all). Let's handle both errors the same: by falling back to the best-effort option, namely to rename without POSIX semantics. This fixes https://github.com/git-for-windows/git/issues/5427 Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/mingw.c b/compat/mingw.c index c331c3ac32a8f9..d53ce38b7f829b 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2277,7 +2277,7 @@ int mingw_rename(const char *pold, const char *pnew) * current system doesn't support FileRenameInfoEx. Keep us * from using it in future calls and retry. */ - if (gle == ERROR_INVALID_PARAMETER) { + if (gle == ERROR_INVALID_PARAMETER || gle == ERROR_NOT_SUPPORTED) { supports_file_rename_info_ex = 0; goto repeat; } From f559d422734ff00dcf42779813edde9fa6069526 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Aug 2025 21:25:18 +0000 Subject: [PATCH 46/47] mingw: support Windows Server 2016 again It was reported to the Git for Windows project that a simple `git init` fails on Windows Server 2016: D:\Dev\test> git init error: could not write config file D:/Dev/test/.git/config: Function not implemented fatal: could not set 'core.repositoryformatversion' to '0' According to https://endoflife.date/windows-server, Windows Server 2016 is officially supported for another one-and-a-half years as of time of writing, so this is not good. The culprit is the `mingw_rename()` changes that try to use POSIX semantics when available, but fail to fall back properly on Windows Server 2016. This fixes https://github.com/git-for-windows/git/issues/5695. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compat/mingw.c b/compat/mingw.c index d53ce38b7f829b..8538e3d1729d25 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2277,7 +2277,9 @@ int mingw_rename(const char *pold, const char *pnew) * current system doesn't support FileRenameInfoEx. Keep us * from using it in future calls and retry. */ - if (gle == ERROR_INVALID_PARAMETER || gle == ERROR_NOT_SUPPORTED) { + if (gle == ERROR_INVALID_PARAMETER || + gle == ERROR_NOT_SUPPORTED || + gle == ERROR_INVALID_FUNCTION) { supports_file_rename_info_ex = 0; goto repeat; } From 721c9e5ce7c6fa4e1a33490f5e5a81eeee814021 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 4 Aug 2025 08:09:37 -0700 Subject: [PATCH 47/47] Git 2.51-rc0 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.51.0.adoc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Documentation/RelNotes/2.51.0.adoc b/Documentation/RelNotes/2.51.0.adoc index 78b4918533f29e..a89d459d2e2db0 100644 --- a/Documentation/RelNotes/2.51.0.adoc +++ b/Documentation/RelNotes/2.51.0.adoc @@ -64,6 +64,9 @@ UI, Workflows & Features * "git for-each-ref" learns "--start-after" option to help applications that want to page its output. + * "git switch" and "git restore" are declared to be no longer + experimental. + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -269,6 +272,18 @@ including security updates, are included in this release. few test helper programs are now closed. (merge 0f1b33815b hl/test-helper-fd-close later to maint). + * Interactive prompt code did not correctly strip CRLF from the end + of line on Windows. + (merge 711a20827b js/prompt-crlf-fix later to maint). + + * The config API had a set of convenience wrapper functions that + implicitly use the_repository instance; they have been removed and + inlined at the calling sites. + + * "git add/etc -p" now honor the diff.context configuration variable, + and also they learn to honor the -U command-line option. + (merge 2b3ae04011 lm/add-p-context later to maint). + * Other code cleanup, docfix, build fix, etc. (merge b257adb571 lo/my-first-ow-doc-update later to maint). (merge 8b34b6a220 ly/sequencer-update-squash-is-fixup-only later to maint). @@ -299,3 +314,9 @@ including security updates, are included in this release. (merge 26552cb62a jk/unleak-reflog-expire-entry later to maint). (merge 339d95fda9 jc/ci-print-test-failures-fix later to maint). (merge 8c3add51a8 cb/meson-avoid-broken-macos-pcre2 later to maint). + (merge 5247da07b8 ps/meson-clar-decls-fix later to maint). + (merge f3ef347bb2 ch/t7450-recursive-clone-test-fix later to maint). + (merge 4ac3302a1a jc/doc-release-vs-clear later to maint). + (merge 3bdd897413 ms/meson-with-ancient-git-wo-ls-files-dedup later to maint). + (merge cca758d324 kh/doc-fast-import-historical later to maint). + (merge 9b0781196a jc/test-hashmap-is-still-here later to maint).