summaryrefslogtreecommitdiff
path: root/commit-graph.c
AgeCommit message (Collapse)AuthorFilesLines
2026-08-17odb: eagerly initialize alternatesPatrick Steinhardt1-4/+0
When creating the object database we initialize the main object database source, but we don't yet initialize its alternates. Instead, we have many calls to `odb_prepare_alternates()` cluttered around the code base whenever we are about to iterate through the sources. This lazy loading doesn't really add much value: the moment where we read any object we _have_ to load the alternates anyway. So given that most of our commands would access the object database this optimization is not really buying us much in the first place. Quite on the contrary, it makes the code harder to understand and is a potential source of bugs in case any callsite forgot to prepare alternates before we iterate through the sources. Historically though there was a reason why we deferred lazy-loading: it may happen that the repository has "core.ignoreCase" configured, and we use that to deduplicate the list of alternates in case we had the same alternate configured multiple times, but with different casing. We used to initialize the object database before we had fully configured the owning repository though, and consequently we couldn't access that configuration yet. This has changed in the preceding commit though where we started to parse "core.ignoreCase" manually. Eagerly prepare alternates both when creating the object database and when flushing its caches. Drop the now-unneeded calls to prepare the alternates that are scattered across the code base. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-30Merge branch 'rs/tempfile-wo-the-repository'Junio C Hamano1-4/+5
The tempfile and lockfile APIs have been refactored to stop depending on the 'the_repository' global variable, and their callers have been updated to use the repository-aware variants. * rs/tempfile-wo-the-repository: use repo_hold_lock_file_for_update{,_mode,_timeout}() with custom repos tempfile: stop using the_repository lockfile: add repo_hold_lock_file_for_update{,_timeout}{,_mode}() refs/packed: use repo_create_tempfile() tempfile: add repo_create_tempfile{,_mode}()
2026-07-19Merge branch 'kk/commit-graph-topo-levels-fix'Junio C Hamano1-1/+6
The 'topo_levels' slab was propagated only to the topmost layer of a split commit-graph chain, causing topological levels for commits in base layers to be recomputed during incremental writes. This has been corrected. * kk/commit-graph-topo-levels-fix: commit-graph: propagate topo_levels slab to all chain layers commit-graph: add trace2 instrumentation for generation DFS
2026-07-14use repo_hold_lock_file_for_update{,_mode,_timeout}() with custom reposRené Scharfe1-4/+5
Apply the config setting core.sharedRepository from the repository at hand instead of from the_repository. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-09commit-graph: propagate topo_levels slab to all chain layersKristofer Karlsson1-1/+1
The topo_levels slab is only propagated to the topmost graph layer instead of all layers in the chain. Commits from lower layers appear to have no generation numbers, so the DFS re-walks the entire ancestry. Fix by making topo_levels visible to all layers, not just the first one. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-09commit-graph: add trace2 instrumentation for generation DFSKristofer Karlsson1-0/+5
Count the number of steps taken in compute_reachable_generation_numbers() and expose it via trace2 to make it easier to detect performance regressions. Add a failing test for such a regression, introduced in 199d452758 (commit-graph: return the prepared commit graph from `prepare_commit_graph()`, 2025-09-04), where incremental commit-graph writes do not see existing generation numbers from lower graph layers and fall back to walking the full ancestry. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06Merge branch 'ps/odb-source-packed'Junio C Hamano1-2/+2
The packed object source has been refactored into a proper struct odb_source. * ps/odb-source-packed: odb/source-packed: drop pointer to "files" parent source midx: refactor interfaces to work on "packed" source odb/source-packed: stub out remaining functions odb/source-packed: wire up `freshen_object()` callback odb/source-packed: wire up `find_abbrev_len()` callback odb/source-packed: wire up `count_objects()` callback odb/source-packed: wire up `for_each_object()` callback odb/source-packed: wire up `read_object_stream()` callback odb/source-packed: wire up `read_object_info()` callback packfile: use higher-level interface to implement `has_object_pack()` odb/source-packed: wire up `reprepare()` callback odb/source-packed: wire up `close()` callback odb/source-packed: start converting to a proper `struct odb_source` odb/source-packed: store pointer to "files" instead of generic source packfile: move packed source into "odb/" subsystem packfile: split out packfile list logic packfile: rename `struct packfile_store` to `odb_source_packed`
2026-07-02packfile: thread odb_source_packed through packed_object_info()Patrick Steinhardt1-1/+1
Add an optional `struct odb_source_packed *source` parameter to `packed_object_info()` and `packed_object_info_with_index_pos()`. This parameter is unused at this point in time, but it will be used in a follow-up commit so that we can record the source of a specific object. Note that callers in "odb/source-packed.c" pass the already-available source, but all other callers pass `NULL` instead. This is fine though, as we only care about populating this info when called via the packed store. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-24Merge branch 'ps/odb-source-packed' into ps/odb-drop-whenceJunio C Hamano1-2/+2
* ps/odb-source-packed: odb/source-packed: drop pointer to "files" parent source midx: refactor interfaces to work on "packed" source odb/source-packed: stub out remaining functions odb/source-packed: wire up `freshen_object()` callback odb/source-packed: wire up `find_abbrev_len()` callback odb/source-packed: wire up `count_objects()` callback odb/source-packed: wire up `for_each_object()` callback odb/source-packed: wire up `read_object_stream()` callback odb/source-packed: wire up `read_object_info()` callback packfile: use higher-level interface to implement `has_object_pack()` odb/source-packed: wire up `reprepare()` callback odb/source-packed: wire up `close()` callback odb/source-packed: start converting to a proper `struct odb_source` odb/source-packed: store pointer to "files" instead of generic source packfile: move packed source into "odb/" subsystem packfile: split out packfile list logic packfile: rename `struct packfile_store` to `odb_source_packed`
2026-06-17Merge branch 'en/commit-graph-timestamp-fix'Junio C Hamano1-1/+1
compute_reachable_generation_numbers() in commit-graph used a 32-bit integer to accumulate parent generations, which is OK for generation number v1 (topological levels), but with generation number v2 (adjusted committer timestamps), it truncated timestamps beyond 2106. Fixed by widening the accumulator to timestamp_t. * en/commit-graph-timestamp-fix: commit-graph: use timestamp_t for max parent generation accumulator
2026-06-17odb/source-packed: wire up `for_each_object()` callbackPatrick Steinhardt1-2/+2
Move `packfile_store_for_each_object()` and its associated helpers from "packfile.c" into "odb/source-packed.c" and wire it up as the `for_each_object()` callback of the "packed" source. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-14commit-graph: use timestamp_t for max parent generation accumulatorElijah Newren1-1/+1
compute_reachable_generation_numbers() computes each commit's generation as max(c->date, max(parent.generation)) + 1 by walking its parents and accumulating their generations into a local uint32_t max_gen = 0; while info->get_generation() returns timestamp_t and compute_generation_from_max() already takes its max_gen parameter as timestamp_t. For v1 (topological levels) the narrowing is harmless because GENERATION_NUMBER_V1_MAX is less than 2^30, but for v2 (corrected committer dates) it silently truncates any parent generation that does not fit in 32 bits, i.e. any parent whose committer timestamp is at or beyond 2106-02-07 UTC (>= 2^32). The truncated max then causes child commits to end up with a corrected committer date that matches the parent's instead of being at least 1 higher. The bad value gets written into the commit-graph and causes problems later, and can be noticed by running `git commit-graph verify`. Widen the accumulator to timestamp_t. This is solely an in-memory arithmetic fix with no on-disk format change: the on-disk format already encodes timestamp_t values and existing readers handle them unchanged. This merely allows the code to compute the correct value to write to disk. The narrowing was introduced in 80c928d947c2 (commit-graph: simplify compute_generation_numbers(), 2023-03-20), which rewired v2 to use the shared compute_reachable_generation_numbers() helper; the helper's local accumulator had been declared uint32_t in the immediately preceding 368d19b0b7fa (commit-graph: refactor compute_topological_levels(), 2023-03-20) when only v1 was using it, where it was harmless. Add a new test with a future-dated parent and a present-day child; without the above fix, `git commit-graph verify` reports the descendant's stored generation as below parent + 1. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05setup: stop initializing object database without repositoryPatrick Steinhardt1-2/+2
The function `setup_git_directory_gently()` is responsible for discovering and setting up a Git repository based on various environment variables and the current working directory. The result is thus a fully usable Git repository. One oddity of this function is that we may set up the object database even in the case where we don't have a repository, namely in the case where the `GIT_DIR_EXPLICIT` environment variable is set but points to a non-existent repository. If so, we call `setup_git_env_internal()` with the value of the environment variable so that the repository's Git directory is configured, even if it points to a non-existent directory. Historically though, this function didn't only configure the repository, but also initialized the object database. We retained this behaviour from a preceding commit, even though it really doesn't make much sense in the first place -- there is no repository, so we don't have an object database either. There seemingly isn't much of a reason to construct the object database, as we typically won't try to read objects when we don't have an object database. There's one exception though: git-index-pack(1) may run outside of a repository, which can be used to perform consistency checks for a packfile. The code path is _almost_ working: we already know to call `parse_object_buffer()`, which can read objects without an object database being available. And that works for all object types except for commits, because `parse_commit_buffer()` calls `parse_commit_graph()`, and that function doesn't handle the case where we don't have an object database. Fix this instance to check for the object database instead of checking for the Git directory having been initialized. With this fixed, we can now stop constructing an object database completely. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-07Merge branch 'ps/commit-graph-overflow-fix'Junio C Hamano1-3/+34
Fix a regression in writing the commit-graph where commits with dates exceeding 34 bits (beyond year 2514) could cause an underflow and crash Git during the generation data overflow chunk writing. * ps/commit-graph-overflow-fix: commit-graph: fix writing generations with dates exceeding 34 bits
2026-03-24commit-graph: fix writing generations with dates exceeding 34 bitsPatrick Steinhardt1-3/+34
The `timestamp_t` type is declared as `uintmax_t` and thus typically has 64 bits of precision. Usually, the full precision of such dates is not required: it would be comforting to know that Git is still around in millions of years, but all in all the chance is rather low. We abuse this fact in the commit-graph: instead of storing the full 64 bits of precision, committer dates only store 34 bits. This is still plenty of headroom, as it means that we can represent dates until year 2514. Commits which are dated beyond that year will simply get a date whose remaining bits are masked. The result of this is somewhat curious: the committer date will be different depending on whether a commit gets parsed via the commit-graph or via the object database. This isn't really too much of an issue in general though, as we don't typically use the date parsed from the commit-graph in user-facing output. But with 024b4c9697 (commit: make `repo_parse_commit_no_graph()` more robust, 2026-02-16) it started to become a problem when writing the commit-graph itself. This commit changed `repo_parse_commit_no_graph()` so that we re-parse the commit via the object database in case it was already parsed beforehand via the commit-graph. The consequence is that we may now act with two different commit dates at different stages: - Initially, we use the 34-bit precision timestamp when writing the chunk generation data. We thus correctly compute the offsets relative to the on-disk timestamp here. - Later, when writing the overflow data, we may end up with the full-precision timestamp. When the date is larger than 34 bits the result of this is an underflow when computing the offset. This causes a mismatch in the number of generation data overflow records we want to write, and that ultimately causes Git to die. Introduce a new helper function that computes the generation offset for a commit while correctly masking the date to 34 bits. This makes the previously-implicit assumptions about the commit date precision explicit and thus hopefully less fragile going forward. Adapt sites that compute the offset to use the function. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-20odb: introduce `struct odb_for_each_object_options`Patrick Steinhardt1-1/+4
The `odb_for_each_object()` function only accepts a bitset of flags. In a subsequent commit we'll want to change object iteration to also support iterating over only those objects that have a specific prefix. While we could of course add the prefix to the function signature, or alternatively introduce a new function, both of these options don't really seem to be that sensible. Instead, introduce a new `struct odb_for_each_object_options` that can be passed to a new `odb_for_each_object_ext()` function. Splice through the options structure into the respective object database sources. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-12odb: introduce generic object countingPatrick Steinhardt1-1/+2
Similar to the preceding commit, introduce counting of objects on the object database level, replacing the logic that we have in `repo_approximate_object_count()`. Note that the function knows to cache the object count. It's unclear whether this cache is really required as we shouldn't have that many cases where we count objects repeatedly. But to be on the safe side the caching mechanism is retained, with the only excepting being that we also have to use the passed flags as caching key. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-05odb: embed base source in the "files" backendPatrick Steinhardt1-2/+4
The "files" backend is implemented as a pointer in the `struct odb_source`. This contradicts our typical pattern for pluggable backends like we use it for example in the ref store or for object database streams, where we typically embed the generic base structure in the specialized implementation. This pattern has a couple of small benefits: - We avoid an extra allocation. - We hide implementation details in the generic structure. - We can easily downcast from a generic backend to the specialized structure and vice versa because the offsets are known at compile time. - It becomes trivial to identify locations where we depend on backend specific logic because the cast needs to be explicit. Refactor our "files" object database source to do the same and embed the `struct odb_source` in the `struct odb_source_files`. There are still a bunch of sites in our code base where we do have to access internals of the "files" backend. The intent is that those will go away over time, but this will certainly take a while. Meanwhile, provide a `odb_source_files_downcast()` function that can convert a generic source into a "files" source. As we only have a single source the downcast succeeds unconditionally for now. Eventually though the intent is to make the cast `BUG()` in case the caller requests to downcast a non-"files" backend to a "files" backend. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-05odb: introduce "files" sourcePatrick Steinhardt1-1/+1
Introduce a new "files" object database source. This source encapsulates access to both loose object files and the packfile store, similar to how the "files" backend for refs encapsulates access to loose refs and the packed-refs file. Note that for now the "files" source is still a direct member of a `struct odb_source`. This architecture will be reversed in the next commit so that the files source contains a `struct odb_source`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-23Merge branch 'ps/odb-for-each-object' into ps/odb-sourcesJunio C Hamano1-14/+32
* ps/odb-for-each-object: odb: drop unused `for_each_{loose,packed}_object()` functions reachable: convert to use `odb_for_each_object()` builtin/pack-objects: use `packfile_store_for_each_object()` odb: introduce mtime fields for object info requests treewide: drop uses of `for_each_{loose,packed}_object()` treewide: enumerate promisor objects via `odb_for_each_object()` builtin/fsck: refactor to use `odb_for_each_object()` odb: introduce `odb_for_each_object()` packfile: introduce function to iterate through objects packfile: extract function to iterate through objects of a store object-file: introduce function to iterate through objects object-file: extract function to read object info from path odb: fix flags parameter to be unsigned odb: rename `FOR_EACH_OBJECT_*` flags
2026-02-13Merge branch 'ps/commit-list-functions-renamed'Junio C Hamano1-1/+1
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-01-26treewide: drop uses of `for_each_{loose,packed}_object()`Patrick Steinhardt1-13/+31
We're using `for_each_loose_object()` and `for_each_packed_object()` at a couple of callsites to enumerate all loose and packed objects, respectively. These functions will be removed in a subsequent commit in favor of the newly introduced `odb_source_loose_for_each_object()` and `packfile_store_for_each_object()` replacements. Prepare for this by refactoring the sites accordingly. Note that ideally, we'd convert all callsites to use the generic `odb_for_each_object()` function already. But for some callers this is not possible (yet), and it would require some significant refactorings to make this work. Converting these site will thus be deferred to a later patch series. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-26odb: rename `FOR_EACH_OBJECT_*` flagsPatrick Steinhardt1-2/+2
Rename the `FOR_EACH_OBJECT_*` flags to have an `ODB_` prefix. This prepares us for a new upcoming `odb_for_each_object()` function and ensures that both the function and its flags have the same prefix. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-21Merge branch 'ps/read-object-info-improvements'Junio C Hamano1-1/+1
The object-info API has been cleaned up. * ps/read-object-info-improvements: packfile: drop repository parameter from `packed_object_info()` packfile: skip unpacking object header for disk size requests packfile: disentangle return value of `packed_object_info()` packfile: always populate pack-specific info when reading object info packfile: extend `is_delta` field to allow for "unknown" state packfile: always declare object info to be OI_PACKED object-file: always set OI_LOOSE when reading object info
2026-01-15Merge branch 'ps/read-object-info-improvements' into ps/odb-for-each-objectJunio C Hamano1-1/+1
* ps/read-object-info-improvements: packfile: drop repository parameter from `packed_object_info()` packfile: skip unpacking object header for disk size requests packfile: disentangle return value of `packed_object_info()` packfile: always populate pack-specific info when reading object info packfile: extend `is_delta` field to allow for "unknown" state packfile: always declare object info to be OI_PACKED object-file: always set OI_LOOSE when reading object info
2026-01-15commit: rename `free_commit_list()` to conform to coding guidelinesPatrick Steinhardt1-1/+1
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-12packfile: drop repository parameter from `packed_object_info()`Patrick Steinhardt1-1/+1
The function `packed_object_info()` takes a packfile and offset and returns the object info for the corresponding object. Despite these two parameters though it also takes a repository pointer. This is redundant information though, as `struct packed_git` already has a repository pointer that is always populated. Drop the redundant parameter. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-25commit-graph: use commit_stackRené Scharfe1-47/+39
Replace a commit array implementation with commit_stack. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-04refs: expose peeled object ID via the iteratorPatrick Steinhardt1-1/+1
Both the "files" and "reftable" backend are able to store peeled values for tags in the respective formats. This allows for a more efficient lookup of the target object of such a tag without having to manually peel via the object database. The infrastructure to access these peeled object IDs is somewhat funky though. When iterating through objects, we store a pointer reference to the current iterator in a global variable. The callbacks invoked by that iterator are then expected to call `peel_iterated_oid()`, which checks whether the globally-stored iterator's current reference refers to the one handed into that function. If so, we ask the iterator to peel the object, otherwise we manually peel the object via the object database. Depending on global state like this is somewhat weird and also quite fragile. Introduce a new `struct reference::peeled_oid` field that can be populated by the reference backends. This field can be accessed via a new function `reference_get_peeled_oid()` that either uses that value, if set, or alternatively peels via the ODB. With this change we don't have to rely on global state anymore, but make the peeled object ID available to the callback functions directly. Adjust trivial callers that already have a `struct reference` available. Remaining callers will be adjusted in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-04refs: introduce wrapper struct for `each_ref_fn`Patrick Steinhardt1-8/+6
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-10-13Merge branch 'ps/commit-graph-per-object-source'Junio C Hamano1-63/+53
Code clean-up around commit-graph. * ps/commit-graph-per-object-source: commit-graph: pass graphs that are to be merged as parameter commit-graph: return commit graph from `repo_find_commit_pos_in_graph()` commit-graph: return the prepared commit graph from `prepare_commit_graph()` revision: drop explicit check for commit graph blame: drop explicit check for commit graph
2025-09-08Merge branch 'tc/last-modified'Junio C Hamano1-1/+6
A new command "git last-modified" has been added to show the closest ancestor commit that touched each path. * tc/last-modified: last-modified: use Bloom filters when available t/perf: add last-modified perf script last-modified: new subcommand to show when files were last modified
2025-09-04commit-graph: pass graphs that are to be merged as parameterPatrick Steinhardt1-8/+10
When determining whether or not we want to merge a commit graph chain we retrieve the graph that is to be merged via the context's repository. With an upcoming change though it will become a bit more complex to figure out the commit graph, which would lead to code duplication. Prepare for this change by passing the graph that is to be merged as a parameter. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-09-04commit-graph: return commit graph from `repo_find_commit_pos_in_graph()`Patrick Steinhardt1-6/+12
The function `repo_find_commit_pos_in_graph()` takes a commit as input and tries to figure out whether the given repository has a commit graph that contains that specific commit. If so, it returns the corresponding position of that commit inside the graph. Right now though we only return the position, but not the actual graph that the commit has been found in. This is sensible as repositories always have the graph in `struct repository::objects::commit_graph`. Consequently, the caller always knows where to find it. But in a subsequent change we're going to move the graph into the object sources. This would require callers of the function to loop through all sources to find the relevant commit graph. Refactor the code so that we instead return the commit-graph that the commit has been found with. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-09-04commit-graph: return the prepared commit graph from `prepare_commit_graph()`Patrick Steinhardt1-50/+32
When making use of commit graphs, one needs to first prepare them by calling `prepare_commit_graph()`. Once that function was called and the commit graph was prepared successfully, the caller is now expected to access the graph directly via `struct object_database::commit_graph`. In a subsequent change, we're going to move the commit graph pointer from `struct object_database` into `struct odb_source`. With this change, semantics will change so that we use the commit graph of the first source that has one. Consequently, all callers that currently deference the `commit_graph` pointer would now have to loop around the list of sources to find the commit graph. This would become quite unwieldy. So instead of shifting the burden onto such callers, adapt `prepare_commit_graph()` to return the prepared commit graph, if any. Like this, callers are expected to call that function and then use the returned commit graph. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-28last-modified: use Bloom filters when availableToon Claes1-1/+6
Our 'git last-modified' performs a revision walk, and computes a diff at each point in the walk to figure out whether a given revision changed any of the paths it considers interesting. When changed-path Bloom filters are available, we can avoid computing many such diffs. Before computing a diff, we first check if any of the remaining paths of interest were possibly changed at a given commit by consulting its Bloom filter. If any of them are, we are resigned to compute the diff. If none of those queries returned "maybe", we know that the given commit doesn't contain any changed paths which are interesting to us. So, we can avoid computing it in this case. Comparing the perf test results on git.git: Test HEAD~ HEAD ------------------------------------------------------------------------------------ 8020.1: top-level last-modified 4.49(4.34+0.11) 2.22(2.05+0.09) -50.6% 8020.2: top-level recursive last-modified 5.64(5.45+0.11) 5.62(5.30+0.11) -0.4% 8020.3: subdir last-modified 0.11(0.06+0.04) 0.07(0.03+0.04) -36.4% Based-on-patch-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-15commit-graph: stop passing in redundant repositoryPatrick Steinhardt1-70/+50
Many of the commit-graph related functions take in both a repository and the object database source (directly or via `struct commit_graph`) for which we are supposed to load such a commit-graph. In the best case this information is simply redundant as the source already contains a reference to its owning object database, which in turn has a reference to its repository. In the worst case this information could even mismatch when passing in a source that doesn't belong to the same repository. Refactor the code so that we only pass in the object database source in those cases. There is one exception though, namely `load_commit_graph_chain_fd_st()`, which is responsible for loading a commit-graph chain. It is expected that parts of the commit-graph chain aren't located in the same object source as the chain file itself, but in a different one. Consequently, this function doesn't work on the source level but on the database level instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-15commit-graph: stop using `the_repository`Patrick Steinhardt1-37/+39
There's still a bunch of uses of `the_repository` in "commit-graph.c", which we want to stop using due to it being a global variable. Refactor the code to stop using `the_repository` in favor of the repository provided via the calling context. This allows us to drop the `USE_THE_REPOSITORY_VARIABLE` macro. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-15commit-graph: stop using `the_hash_algo`Patrick Steinhardt1-13/+14
Stop using `the_hash_algo` as it implicitly relies on `the_repository`. Instead, we either use the hash algo provided via the context or, if there is no such hash algo, we use `the_repository` explicitly. Such uses will be removed in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-15commit-graph: refactor `parse_commit_graph()` to take a repositoryPatrick Steinhardt1-11/+12
Refactor `parse_commit_graph()` so that it takes a repository instead of taking repository settings. On the one hand this allows us to get rid of instances where we access `the_hash_algo` by using the repository's hash algorithm instead. On the other hand it also allows us to move the call of `prepare_repo_settings()` into the function itself. Note that there's one small catch, as the commit-graph fuzzer calls this function directly without having a fully functional repository at hand. And while the fuzzer already initializes `the_repository` with relevant info, the call to `prepare_repo_settings()` would fail because we don't have a fully-initialized repository. Work around the issue by also settings `settings.initialized` to pretend that we've already read the settings. While at it, remove the redundant `parse_commit_graph()` declaration in the fuzzer. It was added together with aa658574bf (commit-graph, fuzz: add fuzzer for commit-graph, 2019-01-15), but as we also declared the same function in "commit-graph.h" it wasn't ever needed. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-15commit-graph: store the hash algorithm instead of its lengthPatrick Steinhardt1-18/+18
The commit-graph stores the length of the hash algorithm it uses. In subsequent commits we'll need to pass the whole hash algorithm around though, which we currently don't have access to. Refactor the code so that we store the hash algorithm instead of only its size. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-15commit-graph: stop using `the_hash_algo` via macrosPatrick Steinhardt1-9/+16
We have two macros `GRAPH_DATA_WIDTH` and `GRAPH_MIN_SIZE` that compute hash-dependent sizes. They do so by using the global `the_hash_algo` variable though, which we want to get rid of over time. Convert these macros into functions that accept the hash algorithm as input parameter. Adapt callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-23config: move Git config parsing into "environment.c"Patrick Steinhardt1-0/+1
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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01odb: rename `has_object()`Patrick Steinhardt1-1/+1
Rename `has_object()` to `odb_has_object()` to match other functions related to the object database and our modern coding guidelines. Introduce a compatibility wrapper 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: rename `oid_object_info()`Patrick Steinhardt1-1/+1
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 alternatesPatrick Steinhardt1-2/+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-07-01object-store: rename `object_directory` to `odb_source`Patrick Steinhardt1-47/+47
The `object_directory` structure is used as an access point for a single object directory like ".git/objects". While the structure isn't yet fully self-contained, the intent is for it to eventually contain all information required to access objects in one specific location. While the name "object directory" is a good fit for now, this will change over time as we continue with the agenda to make pluggable object databases a thing. Eventually, objects may not be accessed via any kind of directory at all anymore, but they could instead be backed by any kind of durable storage mechanism. While it seems quite far-fetched for now, it is thinkable that eventually this might even be some form of a database, for example. As such, the current name of this structure will become worse over time as we evolve into the direction of pluggable ODBs. Immediate next steps will start to carve out proper self-contained object directories, which requires us to pass in these object directories as parameters. Based on our modern naming schema this means that those functions should then be named after their subsystem, which means that we would start to bake the current name into the codebase more and more. Let's preempt this by renaming the structure. There have been a couple alternatives that were discussed: - `odb_backend` was discarded because it led to the association that one object database has a single backend, but the model is that one alternate has one backend. Furthermore, "backend" is more about the actual backing implementation and less about the high-level concept. - `odb_alternate` was discarded because it is a bit of a stretch to also call the main object directory an "alternate". Instead, pick `odb_source` as the new name. It makes it sufficiently clear that there can be multiple sources and does not cause confusion when mixed with the already-existing "alternate" terminology. In the future, this change allows us to easily introduce for example a `odb_files_source` and other format-specific implementations. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01object-store: rename `raw_object_store` to `object_database`Patrick Steinhardt1-1/+1
The `raw_object_store` structure is the central entry point for reading and writing objects in a repository. The main purpose of this structure is to manage object directories and provide an interface to access and write objects in those object directories. Right now, many of the functions associated with the raw object store implicitly rely on `the_repository` to get access to its `objects` pointer, which is the `raw_object_store`. As we want to generally get rid of using `the_repository` across our codebase we will have to convert this implicit dependency on this global variable into an explicit parameter. This conversion can be done by simply passing in an explicit pointer to a repository and then using its `->objects` pointer. But there is a second effort underway, which is to make the object subsystem more selfcontained so that we can eventually have pluggable object backends. As such, passing in a repository wouldn't make a ton of sense, and the goal is to convert the object store interfaces such that we always pass in a reference to the `raw_object_store` instead. This will expose the `raw_object_store` type to a lot more callers though, which surfaces that this type is named somewhat awkwardly. The "raw_" prefix makes readers wonder whether there is a non-raw variant of the object store, but there isn't. Furthermore, we nowadays want to name functions in a way that they can be clearly attributed to a specific subsystem, but calling them e.g. `raw_object_store_has_object()` is just too unwieldy, even when dropping the "raw_" prefix. Instead, rename the structure to `object_database`. This term is already used a lot throughout our codebase, and it cannot easily be mistaken for "object directories", either. Furthermore, its acronym ODB is already well-known and works well as part of a function's name, like for example `odb_has_object()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-05-27Merge branch 'js/misc-fixes'Junio C Hamano1-71/+77
Assorted fixes for issues found with CodeQL. * js/misc-fixes: sequencer: stop pretending that an assignment is a condition bundle-uri: avoid using undefined output of `sscanf()` commit-graph: avoid using stale stack addresses trace2: avoid "futile conditional" Avoid redundant conditions fetch: avoid unnecessary work when there is no current branch has_dir_name(): make code more obvious upload-pack: rename `enum` to reflect the operation commit-graph: avoid malloc'ing a local variable fetch: carefully clear local variable's address after use commit: simplify code