summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2024-03-25builtin/pack-refs: introduce new "--auto" flagPatrick Steinhardt4-2/+57
Calling git-pack-refs(1) will unconditionally cause it to pack all requested refs regardless of the current state of the ref database. For example: - With the "files" backend we will end up rewriting the complete "packed-refs" file even if only a single ref would require compaction. - With the "reftable" backend we will end up always compacting all tables into a single table. This behaviour can be completely unnecessary depending on the backend and is thus wasteful. With the introduction of the `PACK_REFS_AUTO` flag in the preceding commit we can improve this and let the backends decide for themselves whether to pack refs in the first place. Expose this functionality via a new "--auto" flag in git-pack-refs(1), which mirrors the same flag in both git-gc(1) and git-maintenance(1). Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25builtin/pack-refs: release allocated memoryPatrick Steinhardt1-8/+15
Some of the command line options in `cmd_pack_refs()` require us to allocate memory. This memory is never released and thus leaking, but we paper over this leak by declaring the respective variables as `static` function-level variables, which is somewhat awkward. Refactor the code to release the allocated memory and drop the `static` declaration. While at it, remove the useless `flags` variable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25refs/reftable: expose auto compaction via new flagPatrick Steinhardt2-2/+9
Under normal circumstances, the "reftable" backend will automatically perform compaction after appending to the stack. It is thus not necessary and may even be considered wasteful to run git-pack-refs(1) in "reftable"-backed repositories as it will cause the backend to compact all tables into a single one. We do exactly that though when running `git maintenance run --auto` or `git gc --auto`, which gets spawned by Git after running some specific commands. The `--auto` mode is typically only executing optimizations as needed. To do so, we already use several heuristics for the various different data structures in Git to determine whether to optimize them or not. We do not use any heuristics for refs though and instead always optimize them. Introduce a new `PACK_REFS_AUTO` flag that can be passed to the backend. When not handled by the backend we will continue to behave the exact same as we do right now, that is we optimize refs unconditionally. This is done for the "files" backend for now to retain current behaviour, even though we may eventually also want to introduce heuristics here. For the "reftable" backend though we already do have auto-compaction, so we can easily reuse that logic to implement the new auto-packing flag. Note that under normal circumstances, this should always end up being a no-op. After all, we already invoke the code for every single addition to the stack. But there are special cases where it can still be helpful to execute the auto-compaction code explicitly: - Concurrent writers may cause compaction to not run due to locks. - Callers may decide to disable compaction altogether and then pack refs at a later point due to various reasons. - Other implementations of the reftable format may do compaction differently or even not at all. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25refs: remove `PACK_REFS_ALL` flagPatrick Steinhardt2-4/+3
The intent of the `PACK_REFS_ALL` flag is to ask the backend to compact all refs instead of only a subset of them. Thus, this flag gets passed down to `refs_pack_refs()` via `struct pack_refs_opts::flags`. But starting with 4fe42f326e (pack-refs: teach pack-refs --include option, 2023-05-12), the flag's semantics have changed. Instead of being handled by the respective backends, this flag is now getting handled by the callers of `refs_pack_refs()` which will add a single glob ("*") to the list of refs-to-be-packed. Thus, the flag serves no purpose to the ref backends anymore. Remove the flag and replace it with a local variable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25refs: move `struct pack_refs_opts` to where it's usedPatrick Steinhardt1-6/+6
The declaration of `struct pack_refs_opts` is in a seemingly random place. Move it so that it's located right next to its flags and functions that use it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25t/helper: drop pack-refs wrapperPatrick Steinhardt2-24/+9
The test helper provides a "ref-store <store> pack-refs" wrapper that more or less directly invokes `refs_pack_refs()`. This helper is only used in a single test with the "PACK_REFS_PRUNE" and "PACK_REFS_ALL" flags. Both of these flags can directly be accessed via git-pack-refs(1) though via the `--all` and `--prune` flags, which makes the helper superfluous. Refactor the test to use git-pack-refs(1) instead of the test helper. Drop the now-unused test helper command. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25refs/reftable: print errors on compaction failurePatrick Steinhardt2-1/+17
When git-pack-refs(1) fails in the reftable backend we end up printing no error message at all, leaving the caller puzzled as to why compaction has failed. Fix this. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25reftable/stack: gracefully handle failed auto-compaction due to locksPatrick Steinhardt3-1/+76
Whenever we commit a new table to the reftable stack we will end up invoking auto-compaction of the stack to keep the total number of tables at bay. This auto-compaction may fail though in case at least one of the tables which we are about to compact is locked. This is indicated by the compaction function returning `REFTABLE_LOCK_ERROR`. We do not handle this case though, and thus bubble that return value up the calling chain, which will ultimately cause a failure. Fix this bug by ignoring `REFTABLE_LOCK_ERROR`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25reftable/stack: use error codes when locking fails during compactionPatrick Steinhardt1-5/+13
Compaction of a reftable stack may fail gracefully when there is a concurrent process that writes to the reftable stack and which has thus locked either the "tables.list" file or one of the tables. This is expected and can be handled gracefully by some of the callers which invoke compaction. Thus, to indicate this situation to our callers, we return a positive return code from `stack_compact_range()` and bubble it up to the caller. This kind of error handling is somewhat awkward though as many callers in the call chain never even think of handling positive return values. Thus, the result is either that such errors are swallowed by accident, or that we abort operations with an unhelpful error message. Make the code more robust by always using negative error codes when compaction fails, with `REFTABLE_LOCK_ERROR` for the described benign error case. Note that only a single callsite knew to handle positive error codes gracefully in the first place. Subsequent commits will touch up some of the other sites to handle those errors better. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25reftable/error: discern locked/outdated errorsPatrick Steinhardt4-6/+11
We currently throw two different errors into a similar-but-different error code: - Errors when trying to lock the reftable stack. - Errors when trying to write to the reftable stack which has been modified concurrently. This results in unclear error handling and user-visible error messages. Create a new `REFTABLE_OUTDATED_ERROR` so that those error conditions can be clearly told apart from each other. Adjust users of the old `REFTABLE_LOCK_ERROR` to use the new error code as required. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25reftable/stack: fix error handling in `reftable_stack_init_addition()`Patrick Steinhardt1-6/+1
In `reftable_stack_init_addition()` we call `stack_uptodate()` after having created the lockfile to check whether the stack was modified concurrently, which is indicated by a positive return code from the latter function. If so, we return a `REFTABLE_LOCK_ERROR` to the caller and abort the addition. The error handling has an off-by-one though because we check whether the error code is `> 1` instead of `> 0`. Thus, instead of returning the locking error, we would return a positive value. One of the callers of `reftable_stack_init_addition()` works around this bug by repeating the error code check without the off-by-one. But other callers are subtly broken by this bug. Fix this by checking for `err > 0` instead. This has the consequence that `reftable_stack_init_addition()` won't ever return a positive error code anymore, but will instead return `REFTABLE_LOCK_ERROR` now. Thus, we can drop the check for a positive error code in `stack_try_add()` now. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-23editorconfig: add Makefiles to "text files"Max Gautier1-1/+1
The Makefile and makefile fragments use the same indent style than the rest of the code (with some inconsistencies). Add them to the relevant .editorconfig section to make life easier for editors and reviewers. Signed-off-by: Max Gautier <mg@max.gautier.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-22rebase: use child_process_clear() to cleanJeff King2-3/+12
In the run_am() function, we set up a child_process struct to run "git-am", allocating memory for its args and env strvecs. These are normally cleaned up when we call run_command(). But if we encounter certain errors, we exit the function early and try to clean up ourselves by clearing the am.args field. This leaks the "env" strvec. We should use child_process_clear() instead, which covers both. And more importantly, it future proofs us against the struct ever growing more allocated fields. These are unlikely errors to happen in practice, so they don't actually trigger the leak sanitizer in the tests. But we can add a new test which does exercise one of the paths (and fails SANITIZE=leak without this patch). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-22format-patch: fix leak of empty header stringJeff King1-1/+1
The log_write_email_headers() function recently learned to return the "extra_headers_p" variable to the caller as an allocated string. We start by copying rev_info.extra_headers into a strbuf, and then detach the strbuf at the end of the function. If there are no extra headers, we leave the strbuf empty. Likewise, if there are no headers to return, we pass back NULL. This misses a corner case which can cause a leak. The "do we have any headers to copy" check is done by looking for a NULL opt->extra_headers. But the "do we have a non-empty string to return" check is done by checking the length of the strbuf. That means if opt->extra_headers is the empty string, we'll "copy" it into the strbuf, triggering an allocation, but then leak the buffer when we return NULL from the function. We can solve this in one of two ways: 1. Rather than checking headers->len at the end, we could check headers->alloc to see if we allocated anything. That retains the original behavior before the recent change, where an empty extra_headers string is "passed through" to the caller. In practice this doesn't matter, though (the code which eventually looks at the result treats NULL or the empty string the same). 2. Only bother copying a non-empty string into the strbuf. This has the added bonus of avoiding a pointless allocation. Arguably strbuf_addstr() could do this optimization itself, though it may be slightly dangerous to do so (some existing callers may not get a fresh allocation when they expect to). In theory callers are all supposed to use strbuf_detach() in such a case, but there's no guarantee that this is the case. This patch uses option 2. Without it, building with SANITIZE=leak shows many errors in t4021 and elsewhere. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-22t/README: document how to loop around test casesPatrick Steinhardt1-0/+20
In some cases it makes sense to loop around test cases so that we can execute the same test with slightly different arguments. There are some gotchas around quoting here though that are easy to miss and that may lead to easy-to-miss errors and portability issues. Document the proper way to do this in "t/README". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-22t7800: use single quotes for test bodiesPatrick Steinhardt1-20/+20
In eb84c8b6ce (git-difftool--helper: honor `--trust-exit-code` with `--dir-diff`, 2024-02-20) we have started to loop around some of the tests in t7800 so that they are reexecuted with slightly different arguments. As part of that refactoring the quoting of test bodies was changed from single quotes (') to double quotes (") so that the value of the loop variable is accessible to the body. As the test body is later on passed to eval this change was not required though. Let's revert it back to use single quotes as usual in our tests. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-22t7800: improve test descriptions with empty argumentsPatrick Steinhardt1-8/+8
Some of the tests in t7800 are executed repeatedly in a loop with different arguments. To distinguish these tests, the value of that variable is rendered into the test title. But given that one of the values is the empty string, it results in a somewhat awkward test name: difftool ignores exit code Improve this by printing "without options" in case the value is empty. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-21config.txt: describe handling of whitespace furtherDragan Simic1-12/+14
Make it more clear what the whitespace characters are in the context of git configuration files, and significantly improve the description of the leading and trailing whitespace handling, especially how it works out together with the presence of inline comments. Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Dragan Simic <dsimic@manjaro.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-21t1300: add more tests for whitespace and inline commentsDragan Simic1-3/+111
Add a handful of additional tests, to improve the coverage of the handling of configuration file entries whose values contain internal whitespace, leading and/or trailing whitespace, which may or may not be enclosed within quotation marks, or which contain an additional inline comment. At the same time, rework one already existing whitespace-related test a bit, to ensure its consistency with the newly added tests. This change introduced no functional changes to the already existing test. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Dragan Simic <dsimic@manjaro.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-21config: really keep value-internal whitespace verbatimDragan Simic1-4/+9
Fix a bug in function parse_value() that prevented whitespace characters (i.e. spaces and horizontal tabs) found inside configuration option values from being parsed and returned in their original form. The bug caused any number of consecutive whitespace characters to be wrongly "squashed" into the same number of space characters. This bug was introduced back in July 2009, in commit ebdaae372b46 ("config: Keep inner whitespace verbatim"). Further investigation showed that setting a configuration value, by invoking git-config(1), converts value-internal horizontal tabs into "\t" escape sequences, which the buggy value-parsing logic in function parse_value() didn't "squash" into spaces. That's why the test included in the ebdaae37 commit passed, which presumably made the bug remain undetected for this long. On the other hand, value-internal literal horizontal tab characters, found in a configuration file edited by hand, do get "squashed" by the value-parsing logic, so the right choice was to fix this bug by making the value-internal whitespace characters preserved verbatim. Signed-off-by: Dragan Simic <dsimic@manjaro.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-21config: minor addition of whitespaceDragan Simic1-1/+1
In general, binary operators should be enclosed in a pair of leading and trailing space (SP) characters. Thus, clean up one spotted expression that for some reason had a "bunched up" operator. Signed-off-by: Dragan Simic <dsimic@manjaro.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-21The tenth batchJunio C Hamano1-0/+35
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-21Merge branch 'bb/iso-strict-utc'Junio C Hamano2-5/+10
The output format for dates "iso-strict" has been tweaked to show a time in the Zulu timezone with "Z" suffix, instead of "+00:00". * bb/iso-strict-utc: date: make "iso-strict" conforming for the UTC timezone
2024-03-21Merge branch 'bb/t0006-negative-tz-offset'Junio C Hamano1-0/+8
More tests on showing time with negative TZ offset. * bb/t0006-negative-tz-offset: t0006: add more tests with a negative TZ offset
2024-03-21Merge branch 'jw/doc-show-untracked-files-fix'Junio C Hamano1-1/+1
The status.showUntrackedFiles configuration variable was incorrectly documented to accept "false", which has been corrected. * jw/doc-show-untracked-files-fix: doc: status.showUntrackedFiles does not take "false"
2024-03-21Merge branch 'dg/user-manual-hash-example'Junio C Hamano1-2/+34
User manual (the original one) update. * dg/user-manual-hash-example: Documentation/user-manual.txt: example for generating object hashes
2024-03-21Merge branch 'ja/doc-markup-fixes'Junio C Hamano4-48/+57
Mark-ups used in the documentation has been improved for consistency. * ja/doc-markup-fixes: doc: git-clone: format placeholders doc: git-clone: format verbatim words doc: git-init: rework config item init.templateDir doc: git-init: rework definition lists doc: git-init: format placeholders doc: git-init: format verbatim parts
2024-03-21Merge branch 'pb/ci-win-artifact-names-fix'Junio C Hamano1-2/+2
CI update. * pb/ci-win-artifact-names-fix: ci(github): make Windows test artifacts name unique
2024-03-21Merge branch 'ps/reftable-reflog-iteration-perf'Junio C Hamano10-211/+154
The code to iterate over reflogs in the reftable has been optimized to reduce memory allocation and deallocation. Reviewed-by: Josh Steadmon <steadmon@google.com> cf. <Ze9eX-aaWoVaqsPP@google.com> * ps/reftable-reflog-iteration-perf: refs/reftable: track last log record name via strbuf reftable/record: use scratch buffer when decoding records reftable/record: reuse message when decoding log records reftable/record: reuse refnames when decoding log records reftable/record: avoid copying author info reftable/record: convert old and new object IDs to arrays refs/reftable: reload correct stack when creating reflog iter
2024-03-21Merge branch 'jc/safe-implicit-bare'Junio C Hamano2-5/+49
Users with safe.bareRepository=explicit can still work from within $GIT_DIR of a seconary worktree (which resides at .git/worktrees/$name/) of the primary worktree without explicitly specifying the $GIT_DIR environment variable or the --git-dir=<path> option. * jc/safe-implicit-bare: setup: notice more types of implicit bare repositories
2024-03-21Merge branch 'fs/find-end-of-log-message-fix'Junio C Hamano2-2/+19
The code to find the effective end of log message can fall into an endless loop, which has been corrected. * fs/find-end-of-log-message-fix: wt-status: don't find scissors line beyond buf len
2024-03-21Merge branch 'ps/reftable-block-search-fix'Junio C Hamano2-1/+3
The reftable code has its own custom binary search function whose comparison callback has an unusual interface, which caused the binary search to degenerate into a linear search, which has been corrected. * ps/reftable-block-search-fix: reftable/block: fix binary search over restart counter reftable/record: fix memory leak when decoding object records
2024-03-21Merge branch 'ps/reftable-stack-tempfile'Junio C Hamano5-181/+176
The code in reftable backend that creates new table files works better with the tempfile framework to avoid leaving cruft after a failure. * ps/reftable-stack-tempfile: reftable/stack: register compacted tables as tempfiles reftable/stack: register lockfiles during compaction reftable/stack: register new tables as tempfiles lockfile: report when rollback fails
2024-03-21Merge branch 'rs/opt-parse-long-fixups'Junio C Hamano3-64/+100
The parse-options code that deals with abbreviated long option names have been cleaned up. Reviewed-by: Josh Steadmon <steadmon@google.com> cf. <ZfDM5Or3EKw7Q9SA@google.com> * rs/opt-parse-long-fixups: parse-options: rearrange long_name matching code parse-options: normalize arg and long_name before comparison parse-options: detect ambiguous self-negation parse-options: factor out register_abbrev() and struct parsed_option parse-options: set arg of abbreviated option lazily parse-options: recognize abbreviated negated option with arg
2024-03-21reftable: fix tests being broken by NFS' delete-after-close semanticsPatrick Steinhardt1-1/+11
It was reported that the reftable unit tests in t0032 fail with the following assertion when running on top of NFS: running test_reftable_stack_compaction_concurrent_clean reftable/stack_test.c: 1063: failed assertion count_dir_entries(dir) == 2 Aborted Setting a breakpoint immediately before the assertion in fact shows the following list of files: ./stack_test-1027.QJBpnd ./stack_test-1027.QJBpnd/0x000000000001-0x000000000003-dad7ac80.ref ./stack_test-1027.QJBpnd/.nfs000000000001729f00001e11 ./stack_test-1027.QJBpnd/tables.list Note the weird ".nfs*" file? This file is maintained by NFS clients in order to emulate delete-after-last-close semantics that we rely on in the reftable code [1]. Instead of unlinking the file right away and keeping it open in the client, the NFS client will rename it to ".nfs*" and then delete that temporary file when the last reference to it gets dropped. Quoting the NFS FAQ: > D2. What is a "silly rename"? Why do these .nfsXXXXX files keep > showing up? > > A. Unix applications often open a scratch file and then unlink it. > They do this so that the file is not visible in the file system name > space to any other applications, and so that the system will > automatically clean up (delete) the file when the application exits. > This is known as "delete on last close", and is a tradition among > Unix applications. > > Because of the design of the NFS protocol, there is no way for a > file to be deleted from the name space but still remain in use by an > application. Thus NFS clients have to emulate this using what > already exists in the protocol. If an open file is unlinked, an NFS > client renames it to a special name that looks like ".nfsXXXXX". > This "hides" the file while it remains in use. This is known as a > "silly rename." Note that NFS servers have nothing to do with this > behavior. This of course throws off the assertion that we got exactly two files in that directory. The test in question triggers this behaviour by holding two open file descriptors to the "tables.list" file. One of the references is because we are about to append to the stack, whereas the other reference is because we want to compact it. As the compaction has just finished we already rewrote "tables.list" to point to the new contents, but the other file descriptor pointing to the old version is still open. Thus we trigger the delete-after-last-close emulation. Furthermore, it was reported that this behaviour only triggers with 4f36b8597c (reftable/stack: fix race in up-to-date check, 2024-01-18). This is expected as well because it is the first point in time where we actually keep the "tables.list" file descriptor open for the stat cache. Fix this bug by skipping over any files that start with a leading dot when counting files. While we could explicitly check for a prefix of ".nfs", other network file systems like SMB for example do the same trickery but with a ".smb" prefix. In any case though, this loosening of the assertion should be fine given that the reftable library would never write files with leading dots by itself. [1]: https://nfs.sourceforge.net/#faq_d2 Reported-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-20contrib: drop hg-to-git scriptJeff King2-275/+0
The hg-to-git script is full of command injection vulnerabilities against malicious branch and tag names. It's also old and largely unmaintained; the last commit was over 4 years ago, and the last code change before that was from 2013. Users are better off with a modern remote-helper tool like cinnabar or remote-hg. So rather than spending time to fix it, let's just get rid of it. Reported-by: Matthew Rollings <admin@stealthcopter.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-20transport-helper: send "true" value for object-format optionJeff King2-6/+5
The documentation in gitremote-helpers.txt claims that after a helper has advertised the "object-format" capability, Git may then send "option object-format true" to indicate that it would like to hear which object format the helper is using when it returns refs. However, the code implementing this has always written just "option object-format", without the extra "true" value. Nobody noticed in practice or in the tests because the only two helpers we ship are: - remote-curl, which quietly converts missing values into "true". This goes all the way back to ef08ef9ea0 (remote-helpers: Support custom transport options, 2009-10-30), despite the fact that I don't think any other option has ever made use of it. - remote-testgit in t5801 does insist on having a "true" value. But since it sends the ":object-format" response regardless of whether it thinks the caller asked for it (technically breaking protocol), everything just works, albeit with an extra shell error: .../git/t/t5801/git-remote-testgit: 150: test: =: unexpected operator printed to stderr, which you can see running t5801 with --verbose. (The problem is that $val is the empty string, and since we don't double-quote it in "test $val = true", we invoke "test = true" instead). When the documentation and code do not match, it is often good to fix the documentation rather than break compatibility. And in this case, we have had the mis-match since 8b85ee4f47 (transport-helper: implement object-format extensions, 2020-05-25). However, the sha256 feature was listed as experimental until 8e42eb0e9a (doc: sha256 is no longer experimental, 2023-07-31). It's possible there are some third party helpers that tried to follow the documentation, and are broken. Changing the code will fix them. It's also possible that there are ones that follow the code and will be broken if we change it. I suspect neither is the case given that no helper authors have brought this up as an issue (I only noticed it because I was running t5801 in verbose mode for other reasons and wondered about the weird shell error). That, coupled with the relative new-ness of sha256, makes me think nobody has really worked on helpers for it yet, which gives us an opportunity to correct the code before too much time passes. And doing so has some value: it brings "object-format" in line with the syntax of other options, making the protocol more consistent. It also lets us use set_helper_option(), which has better error reporting. Note that we don't really need to allow any other values like "false" here. The point is for Git to tell the helper that it understands ":object-format" lines coming back as part of the ref listing. There's no point in future versions saying "no, I don't understand that". To make sure everything works as expected, we can improve the remote-testgit helper from t5801 to send the ":object-format" line only if the other side correctly asked for it (which modern Git will always do). With that test change and without the matching code fix here, t5801 will fail when run with GIT_TEST_DEFAULT_HASH=sha256. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-20transport-helper: drop "object-format <algo>" optionJeff King2-12/+4
The documentation in gitremote-helpers.txt claims that helpers should accept an object-format option from Git whose value is either: 1. "true", in which case the helper is merely told that Git understands the special ":object-format" response, and will send it 2. an algorithm name that the helper should use However, Git has never sent the second form, and it's not clear if it would ever be useful. When interacting with a remote Git repository, we generally discover what _their_ object format is, and then decide what to do with a mismatch (where that is currently just "bail out", but could eventually be on-the-fly conversion and interop). And that is true for native protocols, but also for transport helpers like remote-curl that talk to remote Git repositories. There we send back an ":object-format" line telling Git what remote-curl detected on the other side. And this is true even for pushes (since we get it via receive-pack's advertisement). And it is even true for dumb-http, as we guess at the algorithm based on the hash size, due to ac093d0790 (remote-curl: detect algorithm for dumb HTTP by size, 2020-06-19). The one case where it _isn't_ true is dumb-http talking to an empty repository. There we have no clue what the remote hash is, so remote-curl just sends back its default. If we kept the "object-format <algo>" form then in theory Git could say "object-format sha256" to change that default. But it doesn't really accomplish anything. We still may or may not be mis-matched with the other side. For a fetch that's OK, since it's by definition a noop. For a push into an empty repository, it might matter (though the dumb http-push DAV code seems happy to clobber a remote sha256 info/refs and corrupt the repository). If we want to pursue making this work, I think we'd be better off improving detection of the object format of empty repositories over dumb-http (e.g., an "info/object-format" file). But what about helpers that _aren't_ talking to another Git repo? Consider something like git-cinnabar, which is converting on the fly to/from hg. Most of the heavy lifting is done by fast-import/export, but some oids may still pass between Git and the helper. Could "object-format <algo>" be useful to tell the helper what oids we expect to see? Possibly, but in practice this isn't necessary. Git-cinnabar for example already peeks at the local-repo .git/config to check its object-format (and currently just bails if it is sha256). So I think the "object-format" extension really is only useful for the helper telling Git what object-format it found, and not the other way around. Note that this patch can't break any remote helpers; we're not changing the code on the Git side at all, but just bringing the documentation in line with what Git has always done. It does remove the receiving support in remote-curl.c, but that code was never actually triggered. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-20transport-helper: use write helpers more consistentlyJeff King1-3/+3
The transport-helper code provides some functions for writing to the helper process, but there are a few spots that don't use them. We should do so consistently because: 1. They detect errors on write (though in practice this means the helper process went away, and we'd see the problem as soon as we try to read the response). 2. They dump the written bytes to the GIT_TRANSPORT_HELPER_DEBUG stream. It's doubly confusing to miss some writes but not others, as you see a partial conversation. The "list" ones go all the way back to the beginning of the transport helper code; they were just missed when most writes were converted in bf3c523c3f (Add remote helper debug mode, 2009-12-09). The nearby "object-format" write presumably just cargo-culted them, as it's only a few lines away. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-20doc/gitremote-helpers: fix more missing single-quotesJeff King1-3/+3
There are a few cases left in gitremote-helpers.txt that are missing a closing quote, so you end up with: 'option deepen-since <timestamp> with a stray opening quote instead of rendering correctly in italics. These should have been part of 51d41dc243 (doc/gitremote-helpers: fix missing single-quote, 2024-03-07), but apparently my eyesight is not what it once was. Hopefully this is now all of them. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19format-patch: simplify after-subject MIME header handlingJeff King1-8/+6
In log_write_email_headers(), we append our MIME headers to the set of extra headers by creating a new strbuf, adding the existing headers, and then adding our new ones. We had to do it this way when our output buffer might point to the constant opt->extra_headers variable. But since the previous commit, we always make a local copy of that variable. Let's turn that into a strbuf, which lets the MIME code simply append to it. That simplifies the function and avoids a pointless extra copy of the headers. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19format-patch: return an allocated string from log_write_email_headers()Jeff King4-7/+9
When pretty-printing a commit in the email format, we have to fill in the "after subject" field of the pretty_print_context with any extra headers the user provided (e.g., from "--to" or "--cc" options) plus any special MIME headers. We return an out-pointer that sometimes points to a newly heap-allocated string and sometimes not. To avoid leaking, we store the allocated version in a buffer with static lifetime, which is ugly. Worse, as we extend the header feature, we'll end up having to repeat this ugly pattern. Instead, let's have our out-pointer pass ownership back to the caller, and duplicate the string when necessary. This does mean one extra allocation per commit when you use extra headers, but in the context of format-patch which is showing diffs, I don't think that's even measurable. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19log: do not set up extra_headers for non-email formatsJeff King1-3/+1
The commit pretty-printer code has an "after_subject" parameter which it uses to insert extra headers into the email format. In show_log() we set this by calling log_write_email_headers() if we are using an email format, but otherwise default the variable to the rev_info.extra_headers variable. Since the pretty-printer code will ignore after_subject unless we are using an email format, this default is pointless. We can just set after_subject directly, eliminating an extra variable. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19pretty: drop print_email_subject flagJeff King5-16/+9
With one exception, the print_email_subject flag is set if and only if the commit format is email based: - in make_cover_letter() we set it along with CMIT_FMT_EMAIL explicitly - in show_log(), we set it if cmit_fmt_is_mail() is true. That covers format-patch as well as "git log --format=email" (or mboxrd). The one exception is "rev-list --format=email", which somewhat nonsensically prints the author and date as email headers, but no subject, like: $ git rev-list --format=email HEAD commit 64fc4c2cdd4db2645eaabb47aa4bac820b03cdba From: Jeff King <peff@peff.net> Date: Tue, 19 Mar 2024 19:39:26 -0400 this is the subject this is the body It's doubtful that this is a useful format at all (the "commit" lines replace the "From" lines that would make it work as an actual mbox). But I think that printing the subject as a header (like this patch does) is the least surprising thing to do. So let's drop this field, making the code a little simpler and easier to reason about. Note that we do need to set the "rev" field of the pretty_print_context in rev-list, since that is used to check for subject_prefix, etc. It's not possible to set those fields via rev-list, so we'll always just print "Subject: ". But unless we pass in our rev_info, fmt_output_email_subject() would segfault trying to figure it out. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19pretty: split oneline and email subject printingJeff King3-15/+17
The pp_title_line() function is used for two formats: the oneline format and the subject line of the email format. But most of the logic in the function does not make any sense for oneline; it is about special formatting of email headers. Lumping the two formats together made sense long ago in 4234a76167 (Extend --pretty=oneline to cover the first paragraph, 2007-06-11), when there was a lot of manual logic to paste lines together. But later, 88c44735ab (pretty: factor out format_subject(), 2008-12-27) pulled that logic into its own function. We can implement the oneline format by just calling that one function. This makes the intention of the code much more clear, as we know we only need to worry about those extra email options when dealing with actual email. While the intent here is cleanup, it is possible to trigger these cases in practice by running format-patch with an explicit --oneline option. But if you did, the results are basically nonsense. For example, with the preserve_subject flag: $ printf "%s\n" one two three | git commit --allow-empty -F - $ git format-patch -1 --stdout -k | grep ^Subject Subject: =?UTF-8?q?one=0Atwo=0Athree?= $ git format-patch -1 --stdout -k --oneline --no-signature 2af7fbe one two three Or with extra headers: $ git format-patch -1 --stdout --cc=me --oneline --no-signature 2af7fbe one two three Cc: me So I'd actually consider this to be an improvement, though you are probably crazy to use other formats with format-patch in the first place (arguably it should forbid non-email formats entirely, but that's a bigger change). As a bonus, it eliminates some pointless extra allocations for the oneline output. The email code, since it has to deal with wrapping, formats into an extra auxiliary buffer. The speedup is tiny, though like "rev-list --no-abbrev --format=oneline" seems to improve by a consistent 1-2% for me. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19shortlog: stop setting pp.print_email_subjectJeff King1-1/+0
When shortlog processes a commit using its internal traversal, it may pretty-print the subject line for the summary view. When we do so, we set the "print_email_subject" flag in the pretty-print context. But this flag does nothing! Since we are using CMIT_FMT_USERFORMAT, we skip most of the usual formatting code entirely. This flag is there due to commit 6d167fd7cc (pretty: use fmt_output_email_subject(), 2017-03-01). But that just switched us away from setting an empty "subject" header field, which was similarly useless. That was added by dd2e794a21 (Refactor pretty_print_commit arguments into a struct, 2009-10-19). Before using the struct, we had to pass _something_ as the argument, so we passed the empty string (a NULL would have worked equally well). So this setting has never done anything, and we can drop the line. That shortens the code, but more importantly, makes it easier to reason about and refactor the other users of this flag. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-19apply: parse names out of "diff --git" more carefullyJunio C Hamano2-1/+30
"git apply" uses the pathname parsed out of the "diff --git" header to decide which path is being patched, but this is used only when there is no other names available in the patch. When there is any content change (like we can see in this patch, that modifies the contents of "apply.c") or rename (which comes with "rename from" and "rename to" extended diff headers), the names are available without having to parse this header. When we do need to parse this header, a special care needs to be taken, as the name of a directory or a file can have a SP in it so it is not like "find a space, and take everything before the space and that is the preimage filename, everything after the space is the postimage filename". We have a loop that stops at every SP on the "diff --git a/dir/file b/dir/foo" line and see if that SP is the right place that separates such a pair of names. Unfortunately, this loop can terminate prematurely when a crafted directory name ended with a SP. The next pathname component after that SP (i.e. the beginning of the possible postimage filename) will be a slash, and instead of rejecting that position as the valid separation point between pre- and post-image filenames and keep looping, we stopped processing right there. The fix is simple. Instead of stopping and giving up, keep going on when we see such a condition. Reported-by: Han Young <hanyang.tony@bytedance.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-18Merge branch 'ps/reftable-stack-tempfile' into ps/pack-refs-autoJunio C Hamano5-181/+176
* ps/reftable-stack-tempfile: reftable/stack: register compacted tables as tempfiles reftable/stack: register lockfiles during compaction reftable/stack: register new tables as tempfiles lockfile: report when rollback fails
2024-03-18The ninth batchJunio C Hamano1-0/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-18Merge branch 'jk/doc-remote-helpers-markup-fix'Junio C Hamano1-1/+1
Doc mark-up fix. * jk/doc-remote-helpers-markup-fix: doc/gitremote-helpers: fix missing single-quote