summaryrefslogtreecommitdiff
path: root/submodule.c
AgeCommit message (Collapse)AuthorFilesLines
3 daysMerge branch 'pz/fetch-submodule-errors-config' into seenJunio C Hamano1-15/+43
The 'git fetch' command can now configure how submodule fetch errors are handled via 'fetch.submoduleErrors' and '--submodule-errors', making them non-fatal. A premature failure during recursive submodule fetches has been fixed by deferring the error until the OID-based retry phase fails. * pz/fetch-submodule-errors-config: fetch: add fetch.submoduleErrors to make submodule fetch errors non-fatal submodule: fix premature failure in recursive submodule fetch
11 dayssubmodule-config: remove uses of `the_repository`Patrick Steinhardt1-1/+1
Several functions in the submodule-config subsystem implicitly depend on `the_repository`. Refactor these to take a `struct repository` as parameter and adapt callers accordingly. Note that as usual with these refactorings, callers simply pass `the_repository` even if they already have a different repository available in the calling context. This simplifies the migration and ensures that we don't have a change in behaviour. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-27Merge branch 'ps/refs-wo-the-repository'Junio C Hamano1-1/+1
The ref subsystem and the worktree API have been refactored to pass a repository pointer down the call chain, allowing them to drop references to the global 'the_repository' variable. As part of this, the handling of the 'core.packedRefsTimeout' configuration has been moved into the per-repository ref store structure. * ps/refs-wo-the-repository: refs: remove remaining uses of `the_repository` worktree: pass repository to public functions worktree: pass repository to file-local functions worktree: refactor code to use available repositories refs/files: drop `USE_THE_REPOSITORY_VARIABLE` refs/packed: de-globalize handling of "core.packedRefsTimeout"
2026-07-19Merge branch 'ty/migrate-ignorecase'Junio C Hamano1-1/+1
The global configuration variable 'ignore_case' (representing the 'core.ignorecase' configuration) has been migrated into 'struct repo_config_values' to tie it to a specific repository instance. * ty/migrate-ignorecase: config: use repo_ignore_case() to access core.ignorecase environment: move ignore_case into repo_config_values
2026-07-16Merge branch 'js/coverity-fixes'Junio C Hamano1-9/+10
Various resource leaks, invalid file descriptor closures, and process handle ownership issues flagged by Coverity have been fixed. * js/coverity-fixes: mingw: make `exit_process()` own the process handle on all paths fsmonitor: plug token-data leak on early daemon-startup failures reftable/table: release filter on error path imap-send: avoid leaking the IMAP upload buffer worktree: fix resource leaks when branch creation fails submodule: fix cwd leak in `get_superproject_working_tree()` dir: free allocations on parse-error paths in `read_one_dir()` line-log: avoid redundant copy that leaks in process_ranges run-command: avoid `close(-1)` in `start_command()` error paths download_https_uri_to_file(): do not leak fd upon failure loose: avoid closing invalid fd on error path load_one_loose_object_map(): fix resource leak
2026-07-16fetch: add fetch.submoduleErrors to make submodule fetch errors non-fatalPaulius Zaleckas1-2/+6
When fetching with --recurse-submodules, a submodule commit that is not yet reachable from any of the submodule's remote refs causes the entire fetch to fail. This is overly strict when the missing commit belongs to an upstream branch that is still being prepared (e.g. an in-progress merge topic): the local branch does not need that commit, so there is no reason to treat its absence as fatal. Add a new config key fetch.submoduleErrors (values: fail/warn) and a corresponding --submodule-errors=(fail|warn) command-line option that control this behaviour. The default remains fail (existing behaviour); setting the value to warn causes submodule fetch failures to be reported on stderr without affecting the overall exit status of git fetch / git pull. Forward the option to child fetches in add_options_to_argv() so that it also takes effect for `git fetch --all` / `--multiple` (where per-remote child processes handle the submodule recursion themselves) and for nested submodule recursion. The resolved value is forwarded whenever it was set explicitly, in either direction: the per-remote children re-read the repository configuration, so a command-line --submodule-errors=fail must be passed down to them to override fetch.submoduleErrors=warn from the configuration. When neither the configuration nor the command line sets a value, nothing is forwarded and the child processes fall back to their own configuration. Helped-by: Jean-Noël Avila <avila.jn@gmail.com> Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Paulius Zaleckas <paulius.zaleckas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-16submodule: fix premature failure in recursive submodule fetchPaulius Zaleckas1-14/+38
When git fetch --recurse-submodules encounters a failure fetching a submodule's refs (phase 1), it immediately marks the overall operation as failed, even though a subsequent OID-based fetch (phase 2) is about to be attempted for any missing commits. If phase 2 succeeds, the overall result should be success, but the prematurely set failure flag makes it look like an error. Restructure fetch_finish() so that a phase-1 failure does not record an error immediately. Instead, the decision is deferred: - If missing commits trigger a phase-2 (OID-based) retry and that retry succeeds, no error is recorded. - If the phase-2 retry also fails, the error is recorded then. - If the submodule was fetched unconditionally (RECURSE_SUBMODULES_ON) and is not in the changed list, a phase-1 failure is recorded right away since there is no OID retry to fall back on. - If phase 1 fails but all required commits are already present locally, there is no retry to defer to; the failure is still recorded, since the fetch itself went wrong (e.g. a transport error) even though the wanted commits happen to be available. This resolves the NEEDSWORK comment added by bd5e567dc7 (submodule: explain first attempt failure clearly, 2019-03-13). Extract the common error-recording logic into a helper record_fetch_error() and use it in fetch_start_failure() and for the "Could not access submodule" error in get_fetch_task_from_index() as well; the latter now also lists the submodule in the final error summary. Add a test ensuring a failed submodule fetch is still reported when the gitlinked commits happen to be present locally. Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Paulius Zaleckas <paulius.zaleckas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-16worktree: pass repository to public functionsPatrick Steinhardt1-1/+1
Refactor remaining public functions that still depend on `the_repository` to instead receive a repository as parameter. This allows us to get rid of `USE_THE_REPOSITORY_VARIABLE`. Adapt callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06Merge branch 'jk/setup-gitfile-diag-fix'Junio C Hamano1-1/+1
A regression in the error diagnosis code for invalid .git files has been fixed, avoiding a potential NULL-pointer crash when reporting that a .git file does not point to a valid repository. * jk/setup-gitfile-diag-fix: read_gitfile(): simplify NOT_A_REPO error message
2026-07-05submodule: fix cwd leak in `get_superproject_working_tree()`Johannes Schindelin1-9/+10
`get_superproject_working_tree()` allocates cwd via `xgetcwd()` at the top of the function, but two early-return paths (when not inside a work tree, and when strbuf_realpath for "../" fails) return 0 without freeing it. Redirect these early returns through a cleanup label that frees cwd before returning. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-19config: use repo_ignore_case() to access core.ignorecaseTian Yuchen1-1/+1
Replace the accesses to the global 'ignore_case' variable with calls to 'repo_ignore_case(the_repository)'. This step eliminates the 'ignore_case' global state. Note on compat/win32/path-utils.c: To eliminate the global state, several helper functions (e.g. 'win32_fspathncmp()') now read from 'repo_ignore_case(the_repository)'. While this introduces dependency on 'repository.h' into the 'compat/', it avoids massive refactoring of the signatures across the codebase. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com> Mentored-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Tian Yuchen <cat@malon.dev> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-16read_gitfile(): simplify NOT_A_REPO error messageJeff King1-1/+1
If a .git file is well-formed but points to a directory that is not itself a valid repository, then we say: fatal: not a git repository: <pointed-to-repo> without mentioning the .git file that pointed us there in the first place. Doing so could better help the user understand the source of the problem. In theory the most helpful thing we could do is mention both paths, like: gitfile '<gitfile>' points to invalid repository: <pointed-to-repo> But there's another catch: when we generate the error, we don't always know the pointed-to repository! This leads to a potential segfault. The message comes from read_gitfile_error_die(). Originally we only called that function from inside read_gitfile_gently(), passing in both the gitfile path and the pointed-to path. But that changed in 1dd27bfbfd (setup: improve error diagnosis for invalid .git files, 2026-03-04). Since then, the caller in setup_git_directory_gently(), even if it wants to die on error, always passes in the "return_error_code" flag, asking the function to instead return a numeric error code. And then it calls read_gitfile_error_die() itself, passing NULL for the pointed-to path. If we get the READ_GITFILE_ERR_NOT_A_REPO code, we form a message using that NULL pointer, and either segfault or get garbage like "not a git repository: (null)", depending on the platform. We could fix this by having the function pass out both the numeric error code and the pointed-to path. But that creates a new headache: we have to allocate that string on the heap and pass ownership back to the caller. So now every caller has to be aware of it (and either free the result, or signal that they are not interested by using an extra parameter). Instead, let's just drop the pointed-to path from the error message entirely, and mention only the gitfile. This fixes the NULL dereference without introducing any more complexity. The user-facing error message is not as detailed as it could be, but is better than the original. Since it mentions the gitfile, a user investigating the situation can look there to find the pointed-to path (whereas you could not go the other way from the original message). There's an existing test in t0002 which triggers this case, but we didn't notice the problem because it checks only that we said "not a repository", and not the full string. So if we print "(null)" it is happy. It will probably crash on some non-glibc platforms, but nobody seems to have reported it yet (the breakage is recent-ish as of v2.54). I'm also somewhat surprised that building with ASan/UBSan doesn't catch this, but it doesn't seem to (and I found an open issue with somebody asking for NULL printf checks to be implemented in the sanitizers). We'll tweak the test to match the new error, but there's no need to beef it up further, since we're not showing the pointed-to path at all. We also racily trigger this in t7450. During parallel cloning we might see one of several errors, including this one. And so we must update that message, too (you can otherwise find the failure pretty quickly by running t7450 with --stress). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-15Merge branch 'ob/more-repo-config-values'Junio C Hamano1-3/+4
Many core configuration variables have been migrated from global variables into 'repo_config_values' to tie them to a specific repository instance, avoiding cross-repository state leakage. * ob/more-repo-config-values: environment: move "warn_on_object_refname_ambiguity" into `struct repo_config_values` environment: move "sparse_expect_files_outside_of_patterns" into `struct repo_config_values` environment: move "core_sparse_checkout_cone" into `struct repo_config_values` environment: move "precomposed_unicode" into `struct repo_config_values` environment: move "pack_compression_level" into `struct repo_config_values` environment: move `zlib_compression_level` into `struct repo_config_values` environment: move "check_stat" into `struct repo_config_values` environment: move "trust_ctime" into `struct repo_config_values`
2026-06-03environment: move "warn_on_object_refname_ambiguity" into `struct ↵Olamide Caleb Bello1-3/+4
repo_config_values` The `core.warnAmbiguousRefs` configuration was previously stored in a global `int` variable, making it shared across repository instances and risking cross‑repository state leakage. Store it instead in `repo_config_values`, where eagerly‑parsed repository configuration lives. This option is parsed eagerly because ambiguity warnings influence how users interpret object references in many commands; a lazy parse could cause these warnings to behave inconsistently or to appear for the wrong repository, confusing users and hindering libification. This preserves the existing behavior while tying the value to the repository from which it was read, avoiding cross‑repository state leakage and continuing the effort to reduce reliance on global configuration state. Update all references to use `repo_config_values()`. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `is_inside_work_tree()`Patrick Steinhardt1-1/+1
Similar as with the preceding commit, `is_inside_work_tree()` determines whether the current working directory is located inside the worktree of `the_repository`. Perform the same refactoring by dropping the caching mechanism and injecting the repository that shall be checked. Note that, same as in the preceding commit, we're also resolving the worktree path via `realpath()`. In theory this step is not necessary as we always set the worktree path via `repo_set_worktree()`, and that function already resolves the path for us. But resolving the path a second time is unlikely to matter performance-wise, and it feels fragile to rely on the repository's worktree path being absolute. We thus perform the same extra step even though it's ultimately not required. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-01Merge branch 'rs/use-strvec-pushv'Junio C Hamano1-3/+1
Code paths that loop over another array to push each element into a strvec have been rewritten to use strvec_pushv() instead. * rs/use-strvec-pushv: use strvec_pushv() to add another strvec
2026-03-24use strvec_pushv() to add another strvecJunio C Hamano1-3/+1
Add and apply a semantic patch that simplifies the code by letting strvec_pushv() append the items of a second strvec instead of pushing them one by one. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-23Merge branch 'ng/submodule-default-remote'Junio C Hamano1-2/+15
Instead of hardcoded 'origin', use the configured default remote when fetching from submodules. * ng/submodule-default-remote: submodule: fetch missing objects from default remote
2026-03-16Merge branch 'ty/setup-error-tightening'Junio C Hamano1-1/+1
While discovering a ".git" directory, the code treats any stat() failure as a sign that a filesystem entity .git does not exist there, and ignores ".git" that is not a "gitdir" file or a directory. The code has been tightened to notice and report filesystem corruption better. * ty/setup-error-tightening: setup: improve error diagnosis for invalid .git files
2026-03-04setup: improve error diagnosis for invalid .git filesTian Yuchen1-1/+1
'read_gitfile_gently()' treats any non-regular file as 'READ_GITFILE_ERR_NOT_A_FILE' and fails to discern between 'ENOENT' and other stat failures. This flawed error reporting is noted by two 'NEEDSWORK' comments. Address these comments by introducing two new error codes: 'READ_GITFILE_ERR_MISSING'(which groups the "file missing" scenarios together) and 'READ_GITFILE_ERR_IS_A_DIR': 1. Update 'read_gitfile_error_die()' to treat 'IS_A_DIR', 'MISSING', 'NOT_A_FILE' and 'STAT_FAILED' as non-fatal no-ops. This accommodates intentional non-repo scenarios (e.g., GIT_DIR=/dev/null). 2. Explicitly catch 'NOT_A_FILE' and 'STAT_FAILED' during discovery and call 'die()' if 'die_on_error' is set. 3. Unconditionally pass '&error_code' to 'read_gitfile_gently()'. 4. Only invoke 'is_git_directory()' when we explicitly receive 'READ_GITFILE_ERR_IS_A_DIR', avoiding redundant checks. Additionally, audit external callers of 'read_gitfile_gently()' in 'submodule.c' and 'worktree.c' to accommodate the refined error codes. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-03submodule: fetch missing objects from default remoteNasser Grainawi1-2/+15
When be76c21282 (fetch: ensure submodule objects fetched, 2018-12-06) added support for fetching a missing submodule object by id, it hardcoded the remote name as "origin" and deferred anything more complicated for a later patch. Implement the NEEDSWORK item to remove the hardcoded assumption by adding and using a submodule helper subcmd 'get-default-remote'. Fixing this lets 'git fetch --recurse-submodules' succeed when the fetched commit(s) in the superproject trigger a submodule fetch, and that submodule's default remote name is not "origin". Add non-"origin" remote tests to t5526-fetch-submodules.sh and t5572-pull-submodule.sh demonstrating this works as expected and add dedicated tests for get-default-remote. Signed-off-by: Nasser Grainawi <nasser.grainawi@oss.qualcomm.com> Reviewed-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-23refs: rename `each_ref_fn`Patrick Steinhardt1-1/+1
Similar to the preceding commit, rename `each_ref_fn` to better match our current best practices around how we name things. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-13Merge branch 'ps/commit-list-functions-renamed'Junio C Hamano1-2/+2
Rename three functions around the commit_list data structure. * ps/commit-list-functions-renamed: commit: rename `free_commit_list()` to conform to coding guidelines commit: rename `reverse_commit_list()` to conform to coding guidelines commit: rename `copy_commit_list()` to conform to coding guidelines
2026-02-05Merge branch 'ar/submodule-gitdir-tweak'Junio C Hamano1-33/+190
Avoid local submodule repository directory paths overlapping with each other by encoding submodule names before using them as path components. * ar/submodule-gitdir-tweak: submodule: detect conflicts with existing gitdir configs submodule: hash the submodule name for the gitdir path submodule: fix case-folding gitdir filesystem collisions submodule--helper: fix filesystem collisions by encoding gitdir paths builtin/credential-store: move is_rfc3986_unreserved to url.[ch] submodule--helper: add gitdir migration command submodule: allow runtime enabling extensions.submodulePathConfig submodule: introduce extensions.submodulePathConfig builtin/submodule--helper: add gitdir command submodule: always validate gitdirs inside submodule_name_to_gitdir submodule--helper: use submodule_name_to_gitdir in add_submodule
2026-01-15commit: rename `free_commit_list()` to conform to coding guidelinesPatrick Steinhardt1-2/+2
Our coding guidelines say that: Functions that operate on `struct S` are named `S_<verb>()` and should generally receive a pointer to `struct S` as first parameter. While most of the functions related to `struct commit_list` already follow that naming schema, `free_commit_list()` doesn't. Rename the function to address this and adjust all of its callers. Add a compatibility wrapper for the old function name to ease the transition and avoid any semantic conflicts with in-flight patch series. This wrapper will be removed once Git 2.53 has been released. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12submodule: detect conflicts with existing gitdir configsAdrian Ratiu1-0/+61
Credit goes to Emily and Josh for testing and noticing a corner-case which caused conflicts with existing gitdir configs to silently pass validation, then fail later in add_submodule() with a cryptic error: fatal: A git directory for 'nested%2fsub' is found locally with remote(s): origin /.../trash directory.t7425-submodule-gitdir-path-extension/sub This change ensures the validation step checks existing gitdirs for conflicts. We only have to do this for submodules having gitdirs, because those without submodule.%s.gitdir need to be migrated and will throw an error earlier in the submodule codepath. Quoting Josh: My testing setup has been as follows: * Using our locally-built Git with our downstream patch of [1] included: * create a repo "sub" * create a repo "super" * In "super": * mkdir nested * git submodule add ../sub nested/sub * Verify that the submodule's gitdir is .git/modules/nested%2fsub * Using a build of git from upstream `next` plus this series: * git config set --global extensions.submodulepathconfig true * git clone --recurse-submodules super super2 * create a repo "nested%2fsub" * In "super2": * git submodule add ../nested%2fsub At this point I'd expect the collision detection / encoding to take effect, but instead I get the error listed above. End quote Suggested-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12submodule: fix case-folding gitdir filesystem collisionsAdrian Ratiu1-1/+52
Add a new check when extension.submodulePathConfig is enabled, to detect and prevent case-folding filesystem colisions. When this new check is triggered, a stricter casefolding aware URI encoding is used to percent-encode uppercase characters. By using this check/retry mechanism the uppercase encoding is only applied when necessary, so case-sensitive filesystems are not affected. Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12submodule--helper: fix filesystem collisions by encoding gitdir pathsAdrian Ratiu1-1/+41
Fix nested filesystem collisions by url-encoding gitdir paths stored in submodule.%s.gitdir, when extensions.submodulePathConfig is enabled. Credit goes to Junio and Patrick for coming up with this design: the encoding is only applied when necessary, to newly added submodules. Existing modules don't need the encoding because git already errors out when detecting nested gitdirs before this patch. This commit adds the basic url-encoding and some tests. Next commits extend the encode -> validate -> retry loop to fix more conflicts. Suggested-by: Junio C Hamano <gitster@pobox.com> Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12submodule: introduce extensions.submodulePathConfigAdrian Ratiu1-26/+35
The idea of this extension is to abstract away the submodule gitdir path implementation: everyone is expected to use the config and not worry about how the path is computed internally, either in git or other implementations. With this extension enabled, the submodule.<name>.gitdir repo config becomes the single source of truth for all submodule gitdir paths. The submodule.<name>.gitdir config is added automatically for all new submodules when this extension is enabled. Git will throw an error if the extension is enabled and a config is missing, advising users how to migrate. Migration is manual for now. E.g. to add a missing config entry for an existing "foo" module: git config submodule.foo.gitdir .git/modules/foo Suggested-by: Junio C Hamano <gitster@pobox.com> Suggested-by: Phillip Wood <phillip.wood123@gmail.com> Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12submodule: always validate gitdirs inside submodule_name_to_gitdirAdrian Ratiu1-8/+4
Move the ad-hoc validation checks sprinkled across the source tree, after calling submodule_name_to_gitdir() into the function proper, which now always validates the gitdir before returning it. This simplifies the API and helps to: 1. Avoid redundant validation calls after submodule_name_to_gitdir(). 2. Avoid the risk of callers forgetting to validate. 3. Ensure gitdir paths provided by users via configs are always valid (config gitdir paths are added in a subsequent commit). The validation function can still be called as many times as needed outside submodule_name_to_gitdir(), for example we keep two calls which are still required, to avoid parallel clone races by re-running the validation in builtin/submodule-helper.c. Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-04refs: introduce wrapper struct for `each_ref_fn`Patrick Steinhardt1-9/+3
The `each_ref_fn` callback function type is used across our code base for several different functions that iterate through reference. There's a bunch of callbacks implementing this type, which makes any changes to the callback signature extremely noisy. An example of the required churn is e8207717f1 (refs: add referent to each_ref_fn, 2024-08-09): adding a single argument required us to change 48 files. It was already proposed back then [1] that we might want to introduce a wrapper structure to alleviate the pain going forward. While this of course requires the same kind of global refactoring as just introducing a new parameter, it at least allows us to more change the callback type afterwards by just extending the wrapper structure. One counterargument to this refactoring is that it makes the structure more opaque. While it is obvious which callsites need to be fixed up when we change the function type, it's not obvious anymore once we use a structure. That being said, we only have a handful of sites that actually need to populate this wrapper structure: our ref backends, "refs/iterator.c" as well as very few sites that invoke the iterator callback functions directly. Introduce this wrapper structure so that we can adapt the iterator interfaces more readily. [1]: <ZmarVcF5JjsZx0dl@tanuki> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-09-22treewide: use setup_revisions_from_strvec() when we have a strvecJeff King1-1/+1
The previous commit introduced a wrapper to make using setup_revisions() with a strvec easier and safer. It converted spots that were already doing most of what the wrapper did. Let's now convert spots where we were not setting up the free_removed_argv_elements flag. As discussed in the previous commit, this probably isn't fixing any bugs or leaks (since these sites wouldn't trigger the re-shuffling of argv that causes them). This is mostly future-proofing us against setup_revisions() becoming more aggressive about its re-shuffling. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-23config: drop `git_config_set_in_file_gently()` wrapperPatrick Steinhardt1-1/+1
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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01odb: rename `oid_object_info()`Patrick Steinhardt1-3/+2
Rename `oid_object_info()` to `odb_read_object_info()` as well as their `_extended()` variant to match other functions related to the object database and our modern coding guidelines. Introduce compatibility wrappers so that any in-flight topics will continue to compile. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01odb: get rid of `the_repository` when handling submodule sourcesPatrick Steinhardt1-26/+0
The "--recursive" flag for git-grep(1) allows users to grep for a string across submodule boundaries. To make this work we add each submodule's object sources to our own object database so that the objects can be accessed directly. The infrastructure for this depends on a global string list of submodule paths. The caller is expected to call `add_submodule_odb_by_path()` for each source and the object database will then eventually register all submodule sources via `do_oid_object_info_extended()` in case it isn't able to look up a specific object. This reliance on global state is of course suboptimal with regards to our libification efforts. Refactor the logic so that the list of submodule sources is instead tracked in the object database itself. This allows us to lose the condition of `r == the_repository` before registering submodule sources as we only ever add submodule sources to `the_repository` anyway. As such, behaviour before and after this refactoring should always be the same. Rename the functions accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01odb: get rid of `the_repository` when handling alternatesPatrick Steinhardt1-1/+2
The functions to manage alternates all depend on `the_repository`. Refactor them to accept an object database as a parameter and adjust all callers. The functions are renamed accordingly. Note that right now the situation is still somewhat weird because we end up using the object store path provided by the object store's repository anyway. Consequently, we could have instead passed in a pointer to the repository instead of passing in the pointer to the object store. This will be addressed in subsequent commits though, where we will start to use the path owned by the object store itself. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01object-store: rename files to "odb.{c,h}"Patrick Steinhardt1-1/+1
In the preceding commits we have renamed the structures contained in "object-store.h" to `struct object_database` and `struct odb_backend`. As such, the code files "object-store.{c,h}" are confusingly named now. Rename them to "odb.{c,h}" accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-15object-store: merge "object-store-ll.h" and "object-store.h"Patrick Steinhardt1-1/+1
The "object-store-ll.h" header has been introduced to keep transitive header dependendcies and compile times at bay. Now that we have created a new "object-store.c" file though we can easily move the last remaining additional bit of "object-store.h", the `odb_path_map`, out of the header. Do so. As the "object-store.h" header is now equivalent to its low-level alternative we drop the latter and inline it into the former. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-15object-file: move `safe_create_leading_directories()` into "path.c"Patrick Steinhardt1-1/+1
The `safe_create_leading_directories()` function and its relatives are located in "object-file.c", which is not a good fit as they provide generic functionality not related to objects at all. Move them into "path.c", which already hosts `safe_create_dir()` and its relative `safe_create_dir_in_gitdir()`. "path.c" is free of `the_repository`, but the moved functions depend on `the_repository` to read the "core.sharedRepository" config. Adapt the function signature to accept a repository as argument to fix the issue and adjust callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-03-10hash: stop depending on `the_repository` in `null_oid()`Patrick Steinhardt1-14/+14
The `null_oid()` function returns the object ID that only consists of zeroes. Naturally, this ID also depends on the hash algorithm used, as the number of zeroes is different between SHA1 and SHA256. Consequently, the function returns the hash-algorithm-specific null object ID. This is currently done by depending on `the_hash_algo`, which implicitly makes us depend on `the_repository`. Refactor the function to instead pass in the hash algorithm for which we want to retrieve the null object ID. Adapt callsites accordingly by passing in `the_repository`, thus bubbling up the dependency on that global variable by one layer. There are a couple of trivial exceptions for subsystems that already got rid of `the_repository`. These subsystems instead use the repository that is available via the calling context: - "builtin/grep.c" - "grep.c" - "refs/debug.c" There are also two non-trivial exceptions: - "diff-no-index.c": Here we know that we may not have a repository initialized at all, so we cannot rely on `the_repository`. Instead, we adapt `diff_no_index()` to get a `struct git_hash_algo` as parameter. The only caller is located in "builtin/diff.c", where we know to call `repo_set_hash_algo()` in case we're running outside of a Git repository. Consequently, it is fine to continue passing `the_repository->hash_algo` even in this case. - "builtin/ls-files.c": There is an in-flight patch series that drops `USE_THE_REPOSITORY_VARIABLE` in this file, which causes a semantic conflict because we use `null_oid()` in `show_submodule()`. The value is passed to `repo_submodule_init()`, which may use the object ID to resolve a tree-ish in the superproject from which we want to read the submodule config. As such, the object ID should refer to an object in the superproject, and consequently we need to use its hash algorithm. This means that we could in theory just not bother about this edge case at all and just use `the_repository` in "diff-no-index.c". But doing so would feel misdesigned. Remove the `USE_THE_REPOSITORY_VARIABLE` preprocessor define in "hash.c". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-02-07submodule: refactor `submodule_to_gitdir()` to accept a repoPatrick Steinhardt1-5/+6
The `submodule_to_gitdir()` function implicitly uses `the_repository` to resolve submodule paths. Refactor the function to instead accept a repo as parameter to remove the dependency on global state. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-02-07path: refactor `repo_git_path()` family of functionsPatrick Steinhardt1-2/+2
As explained in an earlier commit, we're refactoring path-related functions to provide a consistent interface for computing paths into the commondir, gitdir and worktree. Refactor the "gitdir" family of functions accordingly. Note that the `repo_git_pathv()` function is converted into an internal implementation detail. It is only used to implement `the_repository` compatibility shims and will eventually be removed from the public interface. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-23Merge branch 'sk/calloc-not-malloc-plus-memset'Junio C Hamano1-5/+5
Code clean-up. * sk/calloc-not-malloc-plus-memset: git: use calloc instead of malloc + memset where possible
2024-12-18git: use calloc instead of malloc + memset where possibleSeija Kijin1-5/+5
Avoid calling malloc + memset by calling calloc. Signed-off-by: Seija Kijin <doremylover123@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt1-0/+1
Mark code units that generate warnings with `-Wsign-compare`. This allows for a structured approach to get rid of all such warnings over time in a way that can be easily measured. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-11-12refspec: store raw refspecs inside refspec_itemJeff King1-2/+2
The refspec struct keeps two matched arrays: one for the refspec_item structs and one for the original raw refspec strings. The main reason for this is that there are other users of refspec_item that do not care about the raw strings. But it does make managing the refspec struct awkward, as we must keep the two arrays in sync. This has led to bugs in the past (both leaks and double-frees). Let's just store a copy of the raw refspec string directly in each refspec_item struct. This simplifies the handling at a small cost: 1. Direct callers of refspec_item_init() will now get an extra copy of the refspec string, even if they don't need it. This should be negligible, as the struct is already allocating two strings for the parsed src/dst values (and we tend to only do it sparingly anyway for things like the TAG_REFSPEC literal). 2. Users of refspec_appendf() will now generate a temporary string, copy it, and then free the result (versus handing off ownership of the temporary string). We could get around this by having a "nodup" variant of refspec_item_init(), but it doesn't seem worth the extra complexity for something that is not remotely a hot code path. Code which accesses refspec->raw now needs to look at refspec->item.raw. Other callers which just use refspec_item directly can remain the same. We'll free the allocated string in refspec_item_clear(), which they should be calling anyway to free src/dst. One subtle note: refspec_item_init() can return an error, in which case we'll still have set its "raw" field. But that is also true of the "src" and "dst" fields, so any caller which does not _clear() the failed item is already potentially leaking. In practice most code just calls die() on an error anyway, but you can see the exception in valid_fetch_refspec(), which does correctly call _clear() even on error. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-11-12refspec: drop separate raw_nr countJeff King1-2/+2
A refspec struct contains zero or more refspec_item structs, along with matching "raw" strings. The items and raw strings are kept in separate arrays, but those arrays will always have the same length (because we write them only via refspec_append_nodup(), which grows both). This can lead to bugs when manipulating the array, since the arrays and lengths must be modified in lockstep. For example, the bug fixed in the previous commit, which forgot to decrement raw_nr. So let's get rid of "raw_nr" and have only "nr", making this kind of bug impossible (and also making it clear that the two are always matched, something that existing code already assumed but was not guaranteed by the interface). Even though we'd expect "alloc" and "raw_alloc" to likewise move in lockstep, we still need to keep separate counts there if we want to continue to use ALLOC_GROW() for both. Conceptually this would all be simpler if refspec_item just held onto its own raw string, and we had a single array. But there are callers which use refspec_item outside of "struct refspec" (and so don't hold on to a matching "raw" string at all), which we'd possibly need to adjust. So let's not worry about refactoring that for now, and just get rid of the redundant count variable. That is the first step on the road to combining them anyway. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02Merge branch 'ps/leakfixes-part-7'Junio C Hamano1-2/+7
More leak-fixes. * ps/leakfixes-part-7: (23 commits) diffcore-break: fix leaking filespecs when merging broken pairs revision: fix leaking parents when simplifying commits builtin/maintenance: fix leak in `get_schedule_cmd()` builtin/maintenance: fix leaking config string promisor-remote: fix leaking partial clone filter grep: fix leaking grep pattern submodule: fix leaking submodule ODB paths trace2: destroy context stored in thread-local storage builtin/difftool: plug several trivial memory leaks builtin/repack: fix leaking configuration diffcore-order: fix leaking buffer when parsing orderfiles parse-options: free previous value of `OPTION_FILENAME` diff: fix leaking orderfile option builtin/pull: fix leaking "ff" option dir: fix off by one errors for ignored and untracked entries builtin/submodule--helper: fix leaking remote ref on errors t/helper: fix leaking subrepo in nested submodule config helper builtin/submodule--helper: fix leaking error buffer builtin/submodule--helper: clear child process when not running it submodule: fix leaking update strategy ...
2024-09-27submodule: fix leaking submodule ODB pathsPatrick Steinhardt1-2/+2
In `add_submodule_odb_by_path()` we add a path into a global string list. The list is initialized with `NODUP`, which means that we do not pass ownership of strings to the list. But we use `xstrdup()` when we insert a path, with the consequence that the string will never get free'd. Plug the leak by marking the list as `DUP`. There is only a single callsite where we insert paths anyway, and as explained above that callsite was mishandling the allocation. This leak is exposed by t7814, but plugging it does not make the whole test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27submodule: fix leaking update strategyPatrick Steinhardt1-0/+5
We're not freeing the submodule update strategy command. Provide a helper function that does this for us and call it in `update_data_release()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>