summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2025-12-16Merge branch 'ps/object-read-stream'Junio C Hamano20-729/+779
The "git_istream" abstraction has been revamped to make it easier to interface with pluggable object database design. * ps/object-read-stream: streaming: drop redundant type and size pointers streaming: move into object database subsystem streaming: refactor interface to be object-database-centric streaming: move logic to read packed objects streams into backend streaming: move logic to read loose objects streams into backend streaming: make the `odb_read_stream` definition public streaming: get rid of `the_repository` streaming: rely on object sources to create object stream packfile: introduce function to read object info from a store streaming: move zlib stream into backends streaming: create structure for filtered object streams streaming: create structure for packed object streams streaming: create structure for loose object streams streaming: create structure for in-core object streams streaming: allocate stream inside the backend-specific logic streaming: explicitly pass packfile info when streaming a packed object streaming: propagate final object type via the stream streaming: drop the `open()` callback function streaming: rename `git_istream` into `odb_read_stream`
2025-12-16diff-files: fix copy detectionRené Scharfe2-4/+31
Copy detection cannot work when comparing the index to the working tree because Git ignores files that it is not explicitly told to track. It should work in the other direction, though, i.e. for a reverse diff of the deletion of a copy from the index. d1f2d7e8ca (Make run_diff_index() use unpack_trees(), not read_tree(), 2008-01-19) broke it with a seemingly stray change to run_diff_files(). We didn't notice because there's no test for that. But even if we had one, it might have gone unnoticed because the breakage only happens with index preloading, which requires at least 1000 entries (more than most test repos have) and is racy because it runs in parallel with the actual command. Fix copy detection by queuing up-to-date and skip-worktree entries using diff_same(). While at it, use diff_same() also for queuing unchanged files not flagged as up-to-date, i.e. clean submodules and entries where preloading was not done at all or not quickly enough. It uses less memory than diff_change() and doesn't unnecessarily set the diff flag has_changes. Add two tests to cover running both without and with preloading. The first one passes reliably with the original code. The second one enables preloading and thus is racy. It has a good chance to pass even without the fix, but fails within seconds when running the test script with --stress. With the fix it runs fine for several minutes, until my patience runs out. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-16Merge branch 'rs/diff-index-find-copies-harder-optim' into ↵Junio C Hamano3-7/+31
rs/diff-files-r-find-copies-fix * rs/diff-index-find-copies-harder-optim: diff-index: don't queue unchanged filepairs with diff_change()
2025-12-16docs: clarify git-rev-list(1) --filter behaviorJustin Tobler1-1/+3
When using the --filter option for git-rev-list(1), objects that are explicitly provided ignore filters and are always printed unless the --filter-provided-objects option is also specified. Clarify this behavior in the documentation. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-16scalar: document config settingsDerrick Stolee2-0/+168
Add user-facing documentation that justifies the values being set by 'scalar clone', 'scalar register', and 'scalar reconfigure'. Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-15Merge branch 'ps/object-read-stream' into ps/packfile-store-in-odb-sourceJunio C Hamano20-729/+779
* ps/object-read-stream: streaming: drop redundant type and size pointers streaming: move into object database subsystem streaming: refactor interface to be object-database-centric streaming: move logic to read packed objects streams into backend streaming: move logic to read loose objects streams into backend streaming: make the `odb_read_stream` definition public streaming: get rid of `the_repository` streaming: rely on object sources to create object stream packfile: introduce function to read object info from a store streaming: move zlib stream into backends streaming: create structure for filtered object streams streaming: create structure for packed object streams streaming: create structure for loose object streams streaming: create structure for in-core object streams streaming: allocate stream inside the backend-specific logic streaming: explicitly pass packfile info when streaming a packed object streaming: propagate final object type via the stream streaming: drop the `open()` callback function streaming: rename `git_istream` into `odb_read_stream`
2025-12-14The eighth batchJunio C Hamano1-0/+18
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14Merge branch 'je/doc-data-model'Junio C Hamano1-2/+0
Docfix. * je/doc-data-model: doc: remove stray text in Git data model
2025-12-14Merge branch 'lo/repo-struct-z'Junio C Hamano3-7/+19
"git repo struct" learned to take "-z" as a synonym to "--format=nul". * lo/repo-struct-z: repo: add -z as an alias for --format=nul to git-repo-structure repo: use [--format=... | -z] instead of [-z] in git-repo-info synopsis repo: remove blank line from Documentation/git-repo.adoc
2025-12-14Merge branch 'kh/advise-w-git-help-in-branch'Junio C Hamano3-5/+5
A help message from "git branch" now mentions "git help" instead of "man" when suggesting to read some documentation. * kh/advise-w-git-help-in-branch: branch: advice using git-help(1) instead of man(1)
2025-12-14Merge branch 'je/doc-pull'Junio C Hamano1-2/+2
Doc fixup. * je/doc-pull: doc: git-pull: fix 'git --rebase abort' typo
2025-12-14Merge branch 'tc/meson-cross-compile-fix'Junio C Hamano2-2/+3
Build fix. * tc/meson-cross-compile-fix: meson: use is_cross_build() where possible meson: only detect ICONV_OMITS_BOM if possible meson: ignore subprojects/.wraplock
2025-12-14Merge branch 'js/last-modified-with-sparse-checkouts'Junio C Hamano2-1/+10
"git last-modified" used to mishandle "--" to mark the beginning of pathspec, which has been corrected. * js/last-modified-with-sparse-checkouts: last-modified: support sparse checkouts
2025-12-14Merge branch 'rs/diff-index-find-copies-harder-optim'Junio C Hamano3-7/+31
Halve the memory consumed by artificial filepairs created during "git diff --find-copioes-harder", also making the operation run faster. * rs/diff-index-find-copies-harder-optim: diff-index: don't queue unchanged filepairs with diff_change()
2025-12-14Merge branch 'tc/last-modified-active-paths-optimization'Junio C Hamano1-1/+1
Recent optimization to "last-modified" command introduced use of uninitialized block of memory, which has been corrected. * tc/last-modified-active-paths-optimization: last-modified: fix use of uninitialized memory
2025-12-14doc: replay: link section using markupKristoffer Haugsbakk1-1/+2
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14replay: improve --contained and add to docKristoffer Haugsbakk2-1/+5
There is no documentation for `--contained`. Start by copying the text from `replay_options` in `builtin/ replay.c`. But some people think that the existing text is a bit unclear; what does it mean for a branch to be contained in a revision range? Let’s include the implied commits here: the branches that point at commits in the range. Also use “update” instead of “advance”. “Update” is the verb commonly used in this context. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14doc: replay: mention no output on conflictsKristoffer Haugsbakk1-0/+4
Some commands will produce output on stderr if there are conflicts, but git-replay(1) is completely silent. Explicitly spell that out. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14t4014: support Git version strings with spacesRené Scharfe1-1/+1
git --version reports its version with the prefix "git version ". Remove precisely this string instead of everything up to and including the rightmost space to avoid butchering version strings that contain spaces. This helps Apple's release of Git, which reports its version like this: "git version 2.50.1 (Apple Git-155)". Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13cocci: use MEMZERO_ARRAY() a bit moreJunio C Hamano3-6/+6
Existing code in files that have been fairly stable trigger the "make coccicheck" suggestions due to the new check. Rewrite them to use MEMZERO_ARRAY() Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13coccicheck: emit the contents of cocci patchJunio C Hamano1-1/+1
Telling the user "you got some error messages" without showing what the errors are is almost useless in CI environment, as the errors cannot be examined without downloading build artifacts. Arrange it to spew out the output when it fails. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13Merge branch 'tc/memzero-array' into jc/memzero-arrayJunio C Hamano10-10/+36
* tc/memzero-array: contrib/coccinelle: pass include paths to spatch(1) git-compat-util: introduce MEMZERO_ARRAY() macro last-modified: fix use of uninitialized memory
2025-12-13scalar: alphabetize and simplify configDerrick Stolee1-30/+30
The config values set by Scalar went through an audit in the previous changes, so now reorganize the settings and simplify their purpose. First, alphabetize the config options, except put the platform-specific options at the end. This groups two Windows-specific settings and only one non-Windows setting. Also, this removes the 'overwrite_on_reconfigure' setting for many of these options. That setting made nearly all of these options "required" for scalar enlistments, restricting use for users. Instead, now nearly all options have removed this setting. However, there is one setting that still has this, which is index.skipHash, which was previously being set to _false_ when we actually prefer the value of true. Keep the overwrite here to help Scalar users upgrade to the new version. We may remove that overwrite in the future once we belive that most of the users who have the false value have upgraded to a version that overwrites that to 'true'. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13scalar: remove stale config valuesDerrick Stolee2-15/+10
These config values were added in the original Scalar contribution, d0feac4e8c (scalar: 'register' sets recommended config and starts maintenance, 2021-12-03), but were never fully checked for validity in the upstream Git project. At the time, Scalar was only intended for the contrib/ directory so did not have as rigorous of an investigation. Each config option has its own justification for removal: * core.preloadIndex: This value is true by default, now. Removing this causes some changes required to the tests that checked this config value. Use gui.gcwarning=false instead. * core.fscache: This config does not exist in the core Git project, but is instead a config option for a Git for Windows feature. * core.multiPackIndex: This config value is now enabled by default, so does not need to be called out specifically. It was originally included to make sure the background maintenance that created multi-pack-indexes would result in the expected performance improvements. * credential.validate: This option is not something specific to Git but instead an older version of Git Credential Manager for Windows. That software was replaced several years ago by the cross-platform Git Credential Manger so this option is no longer needed to help users who were on that older software. * pack.useSparse=true: This value is now Git's default as of de3a864114 (config: set pack.useSparse=true by default, 2020-03-20) so we don't need it set by Scalar. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13scalar: use index.skipHash=true for performanceDerrick Stolee2-1/+5
The index.skipHash config option has been set to 'false' by Scalar since 4933152cbb (scalar: enable path-walk during push via config, 2025-05-16) but that commit message is trying to communicate the exact opposite: that the 'true' value is what we want instead. This means that we've been disabling this performance benefit for Scalar repos unintentionally. Fix this issue before we add justification for the config options set in this list. Oddly, enabling index.skipHash causes a test issue during 'test_commit' in one of the Scalar tests when GIT_TEST_SPLIT_INDEX is enabled (as caught by the linux-test-vars build). I'm fixing the test by disabling the environment variable, but the issue should be resolved in a series focused on the split index. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13scalar: annotate config file with "set by scalar"Derrick Stolee2-7/+20
A repo may have config options set by 'scalar clone' or 'scalar register' and then updated by 'scalar reconfigure'. It can be helpful to point out which of those options were set by the latest scalar recommendations. Add "# set by scalar" to the end of each config option to assist users in identifying why these config options were set in their repo. Use a new helper method to simplify the two callsites. Co-authored-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-12pull: move options[] array into function scopeK Jayatheerth1-142/+141
Unless there are good reasons, it is customary to have the options[] array used with the parse-options API declared in function scope rather than at file scope. Move builtin/pull.c:cmd_pull()’s options[] array into the function to match that convention. Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-12FLEX_ARRAY: require platforms to support the C99 syntaxJunio C Hamano1-31/+2
Before C99 syntax to express that the final member in a struct is an array of unknown number of elements, i.e., struct { ... T flexible_array[]; }; came along, GNU introduced their own extension to declare such a member with 0 size, i.e., T flexible_array[0]; and the compilers that did not understand even that were given a way to emulate it by wasting one element, i.e., T flexible_array[1]; As we are using more and more C99 language features, let's see if the platforms that still need to resort to the historical forms of flexible array member support are still there, by forcing all the flex array definitions to use the C99 syntax and see if anybody screams (in which case reverting the changes is rather easy). Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-12replay: move onto NULL check before first useRené Scharfe1-3/+3
cmd_replay() aborts if the pointer "onto" is NULL after argument parsing, e.g. when specifying a non-existing commit with --onto. 15cd4ef1f4 (replay: make atomic ref updates the default behavior, 2025-11-06) added code that dereferences this pointer before the check. Switch their places to avoid a segmentation fault. Reported-by: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-12Merge branch 'sa/replay-atomic-ref-updates' into rs/replay-wrong-onto-fixJunio C Hamano4-43/+277
* sa/replay-atomic-ref-updates: replay: add replay.refAction config option replay: make atomic ref updates the default behavior replay: use die_for_incompatible_opt2() for option validation
2025-12-12Makefile: help macOS novices by mentioning MacPortsJunio C Hamano1-1/+2
Since Aug 2006, the DarwinPorts project renamed themselves as MacPorts. Those who are not intimately familiar with the Opensource ecosystem around macOS from olden days, the name DarwinPorts may not ring a bell, even when they are using MacPorts. Signed-off-by: Junio C Hamano <gitster@pobox.com> Reviewed-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: write alternates via sourcesPatrick Steinhardt1-16/+35
Refactor writing of alternates so that the actual business logic is structured around the object database source we want to write the alternate to. Same as with the preceding commit, this will eventually allow us to have different logic for writing alternates depending on the backend used. Note that after the refactoring we start to call `odb_add_alternate_recursively()` unconditionally. This is fine though as we know to skip adding sources that are tracked already. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: read alternates via sourcesPatrick Steinhardt1-6/+6
Adapt how we read alternates so that the interface is structured around the object database source we're reading from. This will eventually allow us to abstract away this behaviour with pluggable object databases so that every format can have its own mechanism for listing alternates. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: drop forward declaration of `read_info_alternates()`Patrick Steinhardt1-71/+54
Now that we have removed the mutual recursion in the preceding commit it is not necessary anymore to have a forward declaration of the `read_info_alternates()` function. Move the function and its dependencies further up so that we can remove it. Note that this commit also removes the function documentation of `read_info_alternates()`. It's unclear what it's documenting, but it for sure isn't documenting the modern behaviour of the function anymore. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: remove mutual recursion when parsing alternatesPatrick Steinhardt1-33/+27
When adding an alternative object database source we not only have to consider the added source itself, but we also have to add _its_ sources to our database. We implement this via mutual recursion: 1. We first call `link_alt_odb_entries()`. 2. `link_alt_odb_entries()` calls `parse_alternates()`. 3. We then add each alternate via `odb_add_alternate_recursively()`. 4. `odb_add_alternate_recursively()` calls `link_alt_odb_entries()` again. This flow is somewhat hard to follow, but more importantly it means that parsing of alternates is somewhat tied to the recursive behaviour. Refactor the function to remove the mutual recursion between adding sources and parsing alternates. The parsing step thus becomes completely oblivious to the fact that there is recursive behaviour going on at all. The recursion is handled by `odb_add_alternate_recursively()` instead, which now recurses with itself. This refactoring allows us to move parsing of alternates into object database sources in a subsequent step. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: stop splitting alternate in `odb_add_to_alternates_file()`Patrick Steinhardt1-1/+1
When calling `odb_add_to_alternates_file()` we know to add the newly added source to the object database in case we have already loaded alternates. This is done so that we can make its objects accessible immediately without having to fully reload all alternates. The way we do this though is to call `link_alt_odb_entries()`, which adds _multiple_ sources to the object database source in case we have newline-separated entries. This behaviour is not documented in the function documentation of `odb_add_to_alternates_file()`, and all callers only ever pass a single directory to it. It's thus entirely surprising and a conceptual mismatch. Fix this issue by directly calling `odb_add_alternate_recursively()` instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: move computation of normalized objdir into `alt_odb_usable()`Patrick Steinhardt1-12/+15
The function `alt_odb_usable()` receives as input the object database, the path it's supposed to determine usability for as well as the normalized path of the main object directory of the repository. The last part is derived by the function's caller from the object database. As we already pass the object database to `alt_odb_usable()` it is redundant information. Drop the extra parameter and compute the normalized object directory in the function itself. While at it, rename the function to `odb_is_source_usable()` to align it with modern terminology. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: resolve relative alternative paths when parsingPatrick Steinhardt1-32/+32
Parsing alternates and resolving potential relative paths is currently handled in two separate steps. This has the effect that the logic to retrieve alternates is not entirely self-contained. We want it to be just that though so that we can eventually move the logic to list alternates into the `struct odb_source`. Move the logic to resolve relative alternative paths into `parse_alternates()`. Besides bringing us a step closer towards the above goal, it also neatly separates concerns of generating the list of alternatives and linking them into the object database. Note that we ignore any errors when the relative path cannot be resolved. This isn't really a change in behaviour though: if the path cannot be resolved to a directory then `alt_odb_usable()` still knows to bail out. While at it, rename the function to `odb_add_alternate_recursively()` to more clearly indicate what its intent is and to align it with modern terminology. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11odb: refactor parsing of alternates to be self-containedPatrick Steinhardt1-30/+40
Parsing of the alternates file and environment variable is currently split up across multiple different functions and is entangled with `link_alt_odb_entries()`, which is responsible for linking the parsed object database sources. This results in two downsides: - We have mutual recursion between parsing alternates and linking them into the object database. This is because we also parse alternates that the newly added sources may have. - We mix up the actual logic to parse the data and to link them into place. Refactor the logic so that parsing of the alternates file is entirely self-contained. Note that this doesn't yet fix the above two issues, but it is a necessary step to get there. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11contrib/coccinelle: pass include paths to spatch(1)Toon Claes2-1/+7
In the previous commit a new coccinelle rule is added. But neiter `make coccicheck` nor `meson compile coccicheck` did detect a case in builtin/last-modified.c. This case involves the field `scratch` in `struct last_modified`. This field is of type `struct bitmap` and that struct has a member `eword_t *words`. Both are defined in `ewah/ewok.h`. Now, while builtin/last-modified.c does include that header (with the subdir in the #include directive), it seems coccinelle does not process it. So it's unaware of the type of `words` in the bitmap, and it doesn't recognize the rule from previous commit that uses: type T; T *ptr; Fix coccicheck by passing all possible include paths inside the Git project so spatch(1) can find the headers and can determine the types. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11git-compat-util: introduce MEMZERO_ARRAY() macroToon Claes8-9/+29
Introduce a new macro MEMZERO_ARRAY() that zeroes the memory allocated by ALLOC_ARRAY() and friends. And add coccinelle rule to enforce the use of this macro. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11Merge branch 'tc/last-modified-active-paths-optimization' into tc/memzero-arrayJunio C Hamano1-1/+1
* tc/last-modified-active-paths-optimization: last-modified: fix use of uninitialized memory
2025-12-11midx-write: skip rewriting MIDX with `--stdin-packs` unless neededPatrick Steinhardt3-28/+154
In `write_midx_internal()` we know to skip rewriting the multi-pack index in case the existing one already covers all packs. This logic does not know to handle `git multi-pack-index write --stdin-packs` though, so we end up always rewriting the MIDX in this case even if the MIDX would not change. With our default maintenance strategy this isn't really much of a problem, as git-gc(1) does not use the "--stdin-packs" option. But that is changing with geometric repacking, where "--stdin-packs" is used to explicitly select the packfiles part of the geometric sequence. This issue can be demonstrated trivially with a benchmark in the Git repository: executing `git repack --geometric=2 --write-midx -d` in the Git repository takes more than 3 seconds only to end up with the same multi-pack index as we already had before. The logic that decides if we need to rewrite the MIDX only checks whether the number of packfiles covered will change. That check is of course too lenient for "--stdin-packs", as it could happen that we want to cover a different-but-same-size set of packfiles. But there is no inherent reason why we cannot handle "--stdin-packs". Improve the logic to not only check for the number of packs, but to also verify that we are asked to generate a MIDX for the _same_ packs. This allows us to also skip no-op rewrites for "--stdin-packs". Helped-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11midx-write: extract function to test whether MIDX needs updatingPatrick Steinhardt1-3/+36
In `write_midx_internal()` we know to skip writing the new multi-pack index in case it would be the same as the existing one. This logic does not handle the `--stdin-packs` option yet though, so we end up always rewriting the MIDX if that option is passed to us. Extract the logic to decide whether or not to rewrite the MIDX into a separate function. This will allow us to extend that feature in the next commit to address the above issue. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-11midx: fix `BUG()` when getting preferred pack without a reverse indexPatrick Steinhardt3-2/+16
The function `midx_preferred_pack()` returns the preferred pack for a given multi-pack index. To compute the preferred pack we: 1. Take the first position indexed by the MIDX in pseudo-pack order. 2. Convert this pseudo-pack position into the MIDX position. 3. We then look up the pack that corresponds to this MIDX position. This reliably returns the preferred pack given that all of its contained objects will be up front in pseudo-pack order. The second step that turns the pseudo-pack order into MIDX order requires the reverse index though, which may not exist for example when the MIDX does not have a bitmap. And in that case one may easily hit a bug: BUG: ../pack-revindex.c:491: pack_pos_to_midx: reverse index not yet loaded In theory, `midx_preferred_pack()` already knows to handle the case where no reverse index exists, as it calls `load_midx_revindex()` before calling into `midx_preferred_pack()`. But we only check for negative return values there, even though the function returns a positive error code in case the reverse index does not exist. Fix the issue by testing for a non-zero return value instead, same as all the other callers of this function already do. While at it, document the return value of `load_midx_revindex()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-10fetch: fix failed batched updates skipping operationsKarthik Nayak2-1/+93
Fix a regression introduced with batched updates in 0e358de64a (fetch: use batched reference updates, 2025-05-19) when fetching references. In the `do_fetch()` function, we jump to cleanup if committing the transaction fails, regardless of whether using batched or atomic updates. This skips three subsequent operations: - Update 'FETCH_HEAD' as part of `commit_fetch_head()`. - Add upstream tracking information via `set_upstream()`. - Setting remote 'HEAD' values when `do_set_head` is true. For atomic updates, this is expected behavior. For batched updates, we want to continue with these operations even if some refs fail to update. Skipping `commit_fetch_head()` isn't actually a regression because 'FETCH_HEAD' is already updated via `append_fetch_head()` when not using '--atomic'. However, we add a test to validate this behavior. Skipping the other two operations (upstream tracking and remote HEAD) is a regression. Fix this by only jumping to cleanup when using '--atomic', allowing batched updates to continue with post-fetch operations. Add tests to prevent future regressions. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-10fetch: fix non-conflicting tags not being committedKarthik Nayak2-0/+70
The commit 0e358de64a (fetch: use batched reference updates, 2025-05-19) updated the 'git-fetch(1)' command to use batched updates. This batches updates to gain performance improvements. When fetching references, each update is added to the transaction. Finally, when committing, individual updates are allowed to fail with reason, while the transaction itself succeeds. One scenario which was missed here, was fetching tags. When fetching conflicting tags, the `fetch_and_consume_refs()` function returns '1', which skipped committing the transaction and directly jumped to the cleanup section. This mean that no updates were applied. This also extends to backfilling tags which is done when fetching specific refspecs which contains tags in their history. Fix this by committing the transaction when we have an error code and not using an atomic transaction. This ensures other references are applied even when some updates fail. The cleanup section is reached with `retcode` set in several scenarios: - `truncate_fetch_head()`, `open_fetch_head()` and `prune_refs()` set `retcode` before the transaction is created, so no commit is attempted. - `fetch_and_consume_refs()` and `backfill_tags()` are the primary cases this fix targets, both setting a positive `retcode` to trigger the committing of the transaction. This simplifies error handling and ensures future modifications to `do_fetch()` don't need special handling for batched updates. Add tests to check for this regression. While here, add a missing cleanup from previous test. Reported-by: David Bohman <debohman@gmail.com> Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-09doc: fix `update-ref` `symref-create` formattingSam Bostock1-1/+1
`symref-create` should be followed `::`, not `:`. The lack of second colon (`:`) causes it to appear as regular text (`<p>`) instead of as a description list term (`<dt>`) in the HTML documentation. Signed-off-by: Sam Bostock <sam@sambostock.ca> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-09packfile: skip hash checks in add_promisor_object()Aaron Plattner1-1/+2
When is_promisor_object() is called for the first time, it lazily initializes a set of all promisor objects by iterating through all objects in promisor packs. For each object, add_promisor_object() calls parse_object(), which decompresses and hashes the entire object. For repositories with large pack files, this can take an extremely long time. For example, on a production repository with a 176 GB promisor pack: $ time ~/git/git/git-rev-list --objects --all --exclude-promisor-objects --quiet ________________________________________________________ Executed in 76.10 mins fish external usr time 72.10 mins 1.83 millis 72.10 mins sys time 3.56 mins 0.17 millis 3.56 mins add_promisor_object() just wants to construct the set of all promisor objects, so it doesn't really need to verify the hash of every object. Set PARSE_OBJECT_SKIP_HASH_CHECK to skip the hash check. This has the side effect of skipping decompression of blob objects completely, saving a significant amount of time: $ time ~/git/git/git-rev-list --objects --all --exclude-promisor-objects --quiet ________________________________________________________ Executed in 124.70 secs fish external usr time 46.94 secs 0.00 millis 46.94 secs sys time 43.11 secs 1.03 millis 43.11 secs Signed-off-by: Aaron Plattner <aplattner@nvidia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-09object: apply skip_hash and discard_tree optimizations to unknown blobs tooAaron Plattner1-2/+2
parse_object_with_flags() has an optimization to skip parsing blobs if PARSE_OBJECT_SKIP_HASH_CHECK is set and the object hasn't been seen before or might be a blob but hasn't been parsed yet. The latter can happen, for example, if add_tree_entries() walks a path that references a blob object that hasn't been seen before: lookup_blob() marks the referenced oid as being a blob, but does not provide any additional information about it until it is parsed. It's possible for an object to be created without even a type, such as when prepare_revision_walk() uses mark_uninteresting() to mark all promisor objects as uninteresting. These objects have obj->parsed == false and obj->type == OBJ_NONE. The skip_hash optimization does not consider this kind of object, so parse_object_with_flags() proceeds to fully parse the object to determine its type. Improve the optimization by applying it to OBJ_NONE objects as well as OBJ_BLOB ones. Apply a similar fix for trees. Fixes: 8db2dad7a045 ("parse_object(): check on-disk type of suspected blob") Signed-off-by: Aaron Plattner <aplattner@nvidia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>