summaryrefslogtreecommitdiff
path: root/t
AgeCommit message (Collapse)AuthorFilesLines
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>
2022-01-03Merge branch 'en/sparse-checkout-set'Libravatar Junio C Hamano1-1/+9
The "init" and "set" subcommands in "git sparse-checkout" have been unified for a better user experience and performance. * en/sparse-checkout-set: sparse-checkout: remove stray trailing space clone: avoid using deprecated `sparse-checkout init` Documentation: clarify/correct a few sparsity related statements git-sparse-checkout.txt: update to document init/set/reapply changes sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} sparse-checkout: enable `set` to initialize sparse-checkout mode sparse-checkout: split out code for tweaking settings config sparse-checkout: disallow --no-stdin as an argument to set sparse-checkout: add sanity-checks on initial sparsity state sparse-checkout: break apart functions for sparse_checkout_(set|add) sparse-checkout: pass use_stdin as a parameter instead of as a global
2022-01-03Merge branch 'es/test-chain-lint'Libravatar Junio C Hamano161-845/+738
Broken &&-chains in the test scripts have been corrected. * es/test-chain-lint: t6000-t9999: detect and signal failure within loop t5000-t5999: detect and signal failure within loop t4000-t4999: detect and signal failure within loop t0000-t3999: detect and signal failure within loop tests: simplify by dropping unnecessary `for` loops tests: apply modern idiom for exiting loop upon failure tests: apply modern idiom for signaling test failure tests: fix broken &&-chains in `{...}` groups tests: fix broken &&-chains in `$(...)` command substitutions tests: fix broken &&-chains in compound statements tests: use test_write_lines() to generate line-oriented output tests: simplify construction of large blocks of text t9107: use shell parameter expansion to avoid breaking &&-chain t6300: make `%(raw:size) --shell` test more robust t5516: drop unnecessary subshell and command invocation t4202: clarify intent by creating expected content less cleverly t1020: avoid aborting entire test script when one test fails t1010: fix unnoticed failure on Windows t/lib-pager: use sane_unset() to avoid breaking &&-chain
2021-12-22Merge branch 'es/chainlint'Libravatar Junio C Hamano71-293/+339
The chainlint test script linter in the test suite has been updated. * es/chainlint: chainlint.sed: stop splitting "(..." into separate lines "(" and "..." chainlint.sed: swallow comments consistently chainlint.sed: stop throwing away here-doc tags chainlint.sed: don't mistake `<< word` in string as here-doc operator chainlint.sed: make here-doc "<<-" operator recognition more POSIX-like chainlint.sed: drop subshell-closing ">" annotation chainlint.sed: drop unnecessary distinction between ?!AMP?! and ?!SEMI?! chainlint.sed: tolerate harmless ";" at end of last line in block chainlint.sed: improve ?!SEMI?! placement accuracy chainlint.sed: improve ?!AMP?! placement accuracy t/Makefile: optimize chainlint self-test t/chainlint/one-liner: avoid overly intimate chainlint.sed knowledge t/chainlint/*.test: generalize self-test commentary t/chainlint/*.test: fix invalid test cases due to mixing quote types t/chainlint/*.test: don't use invalid shell syntax
2021-12-22Merge branch 'jz/apply-quiet-and-allow-empty'Libravatar Junio C Hamano1-4/+18
"git apply" has been taught to ignore a message without a patch with the "--allow-empty" option. It also learned to honor the "--quiet" option given from the command line. * jz/apply-quiet-and-allow-empty: git-apply: add --allow-empty flag git-apply: add --quiet flag
2021-12-22Merge branch 'ab/common-main-cleanup'Libravatar Junio C Hamano1-2/+3
Code clean-up. * ab/common-main-cleanup: common-main.c: call exit(), don't return
2021-12-22Merge branch 'ab/fetch-set-upstream-while-detached'Libravatar Junio C Hamano1-0/+22
"git fetch --set-upstream" did not check if there is a current branch, leading to a segfault when it is run on a detached HEAD, which has been corrected. * ab/fetch-set-upstream-while-detached: pull, fetch: fix segfault in --set-upstream option
2021-12-21Merge branch 'ld/sparse-diff-blame'Libravatar Junio C Hamano2-18/+95
Teach diff and blame to work well with sparse index. * ld/sparse-diff-blame: blame: enable and test the sparse index diff: enable and test the sparse index diff: replace --staged with --cached in t1092 tests repo-settings: prepare_repo_settings only in git repos test-read-cache: set up repo after git directory commit-graph: return if there is no git directory git: ensure correct git directory setup with -h
2021-12-21Merge branch 'ak/protect-any-current-branch'Libravatar Junio C Hamano4-4/+43
"git fetch" without the "--update-head-ok" option ought to protect a checked out branch from getting updated, to prevent the working tree that checks it out to go out of sync. The code was written before the use of "git worktree" got widespread, and only checked the branch that was checked out in the current worktree, which has been updated. (originally called ak/fetch-not-overwrite-any-current-branch) * ak/protect-any-current-branch: branch: protect branches checked out in all worktrees receive-pack: protect current branch for bare repository worktree receive-pack: clean dead code from update_worktree() fetch: protect branches checked out in all worktrees worktree: simplify find_shared_symref() memory ownership model branch: lowercase error messages receive-pack: lowercase error messages fetch: lowercase error messages
2021-12-21Merge branch 'fs/ssh-signing-other-keytypes'Libravatar Junio C Hamano3-3/+28
The cryptographic signing using ssh keys can specify literal keys for keytypes whose name do not begin with the "ssh-" prefix by using the "key::" prefix mechanism (e.g. "key::ecdsa-sha2-nistp256"). * fs/ssh-signing-other-keytypes: ssh signing: make sign/amend test more resilient ssh signing: support non ssh-* keytypes
2021-12-21Merge branch 'fs/ssh-signing-key-lifetime'Libravatar Junio C Hamano5-13/+244
Extend the signing of objects with SSH keys and learn to pay attention to the key validity time range when verifying. * fs/ssh-signing-key-lifetime: ssh signing: verify ssh-keygen in test prereq ssh signing: make fmt-merge-msg consider key lifetime ssh signing: make verify-tag consider key lifetime ssh signing: make git log verify key lifetime ssh signing: make verify-commit consider key lifetime ssh signing: add key lifetime test prereqs ssh signing: use sigc struct to pass payload t/fmt-merge-msg: make gpgssh tests more specific t/fmt-merge-msg: do not redirect stderr
2021-12-21Merge branch 'jk/log-decorate-opts-with-implicit-decorate'Libravatar Junio C Hamano1-0/+37
When "git log" implicitly enabled the "decoration" processing without being explicitly asked with "--decorate" option, it failed to read and honor the settings given by the "--decorate-refs" option. * jk/log-decorate-opts-with-implicit-decorate: log: load decorations with --simplify-by-decoration log: handle --decorate-refs with userformat "%d"
2021-12-21Merge branch 'en/rebase-x-wo-git-dir-env'Libravatar Junio C Hamano1-0/+23
"git rebase -x" by mistake started exporting the GIT_DIR and GIT_WORK_TREE environment variables when the command was rewritten in C, which has been corrected. * en/rebase-x-wo-git-dir-env: sequencer: do not export GIT_DIR and GIT_WORK_TREE for 'exec'
2021-12-15sparse-checkout: add sanity-checks on initial sparsity stateLibravatar Elijah Newren1-1/+9
Most sparse-checkout subcommands (list, add, reapply) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case. Also document with a comment why we do not exit early in `disable` even when core.sparseCheckout starts as false. Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Victoria Dye <vdye@github.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-15Merge branch 'hn/allow-bogus-oid-in-ref-tests'Libravatar Junio C Hamano5-62/+121
The test helper for refs subsystem learned to write bogus and/or nonexistent object name to refs to simulate error situations we want to test Git in. * hn/allow-bogus-oid-in-ref-tests: t1430: create valid symrefs using test-helper t1430: remove refs using test-tool refs: introduce REF_SKIP_REFNAME_VERIFICATION flag refs: introduce REF_SKIP_OID_VERIFICATION flag refs: update comment. test-ref-store: plug memory leak in cmd_delete_refs test-ref-store: parse symbolic flag constants test-ref-store: remove force-create argument for create-reflog
2021-12-15Merge branch 're/color-default-reset'Libravatar Junio C Hamano1-0/+16
"default" and "reset" colors have been added to our palette. * re/color-default-reset: color: allow colors to be prefixed with "reset" color: support "default" to restore fg/bg color color: add missing GIT_COLOR_* white/black constants
2021-12-15Merge branch 'ew/test-wo-fsync'Libravatar Junio C Hamano1-0/+7
Allow running our tests while disabling fsync. * ew/test-wo-fsync: tests: disable fsync everywhere
2021-12-15Merge branch 'ds/sparse-deep-pattern-checkout-fix'Libravatar Junio C Hamano1-1/+15
The sparse-index/sparse-checkout feature had a bug in its use of the matching code to determine which path is in or outside the sparse checkout patterns. * ds/sparse-deep-pattern-checkout-fix: unpack-trees: use traverse_path instead of name t1092: add deeper changes during a checkout
2021-12-15Merge branch 'js/test-initial-branch-override-cleanup'Libravatar Junio C Hamano17-50/+0
Many tests that used to need GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME mechanism to force "git" to use 'master' as the default name for the initial branch no longer need it; the use of the mechanism from them have been removed. * js/test-initial-branch-override-cleanup: tests: set GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME only when needed
2021-12-15Merge branch 'es/worktree-chatty-to-stderr'Libravatar Junio C Hamano3-26/+20
"git worktree add" showed "Preparing worktree" message to the standard output stream, but when it failed, the message from die() went to the standard error stream. Depending on the order the stdio streams are flushed at the program end, this resulted in confusing output. It has been corrected by sending all the chatty messages to the standard error stream. * es/worktree-chatty-to-stderr: git-worktree.txt: add missing `-v` to synopsis for `worktree list` worktree: send "chatty" messages to stderr
2021-12-15Merge branch 'hn/reflog-tests'Libravatar Junio C Hamano5-12/+30
Prepare tests on ref API to help testing reftable backends. * hn/reflog-tests: refs/debug: trim trailing LF from reflog message test-ref-store: tweaks to for-each-reflog-ent format t1405: check for_each_reflog_ent_reverse() more thoroughly test-ref-store: don't add newline to reflog message show-branch: show reflog message
2021-12-15Merge branch 'es/pretty-describe-more'Libravatar Junio C Hamano1-0/+16
Extend "git log --format=%(describe)" placeholder to allow passing selected command-line options to the underlying "git describe" command. * es/pretty-describe-more: pretty: add abbrev option to %(describe) pretty: add tag option to %(describe) pretty.c: rework describe options parsing for better extensibility
2021-12-15Merge branch 'ab/run-command'Libravatar Junio C Hamano2-5/+6
API clean-up. * ab/run-command: run-command API: remove "env" member, always use "env_array" difftool: use "env_array" to simplify memory management run-command API: remove "argv" member, always use "args" run-command API users: use strvec_push(), not argv construction run-command API users: use strvec_pushl(), not argv construction run-command tests: use strvec_pushv(), not argv assignment run-command API users: use strvec_pushv(), not argv assignment upload-archive: use regular "struct child_process" pattern worktree: stop being overly intimate with run_command() internals
2021-12-15Merge branch 'hn/t1404-df-limitation-is-ref-files-only'Libravatar Junio C Hamano1-16/+16
Test update. * hn/t1404-df-limitation-is-ref-files-only: t1404: mark directory/file conflict tests with REFFILES
2021-12-15Merge branch 'en/zdiff3'Libravatar Junio C Hamano1-0/+90
"Zealous diff3" style of merge conflict presentation has been added. * en/zdiff3: update documentation for new zdiff3 conflictStyle xdiff: implement a zealous diff3, or "zdiff3"
2021-12-15Merge branch 'ds/trace2-regions-in-tests'Libravatar Junio C Hamano6-9/+12
The default setting for trace2 event nesting was too low to cause test failures, which is worked around by bumping it up in the test framework. * ds/trace2-regions-in-tests: t/t*: remove custom GIT_TRACE2_EVENT_NESTING test-lib.sh: set GIT_TRACE2_EVENT_NESTING
2021-12-15Merge branch 'fs/test-prereq'Libravatar Junio C Hamano4-4/+55
The test framework learns to list unsatisfied test prerequisites, and optionally error out when prerequisites that are expected to be satisfied are not. * fs/test-prereq: test-lib: make BAIL_OUT() work in tests and prereq test-lib: introduce required prereq for test runs test-lib: show missing prereq summary
2021-12-15Merge branch 'ab/mark-leak-free-tests-even-more'Libravatar Junio C Hamano104-0/+152
More tests are marked as leak-free. * ab/mark-leak-free-tests-even-more: leak tests: mark some fast-import tests as passing with SANITIZE=leak leak tests: mark some config tests as passing with SANITIZE=leak leak tests: mark some status tests as passing with SANITIZE=leak leak tests: mark some clone tests as passing with SANITIZE=leak leak tests: mark some add tests as passing with SANITIZE=leak leak tests: mark some diff tests as passing with SANITIZE=leak leak tests: mark some apply tests as passing with SANITIZE=leak leak tests: mark some notes tests as passing with SANITIZE=leak leak tests: mark some update-index tests as passing with SANITIZE=leak leak tests: mark some rev-parse tests as passing with SANITIZE=leak leak tests: mark some rev-list tests as passing with SANITIZE=leak leak tests: mark some misc tests as passing with SANITIZE=leak leak tests: mark most gettext tests as passing with SANITIZE=leak leak tests: mark "sort" test as passing SANITIZE=leak leak tests: mark a read-tree test as passing SANITIZE=leak
2021-12-15Merge branch 'hn/reftable'Libravatar Junio C Hamano4-1/+41
The "reftable" backend for the refs API, without integrating into the refs subsystem, has been added. * hn/reftable: Add "test-tool dump-reftable" command. reftable: add dump utility reftable: implement stack, a mutable database of reftable files. reftable: implement refname validation reftable: add merged table view reftable: add a heap-based priority queue for reftable records reftable: reftable file level tests reftable: read reftable files reftable: generic interface to tables reftable: write reftable files reftable: a generic binary tree implementation reftable: reading/writing blocks Provide zlib's uncompress2 from compat/zlib-compat.c reftable: (de)serialization for the polymorphic record type. reftable: add blocksource, an abstraction for random access reads reftable: utility functions reftable: add error related functionality reftable: add LICENSE hash.h: provide constants for the hash IDs
2021-12-13git-apply: add --allow-empty flagLibravatar Jerry Zhang1-4/+18
Some users or scripts will pipe "git diff" output to "git apply" when replaying diffs or commits. In these cases, they will rely on the return value of "git apply" to know whether the diff was applied successfully. However, for empty commits, "git apply" will fail. This complicates scripts since they have to either buffer the diff and check its length, or run diff again with "exit-code", essentially doing the diff twice. Add the "--allow-empty" flag to "git apply" which allows it to handle both empty diffs and empty commits created by "git format-patch --always" by doing nothing and returning 0. Add tests for both with and without --allow-empty. Signed-off-by: Jerry Zhang <jerry@skydio.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: stop splitting "(..." into separate lines "(" and "..."Libravatar Eric Sunshine9-35/+37
Because `sed` is line-oriented, for ease of implementation, when chainlint.sed encounters an opening subshell in which the first command is cuddled with the "(", it splits the line into two lines: one containing only "(", and the other containing whatever follows "(". This allows chainlint.sed to get by with a single set of regular expressions for matching shell statements rather than having to duplicate each expression (one set for matching non-cuddled statements, and one set for matching cuddled statements). However, although syntactically and semantically immaterial, this transformation has no value to test authors and might even confuse them into thinking that the linter is misbehaving by inserting (whitespace) line-noise into the shell code it is validating. Moreover, it also allows an implementation detail of chainlint.sed to seep into the chainlint self-test "expect" files, which potentially makes it difficult to reuse the self-tests should a more capable chainlint ever be developed. To address these concerns, stop splitting cuddled "(..." into two lines. Note that, as an implementation artifact, due to sed's line-oriented nature, this change inserts a blank line at output time just before the "(..." line is emitted. It would be possible to suppress this blank line but doing so would add a fair bit of complexity to chainlint.sed. Therefore, rather than suppressing the extra blank line, the Makefile's `check-chainlint` target which runs the chainlint self-tests is instead modified to ignore blank lines when comparing chainlint output against the self-test "expect" output. This is a reasonable compromise for two reasons. First, the purpose of the chainlint self-tests is to verify that the ?!AMP?! annotations are being correctly added; precise whitespace is immaterial. Second, by necessity, chainlint.sed itself already throws away all blank lines within subshells since, when checking for a broken &&-chain, it needs to check the final _statement_ in a subshell, not the final _line_ (which might be blank), thus it has never made any attempt to precisely reproduce blank lines in its output. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: swallow comments consistentlyLibravatar Eric Sunshine6-4/+52
When checking for broken a &&-chain, chainlint.sed knows that the final statement in a subshell should not end with `&&`, so it takes care to make a distinction between the final line which is an actual statement and any lines which may be mere comments preceding the closing ')'. As such, it swallows comment lines so that they do not interfere with the &&-chain check. However, since `sed` does not provide any sort of real recursion, chainlint.sed only checks &&-chains in subshells one level deep; it doesn't do any checking in deeper subshells or in `{...}` blocks within subshells. Furthermore, on account of potential implementation complexity, it doesn't check &&-chains within `case` arms. Due to an oversight, it also doesn't swallow comments inside deep subshells, `{...}` blocks, or `case` statements, which makes its output inconsistent (swallowing comments in some cases but not others). Unfortunately, this inconsistency seeps into the chainlint self-test "expect" files, which potentially makes it difficult to reuse the self-tests should a more capable chainlint ever be developed. Therefore, teach chainlint.sed to consistently swallow comments in all cases. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: stop throwing away here-doc tagsLibravatar Eric Sunshine11-29/+35
The purpose of chainlint is to highlight problems it finds in test code by inserting annotations at the location of each problem. Arbitrarily eliding bits of the code it is checking is not helpful, yet this is exactly what chainlint.sed does by cavalierly and unnecessarily dropping the here-doc operator and tag; i.e. `cat <<TAG` becomes simply `cat` in the output. This behavior can make it more difficult for the test writer to align the annotated output of chainlint.sed with the original test code. Address this by retaining here-doc tags. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: don't mistake `<< word` in string as here-doc operatorLibravatar Eric Sunshine3-2/+36
Tighten here-doc recognition to prevent it from being fooled by text which looks like a here-doc operator but happens merely to be the content of a string, such as this real-world case from t7201: echo "<<<<<<< ours" && echo ourside && echo "=======" && echo theirside && echo ">>>>>>> theirs" This problem went unnoticed because chainlint.sed is not a real parser, but rather applies heuristics to pretend to understand shell code. In this case, it saw what it thought was a here-doc operator (`<< ours`), and fell off the end of the test looking for the closing tag "ours" which it never found, thus swallowed the remainder of the test without checking it for &&-chain breakage. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: make here-doc "<<-" operator recognition more POSIX-likeLibravatar Eric Sunshine1-4/+4
According to POSIX, "<<" and "<<-" are distinct shell operators. For the latter to be recognized, no whitespace is allowed before the "-", though whitespace is allowed after the operator. However, the chainlint patterns which identify here-docs are both too loose and too tight, incorrectly allowing whitespace between "<<" and "-" but disallowing it between "-" and the here-doc tag. Fix the patterns to better match POSIX. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: drop subshell-closing ">" annotationLibravatar Eric Sunshine39-89/+80
chainlint.sed inserts a ">" annotation at the beginning of a line to signal that its heuristics have identified an end-of-subshell. This was useful as a debugging aid during development of the script, but it has no value to test writers and might even confuse them into thinking that the linter is misbehaving by inserting line-noise into the shell code it is validating. Moreover, its presence also potentially makes it difficult to reuse the chainlint self-test "expect" output should a more capable linter ever be developed. Therefore, drop the ">" annotation. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: drop unnecessary distinction between ?!AMP?! and ?!SEMI?!Libravatar Eric Sunshine5-25/+24
>From inception, when chainlint.sed encountered a line using semicolon to separate commands rather than `&&`, it would insert a ?!SEMI?! annotation at the beginning of the line rather ?!AMP?! even though the &&-chain is also broken by the semicolon. Given a line such as: ?!SEMI?! cmd1; cmd2 && the ?!SEMI?! annotation makes it easier to see what the problem is than if the output had been: ?!AMP?! cmd1; cmd2 && which might confuse the test author into thinking that the linter is broken (since the line clearly ends with `&&`). However, now that the ?!AMP?! an ?!SEMI?! annotations are inserted at the point of breakage rather than at the beginning of the line, and taking into account that both represent a broken &&-chain, there is little reason to distinguish between the two. Using ?!AMP?! alone is sufficient to point the test author at the problem. For instance, in: cmd1; ?!AMP?! cmd2 && cmd3 it is clear that the &&-chain is broken between `cmd1` and `cmd2`. Likewise, in: cmd1 && cmd2 ?!AMP?! cmd3 it is clear that the &&-chain is broken between `cmd2` and `cmd3`. Finally, in: cmd1; ?!AMP?! cmd2 ?!AMP?! cmd3 it is clear that the &&-chain is broken between each command. Hence, there is no longer a good reason to make a distinction between a broken &&-chain due to a semicolon and a broken chain due to a missing `&&` at end-of-line. Therefore, drop the ?!SEMI?! annotation and use ?!AMP?! exclusively. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: tolerate harmless ";" at end of last line in blockLibravatar Eric Sunshine2-7/+8
chainlint.sed flags ";" when used as a command terminator since it breaks the &&-chain, thus can allow failures to go undetected. However, when a command terminated by ";" is the last command in the body of a compound statement, such as `command-2` in: if test $# -gt 1 then command-1 && command-2; fi then the ";" is harmless and the exit code from `command-2` is passed through untouched and becomes the exit code of the compound statement, as if the ";" was not present. Therefore, tolerate a trailing ";" in this position rather than complaining about broken &&-chain. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: improve ?!SEMI?! placement accuracyLibravatar Eric Sunshine5-18/+18
When chainlint.sed detects commands separated by a semicolon rather than by `&&`, it places a ?!SEMI?! annotation at the beginning of the line. However, this is an unusual location for programmers accustomed to error messages (from compilers, for instance) indicating the exact point of the problem. Therefore, relocate the ?!SEMI?! annotation to the location of the semicolon in order to better direct the programmer's attention to the source of the problem. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13chainlint.sed: improve ?!AMP?! placement accuracyLibravatar Eric Sunshine23-38/+38
When chainlint.sed detects a broken &&-chain, it places an ?!AMP?! annotation at the beginning of the line. However, this is an unusual location for programmers accustomed to error messages (from compilers, for instance) indicating the exact point of the problem. Therefore, relocate the ?!AMP?! annotation to the end of the line in order to better direct the programmer's attention to the source of the problem. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13t/Makefile: optimize chainlint self-testLibravatar Eric Sunshine1-6/+4
Rather than running `chainlint` and `diff` once per self-test -- which may become expensive as more tests are added -- instead run `chainlint` a single time over all tests bodies collectively and compare the result to the collective "expected" output. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13t/chainlint/one-liner: avoid overly intimate chainlint.sed knowledgeLibravatar Eric Sunshine2-2/+2
The purpose of chainlint.sed is to detect &&-chain breakage only within subshells (one level deep); it doesn't bother checking for top-level &&-chain breakage since the &&-chain checker built into t/test-lib.sh should detect broken &&-chains outside of subshells by making them magically exit with code 117. Unfortunately, one of the chainlint.sed self-tests has overly intimate knowledge of this particular division of responsibilities and only cares about what chainlint.sed itself will produce, while ignoring the fact that a more all-encompassing linter would complain about a broken &&-chain outside the subshell. This makes it difficult to re-use the test with a more capable chainlint implementation should one ever be developed. Therefore, adjust the test and its "expected" output to avoid being specific to the tunnel-vision of this one implementation. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-13t/chainlint/*.test: generalize self-test commentaryLibravatar Eric Sunshine6-9/+6
The purpose of chainlint.sed is to detect &&-chain breakage only within subshells (one level deep); it doesn't bother checking for top-level &&-chain breakage since the &&-chain checker built into t/test-lib.sh should detect broken &&-chains outside of subshells by making them magically exit with code 117. However, this division of labor may not always be the case if a more capable chainlint implementation is ever developed. Beyond that, due to being sed-based and due to its use of heuristics, chainlint.sed has several limitations (such as being unable to detect &&-chain breakage in subshells more than one level deep since it only manually emulates recursion into a subshell). Some of the comments in the chainlint self-tests unnecessarily reflect the limitations of chainlint.sed even though those limitations are not what is being tested. Therefore, simplify and generalize the comments to explain only what is being tested, thus ensuring that they won't become outdated if a more capable chainlint is ever developed. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>