summaryrefslogtreecommitdiff
path: root/t
AgeCommit message (Collapse)AuthorFilesLines
2022-02-16Merge branch 'ab/do-not-hide-failures-in-git-dot-pm'Libravatar Junio C Hamano4-4/+0
Git.pm update. * ab/do-not-hide-failures-in-git-dot-pm: perl Git.pm: don't ignore signalled failure in _cmd_close()
2022-02-16Merge branch 'js/no-more-legacy-stash'Libravatar Junio C Hamano1-15/+0
Removal of unused code and doc. * js/no-more-legacy-stash: stash: stop warning about the obsolete `stash.useBuiltin` config setting stash: remove documentation for `stash.useBuiltin` add: remove support for `git-legacy-stash` git-sh-setup: remove remnant bits referring to `git-legacy-stash`
2022-02-16Merge branch 'js/diff-filter-negation-fix'Libravatar Junio C Hamano1-0/+13
"git diff --diff-filter=aR" is now parsed correctly. * js/diff-filter-negation-fix: diff-filter: be more careful when looking for negative bits diff.c: move the diff filter bits definitions up a bit docs(diff): lose incorrect claim about `diff-files --diff-filter=A`
2022-02-16Merge branch 'en/fetch-negotiation-default-fix'Libravatar Junio C Hamano1-3/+21
Interaction between fetch.negotiationAlgorithm and feature.experimental configuration variables has been corrected. * en/fetch-negotiation-default-fix: repo-settings: rename the traditional default fetch.negotiationAlgorithm repo-settings: fix error handling for unknown values repo-settings: fix checking for fetch.negotiationAlgorithm=default
2022-02-16Merge branch 'tb/midx-bitmap-corruption-fix'Libravatar Junio C Hamano5-141/+263
A bug that made multi-pack bitmap and the object order out-of-sync, making the .midx data corrupt, has been fixed. * tb/midx-bitmap-corruption-fix: pack-bitmap.c: gracefully fallback after opening pack/MIDX midx: read `RIDX` chunk when present t/lib-bitmap.sh: parameterize tests over reverse index source t5326: move tests to t/lib-bitmap.sh t5326: extract `test_rev_exists` t5326: drop unnecessary setup pack-revindex.c: instrument loading on-disk reverse index midx.c: make changing the preferred pack safe t5326: demonstrate bitmap corruption after permutation
2022-02-16Merge branch 'en/remerge-diff'Libravatar Junio C Hamano3-4/+305
"git log --remerge-diff" shows the difference from mechanical merge result and the result that is actually recorded in a merge commit. * en/remerge-diff: diff-merges: avoid history simplifications when diffing merges merge-ort: mark conflict/warning messages from inner merges as omittable show, log: include conflict/warning messages in --remerge-diff headers diff: add ability to insert additional headers for paths merge-ort: format messages slightly different for use in headers merge-ort: mark a few more conflict messages as omittable merge-ort: capture and print ll-merge warnings in our preferred fashion ll-merge: make callers responsible for showing warnings log: clean unneeded objects during `log --remerge-diff` show, log: provide a --remerge-diff capability
2022-02-16Merge branch 'hn/reftable-coverity-fixes'Libravatar Junio C Hamano1-4/+5
Problems identified by Coverity in the reftable code have been corrected. * hn/reftable-coverity-fixes: reftable: add print functions to the record types reftable: make reftable_record a tagged union reftable: remove outdated file reftable.c reftable: implement record equality generically reftable: make reftable-record.h function signatures const correct reftable: handle null refnames in reftable_ref_record_equal reftable: drop stray printf in readwrite_test reftable: order unittests by complexity reftable: all xxx_free() functions accept NULL arguments reftable: fix resource warning reftable: ignore remove() return value in stack_test.c reftable: check reftable_stack_auto_compact() return value reftable: fix resource leak blocksource.c reftable: fix resource leak in block.c error path reftable: fix OOB stack write in print functions
2022-02-16Merge branch 'ld/sparse-index-bash-completion'Libravatar Junio C Hamano1-0/+138
The command line completion (in contrib/) learns to complete arguments to give to "git sparse-checkout" command. * ld/sparse-index-bash-completion: completion: handle unusual characters for sparse-checkout completion: improve sparse-checkout cone mode directory completion completion: address sparse-checkout issues
2022-02-11Merge branch 'tg/fetch-prune-exit-code-fix'Libravatar Junio C Hamano1-0/+11
When "git fetch --prune" failed to prune the refs it wanted to prune, the command issued error messages but exited with exit status 0, which has been corrected. * tg/fetch-prune-exit-code-fix: fetch --prune: exit with error if pruning fails
2022-02-11Merge branch 'rc/negotiate-only-typofix'Libravatar Junio C Hamano1-1/+1
Typofix. * rc/negotiate-only-typofix: fetch: fix negotiate-only error message
2022-02-11Merge branch 'ab/no-errno-from-resolve-ref-unsafe'Libravatar Junio C Hamano1-2/+1
Remaining code-clean-up. * ab/no-errno-from-resolve-ref-unsafe: refs API: remove "failure_errno" from refs_resolve_ref_unsafe() sequencer: don't use die_errno() on refs_resolve_ref_unsafe() failure
2022-02-11Merge branch 'bc/csprng-mktemps'Libravatar Junio C Hamano3-0/+31
Pick a better random number generator and use it when we prepare temporary filenames. * bc/csprng-mktemps: wrapper: use a CSPRNG to generate random file names wrapper: add a helper to generate numbers from a CSPRNG
2022-02-11Merge branch 'bc/clarify-eol-attr'Libravatar Junio C Hamano1-0/+6
Doc and test update around the eol attribute. * bc/clarify-eol-attr: docs: correct documentation about eol attribute t0027: add tests for eol without text in .gitattributes
2022-02-09Merge branch 'js/sparse-vs-split-index'Libravatar Junio C Hamano1-28/+26
Mark in various places in the code that the sparse index and the split index features are mutually incompatible. * js/sparse-vs-split-index: split-index: it really is incompatible with the sparse index t1091: disable split index sparse-index: sparse index is disallowed when split index is active
2022-02-09Merge branch 'jt/clone-not-quite-empty'Libravatar Junio C Hamano1-0/+15
Cloning from a repository that does not yet have any branches or tags but has other refs resulted in a "remote transport reported error", which has been corrected. * jt/clone-not-quite-empty: clone: support unusual remote ref configurations
2022-02-09Merge branch 'jt/sparse-checkout-leading-dir-fix'Libravatar Junio C Hamano1-0/+6
"git sparse-checkout init" failed to write into $GIT_DIR/info directory when the repository was created without one, which has been corrected to auto-create it. * jt/sparse-checkout-leading-dir-fix: sparse-checkout: create leading directory
2022-02-09Merge branch 'ab/config-based-hooks-2'Libravatar Junio C Hamano2-2/+136
More "config-based hooks". * ab/config-based-hooks-2: run-command: remove old run_hook_{le,ve}() hook API receive-pack: convert push-to-checkout hook to hook.h read-cache: convert post-index-change to use hook.h commit: convert {pre-commit,prepare-commit-msg} hook to hook.h git-p4: use 'git hook' to run hooks send-email: use 'git hook run' for 'sendemail-validate' git hook run: add an --ignore-missing flag hooks: convert worktree 'post-checkout' hook to hook library hooks: convert non-worktree 'post-checkout' hook to hook library merge: convert post-merge to use hook.h am: convert applypatch-msg to use hook.h rebase: convert pre-rebase to use hook.h hook API: add a run_hooks_l() wrapper am: convert {pre,post}-applypatch to use hook.h gc: use hook library for pre-auto-gc hook hook API: add a run_hooks() wrapper hook: add 'run' subcommand
2022-02-09Merge branch 'jc/name-rev-stdin'Libravatar Junio C Hamano6-19/+25
"git name-rev --stdin" does not behave like usual "--stdin" at all. Start the process of renaming it to "--annotate-stdin". * jc/name-rev-stdin: name-rev.c: use strbuf_getline instead of limited size buffer name-rev: deprecate --stdin in favor of --annotate-stdin
2022-02-09Merge branch 'gc/fetch-negotiate-only-early-return'Libravatar Junio C Hamano2-0/+24
"git fetch --negotiate-only" is an internal command used by "git push" to figure out which part of our history is missing from the other side. It should never recurse into submodules even when fetch.recursesubmodules configuration variable is set, nor it should trigger "gc". The code has been tightened up to ensure it only does common ancestry discovery and nothing else. * gc/fetch-negotiate-only-early-return: fetch: help translators by reusing the same message template fetch --negotiate-only: do not update submodules fetch: skip tasks related to fetching objects fetch: use goto cleanup in cmd_fetch()
2022-02-09Merge branch 'pw/add-p-hunk-split-fix'Libravatar Junio C Hamano1-5/+43
"git add -p" rewritten in C regressed hunk splitting in some cases, which has been corrected. * pw/add-p-hunk-split-fix: builtin add -p: fix hunk splitting t3701: clean up hunk splitting tests
2022-02-09Merge branch 'jt/conditional-config-on-remote-url'Libravatar Junio C Hamano1-0/+118
The conditional inclusion mechanism of configuration files using "[includeIf <condition>]" learns to base its decision on the URL of the remote repository the repository interacts with. * jt/conditional-config-on-remote-url: config: include file if remote URL matches a glob config: make git_config_include() static
2022-02-09Merge branch 'en/merge-ort-restart-optim-fix'Libravatar Junio C Hamano1-0/+67
The merge-ort misbehaved when merge.renameLimit configuration is set too low and failed to find all renames. * en/merge-ort-restart-optim-fix: merge-ort: avoid assuming all renames detected
2022-02-09Merge branch 'js/test-unset-trace2-parents'Libravatar Junio C Hamano1-0/+2
Avoid tests that are run under GIT_TRACE2 set from failing unnecessarily. * js/test-unset-trace2-parents: test-lib: unset trace2 parent envvars
2022-02-08completion: handle unusual characters for sparse-checkoutLibravatar Lessley Dennington1-0/+49
Update the __gitcomp_directories method to de-quote and handle unusual characters in directory names. Although this initially involved an attempt to re-use the logic in __git_index_files, this method removed subdirectories (e.g. folder1/0/ became folder1/), so instead new custom logic was placed directly in the __gitcomp_directories method. Note there are two tests for this new functionality - one for spaces and accents and one for backslashes and tabs. The backslashes and tabs test uses FUNNYNAMES to avoid running on Windows. This is because: 1. Backslashes are explicitly not allowed in Windows file paths. 2. Although tabs appear to be allowed when creating a file in a Windows bash shell, they actually are not renderable (and appear as empty boxes in the shell). Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de> Co-authored-by: Lessley Dennington <lessleydennington@gmail.com> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-08completion: improve sparse-checkout cone mode directory completionLibravatar Lessley Dennington1-16/+22
Use new __gitcomp_directories method to complete directory names in cone mode sparse-checkouts. This method addresses the caveat of poor performance in monorepos from the previous commit (by completing only one level of directories). The unusual character caveat from the previous commit will be fixed by the final commit in this series. Co-authored-by: Elijah Newren <newren@gmail.com> Co-authored-by: Lessley Dennington <lessleydennington@gmail.com> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-08completion: address sparse-checkout issuesLibravatar Lessley Dennington1-0/+83
Correct multiple issues with tab completion of the git sparse-checkout command. These issues were: 1. git sparse-checkout <TAB> previously resulted in an incomplete list of subcommands (it was missing reapply and add). 2. Subcommand options were not tab-completable. 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed both file names and directory names. While this may be a less surprising behavior for non-cone mode, cone mode sparse checkouts should complete only directory names. Note that while the new strategy of just using git ls-tree to complete on directory names is simple and a step in the right direction, it does have some caveats. These are: 1. Likelihood of poor performance in large monorepos (as a result of recursively completing directory names). 2. Inability to handle paths containing unusual characters. These caveats will be fixed by subsequent commits in this series. Signed-off-by: Lessley Dennington <lessleydennington@gmail.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-05Merge branch 'ms/update-index-racy'Libravatar Junio C Hamano3-5/+122
"git update-index --refresh" has been taught to deal better with racy timestamps (just like "git status" already does). * ms/update-index-racy: update-index: refresh should rewrite index in case of racy timestamps t7508: add tests capturing racy timestamp handling t7508: fix bogus mtime verification test-lib: introduce API for verifying file mtime
2022-02-05Merge branch 'ab/cat-file'Libravatar Junio C Hamano2-0/+134
Assorted updates to "git cat-file", especially "-h". * ab/cat-file: cat-file: s/_/-/ in typo'd usage_msg_optf() message cat-file: don't whitespace-pad "(...)" in SYNOPSIS and usage output cat-file: use GET_OID_ONLY_TO_DIE in --(textconv|filters) object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLY cat-file: correct and improve usage information cat-file: fix remaining usage bugs cat-file: make --batch-all-objects a CMDMODE cat-file: move "usage" variable to cmd_cat_file() cat-file docs: fix SYNOPSIS and "-h" output parse-options API: add a usage_msg_optf() cat-file tests: test messaging on bad objects/paths cat-file tests: test bad usage
2022-02-05Merge branch 'pb/pull-rebase-autostash-fix'Libravatar Junio C Hamano1-0/+13
"git pull --rebase" ignored the rebase.autostash configuration variable when the remote history is a descendant of our history, which has been corrected. * pb/pull-rebase-autostash-fix: pull --rebase: honor rebase.autostash when fast-forwarding
2022-02-02diff-merges: avoid history simplifications when diffing mergesLibravatar Elijah Newren1-1/+57
Doing diffs for merges are special; they should typically avoid history simplification. For example, with git log --diff-merges=first-parent -- path the default history simplification would remove merge commits from consideration if the file "path" matched the second parent. That is counter to what the user wants when looking for first-parent diffs. Similar comments can be made for --diff-merges=separate (which diffs against both parents) and --diff-merges=remerge (which diffs against a remerge of the merge commit). However, history simplification still makes sense if not doing diffing merges, and it also makes sense for the combined and dense-combined forms of diffing merges (because both of those are defined to only show a diff when the merge result at the relevant paths differs from *both* parents). So, for separate, first-parent, and remerge styles of diff-merges, turn off history simplification. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-02show, log: include conflict/warning messages in --remerge-diff headersLibravatar Elijah Newren1-0/+144
Conflicts such as modify/delete, rename/rename, or file/directory are not representable via content conflict markers, and the normal output messages notifying users about these were dropped with --remerge-diff. While we don't want these messages randomly shown before the commit and diff headers, we do want them to still be shown; include them as part of the diff headers instead. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-02merge-ort: capture and print ll-merge warnings in our preferred fashionLibravatar Elijah Newren2-4/+14
Instead of immediately printing ll-merge warnings to stderr, we save them in our output strbuf. Besides allowing us to move these warnings to a special file for --remerge-diff, this has two other benefits for regular merges done by merge-ort: * The deferral of messages ensures we can print all messages about any given path together (merge-recursive was known to sometimes intersperse messages about other paths, particularly when renames were involved). * The deferral of messages means we can avoid printing spurious conflict messages when we just end up aborting due to local user modifications in the way. (In contrast to merge-recursive.c which prematurely checks for local modifications in the way via unpack_trees() and gets the check wrong both in terms of false positives and false negatives relative to renames, merge-ort does not perform the local modifications in the way check until the checkout() step after the full merge has been computed.) Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-02show, log: provide a --remerge-diff capabilityLibravatar Elijah Newren1-0/+91
When this option is specified, we remerge all (two parent) merge commits and diff the actual merge commit to the automatically created version, in order to show how users removed conflict markers, resolved the different conflict versions, and potentially added new changes outside of conflict regions in order to resolve semantic merge problems (or, possibly, just to hide other random changes). This capability works by creating a temporary object directory and marking it as the primary object store. This makes it so that any blobs or trees created during the automatic merge are easily removable afterwards by just deleting all objects from the temporary object directory. There are a few ways that this implementation is suboptimal: * `log --remerge-diff` becomes slow, because the temporary object directory can fill with many loose objects while running * the log output can be muddied with misplaced "warning: cannot merge binary files" messages, since ll-merge.c unconditionally writes those messages to stderr while running instead of allowing callers to manage them. * important conflict and warning messages are simply dropped; thus for conflicts like modify/delete or rename/rename or file/directory which are not representable with content conflict markers, there may be no way for a user of --remerge-diff to know that there had been a conflict which was resolved (and which possibly motivated other changes in the merge commit). * when fixing the previous issue, note that some unimportant conflict and warning messages might start being included. We should instead make sure these remain dropped. Subsequent commits will address these issues. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-02repo-settings: rename the traditional default fetch.negotiationAlgorithmLibravatar Elijah Newren1-1/+1
Give the traditional default fetch.negotiationAlgorithm the name 'consecutive'. Also allow a choice of 'default' to have Git decide between the choices (currently, picking 'skipping' if feature.experimental is true and 'consecutive' otherwise). Update the documentation accordingly. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-02repo-settings: fix error handling for unknown valuesLibravatar Elijah Newren1-0/+7
In commit af3a67de01 ("negotiator: unknown fetch.negotiationAlgorithm should error out", 2018-08-01), error handling for an unknown fetch.negotiationAlgorithm was added with the code die()ing. This was also added to the documentation for the fetch.negotiationAlgorithm option, to make it explicit that the code would die on unknown values. This behavior was lost with commit aaf633c2ad ("repo-settings: create feature.experimental setting", 2019-08-13). Restore it so that the behavior again matches the documentation. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-02repo-settings: fix checking for fetch.negotiationAlgorithm=defaultLibravatar Elijah Newren1-3/+14
In commit 3050b6dfc75d (repo-settings.c: simplify the setup, 2021-09-21), the branch for handling fetch.negotiationAlgorithm=default was deleted. Since this value is documented in Documentation/config/fetch.txt, restore the check for this value. Note that this change caused an observable bug: if someone sets feature.experimental=true in config, and then passes "-c fetch.negotiationAlgorithm=default" on the command line in an attempt to override the config, then the override is ignored. Fix the bug by not ignoring the value of "default". Technically, before commit 3050b6dfc75d, repo-settings would treat any fetch.negotiationAlgorithm value other than "skipping" or "noop" as a request for "default", but I think it probably makes more sense to ignore such broken requests and leave fetch.negotiationAlgorithm with the default value rather than the value of "default". (If that sounds confusing, note that "default" is usually the default value, but when feature.experimental=true, "skipping" is the default value.) Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-01perl Git.pm: don't ignore signalled failure in _cmd_close()Libravatar Ævar Arnfjörð Bjarmason4-4/+0
Fix misbehavior in Git.pm that dates back to the very first version of the library in git.git added in b1edc53d062 (Introduce Git.pm (v4), 2006-06-24). When we fail to execute a command we shouldn't ignore all signals, those can happen e.g. if abort() is called, or if the command segfaults. Because of this we'd consider e.g. a command that died due to LSAN exiting with abort() successful, as is the case with the tests listed as running successfully with SANITIZE=leak in 9081a421a6d (checkout: fix "branch info" memory leaks, 2021-11-16). We did run them successfully, but only because we ignored these errors. This was then made worse by the use of "abort_on_error=1" for LSAN added in 85b81b35ff9 (test-lib: set LSAN_OPTIONS to abort by default, 2017-09-05). Doing that makes sense, but without providing that option we'd have a "$? >> 8" of "23" on failure, with abort_on_error=1 we'll get "0". All of our tests pass even without the SIGPIPE exception being added here, but as the code appears to have been trying to ignore it let's keep ignoring it for now. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-31fetch --prune: exit with error if pruning failsLibravatar Thomas Gummerer1-0/+11
When pruning refs fails, we print an error to stderr, but still exit 0 from 'git fetch'. Since this is a genuine error, fetch should be exiting with some non-zero exit code. Make it so. The --prune option was introduced in f360d844de ("builtin-fetch: add --prune option", 2009-11-10). Unfortunately it's unclear from that commit whether ignoring the exit code was an oversight or intentional, but it feels like an oversight. Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-28Merge branch 'en/keep-cwd' into maintLibravatar Junio C Hamano1-0/+21
Fix a regression in 2.35 that roke the use of "rebase" and "stash" in a secondary worktree. * en/keep-cwd: sequencer, stash: fix running from worktree subdir
2022-01-28fetch: fix negotiate-only error messageLibravatar Robert Coup1-1/+1
The error message when invoking a negotiate-only fetch without providing any tips incorrectly refers to a --negotiate-tip=* argument. Fix this to use the actual argument, --negotiation-tip=*. Signed-off-by: Robert Coup <robert@coup.net.nz> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-28diff-filter: be more careful when looking for negative bitsLibravatar Johannes Schindelin1-0/+13
The `--diff-filter=<bits>` option allows to filter the diff by certain criteria, for example `R` to only show renamed files. It also supports negating a filter via a down-cased letter, i.e. `r` to show _everything but_ renamed files. However, the code is a bit overzealous when trying to figure out whether `git diff` should start with all diff-filters turned on because the user provided a lower-case letter: if the `--diff-filter` argument starts with an upper-case letter, we must not start with all bits turned on. Even worse, it is possible to specify the diff filters in multiple, separate options, e.g. `--diff-filter=AM [...] --diff-filter=m`. Let's accumulate the include/exclude filters independently, and only special-case the "only exclude filters were specified" case after parsing the options altogether. Note: The code replaced by this commit took pains to avoid setting any unused bits of `options->filter`. That was unnecessary, though, as all accesses happen via the `filter_bit_tst()` function using specific bits, and setting the unused bits has no effect. Therefore, we can simplify the code by using `~0` (or in this instance, `~<unwanted-bit>`). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27stash: stop warning about the obsolete `stash.useBuiltin` config settingLibravatar Johannes Schindelin1-15/+0
In 8a2cd3f5123 (stash: remove the stash.useBuiltin setting, 2020-03-03), we removed support for `stash.useBuiltin`, but left a warning in its place. After almost two years, and several major versions, it is time to remove even that warning. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27pack-bitmap.c: gracefully fallback after opening pack/MIDXLibravatar Taylor Blau2-0/+47
When opening a MIDX/pack-bitmap, we call open_midx_bitmap_1() or open_pack_bitmap_1() respectively in a loop over the set of MIDXs/packs. By design, these functions are supposed to be called over every pack and MIDX, since only one of them should have a valid bitmap. Ordinarily we return '0' from these two functions in order to indicate that we successfully loaded a bitmap To signal that we couldn't load a bitmap corresponding to the MIDX/pack (either because one doesn't exist, or because there was an error with loading it), we can return '-1'. In either case, the callers each enumerate all MIDXs/packs to ensure that at most one bitmap per-kind is present. But when we fail to load a bitmap that does exist (for example, loading a MIDX bitmap without finding a corresponding reverse index), we'll return -1 but leave the 'midx' field non-NULL. So when we fallback to loading a pack bitmap, we'll complain that the bitmap we're trying to populate already is "opened", even though it isn't. Rectify this by setting the '->pack' and '->midx' field back to NULL as appropriate. Two tests are added: one to ensure that the MIDX-to-pack bitmap fallback works, and another to ensure we still complain when there are multiple pack bitmaps in a repository. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27midx: read `RIDX` chunk when presentLibravatar Taylor Blau4-6/+31
When a MIDX contains the new `RIDX` chunk, ensure that the reverse index is read from it instead of the on-disk .rev file. Since we need to encode the object order in the MIDX itself for correctness reasons, there is no point in storing the same data again outside of the MIDX. So, this patch stops writing separate .rev files, and reads it out of the MIDX itself. This is possible to do with relatively little new code, since the format of the RIDX chunk is identical to the data in the .rev file. In other words, we can implement this by pointing the `revindex_data` field at the reverse index chunk of the MIDX instead of the .rev file without any other changes. Note that we have two knobs that are adjusted for the new tests: GIT_TEST_MIDX_WRITE_REV and GIT_TEST_MIDX_READ_RIDX. The former controls whether the MIDX .rev is written at all, and the latter controls whether we read the MIDX's RIDX chunk. Both are necessary to ensure that the test added at the beginning of this series continues to work. This is because we always need to write the RIDX chunk in the MIDX in order to change its checksum, but we want to make sure reading the existing .rev file still works (since the RIDX chunk takes precedence by default). Arguably this isn't a very interesting mode to test, because the precedence rules mean that we'll always read the RIDX chunk over the .rev file. But it makes it impossible for a user to induce corruption in their repository by adjusting the test knobs (since if we had an either/or knob they could stop writing the RIDX chunk, allowing them to tweak the MIDX's object order without changing its checksum). Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27t/lib-bitmap.sh: parameterize tests over reverse index sourceLibravatar Taylor Blau1-6/+14
To prepare for reading the reverse index data out of the MIDX itself, teach the `test_rev_exists` function to take an expected "source" for the reverse index data. When given "rev", it asserts that the MIDX's `.rev` file exists, and is loaded when verifying the integrity of its bitmaps. Otherwise, it ensures that trace2 reports the source of the reverse index data as the same string which was given to test_rev_exists(). The following patch will implement reading the reverse index data from the MIDX itself. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27t5326: move tests to t/lib-bitmap.shLibravatar Taylor Blau2-171/+179
In t5326, we have a handful of tests that we would like to run twice: once using the MIDX's new `RIDX` chunk as the source of the reverse-index cache, and once using the separate `.rev` file. But because these tests mutate the state of the underlying repository, and then make assumptions about those mutations occurring in a certain sequence, simply running the tests twice in the same repository is awkward. Instead, extract the core of interesting tests into t/lib-bitmap.sh to prepare for them to be run twice, each in a separate test script. This means that they can each operate on a separate repository, removing any concerns about mutating state. For now, this patch is a strict cut-and-paste of some tests from t5326. The tests which did not move are not interesting with respect to the source of their reverse index data. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27t5326: extract `test_rev_exists`Libravatar Taylor Blau1-15/+22
To determine which source of data is used for the MIDX's reverse index cache, introduce a helper which forces loading the reverse index, and then looks for the special trace2 event introduced in a previous commit. For now, this helper just looks for when the legacy MIDX .rev file was loaded, but in a subsequent commit will become parameterized over the the reverse index's source. This function replaces checking for the existence of the .rev file. We could write a similar helper to ensure that the .rev file is cleaned up after repacking, but it will make subsequent tests more difficult to write, and provides marginal value since we already check that the MIDX .bitmap file is removed. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27t5326: drop unnecessary setupLibravatar Taylor Blau1-4/+0
The core.multiPackIndex config became true by default back in 18e449f86b (midx: enable core.multiPackIndex by default, 2020-09-25), so it is no longer necessary to enable it explicitly. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27midx.c: make changing the preferred pack safeLibravatar Taylor Blau1-1/+1
The previous patch demonstrates a bug where a MIDX's auxiliary object order can become out of sync with a MIDX bitmap. This is because of two confounding factors: - First, the object order is stored in a file which is named according to the multi-pack index's checksum, and the MIDX does not store the object order. This means that the object order can change without altering the checksum. - But the .rev file is moved into place with finalize_object_file(), which link(2)'s the file into place instead of renaming it. For us, that means that a modified .rev file will not be moved into place if MIDX's checksum was unchanged. This fix is to force the MIDX's checksum to change when the preferred pack changes but the set of packs contained in the MIDX does not. In other words, when the object order changes, the MIDX's checksum needs to change with it (regardless of whether the MIDX is tracking the same or different packs). This prevents a race whereby changing the object order (but not the packs themselves) enables a reader to see the new .rev file with the old MIDX, or similarly seeing the new bitmap with the old object order. But why can't we just stop hardlinking the .rev into place instead adding additional data to the MIDX? Suppose that's what we did. Then when we go to generate the new bitmap, we'll load the old MIDX bitmap, along with the MIDX that it references. That's fine, since the new MIDX isn't moved into place until after the new bitmap is generated. But the new object order *has* been moved into place. So we'll read the old bitmaps in the new order when generating the new bitmap file, meaning that without this secondary change, bitmap generation itself would become a victim of the race described here. This can all be prevented by forcing the MIDX's checksum to change when the object order does. By embedding the entire object order into the MIDX, we do just that. That is, the MIDX's checksum will change in response to any perturbation of the underlying object order. In t5326, this will cause the MIDX's checksum to update (even without changing the set of packs in the MIDX), preventing the stale read problem. Note that this makes it safe to continue to link(2) the MIDX .rev file into place, since it is now impossible to have a .rev file that is out-of-sync with the MIDX whose checksum it references. (But we will do away with MIDX .rev files later in this series anyway, so this is somewhat of a moot point). In theory, it is possible to store a "fingerprint" of the full object order here, so long as that fingerprint changes at least as often as the full object order does. Some possibilities here include storing the identity of the preferred pack, along with the mtimes of the non-preferred packs in a consistent order. But storing a limited part of the information makes it difficult to reason about whether or not there are gaps between the two that would cause us to get bitten by this bug again. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27t5326: demonstrate bitmap corruption after permutationLibravatar Taylor Blau1-0/+31
This patch demonstrates a cause of bitmap corruption that can occur when the contents of the multi-pack index does not change, but the underlying object order does. In this example, we have a MIDX containing two packs, each with a distinct set of objects (pack A corresponds to the tree, blob, and commit from the first patch, and pack B corresponds to the second patch). First, a MIDX is written where the 'A' pack is preferred. As expected, the bitmaps generated there are in-tact. But then, we generate an identical MIDX with a different object order: this time preferring pack 'B'. Due to a bug which will be explained and fixed in the following commit, the MIDX is updated, but the .rev file is not, causing the .bitmap file to be read incorrectly. Specifically, the .bitmap file will contain correct data, but the auxiliary object order in the .rev file is stale, causing readers to get confused by reading the new bitmaps using the old object order. Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>