summaryrefslogtreecommitdiffstats
path: root/builtin (follow)
AgeCommit message (Collapse)AuthorFilesLines
2022-11-23Merge branch 'dd/bisect-helper-subcommand'Junio C Hamano1-100/+129
Fix a regression in the bisect-helper which mistakenly treats arguments to the command given to 'git bisect run' as arguments to the helper. * dd/bisect-helper-subcommand: bisect--helper: parse subcommand with OPT_SUBCOMMAND bisect--helper: move all subcommands into their own functions bisect--helper: remove unused options
2022-11-23Merge branch 'ab/submodule-helper-prep-only'Junio C Hamano2-103/+46
Preparation to remove git-submodule.sh and replace it with a builtin. * ab/submodule-helper-prep-only: submodule--helper: use OPT_SUBCOMMAND() API submodule--helper: drop "update --prefix <pfx>" for "-C <pfx> update" submodule--helper: remove --prefix from "absorbgitdirs" submodule API & "absorbgitdirs": remove "----recursive" option submodule.c: refactor recursive block out of absorb function submodule tests: test for a "foreach" blind-spot submodule--helper: fix a memory leak in "status" submodule tests: add tests for top-level flag output submodule--helper: move "config" to a test-tool
2022-11-21prune: quiet ENOENT on missing directoriesEric Wong1-1/+3
$GIT_DIR/objects/pack may be removed to save inodes in shared repositories. Quiet down prune in cases where either $GIT_DIR/objects or $GIT_DIR/objects/pack is non-existent, but emit the system error in other cases to help users diagnose permissions problems or resource constraints. Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21built-ins: use free() not UNLEAK() if trivial, rm dead codeÆvar Arnfjörð Bjarmason6-33/+35
For a lot of uses of UNLEAK() it would be quite tricky to release the memory involved, or we're missing the relevant *_(release|clear)() functions. But in these cases we have them already, and can just invoke them on the variable(s) involved, instead of UNLEAK(). For "builtin/worktree.c" the UNLEAK() was also added in [1], but the struct member it's unleaking was removed in [2]. The only non-"int" member of that structure is "const char *keep_locked", which comes to us via "argv" or a string literal[3]. We have good visibility via the compiler and tooling (e.g. SANITIZE=address) on bad free()-ing, but none on UNLEAK() we don't need anymore. So let's prefer releasing the memory when it's easy. For "bugreport", "worktree" and "config" we need to start using a "ret = ..." return pattern. For "builtin/bugreport.c" these UNLEAK() were added in [4], and for "builtin/config.c" in [1]. For "config" the code seen here was the only user of the "value" variable. For "ACTION_{RENAME,REMOVE}_SECTION" we need to be sure to return the right exit code in the cases where we were relying on falling through to the top-level. I think there's still a use-case for UNLEAK(), but hat it's changed since then. Using it so that "we can see the real leaks" is counter-productive in these cases. It's more useful to have UNLEAK() be a marker of the remaining odd cases where it's hard to free() the memory for whatever reason. With this change less than 20 of them remain in-tree. 1. 0e5bba53af7 (add UNLEAK annotation for reducing leak false positives, 2017-09-08) 2. d861d34a6ed (worktree: remove extra members from struct add_opts, 2018-04-24) 3. 0db4961c49b (worktree: teach `add` to accept --reason <string> with --lock, 2021-07-15) 4. 0e5bba53af7 and 00d8c311050 (commit: fix "author_ident" leak, 2022-05-12). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21revert: fix parse_options_concat() leakÆvar Arnfjörð Bjarmason1-0/+1
Free memory from parse_options_concat(), which comes from code originally added (then extended) in [1]. At this point we could get several more tests leak-free by free()-ing the xstrdup() just above the line being changed, but that one's trickier than it seems. The sequencer_remove_state() function supposedly owns it, but sometimes we don't call it. I have a fix for it, but it's non-trivial, so let's fix the easy one first. 1. c62f6ec341b (revert: add --ff option to allow fast forward when cherry-picking, 2010-03-06) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21cherry-pick: free "struct replay_opts" membersÆvar Arnfjörð Bjarmason1-0/+3
Call the release_revisions() function added in 1878b5edc03 (revision.[ch]: provide and start using a release_revisions(), 2022-04-13) in cmd_cherry_pick(), as well as freeing the xmalloc()'d "revs" member itself. This is the same change as the one made for cmd_revert() a few lines above it in fd74ac95ac3 (revert: free "struct replay_opts" members, 2022-07-01). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21rebase: don't leak on "--abort"Ævar Arnfjörð Bjarmason1-0/+1
Fix a leak in the recent 6159e7add49 (rebase --abort: improve reflog message, 2022-10-12). Before that commit we'd strbuf_release() the reflog message we were formatting, but when that code was refactored to use "ropts.head_msg" the strbuf_release() was omitted. Ideally the three users of "ropts" in cmd_rebase() should use different "ropts" variables, in practice they're completely separate, as this and the other user in the "switch" statement will "goto cleanup", which won't touch "ropts". The third caller after the "switch" is then unreachable if we take these two branches, so all of them are getting a "{ 0 }" init'd "ropts". So it's OK that we're leaving a stale pointer in "ropts.head_msg", cleaning it up was our responsibility, and it won't be used again. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21ls-files: fix a --with-tree memory leakÆvar Arnfjörð Bjarmason1-0/+1
Fix a memory leak in overlay_tree_on_index(), we need to clear_pathspec() at some point, which might as well be after the last time we use it in the function. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21unpack-file: fix ancient leak in create_temp_file()Ævar Arnfjörð Bjarmason1-0/+1
Fix a leak that's been with us since 3407bb4940c (Add "unpack-file" helper that unpacks a sha1 blob into a tmpfile., 2005-04-18). See 00c8fd493af (cat-file: use streaming API to print blobs, 2012-03-07) for prior art which shows the same API pattern, i.e. free()-ing the result of read_object_file() after it's used. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21built-ins & libs & helpers: add/move destructors, fix leaksÆvar Arnfjörð Bjarmason5-1/+9
Fix various leaks in built-ins, libraries and a test helper here we were missing a call to strbuf_release(), string_list_clear() etc, or were calling them after a potential "return". Comments on individual changes: - builtin/checkout.c: Fix a memory leak that was introduced in [1]. A sibling leak introduced in [2] was recently fixed in [3]. As with [3] we should be using the wt_status_state_free_buffers() API introduced in [4]. - builtin/repack.c: Fix a leak that's been here since this use of "strbuf_release()" was added in a1bbc6c0176 (repack: rewrite the shell script in C, 2013-09-15). We don't use the variable for anything except this loop, so we can instead free it right afterwards. - builtin/rev-parse: Fix a leak that's been here since this code was added in 21d47835386 (Add a parseopt mode to git-rev-parse to bring parse-options to shell scripts., 2007-11-04). - builtin/stash.c: Fix a couple of leaks that have been here since this code was added in d4788af875c (stash: convert create to builtin, 2019-02-25), we strbuf_release()'d only some of the "struct strbuf" we allocated earlier in the function, let's release all of them. - ref-filter.c: Fix a leak in 482c1191869 (gpg-interface: improve interface for parsing tags, 2021-02-11), we don't use the "payload" variable that we ask parse_signature() to populate for us, so let's free it. - t/helper/test-fake-ssh.c: Fix a leak that's been here since this code was added in 3064d5a38c7 (mingw: fix t5601-clone.sh, 2016-01-27). Let's free the "struct strbuf" as soon as we don't need it anymore. 1. c45f0f525de (switch: reject if some operation is in progress, 2019-03-29) 2. 2708ce62d21 (branch: sort detached HEAD based on a flag, 2021-01-07) 3. abcac2e19fa (ref-filter.c: fix a leak in get_head_description, 2022-09-25) 4. 962dd7ebc3e (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21commit: discard partial cache before (re-)reading itÆvar Arnfjörð Bjarmason1-2/+5
The read_cache() in prepare_to_commit() would end up clobbering the pointer we had for a previously populated "the_index.cache_tree" in the very common case of "git commit" stressed by e.g. the tests being changed here. We'd populate "the_index.cache_tree" by calling "update_main_cache_tree" in prepare_index(), but would not end up with a "fully prepared" index. What constitutes an existing index is clearly overly fuzzy, here we'll check "active_nr" (aka "the_index.cache_nr"), but our "the_index.cache_tree" might have been malloc()'d already. Thus the code added in 11c8a74a64a (commit: write cache-tree data when writing index anyway, 2011-12-06) would end up allocating the "cache_tree", and would interact here with code added in 7168624c353 (Do not generate full commit log message if it is not going to be used, 2007-11-28). The result was a very common memory leak. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21{reset,merge}: call discard_index() before returningÆvar Arnfjörð Bjarmason2-0/+3
These two built-ins both deal with the index, but weren't discarding it. In subsequent commits we'll add more free()-ing to discard_index() that we've missed, but let's first call the existing function. We can doubtless add discard_index() (or its alias discard_cache()) to a lot more places, but let's just add it here for now. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-21cocci: apply "pending" index-compatibility to some "builtin/*.c"Ævar Arnfjörð Bjarmason27-143/+160
Apply "index-compatibility.pending.cocci" rule to "builtin/*", but exclude those where we conflict with in-flight changes. As a result some of them end up using only "the_index", so let's have them use the more narrow "USE_THE_INDEX_VARIABLE" rather than "USE_THE_INDEX_COMPATIBILITY_MACROS". Manual changes not made by coccinelle, that were squashed in: * Whitespace-wrap argument lists for repo_hold_locked_index(), repo_read_index_preload() and repo_refresh_and_write_index(), in cases where the line became too long after the transformation. * Change "refresh_cache()" to "refresh_index()" in a comment in "builtin/update-index.c". * For those whose call was followed by perror("<macro-name>"), change it to perror("<function-name>"), referring to the new function. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21{builtin/*,repository}.c: add & use "USE_THE_INDEX_VARIABLE"Ævar Arnfjörð Bjarmason4-4/+4
Split up the "USE_THE_INDEX_COMPATIBILITY_MACROS" into that setting and a more narrow "USE_THE_INDEX_VARIABLE". In the case of these built-ins we only need "the_index" variable, but not the compatibility wrapper for functions we're not using. Let's then have some users of "USE_THE_INDEX_COMPATIBILITY_MACROS" use this more narrow and descriptive define. For context: The USE_THE_INDEX_COMPATIBILITY_MACROS macro was added to test-tool.h in f8adbec9fea (cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch, 2019-01-24). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21cocci & cache.h: apply variable section of "pending" index-compatibilityÆvar Arnfjörð Bjarmason14-106/+107
Mostly apply the part of "index-compatibility.pending.cocci" that renames the global variables like "active_nr", which are a shorthand to referencing (in that case) a struct member as "the_index.cache_nr". In doing so move more of "index-compatibility.pending.cocci" to "index-compatibility.cocci". In the case of "active_nr" we'd have a textual conflict with "ab/various-leak-fixes" in "next"[1]. Let's exclude that specific case while moving the rule over from "pending". 1. 407b94280f8 (commit: discard partial cache before (re-)reading it, 2022-11-08) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21cocci & cache.h: apply a selection of "pending" index-compatibilityÆvar Arnfjörð Bjarmason8-21/+25
Apply a selection of rules in "index-compatibility.pending.cocci" tree-wide, and in doing so migrate them to "index-compatibility.cocci". As in preceding commits the only manual changes here are the macro removals in "cache.h", and the update to the '*.cocci" rules. The rest of the C code changes are the result of applying those updated rules. Move rules for some rarely used cache compatibility macros from "index-compatibility.pending.cocci" to "index-compatibility.cocci" and apply them. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21read-cache API & users: make discard_index() return voidÆvar Arnfjörð Bjarmason1-1/+2
The discard_index() function has not returned non-zero since 7a51ed66f65 (Make on-disk index representation separate from in-core one, 2008-01-14), but we've had various code in-tree still acting as though that might be the case. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21cocci & cache.h: remove rarely used "the_index" compat macrosÆvar Arnfjörð Bjarmason11-19/+20
Since 4aab5b46f44 (Make read-cache.c "the_index" free., 2007-04-01) we've been undergoing a slow migration away from these macros, but haven't made much progress since f8adbec9fea (cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch, 2019-01-24). Let's move forward a bit by changing the users of those macros that are rare enough that we can convert them in one go, and then remove the compatibility shim. The only manual change to the C code here is to "cache.h", the rest is all the result of applying the new "index-compatibility.cocci". Even though it's a one-off, let's keep the coccinelle rules for now. We'll extend them in subsequent commits, and this will help anything that's in-flight or out-of-tree to migrate. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-21builtin/{grep,log}.: don't define "USE_THE_INDEX_COMPATIBILITY_MACROS"Ævar Arnfjörð Bjarmason2-2/+0
Adding "USE_THE_INDEX_COMPATIBILITY_MACROS" to these two appears to have been unnecessary from the start, as going back and compiling f8adbec9fea (cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch, 2019-01-24) without that addition works. Let's not have these ask for the compatibility macros from cache.h that they don't need. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-11-18Merge branch 'jk/branch-delete-detached'Taylor Blau1-6/+3
Fix a bug where `git branch -d` did not work on an orphaned HEAD. * jk/branch-delete-detached: branch: gracefully handle '-d' on orphan HEAD
2022-11-18Merge branch 'vd/skip-cache-tree-update'Taylor Blau2-0/+6
Avoid calling 'cache_tree_update()' when doing so would be redundant. * vd/skip-cache-tree-update: rebase: use 'skip_cache_tree_update' option read-tree: use 'skip_cache_tree_update' option reset: use 'skip_cache_tree_update' option unpack-trees: add 'skip_cache_tree_update' option cache-tree: add perf test comparing update and prime
2022-11-18Merge branch 'tb/repack-expire-to'Taylor Blau1-10/+61
"git repack" learns to send cruft objects out of the way into packfiles outside the repository. * tb/repack-expire-to: builtin/repack.c: implement `--expire-to` for storing pruned objects builtin/repack.c: write cruft packs to arbitrary locations builtin/repack.c: pass "cruft_expiration" to `write_cruft_pack` builtin/repack.c: pass "out" to `prepare_pack_objects`
2022-11-17branch: force-copy a branch to itself via @{-1} is a no-opRubén Justo1-3/+3
Since 52d59cc645 (branch: add a --copy (-c) option to go with --move (-m), 2017-06-18) we can copy a branch to make a new branch with the '-c' (copy) option or to overwrite an existing branch using the '-C' (force copy) option. A no-op possibility is considered when we are asked to copy a branch to itself, to follow the same no-op introduced for the rename (-M) operation in 3f59481e33 (branch: allow a no-op "branch -M <current-branch> HEAD", 2011-11-25). To check for this, in 52d59cc645 we compared the branch names provided by the user, source (HEAD if omitted) and destination, and a match is considered as this no-op. Since ae5a6c3684 (checkout: implement "@{-N}" shortcut name for N-th last branch, 2009-01-17) a branch can be specified using shortcuts like @{-1}. This allows this usage: $ git checkout -b test $ git checkout - $ git branch -C test test # no-op $ git branch -C test @{-1} # oops $ git branch -C @{-1} test # oops As we are using the branch name provided by the user to do the comparison, if one of the branches is provided using a shortcut we are not going to have a match and a call to git_config_copy_section() will happen. This will make a duplicate of the configuration for that branch, and with this progression the second call will produce four copies of the configuration, and so on. Let's use the interpreted branch name instead for this comparison. The rename operation is not affected. Signed-off-by: Rubén Justo <rjusto@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-17receive-pack: only use visible refs for connectivity checkPatrick Steinhardt1-0/+2
When serving a push, git-receive-pack(1) needs to verify that the packfile sent by the client contains all objects that are required by the updated references. This connectivity check works by marking all preexisting references as uninteresting and using the new reference tips as starting point for a graph walk. Marking all preexisting references as uninteresting can be a problem when it comes to performance. Git forges tend to do internal bookkeeping to keep alive sets of objects for internal use or make them easy to find via certain references. These references are typically hidden away from the user so that they are neither advertised nor writeable. At GitLab, we have one particular repository that contains a total of 7 million references, of which 6.8 million are indeed internal references. With the current connectivity check we are forced to load all these references in order to mark them as uninteresting, and this alone takes around 15 seconds to compute. We can optimize this by only taking into account the set of visible refs when marking objects as uninteresting. This means that we may now walk more objects until we hit any object that is marked as uninteresting. But it is rather unlikely that clients send objects that make large parts of objects reachable that have previously only ever been hidden, whereas the common case is to push incremental changes that build on top of the visible object graph. This provides a huge boost to performance in the mentioned repository, where the vast majority of its refs hidden. Pushing a new commit into this repo with `transfer.hideRefs` set up to hide 6.8 million of 7 refs as it is configured in Gitaly leads to a 4.5-fold speedup: Benchmark 1: main Time (mean ± σ): 30.977 s ± 0.157 s [User: 30.226 s, System: 1.083 s] Range (min … max): 30.796 s … 31.071 s 3 runs Benchmark 2: pks-connectivity-check-hide-refs Time (mean ± σ): 6.799 s ± 0.063 s [User: 6.803 s, System: 0.354 s] Range (min … max): 6.729 s … 6.850 s 3 runs Summary 'pks-connectivity-check-hide-refs' ran 4.56 ± 0.05 times faster than 'main' As we mostly go through the same codepaths even in the case where there are no hidden refs at all compared to the code before there is no change in performance when no refs are hidden: Benchmark 1: main Time (mean ± σ): 48.188 s ± 0.432 s [User: 49.326 s, System: 5.009 s] Range (min … max): 47.706 s … 48.539 s 3 runs Benchmark 2: pks-connectivity-check-hide-refs Time (mean ± σ): 48.027 s ± 0.500 s [User: 48.934 s, System: 5.025 s] Range (min … max): 47.504 s … 48.500 s 3 runs Summary 'pks-connectivity-check-hide-refs' ran 1.00 ± 0.01 times faster than 'main' Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-17rev-parse: add `--exclude-hidden=` optionPatrick Steinhardt1-0/+10
Add a new `--exclude-hidden=` option that is similar to the one we just added to git-rev-list(1). Given a section name `uploadpack` or `receive` as argument, it causes us to exclude all references that would be hidden by the respective `$section.hideRefs` configuration. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-17revision: add new parameter to exclude hidden refsPatrick Steinhardt1-0/+1
Users can optionally hide refs from remote users in git-upload-pack(1), git-receive-pack(1) and others via the `transfer.hideRefs`, but there is not an easy way to obtain the list of all visible or hidden refs right now. We'll require just that though for a performance improvement in our connectivity check. Add a new option `--exclude-hidden=` that excludes any hidden refs from the next pseudo-ref like `--all` or `--branches`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-17revision: introduce struct to handle exclusionsPatrick Steinhardt1-4/+4
The functions that handle exclusion of refs work on a single string list. We're about to add a second mechanism for excluding refs though, and it makes sense to reuse much of the same architecture for both kinds of exclusion. Introduce a new `struct ref_exclusions` that encapsulates all the logic related to excluding refs and move the `struct string_list` that holds all wildmatch patterns of excluded refs into it. Rename functions that operate on this struct to match its name. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-17refs: get rid of global list of hidden refsPatrick Steinhardt1-3/+5
We're about to add a new argument to git-rev-list(1) that allows it to add all references that are visible when taking `transfer.hideRefs` et al into account. This will require us to potentially parse multiple sets of hidden refs, which is not easily possible right now as there is only a single, global instance of the list of parsed hidden refs. Refactor `parse_hide_refs_config()` and `ref_is_hidden()` so that both take the list of hidden references as input and adjust callers to keep a local list, instead. This allows us to easily use multiple hidden-ref lists. Furthermore, it allows us to properly free this list before we exit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-16notes: avoid empty line in templateMichael J Gruber1-1/+1
When `git notes` prepares the template it adds an empty newline between the comment header and the content: > > # > # Write/edit the notes for the following object: > > # commit 0f3c55d4c2b7864bffb2d92278eff08d0b2e083f > # etc This is wrong structurally because that newline is part of the comment, too, and thus should be commented. Also, it throws off some positioning strategies of editors and plugins, and it differs from how we do commit templates. Change this to follow the standard set by `git commit`: > > # > # Write/edit the notes for the following object: > # > # commit 0f3c55d4c2b7864bffb2d92278eff08d0b2e083f > Tests pass unchanged after this code change. Signed-off-by: Michael J Gruber <git@grubix.eu> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-15builtin/gc.c: fix use-after-free in maintenance_unregister()Taylor Blau1-3/+2
While trying to fix a move based on an uninitialized value (along with a declaration after the first statement), be0fd57228 (maintenance --unregister: fix uninit'd data use & -Wdeclaration-after-statement, 2022-11-15) unintentionally introduced a use-after-free. The problem arises when `maintenance_unregister()` sees a non-NULL `config_file` string and thus tries to call git_configset_get_value_multi() to lookup the corresponding values. We store the result off, and then call git_configset_clear(), which frees the pointer that we just stored. We then try to read that now-freed pointer a few lines below, and there we have our use-after-free: $ ./t7900-maintenance.sh -vxi --run=23 --valgrind [...] + git maintenance unregister --config-file ./other ==3048727== Invalid read of size 8 ==3048727== at 0x1869CA: maintenance_unregister (gc.c:1590) ==3048727== by 0x188F42: cmd_maintenance (gc.c:2651) ==3048727== by 0x128C62: run_builtin (git.c:466) ==3048727== by 0x12907E: handle_builtin (git.c:721) ==3048727== by 0x1292EC: run_argv (git.c:788) ==3048727== by 0x12988E: cmd_main (git.c:926) ==3048727== by 0x21ED39: main (common-main.c:57) ==3048727== Address 0x4b38bc8 is 24 bytes inside a block of size 64 free'd ==3048727== at 0x484617B: free (vg_replace_malloc.c:872) ==3048727== by 0x2D207E: free_individual_entries (hashmap.c:188) ==3048727== by 0x2D2153: hashmap_clear_ (hashmap.c:207) ==3048727== by 0x270B5C: git_configset_clear (config.c:2375) ==3048727== by 0x1869AC: maintenance_unregister (gc.c:1585) ==3048727== by 0x188F42: cmd_maintenance (gc.c:2651) ==3048727== by 0x128C62: run_builtin (git.c:466) ==3048727== by 0x12907E: handle_builtin (git.c:721) ==3048727== by 0x1292EC: run_argv (git.c:788) ==3048727== by 0x12988E: cmd_main (git.c:926) ==3048727== by 0x21ED39: main (common-main.c:57) [...] Resolve this via a partial-revert of be0fd57228. The config_set struct now gets a zero initialization, which makes free()-ing it a noop even without calling git_configset_init(). When we do initialize it to a non-zero value, it is only free()'d after our last read of `list`. Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-15maintenance --unregister: fix uninit'd data use & -Wdeclaration-after-statementÆvar Arnfjörð Bjarmason1-2/+3
Since (maintenance: add option to register in a specific config, 2022-11-09) we've been unable to build with "DEVELOPER=1" without "DEVOPTS=no-error", as the added code triggers a "-Wdeclaration-after-statement" warning. And worse than that, the data handed to git_configset_clear() is uninitialized, as can be spotted with e.g.: ./t7900-maintenance.sh -vixd --run=23 --valgrind [...] + git maintenance unregister --force Conditional jump or move depends on uninitialised value(s) at 0x6B5F1E: git_configset_clear (config.c:2367) by 0x4BA64E: maintenance_unregister (gc.c:1619) by 0x4BD278: cmd_maintenance (gc.c:2650) by 0x409905: run_builtin (git.c:466) by 0x40A21C: handle_builtin (git.c:721) by 0x40A58E: run_argv (git.c:788) by 0x40AF68: cmd_main (git.c:926) by 0x5D39FE: main (common-main.c:57) Uninitialised value was created by a stack allocation at 0x4BA22C: maintenance_unregister (gc.c:1557) Let's fix both of these issues, and also move the scope of the variable to the "if" statement it's used in, to make it obvious where it's used. Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-14maintenance: add option to register in a specific configRonan Pigott1-13/+32
maintenance register currently records the maintenance repo exclusively within the user's global configuration, but other configuration files may be relevant when running maintenance if they are included from the global config. This option allows the user to choose where maintenance repos are recorded. Signed-off-by: Ronan Pigott <ronan@rjp.ie> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-14for-each-repo: interpolate repo path argumentsRonan Pigott1-1/+4
This is a quality of life change for git-maintenance, so repos can be recorded with the tilde syntax. The register subcommand will not record repos in this format by default. Signed-off-by: Ronan Pigott <ronan@rjp.ie> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-14Doc: document push.recurseSubmodules=onlyJonathan Tan1-2/+10
Git learned pushing submodules without pushing the superproject by the user specifying --recurse-submodules=only through 6c656c3fe4 ("submodules: add RECURSE_SUBMODULES_ONLY value", 2016-12-20) and 225e8bf778 ("push: add option to push only submodules", 2016-12-20). For users who use this feature regularly, it is desirable to have an equivalent configuration. It turns out that such a configuration (push.recurseSubmodules=only) is already supported, even though it is neither documented nor mentioned in the commit messages, due to the way the --recurse-submodules=only feature was implemented (a function used to parse --recurse-submodules was updated to support "only", but that same function is used to parse push.recurseSubmodules too). What is left is to document it and test it, which is what this commit does. There is a possible point of confusion when recursing into a submodule that itself has the push.recurseSubmodules=only configuration, because if a repository has only its submodules pushed and not itself, its superproject can never be pushed. Therefore, treat such configurations as being "on-demand", and print a warning message. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-12merge-tree.c: allow specifying the merge-base when --stdin is passedKyle Zhao1-2/+19
The previous commit added a `--merge-base` option in order to allow using a specified merge-base for the merge. Extend the input accepted by `--stdin` to also allow a specified merge-base with each merge requested. For example: printf "<b3> -- <b1> <b2>" | git merge-tree --stdin does a merge of b1 and b2, and uses b3 as the merge-base. Signed-off-by: Kyle Zhao <kylezhao@tencent.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-12merge-tree.c: add --merge-base=<commit> optionKyle Zhao1-11/+35
This patch will give our callers more flexibility to use `git merge-tree`, such as: git merge-tree --write-tree --merge-base=branch^ HEAD branch This does a merge of HEAD and branch, but uses branch^ as the merge-base. And the reason why using an option flag instead of a positional argument is to allow additional commits passed to merge-tree to be handled via an octopus merge in the future. Signed-off-by: Kyle Zhao <kylezhao@tencent.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11Turn `git bisect` into a full built-inJohannes Schindelin1-1/+1
Now that the shell script hands off to the `bisect--helper` to do _anything_ (except to show the help), it is but a tiny step to let the helper implement the actual `git bisect` command instead. This retires `git-bisect.sh`, concluding a multi-year journey that many hands helped with, in particular Pranit Bauna, Tanushree Tumane and Miriam Rubio. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect--helper: log: allow arbitrary number of argumentsĐoàn Trần Công Danh1-3/+1
In a later change, we would like to turn bisect into a builtin by renaming bisect--helper. However, there's an oddity that "git bisect log" accepts any number of arguments and it will just ignore them all. Let's prepare for the next step by ignoring any arguments passed to "git bisect--helper log" Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect--helper: handle states directlyJohannes Schindelin1-21/+21
In preparation for making `git bisect` a real built-in, let's prepare the `bisect--helper` built-in to handle `git bisect--helper good` and `git bisect--helper bad`, i.e. eliminate the need of `state` subcommand. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect--helper: emit usage for "git bisect"Ævar Arnfjörð Bjarmason1-15/+36
In subsequent commits we'll be removing "git-bisect.sh" in favor of promoting "bisect--helper" to a "bisect" built-in. In doing that we'll first need to have it support "git bisect--helper <cmd>" rather than "git bisect--helper --<cmd>", and then finally have its "-h" output claim to be "bisect" rather than "bisect--helper". Instead of suffering that churn let's start claiming to be "git bisect" now. In just a few commits this will be true, and in the meantime emitting the "wrong" usage information from the helper is a small price to pay to avoid the churn. Let's also declare "BUILTIN_*" macros, when we eventually migrate the sub-commands themselves to parse_options() we'll be able to re-use the strings. See 0afd556b2e1 (worktree: define subcommand -h in terms of command -h, 2022-10-13) for a recent example. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect--helper: identify as bisect when report errorĐoàn Trần Công Danh1-5/+8
In a later change, we will convert the bisect--helper to be builtin bisect. Let's start by self-identifying it's the real bisect when reporting error. This change is safe since 'git bisect--helper' is an implementation detail, users aren't expected to call 'git bisect--helper'. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect-run: verify_good: account for non-negative exit statusĐoàn Trần Công Danh1-1/+1
Some system never reports negative exit code at all, they reports them as bigger-than-128 instead. We take extra care for those systems in the later check for normal 'do_bisect_run' loop. Let's check it here, too. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect run: keep some of the post-v2.30.0 outputĐoàn Trần Công Danh1-13/+11
Preceding commits fixed output and behavior regressions in d1bbbe45df8 (bisect--helper: reimplement `bisect_run` shell function in C, 2021-09-13), which did not claim to be changing the output of "git bisect run". But some of the output it emitted was subjectively better, so once we've asserted that we're back on v2.29.0 behavior, let's change some of it back: - We now quote the arguments again, but omit the first " " when printing the "running" line. - Ditto for other cases where we emitted the argument - We say "found first bad commit" again, not just "run success" Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Based-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect: fix output regressions in v2.30.0Đoàn Trần Công Danh1-12/+15
When d1bbbe45df8 (bisect--helper: reimplement `bisect_run` shell function in C, 2021-09-13) reimplemented parts of "git bisect run" in C it changed the output we emitted so that: - The "running ..." line was now quoted - We lost the \n after our output - We started saying "bisect found ..." instead of "bisect run success" Arguably some of this is better now, but as d1bbbe45df8 did not advocate for changing the output, let's revert this for now. It'll be easy to change it back if that's what we'd prefer. This does not change the one remaining use of "command.buf" to emit the quoted argument, as that's new in d1bbbe45df8. Some of these cases were not tested for in the tests added in the preceding commit, I didn't have time to fleshen those out, but a look at f1de981e8b6 will show that the other output being adjusted here is now equivalent to what it was before d1bbbe45df8. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect: refactor bisect_run() to match CodingGuidelinesÆvar Arnfjörð Bjarmason1-4/+3
We didn't add "{}" to all "if/else" branches, and one "error" was mis-indented. Let's fix that first, which makes subsequent commits smaller. In the case of the "if" we can simply early return instead. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11Merge branch 'dd/bisect-helper-subcommand' into dd/git-bisect-builtinTaylor Blau1-100/+129
* dd/bisect-helper-subcommand: bisect--helper: parse subcommand with OPT_SUBCOMMAND bisect--helper: move all subcommands into their own functions bisect--helper: remove unused options
2022-11-11bisect--helper: parse subcommand with OPT_SUBCOMMANDĐoàn Trần Công Danh1-70/+17
As of it is, we're parsing subcommand with OPT_CMDMODE, which will continue to parse more options even if the command has been found. When we're running "git bisect run" with a command that expecting a "--log" or "--no-log" arguments, or one of those "--bisect-..." arguments, bisect--helper may mistakenly think those options are bisect--helper's option. We may fix those problems by passing "--" when calling from git-bisect.sh, and skip that "--" in bisect--helper. However, it may interfere with user's "--". Let's parse subcommand with OPT_SUBCOMMAND since that API was born for this specific use-case. Reported-by: Lukáš Doktor <ldoktor@redhat.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect--helper: move all subcommands into their own functionsĐoàn Trần Công Danh1-34/+121
In a later change, we will use OPT_SUBCOMMAND to parse sub-commands to avoid consuming non-option opts. Since OPT_SUBCOMMAND needs a function pointer to operate, let's move it now. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-11bisect--helper: remove unused optionsĐoàn Trần Công Danh1-6/+1
'git-bisect.sh' used to have a 'bisect_next_check' to check if we have both good/bad, old/new terms set or not. In commit 129a6cf344 (bisect--helper: `bisect_next_check` shell function in C, 2019-01-02), a subcommand for bisect--helper was introduced to port the check to C. Since d1bbbe45df (bisect--helper: reimplement `bisect_run` shell function in C, 2021-09-13), all users of 'bisect_next_check' was re-implemented in C, this subcommand was no longer used but we forgot to remove '--bisect-next-check'. 'git-bisect.sh' also used to have a 'bisect_write' function, whose third positional parameter was a "nolog" flag. This flag was only used when 'bisect_start' invoked 'bisect_write' to write the starting good and bad revisions. Then 0f30233a11 (bisect--helper: `bisect_write` shell function in C, 2019-01-02) ported it to C as a command mode of 'bisect--helper', which (incorrectly) added the '--no-log' option, and convert the only place ('bisect_start') that call 'bisect_write' with 'nolog' to 'git bisect--helper --bisect-write' with 'nolog' instead of '--no-log', since 'bisect--helper' has command modes not subcommands, all other command modes see and handle that option as well. This bogus state didn't last long, however, because in the same patch series 06f5608c14 (bisect--helper: `bisect_start` shell function partially in C, 2019-01-02) the C reimplementation of bisect_start() started calling the bisect_write() C function, this time with the right 'nolog' function parameter. From then on there was no need for the '--no-log' option in 'bisect--helper'. Eventually all bisect subcommands were ported to C as 'bisect--helper' command modes, each calling the bisect_write() C function instead, but when the '--bisect-write' command mode was removed in 68efed8c8a (bisect--helper: retire `--bisect-write` subcommand, 2021-02-03) it forgot to remove that '--no-log' option. '--no-log' option had never been used and it's unused now. Let's remove --bisect-next-check and --no-log from option parsing. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-10read-tree: use 'skip_cache_tree_update' optionVictoria Dye1-0/+4
When running 'read-tree' with a single tree and no prefix, 'prime_cache_tree()' is called after the tree is unpacked. In that situation, skip a redundant call to 'cache_tree_update()' in 'unpack_trees()' by enabling the 'skip_cache_tree_update' unpack option. Removing the redundant cache tree update provides a substantial performance improvement to 'git read-tree <tree-ish>', as shown by a test added to 'p0006-read-tree-checkout.sh': Test before after ---------------------------------------------------------------------- read-tree br_ballast_plus_1 3.94(1.80+1.57) 3.00(1.14+1.28) -23.9% Note that the 'read-tree' in 't1022-read-tree-partial-clone.sh' is updated to read two trees, rather than one. The test was first introduced in d3da223f221 (cache-tree: prefetch in partial clone read-tree, 2021-07-23) to exercise the 'cache_tree_update()' code path, as used in 'git merge'. Since this patch drops the call to 'cache_tree_update()' in single-tree 'git read-tree', change the test to use the two-tree variant so that 'cache_tree_update()' is called as intended. Signed-off-by: Victoria Dye <vdye@github.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>