[Outreachy PATCH v3 0/8] stop using the_repository global variable.
- From
Usman Akinyemi <usmanakinyemi202@gmail.com>
- Date
- Mar 6, 2025, 14:35 UTC
- Message-ID
- <20250306143629.1267358-1-usmanakinyemi202@gmail.com>
- In-Reply-To
- <20250219203349.787173-1-usmanakinyemi202@gmail.com>
Remove `the_repository` global variable in favor of the repository argument that gets passed in builtin commands.
These sets of commands are commands that use only RUN_SETUP macro in "git.c". Basically, When `-h` is passed to any of this command outside a Git repository, the `run_builtin()` will call the `cmd_x()` function (where `x` is any of the command from the sets of builtin commands that `the_repository` is removed from) with `repo` set to NULL and then early in the function, `parse_options()` or show_usage_with_options_if_asked() call will give the options help and exit.
Some, functions also uses `the_repository` global internally, so, let's let's refactor them and pass `struct repo` as one of the argument.
As the `repo` value can be NULL if a builtin command is run outside any repository. The current implementation of `repo_config()` will fail if `repo` is NULL. If the `repo` is NULL, the `repo_config()` can ignore the repository configuration but it should read the other configuration sources like the system-side configuration instead of failing.
Teach the `repo_config()` to allow `repo` to be NULL by calling the `read_very_early_config()` which read config but only enumerate system and global settings. This make it possible for us to savely replace `git_config()` with `repo_config()`.
Changes since v2 ================ - Remove preparatory patches that move the `git_config()` below the `usage_with_options()`. - Add a new preparatory patch that teach the `repo_config()` to accept NULL value for `repo` variable. - Add tests to each of the builtin function in this commit to ensure `repo_config()` works as expected. - Make changes to the commit messages.
Usman Akinyemi (8): config: teach repo_config to allow `repo` to be NULL builtin/verify-tag: stop using `the_repository` builtin/verify-commit: stop using `the_repository` builtin/send-pack: stop using `the_repository` builtin/pack-refs: stop using `the_repository` builtin/ls-files: stop using `the_repository` builtin/for-each-ref: stop using `the_repository` builtin/checkout-index: stop using `the_repository`
builtin/checkout-index.c | 43 ++++++++++++++++----------------- builtin/for-each-ref.c | 5 ++-- builtin/ls-files.c | 32 ++++++++++++------------ builtin/pack-refs.c | 8 +++--- builtin/send-pack.c | 7 +++--- builtin/verify-commit.c | 13 +++++----- builtin/verify-tag.c | 7 +++--- config.c | 4 +++ config.h | 3 +++ t/t0610-reftable-basics.sh | 7 ++++++ t/t2006-checkout-index-basic.sh | 7 ++++++ t/t3004-ls-files-basic.sh | 7 ++++++ t/t5400-send-pack.sh | 7 ++++++ t/t6300-for-each-ref.sh | 7 ++++++ t/t7030-verify-tag.sh | 7 ++++++ t/t7510-signed-commit.sh | 7 ++++++ 16 files changed, 110 insertions(+), 61 deletions(-)
Range-diff versus v2:
1: a313f9afb7 < -: ---------- builtin/verify-tag: refactor `cmd_verify_tag()`
-: ---------- > 1: a5c69f3753 config: teach repo_config to allow `repo` to be NULL
2: f993160d90 ! 2: dfa0da4061 builtin/verify-tag: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_verify_tag()` function with `repo` set
to NULL and then early in the function, `parse_options()` call will give
- the options help and exit, without having to consult much of the
- configuration file.
+ the options help and exit.
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
@@ builtin/verify-tag.c: static const char * const verify_tag_usage[] = {
int i = 1, verbose = 0, had_error = 0;
unsigned flags = 0;
@@ builtin/verify-tag.c: int cmd_verify_tag(int argc,
- flags |= GPG_VERIFY_OMIT_STATUS;
- }
+ OPT_END()
+ };
- git_config(git_default_config, NULL);
+ repo_config(repo, git_default_config, NULL);
- while (i < argc) {
+ argc = parse_options(argc, argv, prefix, verify_tag_options,
+ verify_tag_usage, PARSE_OPT_KEEP_ARGV0);
+@@ builtin/verify-tag.c: int cmd_verify_tag(int argc,
struct object_id oid;
const char *name = argv[i++];
@@ builtin/verify-tag.c: int cmd_verify_tag(int argc,
had_error = !!error("tag '%s' not found.", name);
continue;
}
+
+ ## t/t7030-verify-tag.sh ##
+@@ t/t7030-verify-tag.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+ . ./test-lib.sh
+ . "$TEST_DIRECTORY/lib-gpg.sh"
+
++test_expect_success GPG 'verify-tag does not crash with -h' '
++ test_expect_code 129 git verify-tag -h >usage &&
++ test_grep "[Uu]sage: git verify-tag " usage &&
++ test_expect_code 129 nongit git verify-tag -h >usage &&
++ test_grep "[Uu]sage: git verify-tag " usage
++'
++
+ test_expect_success GPG 'create signed tags' '
+ echo 1 >file && git add file &&
+ test_tick && git commit -m initial &&
3: f2f785190d < -: ---------- builtin/verify-commit: refactor `cmd_verify_commit()`
4: 5f8dc0c0ec ! 3: ade2d026cb builtin/verify-commit: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_verify_commit()` function with `repo`
set to NULL and then early in the function, `parse_options()` call will
- give the options help and exit, without having to consult much of the
- configuration file.
+ give the options help and exit.
Pass the repository available in the calling context to `verify_commit()`
to remove it's dependency on the global `the_repository` variable.
@@ builtin/verify-commit.c: static int verify_commit(const char *name, unsigned fla
int i = 1, verbose = 0, had_error = 0;
unsigned flags = 0;
@@ builtin/verify-commit.c: int cmd_verify_commit(int argc,
- if (verbose)
- flags |= GPG_VERIFY_VERBOSE;
+ OPT_END()
+ };
- git_config(git_default_config, NULL);
+ repo_config(repo, git_default_config, NULL);
- /* sometimes the program was terminated because this signal
+ argc = parse_options(argc, argv, prefix, verify_commit_options,
+ verify_commit_usage, PARSE_OPT_KEEP_ARGV0);
+@@ builtin/verify-commit.c: int cmd_verify_commit(int argc,
* was received in the process of writing the gpg input: */
signal(SIGPIPE, SIG_IGN);
while (i < argc)
@@ builtin/verify-commit.c: int cmd_verify_commit(int argc,
had_error = 1;
return had_error;
}
+
+ ## t/t7510-signed-commit.sh ##
+@@ t/t7510-signed-commit.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+ GNUPGHOME_NOT_USED=$GNUPGHOME
+ . "$TEST_DIRECTORY/lib-gpg.sh"
+
++test_expect_success GPG 'verify-commit does not crash with -h' '
++ test_expect_code 129 git verify-commit -h >usage &&
++ test_grep "[Uu]sage: git verify-commit " usage &&
++ test_expect_code 129 nongit git verify-commit -h >usage &&
++ test_grep "[Uu]sage: git verify-commit " usage
++'
++
+ test_expect_success GPG 'create signed commits' '
+ test_oid_cache <<-\EOF &&
+ header sha1:gpgsig
5: d79c3fc1ee < -: ---------- builtin/send-pack: refactor `cmd_send_pack()`
6: f280a9c387 ! 4: e3b58bc6cf builtin/send-pack: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_send_pack()` function with `repo` set
to NULL and then early in the function, `parse_options()` call will give
- the options help and exit, without having to consult much of the
- configuration file.
+ the options help and exit.
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
@@ builtin/send-pack.c: static int send_pack_config(const char *k, const char *v,
struct refspec rs = REFSPEC_INIT_PUSH;
const char *remote_name = NULL;
@@ builtin/send-pack.c: int cmd_send_pack(int argc,
- if (!dest)
- usage_with_options(send_pack_usage, options);
+ OPT_END()
+ };
- git_config(send_pack_config, NULL);
+ repo_config(repo, send_pack_config, NULL);
-
- args.verbose = verbose;
- args.dry_run = dry_run;
+ argc = parse_options(argc, argv, prefix, options, send_pack_usage, 0);
+ if (argc > 0) {
+ dest = argv[0];
@@ builtin/send-pack.c: int cmd_send_pack(int argc,
set_ref_status_for_push(remote_refs, args.send_mirror,
args.force_update);
@@ builtin/send-pack.c: int cmd_send_pack(int argc,
if (helper_status)
print_helper_status(remote_refs);
+
+ ## t/t5400-send-pack.sh ##
+@@ t/t5400-send-pack.sh: test_expect_success setup '
+ echo Rebase &&
+ git log'
+
++test_expect_success 'send-pack does not crash with -h' '
++ test_expect_code 129 git send-pack -h >usage &&
++ test_grep "[Uu]sage: git send-pack " usage &&
++ test_expect_code 129 nongit git send-pack -h >usage &&
++ test_grep "[Uu]sage: git send-pack " usage
++'
++
+ test_expect_success 'pack the source repository' '
+ git repack -a -d &&
+ git prune
7: df192a1b2c < -: ---------- builtin/pack-refs: refactor `cmd_pack_refs()`
8: 845cd1ea7c ! 5: b11e99627c builtin/pack-refs: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_pack_refs()` function with `repo` set
to NULL and then early in the function, `parse_options()` call will give
- the options help and exit, without having to consult much of the
- configuration file.
+ the options help and exit.
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
@@ builtin/pack-refs.c: static char const * const pack_refs_usage[] = {
struct ref_exclusions excludes = REF_EXCLUSIONS_INIT;
struct string_list included_refs = STRING_LIST_INIT_NODUP;
@@ builtin/pack-refs.c: int cmd_pack_refs(int argc,
- if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
- usage_with_options(pack_refs_usage, opts);
-
+ N_("references to exclude")),
+ OPT_END(),
+ };
- git_config(git_default_config, NULL);
+ repo_config(repo, git_default_config, NULL);
- for_each_string_list_item(item, &option_excluded_refs)
- add_ref_exclusion(pack_refs_opts.exclusions, item->string);
+ if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
+ usage_with_options(pack_refs_usage, opts);
@@ builtin/pack-refs.c: int cmd_pack_refs(int argc,
if (!pack_refs_opts.includes->nr)
@@ builtin/pack-refs.c: int cmd_pack_refs(int argc,
clear_ref_exclusions(&excludes);
string_list_clear(&included_refs, 0);
+
+ ## t/t0610-reftable-basics.sh ##
+@@ t/t0610-reftable-basics.sh: export GIT_TEST_DEFAULT_REF_FORMAT
+
+ INVALID_OID=$(test_oid 001)
+
++test_expect_success 'pack-refs does not crash with -h' '
++ test_expect_code 129 git pack-refs -h >usage &&
++ test_grep "[Uu]sage: git pack-refs " usage &&
++ test_expect_code 129 nongit git pack-refs -h >usage &&
++ test_grep "[Uu]sage: git pack-refs " usage
++'
++
+ test_expect_success 'init: creates basic reftable structures' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
9: 2aff17b09c ! 6: 51c80f9273 builtin/ls-files: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_ls_files()` function with `repo` set
to NULL and then early in the function, `show_usage_with_options_if_asked()`
- call will give the options help and exit, without having to consult much
- of the configuration file.
+ call will give the options help and exit.
Pass the repository available in the calling context to both
`expand_objectsize()` and `show_ru_info()` to remove their
@@ builtin/ls-files.c: int cmd_ls_files(int argc,
if (ps_matched && report_path_error(ps_matched, &pathspec)) {
fprintf(stderr, "Did you forget to 'git add'?\n");
+
+ ## t/t3004-ls-files-basic.sh ##
+@@ t/t3004-ls-files-basic.sh: test_expect_success 'ls-files -h in corrupt repository' '
+ test_grep "[Uu]sage: git ls-files " broken/usage
+ '
+
++test_expect_success 'ls-files does not crash with -h' '
++ test_expect_code 129 git ls-files -h >usage &&
++ test_grep "[Uu]sage: git ls-files " usage &&
++ test_expect_code 129 nongit git ls-files -h >usage &&
++ test_grep "[Uu]sage: git ls-files " usage
++'
++
+ test_expect_success SYMLINKS 'ls-files with absolute paths to symlinks' '
+ mkdir subs &&
+ ln -s nosuch link &&
10: 4cc9a4935a < -: ---------- builtin/for-each-ref: refactor `cmd_for_each_ref()`
11: 42c1a7ae74 ! 7: 63bb89291f builtin/for-each-ref: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_for_each_ref()` function with `repo`
set to NULL and then early in the function, `parse_options()` call will
- give the options help and exit, without having to consult much of the
- configuration file.
+ give the options help and exit.
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
@@ builtin/for-each-ref.c: static char const * const for_each_ref_usage[] = {
struct ref_sorting *sorting;
struct string_list sorting_options = STRING_LIST_INIT_DUP;
@@ builtin/for-each-ref.c: int cmd_for_each_ref(int argc,
- if (verify_ref_format(&format))
- usage_with_options(for_each_ref_usage, opts);
+
+ format.format = "%(objectname) %(objecttype)\t%(refname)";
- git_config(git_default_config, NULL);
+ repo_config(repo, git_default_config, NULL);
- sorting = ref_sorting_options(&sorting_options);
- ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
- filter.ignore_case = icase;
+
+ /* Set default (refname) sorting */
+ string_list_append(&sorting_options, "refname");
+
+ ## t/t6300-for-each-ref.sh ##
+@@ t/t6300-for-each-ref.sh: test_expect_success 'Check invalid atoms names are errors' '
+ test_must_fail git for-each-ref --format="%(INVALID)" refs/heads
+ '
+
++test_expect_success 'for-each-ref does not crash with -h' '
++ test_expect_code 129 git for-each-ref -h >usage &&
++ test_grep "[Uu]sage: git for-each-ref " usage &&
++ test_expect_code 129 nongit git for-each-ref -h >usage &&
++ test_grep "[Uu]sage: git for-each-ref " usage
++'
++
+ test_expect_success 'Check format specifiers are ignored in naming date atoms' '
+ git for-each-ref --format="%(authordate)" refs/heads &&
+ git for-each-ref --format="%(authordate:default) %(authordate)" refs/heads &&
12: 232cbef160 ! 8: 8dfe6b40c8 builtin/checkout-index: stop using `the_repository`
@@ Commit message
When `-h` is passed to the command outside a Git repository, the
`run_builtin()` will call the `cmd_checkout_index()` function with `repo`
set to NULL and then early in the function, `show_usage_with_options_if_asked()`
- call will give the options help and exit, without having to consult much
- of the configuration file.
+ call will give the options help and exit.
Pass the repository available in the calling context to both `checkout_all()`
and `checkout_file()` to remove their dependency on the global
@@ builtin/checkout-index.c: int cmd_checkout_index(int argc,
die("Unable to write new index file");
return 0;
}
+
+ ## t/t2006-checkout-index-basic.sh ##
+@@ t/t2006-checkout-index-basic.sh: test_expect_success 'checkout-index -h in broken repository' '
+ test_grep "[Uu]sage" broken/usage
+ '
+
++test_expect_success 'checkout-index does not crash with -h' '
++ test_expect_code 129 git checkout-index -h >usage &&
++ test_grep "[Uu]sage: git checkout-index " usage &&
++ test_expect_code 129 nongit git checkout-index -h >usage &&
++ test_grep "[Uu]sage: git checkout-index " usage
++'
++
+ test_expect_success 'checkout-index reports errors (cmdline)' '
+ test_must_fail git checkout-index -- does-not-exist 2>stderr &&
+ test_grep not.in.the.cache stderr-- 2.48.1