]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
3 years agoprune: quiet ENOENT on missing directories
Eric Wong [Sat, 19 Nov 2022 20:12:13 +0000 (20:12 +0000)] 
prune: quiet ENOENT on missing directories

$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>
3 years agobuilt-ins: use free() not UNLEAK() if trivial, rm dead code
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:51 +0000 (19:17 +0100)] 
built-ins: use free() not UNLEAK() if trivial, rm dead code

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>
3 years agorevert: fix parse_options_concat() leak
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:50 +0000 (19:17 +0100)] 
revert: fix parse_options_concat() leak

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>
3 years agocherry-pick: free "struct replay_opts" members
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:49 +0000 (19:17 +0100)] 
cherry-pick: free "struct replay_opts" members

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>
3 years agorebase: don't leak on "--abort"
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:48 +0000 (19:17 +0100)] 
rebase: don't leak on "--abort"

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>
3 years agoconnected.c: free the "struct packed_git"
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:47 +0000 (19:17 +0100)] 
connected.c: free the "struct packed_git"

The "new_pack" we allocate in check_connected() wasn't being
free'd. Let's do that before we return from the function. This has
leaked ever since "new_pack" was added to this function in
c6807a40dcd (clone: open a shortcut for connectivity check,
2013-05-26).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agosequencer.c: fix "opts->strategy" leak in read_strategy_opts()
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:46 +0000 (19:17 +0100)] 
sequencer.c: fix "opts->strategy" leak in read_strategy_opts()

When "read_strategy_opts()" is called we may have populated the
"opts->strategy" before, so we'll need to free() it to avoid leaking
memory.

We populate it before because we cal get_replay_opts() from within
"rebase.c" with an already populated "opts", which we then copy. Then
if we're doing a "rebase -i" the sequencer API itself will promptly
clobber our alloc'd version of it with its own.

If this code is changed to do, instead of the added free() here a:

if (opts->strategy)
opts->strategy = xstrdup("another leak");

We get a couple of stacktraces from -fsanitize=leak showing how we
ended up clobbering the already allocated value, i.e.:

Direct leak of 6 byte(s) in 1 object(s) allocated from:
    #0 0x7f2e8cd45545 in __interceptor_malloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:75
    #1 0x7f2e8cb0fcaa in __GI___strdup string/strdup.c:42
    #2 0x6c4778 in xstrdup wrapper.c:39
    #3 0x66bcb8 in read_strategy_opts sequencer.c:2902
    #4 0x66bf7b in read_populate_opts sequencer.c:2969
    #5 0x6723f9 in sequencer_continue sequencer.c:5063
    #6 0x4a4f74 in run_sequencer_rebase builtin/rebase.c:348
    #7 0x4a64c8 in run_specific_rebase builtin/rebase.c:753
    #8 0x4a9b8b in cmd_rebase builtin/rebase.c:1824
    #9 0x407a32 in run_builtin git.c:466
    #10 0x407e0a in handle_builtin git.c:721
    #11 0x40803d in run_argv git.c:788
    #12 0x40850f in cmd_main git.c:923
    #13 0x4eee79 in main common-main.c:57
    #14 0x7f2e8ca9f209 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #15 0x7f2e8ca9f2bb in __libc_start_main_impl ../csu/libc-start.c:389
    #16 0x405fd0 in _start (git+0x405fd0)

Direct leak of 4 byte(s) in 1 object(s) allocated from:
    #0 0x7f2e8cd45545 in __interceptor_malloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:75
    #1 0x7f2e8cb0fcaa in __GI___strdup string/strdup.c:42
    #2 0x6c4778 in xstrdup wrapper.c:39
    #3 0x4a3c31 in xstrdup_or_null git-compat-util.h:1169
    #4 0x4a447a in get_replay_opts builtin/rebase.c:163
    #5 0x4a4f5b in run_sequencer_rebase builtin/rebase.c:346
    #6 0x4a64c8 in run_specific_rebase builtin/rebase.c:753
    #7 0x4a9b8b in cmd_rebase builtin/rebase.c:1824
    #8 0x407a32 in run_builtin git.c:466
    #9 0x407e0a in handle_builtin git.c:721
    #10 0x40803d in run_argv git.c:788
    #11 0x40850f in cmd_main git.c:923
    #12 0x4eee79 in main common-main.c:57
    #13 0x7f2e8ca9f209 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #14 0x7f2e8ca9f2bb in __libc_start_main_impl ../csu/libc-start.c:389
    #15 0x405fd0 in _start (git+0x405fd0)

This can be seen in e.g. the 4th test of
"t3404-rebase-interactive.sh".

In the larger picture the ownership of the "struct replay_opts" is
quite a mess, e.g. in this case rebase.c's static "get_replay_opts()"
function partially creates it, but nothing in rebase.c will free()
it. The structure is "mostly owned" by the sequencer API, but it also
expects to get these partially populated versions of it.

It would be better to have rebase keep track of what it allocated, and
free() that, and to pass that as a "const" to the sequencer API, which
would copy what it needs to its own version, and to free() that.

But doing so is a much larger change, and however messy the ownership
boundary is here is consistent with what we're doing already, so let's
just free() this to fix the leak.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agols-files: fix a --with-tree memory leak
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:45 +0000 (19:17 +0100)] 
ls-files: fix a --with-tree memory leak

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>
3 years agorevision API: call graph_clear() in release_revisions()
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:44 +0000 (19:17 +0100)] 
revision API: call graph_clear() in release_revisions()

Call graph_clear() in release_revisions(), this will free memory
allocated by e.g. this command, which will now run without memory
leaks:

git -P log -1 --graph --no-graph --graph

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agounpack-file: fix ancient leak in create_temp_file()
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:43 +0000 (19:17 +0100)] 
unpack-file: fix ancient leak in create_temp_file()

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>
3 years agobuilt-ins & libs & helpers: add/move destructors, fix leaks
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:42 +0000 (19:17 +0100)] 
built-ins & libs & helpers: add/move destructors, fix leaks

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>
3 years agodir.c: free "ident" and "exclude_per_dir" in "struct untracked_cache"
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:41 +0000 (19:17 +0100)] 
dir.c: free "ident" and "exclude_per_dir" in "struct untracked_cache"

When the "ident" member of the structure was added in
1e8fef609e7 (untracked cache: guard and disable on system changes,
2015-03-08) this function wasn't updated to free it. Let's do so.

Let's also free the "exclude_per_dir" memory we've been leaking
since[1], while making sure not to free() the constant ".gitignore"
string we add by default[2].

As we now have three struct members we're freeing let's change
free_untracked_cache() to return early if "uc" isn't defined. We won't
hand it to free() now, but that was just for convenience, once we're
dealing with >=2 struct members this pattern is more convenient.

1. f9e6c649589 (untracked cache: load from UNTR index extension,
   2015-03-08)
2. 039bc64e886 (core.excludesfile clean-up, 2007-11-14)

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoread-cache.c: clear and free "sparse_checkout_patterns"
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:40 +0000 (19:17 +0100)] 
read-cache.c: clear and free "sparse_checkout_patterns"

The "sparse_checkout_patterns" member was added to the "struct
index_state" in 836e25c51b2 (sparse-checkout: hold pattern list in
index, 2021-03-30), but wasn't added to discard_index(). Let's do
that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agocommit: discard partial cache before (re-)reading it
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:39 +0000 (19:17 +0100)] 
commit: discard partial cache before (re-)reading it

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>
3 years ago{reset,merge}: call discard_index() before returning
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:38 +0000 (19:17 +0100)] 
{reset,merge}: call discard_index() before returning

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>
3 years agotests: mark tests as passing with SANITIZE=leak
Ævar Arnfjörð Bjarmason [Tue, 8 Nov 2022 18:17:37 +0000 (19:17 +0100)] 
tests: mark tests as passing with SANITIZE=leak

This marks tests that have been leak-free since various recent
commits, but which were not marked us such when the memory leak was
fixed. These were mostly discovered with the "check" mode added in
faececa53f9 (test-lib: have the "check" mode for SANITIZE=leak
consider leak logs, 2022-07-28).

Commits that fixed the last memory leak in these tests. Per narrowing
down when they started to pass under SANITIZE=leak with "bisect":

- t1022-read-tree-partial-clone.sh:
  7e2619d8ff0 (list_objects_filter_options: plug leak of filter_spec
  strings, 2022-09-08)

- t4053-diff-no-index.sh: 07a6f94a6d0 (diff-no-index: release prefixed
  filenames, 2022-09-07)

- t6415-merge-dir-to-symlink.sh: bac92b1f39f (Merge branch
  'js/ort-clean-up-after-failed-merge', 2022-08-08).

- t5554-noop-fetch-negotiator.sh:
  66eede4a37c (prepare_repo_settings(): plug leak of config values,
  2022-09-08)

- t2012-checkout-last.sh, t7504-commit-msg-hook.sh,
  t91{15,46,60}-git-svn-*.sh: The in-flight "pw/rebase-no-reflog-action"
  series, upon which this is based:
  https://lore.kernel.org/git/pull.1405.git.1667575142.gitgitgadget@gmail.com/

Let's mark all of these as passing with
"TEST_PASSES_SANITIZE_LEAK=true", to have it regression tested,
including as part of the "linux-leaks" CI job.

Additionally, let's remove the "!SANITIZE_LEAK" prerequisite from
tests that now pass, these were marked as failing in:

77e56d55ba6 (diff.c: fix a double-free regression in a18d66cefb,
  2022-03-17)
c4d1d526312 (tests: change some 'test $(git) = "x"' to test_cmp,
  2022-03-07)

These were not spotted with the new "check" mode, but manually, it
doesn't cover these sort of prerequisites. There's few enough that we
shouldn't bother to automate it. They'll be going away sooner than
later.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoMerge branch 'pw/rebase-no-reflog-action' into ab/various-leak-fixes
Junio C Hamano [Mon, 21 Nov 2022 03:32:24 +0000 (12:32 +0900)] 
Merge branch 'pw/rebase-no-reflog-action' into ab/various-leak-fixes

* pw/rebase-no-reflog-action:
  rebase: stop exporting GIT_REFLOG_ACTION
  sequencer: stop exporting GIT_REFLOG_ACTION

3 years agococci: apply "pending" index-compatibility to some "builtin/*.c"
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:38 +0000 (14:07 +0100)] 
cocci: apply "pending" index-compatibility to some "builtin/*.c"

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>
3 years agocache.h & test-tool.h: add & use "USE_THE_INDEX_VARIABLE"
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:37 +0000 (14:07 +0100)] 
cache.h & test-tool.h: add & use "USE_THE_INDEX_VARIABLE"

In a preceding commit we fully applied the
"index-compatibility.pending.cocci" rule to "t/helper/*".

Let's now stop defining "USE_THE_INDEX_COMPATIBILITY_MACROS" in
test-tool.h itself, and instead instead define
"USE_THE_INDEX_VARIABLE" in the individual test helpers that need
it. This mirrors how we do the same thing in the "builtin/" directory.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 years ago{builtin/*,repository}.c: add & use "USE_THE_INDEX_VARIABLE"
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:36 +0000 (14:07 +0100)] 
{builtin/*,repository}.c: add & use "USE_THE_INDEX_VARIABLE"

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>
3 years agococci: apply "pending" index-compatibility to "t/helper/*.c"
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:35 +0000 (14:07 +0100)] 
cocci: apply "pending" index-compatibility to "t/helper/*.c"

Apply the "index-compatibility.pending.cocci" rule to the "t/helper/*"
directory, a subsequent commit will extend cache.h to further narrow
down the use of "USE_THE_INDEX_COMPATIBILITY_MACROS" in this area.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 years agococci & cache.h: apply variable section of "pending" index-compatibility
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:34 +0000 (14:07 +0100)] 
cocci & cache.h: apply variable section of "pending" index-compatibility

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>
3 years agococci & cache.h: apply a selection of "pending" index-compatibility
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:33 +0000 (14:07 +0100)] 
cocci & cache.h: apply a selection of "pending" index-compatibility

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>
3 years agococci: add a index-compatibility.pending.cocci
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:32 +0000 (14:07 +0100)] 
cocci: add a index-compatibility.pending.cocci

Add a coccinelle rule which covers the rest of the macros guarded by
"USE_THE_INDEX_COMPATIBILITY_MACROS" cache.h. If the result of this
were applied it can be reduced down to just:

#ifdef USE_THE_INDEX_COMPATIBILITY_MACROS
extern struct index_state the_index;
#endif

But that patch is just under 2000 lines, so let's first add this as a
"pending", and then incrementally pick changes from it in subsequent
commits. In doing that we'll migrate rules from this
"index-compatibility.pending.cocci" to the "index-compatibility.cocci"
created in a preceding commit.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 years agoread-cache API & users: make discard_index() return void
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:31 +0000 (14:07 +0100)] 
read-cache API & users: make discard_index() return void

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>
3 years agococci & cache.h: remove rarely used "the_index" compat macros
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:30 +0000 (14:07 +0100)] 
cocci & cache.h: remove rarely used "the_index" compat macros

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>
3 years agobuiltin/{grep,log}.: don't define "USE_THE_INDEX_COMPATIBILITY_MACROS"
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:29 +0000 (14:07 +0100)] 
builtin/{grep,log}.: don't define "USE_THE_INDEX_COMPATIBILITY_MACROS"

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>
3 years agocache.h: remove unused "the_index" compat macros
Ævar Arnfjörð Bjarmason [Sat, 19 Nov 2022 13:07:28 +0000 (14:07 +0100)] 
cache.h: remove unused "the_index" compat macros

The "active_alloc" macro added in 228e94f9357 (Move index-related
variables into a structure., 2007-04-01) has not been used since
4aab5b46f44 (Make read-cache.c "the_index" free., 2007-04-01). Let's
remove it.

The rest of these are likewise unused, so let's not keep them
around. E.g. 12cd0bf9b02 (dir: stop using the index compatibility
macros, 2017-05-05) is the last use of "cache_dir_exists".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 years agoThe thirteenth batch
Taylor Blau [Fri, 18 Nov 2022 23:48:53 +0000 (18:48 -0500)] 
The thirteenth batch

Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoMerge branch 'en/sparse-checkout-design'
Taylor Blau [Fri, 18 Nov 2022 23:44:01 +0000 (18:44 -0500)] 
Merge branch 'en/sparse-checkout-design'

Design doc.

* en/sparse-checkout-design:
  sparse-checkout.txt: new document with sparse-checkout directions

3 years agoMerge branch 'jk/branch-delete-detached'
Taylor Blau [Fri, 18 Nov 2022 23:44:00 +0000 (18:44 -0500)] 
Merge branch 'jk/branch-delete-detached'

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

3 years agoMerge branch 'mh/credential-unrecognized-attrs'
Taylor Blau [Fri, 18 Nov 2022 23:43:59 +0000 (18:43 -0500)] 
Merge branch 'mh/credential-unrecognized-attrs'

Docfix.

* mh/credential-unrecognized-attrs:
  docs: clarify that credential discards unrecognised attributes

3 years agoMerge branch 'vd/skip-cache-tree-update'
Taylor Blau [Fri, 18 Nov 2022 23:43:56 +0000 (18:43 -0500)] 
Merge branch 'vd/skip-cache-tree-update'

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

3 years agoMerge branch 'mh/increase-credential-cache-timeout'
Taylor Blau [Fri, 18 Nov 2022 23:43:55 +0000 (18:43 -0500)] 
Merge branch 'mh/increase-credential-cache-timeout'

Update the credential-cache documentation to provide a more realistic
example.

* mh/increase-credential-cache-timeout:
  Documentation: increase example cache timeout to 1 hour

3 years agoMerge branch 'vd/update-refs-delete'
Taylor Blau [Fri, 18 Nov 2022 23:43:10 +0000 (18:43 -0500)] 
Merge branch 'vd/update-refs-delete'

`git rebase --update-refs` would delete references when all `update-ref`
commands in the sequencer were removed, which has been corrected.

* vd/update-refs-delete:
  rebase --update-refs: avoid unintended ref deletion

3 years agoMerge branch 'tb/repack-expire-to'
Taylor Blau [Fri, 18 Nov 2022 23:43:09 +0000 (18:43 -0500)] 
Merge branch 'tb/repack-expire-to'

"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`

3 years agoMerge branch 'ab/sha-makefile-doc'
Taylor Blau [Fri, 18 Nov 2022 23:43:07 +0000 (18:43 -0500)] 
Merge branch 'ab/sha-makefile-doc'

Makefile comments updates and reordering to clarify knobs used to
choose SHA implementations.

* ab/sha-makefile-doc:
  Makefile: discuss SHAttered in *_SHA{1,256} discussion
  Makefile: document default SHA-1 backend on OSX
  Makefile & test-tool: replace "DC_SHA1" variable with a "define"
  Makefile: document SHA-1 and SHA-256 default and selection order
  Makefile: document default SHA-256 backend
  Makefile: rephrase the discussion of *_SHA1 knobs
  Makefile: create and use sections for "define" flag listing
  Makefile: correct DC_SHA1 documentation
  INSTALL: remove discussion of SHA-1 backends
  Makefile: always (re)set DC_SHA1 on fallback

3 years agoMerge branch 'ab/misc-hook-submodule-run-command'
Taylor Blau [Fri, 18 Nov 2022 23:43:04 +0000 (18:43 -0500)] 
Merge branch 'ab/misc-hook-submodule-run-command'

Various test updates.

* ab/misc-hook-submodule-run-command:
  run-command tests: test stdout of run_command_parallel()
  submodule tests: reset "trace.out" between "grep" invocations
  hook tests: fix redirection logic error in 96e7225b310

3 years agodelta-islands: free island-related data after use
Eric Wong [Thu, 17 Nov 2022 23:06:58 +0000 (23:06 +0000)] 
delta-islands: free island-related data after use

On my use case involving 771 islands of Linux on kernel.org,
this reduces memory usage by around 25MB.  The bulk of that
comes from free_remote_islands, since free_config_regexes only
saves around 40k.

This memory is saved early in the memory-intensive pack process,
making it available for the remainder of the long process.

Signed-off-by: Eric Wong <e@80x24.org>
Co-authored-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoparse_object(): check on-disk type of suspected blob
Jeff King [Thu, 17 Nov 2022 22:41:16 +0000 (17:41 -0500)] 
parse_object(): check on-disk type of suspected blob

In parse_object(), we try to handle blobs by streaming rather than
loading them entirely into memory. The most common case here will be
that we haven't seen the object yet and check oid_object_info(), which
tells us we have a blob.

But we trigger this code on one other case: when we have an in-memory
object struct with type OBJ_BLOB (and without its "parsed" flag set,
since otherwise we'd return early from the function). This indicates
that some other part of the code suspected we have a blob (e.g., it was
mentioned by a tree or tag) but we haven't yet looked at the on-disk
copy.

In this case before hitting the streaming path, we check if we have the
object on-disk at all. This is mostly pointless extra work, as the
streaming path would complain if it couldn't open the object (albeit
with the message "hash mismatch", which is a little misleading).

But it's also insufficient to catch all problems. The streaming code
will only tell us "yes, the on-disk object matches the oid". But it
doesn't actually confirm that what we found was indeed a blob, and
neither does repo_has_object_file().

One way to improve this would be to teach stream_object_signature() to
check the type (either by returning it to us to check, or taking an
"expected" type). But there's an even simpler fix here: if we suspect
the object is a blob, just call oid_object_info() to confirm that we
have it on-disk, and that it really is a blob.

This is slightly less efficient than teaching stream_object_signature()
to do it (since it has to open the object already). But this case very
rarely comes up. In practice, we usually don't have any clue what the
type is, in which case we already call oid_object_info(). This
"suspected" case happens only when some other code created an object
struct but didn't actually parse the blob, which is actually tricky to
trigger at all (see the discussion of the test below).

I reworked the conditional a bit so that instead of:

  if ((suspected_blob && oid_object_info() == OBJ_BLOB)
      (no_clue && oid_object_info() == OBJ_BLOB)

we have the simpler:

  if ((suspected_blob || no_clue) && oid_object_info() == OBJ_BLOB)

This is shorter, but also reflects what we really want say, which is
"have we ruled out this being a blob; if not, check it on-disk".

In either case, if oid_object_info() fails to tell us it's a blob, we'll
skip the streaming code path and call repo_read_object_file(), just as
before. And if we really do have a mismatch with the existing object
struct, we'll eventually call lookup_commit(), etc, via
parse_object_buffer(), which will complain that it doesn't match our
existing obj->type.

So this fixes one of the lingering expect_failure cases from 0616617c7e
(t: introduce tests for unexpected object types, 2019-04-09).  That test
works by peeling a tag that claims to point to a blob (triggering us to
create the struct), but really points to something else, which we later
discover when we call parse_object() as part of the actual traversal).
Prior to this commit, we'd quietly check the sha1 and mark the blob as
"parsed". Now we correctly complain about the mismatch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoparse_object(): drop extra "has" check before checking object type
Jeff King [Thu, 17 Nov 2022 22:37:58 +0000 (17:37 -0500)] 
parse_object(): drop extra "has" check before checking object type

When parsing an object of unknown type, we check to see if it's a blob,
so we can use our streaming code path. This uses oid_object_info() to
check the type, but before doing so we call repo_has_object_file(). This
latter is pointless, as oid_object_info() will already fail if the
object is missing. Checking it ahead of time just complicates the code
and is a waste of resources (albeit small).

Let's drop the redundant check.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agobranch: force-copy a branch to itself via @{-1} is a no-op
Rubén Justo [Thu, 17 Nov 2022 01:36:52 +0000 (02:36 +0100)] 
branch: force-copy a branch to itself via @{-1} is a no-op

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>
3 years agoreceive-pack: only use visible refs for connectivity check
Patrick Steinhardt [Thu, 17 Nov 2022 05:47:04 +0000 (06:47 +0100)] 
receive-pack: only use visible refs for connectivity check

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>
3 years agorev-parse: add `--exclude-hidden=` option
Patrick Steinhardt [Thu, 17 Nov 2022 05:47:00 +0000 (06:47 +0100)] 
rev-parse: add `--exclude-hidden=` option

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>
3 years agorevision: add new parameter to exclude hidden refs
Patrick Steinhardt [Thu, 17 Nov 2022 05:46:56 +0000 (06:46 +0100)] 
revision: add new parameter to exclude hidden refs

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>
3 years agorevision: introduce struct to handle exclusions
Patrick Steinhardt [Thu, 17 Nov 2022 05:46:51 +0000 (06:46 +0100)] 
revision: introduce struct to handle exclusions

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>
3 years agorevision: move together exclusion-related functions
Patrick Steinhardt [Thu, 17 Nov 2022 05:46:47 +0000 (06:46 +0100)] 
revision: move together exclusion-related functions

Move together the definitions of functions that handle exclusions of
refs so that related functionality sits in a single place, only.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agorefs: get rid of global list of hidden refs
Patrick Steinhardt [Thu, 17 Nov 2022 05:46:43 +0000 (06:46 +0100)] 
refs: get rid of global list of hidden refs

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>
3 years agorefs: fix memory leak when parsing hideRefs config
Patrick Steinhardt [Thu, 17 Nov 2022 05:46:39 +0000 (06:46 +0100)] 
refs: fix memory leak when parsing hideRefs config

When parsing the hideRefs configuration, we first duplicate the config
value so that we can modify it. We then subsequently append it to the
`hide_refs` string list, which is initialized with `strdup_strings`
enabled. As a consequence we again reallocate the string, but never
free the first duplicate and thus have a memory leak.

While we never clean up the static `hide_refs` variable anyway, this is
no excuse to make the leak worse by leaking every value twice. We are
also about to change the way this variable will be handled so that we do
indeed start to clean it up. So let's fix the memory leak by using the
`string_list_append_nodup()` so that we pass ownership of the allocated
string to `hide_refs`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agonotes: avoid empty line in template
Michael J Gruber [Wed, 16 Nov 2022 15:56:40 +0000 (16:56 +0100)] 
notes: avoid empty line in template

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>
3 years agot7610: use "file:///dev/null", not "/dev/null", fixes MinGW
Ævar Arnfjörð Bjarmason [Tue, 15 Nov 2022 23:40:14 +0000 (00:40 +0100)] 
t7610: use "file:///dev/null", not "/dev/null", fixes MinGW

On MinGW the "/dev/null" is translated to "nul" on command-lines, even
though as in this case it'll never end up referring to an actual file.

So on Windows the fix for the previous "example.com" timeout issue in
8354cf752ec (t7610: fix flaky timeout issue, don't clone from
example.com, 2022-11-05) would yield:

  fatal: repo URL: 'nul' must be absolute or begin with ./|../

Let's evade this yet again by prefixing this with "file://", which
makes this pass in the Windows CI.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agobisect; remove unused "git-bisect.sh" and ".gitignore" entry
Ævar Arnfjörð Bjarmason [Tue, 15 Nov 2022 09:32:42 +0000 (10:32 +0100)] 
bisect; remove unused "git-bisect.sh" and ".gitignore" entry

Since 73fce29427 (Turn `git bisect` into a full built-in, 2022-11-10)
we've used builtin/bisect.c instead of git-bisect.sh to implement the
"bisect" command.

Let's remove the unused leftover script, and the ".gitignore" entry for
the "git-bisect--helper", which also hasn't been built since
73fce29427.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agobuiltin/gc.c: fix use-after-free in maintenance_unregister()
Taylor Blau [Tue, 15 Nov 2022 18:53:17 +0000 (13:53 -0500)] 
builtin/gc.c: fix use-after-free in maintenance_unregister()

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>
3 years agomaintenance --unregister: fix uninit'd data use & -Wdeclaration-after-statement
Ævar Arnfjörð Bjarmason [Tue, 15 Nov 2022 16:04:27 +0000 (17:04 +0100)] 
maintenance --unregister: fix uninit'd data use & -Wdeclaration-after-statement

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>
3 years agomaintenance: add option to register in a specific config
Ronan Pigott [Wed, 9 Nov 2022 19:07:08 +0000 (12:07 -0700)] 
maintenance: add option to register in a specific config

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>
3 years agofor-each-repo: interpolate repo path arguments
Ronan Pigott [Wed, 9 Nov 2022 19:07:07 +0000 (12:07 -0700)] 
for-each-repo: interpolate repo path arguments

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>
3 years agoThe twelfth batch
Taylor Blau [Tue, 15 Nov 2022 00:56:07 +0000 (19:56 -0500)] 
The twelfth batch

Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoMerge branch 'vh/my-first-contribution-typo'
Taylor Blau [Tue, 15 Nov 2022 00:53:55 +0000 (19:53 -0500)] 
Merge branch 'vh/my-first-contribution-typo'

Documentation fix.

* vh/my-first-contribution-typo:
  Documentation: fix typo

3 years agoMerge branch 'ks/partialclone-casing'
Taylor Blau [Tue, 15 Nov 2022 00:53:43 +0000 (19:53 -0500)] 
Merge branch 'ks/partialclone-casing'

Documentation fix.

* ks/partialclone-casing:
  repository-version.txt: partialClone casing change

3 years agoMerge branch 'mh/password-can-be-pat'
Taylor Blau [Tue, 15 Nov 2022 00:53:41 +0000 (19:53 -0500)] 
Merge branch 'mh/password-can-be-pat'

Documentation update to git-credential(1).

* mh/password-can-be-pat:
  Documentation/gitcredentials.txt: mention password alternatives

3 years agoMerge branch 'js/ci-set-output'
Taylor Blau [Tue, 15 Nov 2022 00:53:38 +0000 (19:53 -0500)] 
Merge branch 'js/ci-set-output'

Update the actions/github-script dependency in CI to avoid a
deprecation warning.

* js/ci-set-output:
  ci: use a newer `github-script` version

3 years agoMerge branch 'ab/rev-info-init'
Taylor Blau [Tue, 15 Nov 2022 00:53:37 +0000 (19:53 -0500)] 
Merge branch 'ab/rev-info-init'

Progress on being able to initialize a rev_info struct with a macro.

* ab/rev-info-init:
  revisions API: extend the nascent REV_INFO_INIT macro

3 years agoMerge branch 'al/trace2-clearing-skip-worktree'
Taylor Blau [Tue, 15 Nov 2022 00:53:33 +0000 (19:53 -0500)] 
Merge branch 'al/trace2-clearing-skip-worktree'

Add trace2 counters to the region to clear skip worktree bits in a
sparse checkout.

* al/trace2-clearing-skip-worktree:
  index: raise a bug if the index is materialised more than once
  index: add trace2 region for clear skip worktree

3 years agoMerge branch 'do/modernize-t7001'
Taylor Blau [Tue, 15 Nov 2022 00:53:31 +0000 (19:53 -0500)] 
Merge branch 'do/modernize-t7001'

Modernize test script to avoid "test -f" and friends.

* do/modernize-t7001:
  t7001-mv.sh: modernizing test script using functions

3 years agoDocs: describe how a credential-generating helper works
M Hickford [Sat, 12 Nov 2022 01:44:30 +0000 (01:44 +0000)] 
Docs: describe how a credential-generating helper works

Previously the docs only described storage helpers.

A concrete example: Git Credential Manager can generate credentials
for GitHub and GitLab via OAuth.
https://github.com/GitCredentialManager/git-credential-manager

Signed-off-by: M Hickford <mirth.hickford@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoDocumentation: fix typo
Vlad-Stefan Harbuz [Sun, 13 Nov 2022 12:48:09 +0000 (12:48 +0000)] 
Documentation: fix typo

Signed-off-by: Vlad-Stefan Harbuz <vlad@vladh.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agohttp: redact curl h2h3 headers in info
Glen Choo [Fri, 11 Nov 2022 22:35:06 +0000 (22:35 +0000)] 
http: redact curl h2h3 headers in info

With GIT_TRACE_CURL=1 or GIT_CURL_VERBOSE=1, sensitive headers like
"Authorization" and "Cookie" get redacted. However, since [1], curl's
h2h3 module (invoked when using HTTP/2) also prints headers in its
"info", which don't get redacted. For example,

  echo 'github.com TRUE / FALSE 1698960413304 o foo=bar' >cookiefile &&
  GIT_TRACE_CURL=1 GIT_TRACE_CURL_NO_DATA=1 git \
    -c 'http.cookiefile=cookiefile' \
    -c 'http.version=' \
    ls-remote https://github.com/git/git refs/heads/main 2>output &&
  grep 'cookie' output

produces output like:

  23:04:16.920495 http.c:678              == Info: h2h3 [cookie: o=foo=bar]
  23:04:16.920562 http.c:637              => Send header: cookie: o=<redacted>

Teach http.c to check for h2h3 headers in info and redact them using the
existing header redaction logic. This fixes the broken redaction logic
that we noted in the previous commit, so mark the redaction tests as
passing under HTTP2.

[1] https://github.com/curl/curl/commit/f8c3724aa90472c0e617ddbbc420aa199971eb77

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agot: run t5551 tests with both HTTP and HTTP/2
Jeff King [Fri, 11 Nov 2022 22:35:05 +0000 (22:35 +0000)] 
t: run t5551 tests with both HTTP and HTTP/2

We have occasionally seen bugs that affect Git running only against an
HTTP/2 web server, not an HTTP one. For instance, b66c77a64e (http:
match headers case-insensitively when redacting, 2021-09-22). But since
we have no test coverage using HTTP/2, we only uncover these bugs in the
wild.

That commit gives a recipe for converting our Apache setup to support
HTTP/2, but:

  - it's not necessarily portable

  - we don't want to just test HTTP/2; we really want to do a variety of
    basic tests for _both_ protocols

This patch handles both problems by running a duplicate of t5551
(labeled as t5559 here) with an alternate-universe setup that enables
HTTP/2. So we'll continue to run t5551 as before, but run the same
battery of tests again with HTTP/2. If HTTP/2 isn't supported on a given
platform, then t5559 should bail during the webserver setup, and
gracefully skip all tests (unless GIT_TEST_HTTPD has been changed from
"auto" to "yes", where the point is to complain when webserver setup
fails).

In theory other http-related test scripts could benefit from the same
duplication, but doing t5551 should give us a reasonable check of basic
functionality, and would have caught both bugs we've seen in the wild
with HTTP/2.

A few notes on the implementation:

  - a script enables the server side config by calling enable_http2
    before starting the webserver. This avoids even trying to load any
    HTTP/2 config for t5551 (which is what lets it keep working with
    regular HTTP even on systems that don't support it). This also sets
    a prereq which can be used by individual tests.

  - As discussed in b66c77a64e, the http2 module isn't compatible with
    the "prefork" mpm, so we need to pick something else. I chose
    "event" here, which works on my Debian system, but it's possible
    there are platforms which would prefer something else. We can adjust
    that later if somebody finds such a platform.

  - The test "large fetch-pack requests can be sent using chunked
    encoding" makes sure we use a chunked transfer-encoding by looking
    for that header in the trace. But since HTTP/2 has its own streaming
    mechanisms, we won't find such a header. We could skip the test
    entirely by marking it with !HTTP2. But there's some value in making
    sure that the fetch itself succeeded. So instead, we'll confirm that
    either we're using HTTP2 _or_ we saw the expected chunked header.

  - the redaction tests fail under HTTP/2 with recent versions of curl.
    This is a bug! I've marked them with !HTTP2 here to skip them under
    t5559 for the moment. Using test_expect_failure would be more
    appropriate, but would require a bunch of boilerplate. Since we'll
    be fixing them momentarily, let's just skip them for now to keep the
    test suite bisectable, and we can re-enable them in the commit that
    fixes the bug.

  - one alternative layout would be to push most of t5551 into a
    lib-t5551.sh script, then source it from both t5551 and t5559.
    Keeping t5551 intact seemed a little simpler, as its one less level
    of indirection for people fixing bugs/regressions in the non-HTTP/2
    tests.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agopack-bitmap.c: avoid exposing absolute paths
Teng Long [Thu, 10 Nov 2022 07:10:12 +0000 (15:10 +0800)] 
pack-bitmap.c: avoid exposing absolute paths

In "open_midx_bitmap_1()" and "open_pack_bitmap_1()", when we find that
there are multiple bitmaps, we will only open the first one and then
leave warnings about the remaining pack information, the information
will contain the absolute path of the repository, for example in a
alternates usage scenario. So let's hide this kind of potentially
sensitive information in this commit.

Found-by: XingXin <moweng.xx@antgroup.com>
Signed-off-by: Teng Long <dyroneteng@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agopack-bitmap.c: remove unnecessary "open_pack_index()" calls
Teng Long [Thu, 10 Nov 2022 07:10:11 +0000 (15:10 +0800)] 
pack-bitmap.c: remove unnecessary "open_pack_index()" calls

When trying to open a pack bitmap, we call open_pack_bitmap_1() in a
loop, during which it tries to open up the pack index corresponding
with each available pack.

It's likely that we'll end up relying on objects in that pack later
in the process (in which case we're doing the work of opening the
pack index optimistically), but not guaranteed.

For instance, consider a repository with a large number of small
packs, and one large pack with a bitmap. If we see that bitmap pack
last in our loop which calls open_pack_bitmap_1(), the current code
will have opened *all* pack index files in the repository. If the
request can be served out of the bitmapped pack alone, then the time
spent opening these idx files was wasted.S

Since open_pack_bitmap_1() calls is_pack_valid() later on (which in
turns calls open_pack_index() itself), we can just drop the earlier
call altogether.

Signed-off-by: Teng Long <dyroneteng@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoDoc: document push.recurseSubmodules=only
Jonathan Tan [Mon, 14 Nov 2022 21:37:12 +0000 (13:37 -0800)] 
Doc: document push.recurseSubmodules=only

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>
3 years agodocs: clarify that credential discards unrecognised attributes
M Hickford [Mon, 24 Oct 2022 07:57:48 +0000 (07:57 +0000)] 
docs: clarify that credential discards unrecognised attributes

It was previously unclear how unrecognised attributes are handled.

Signed-off-by: M Hickford <mirth.hickford@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agomerge-tree.c: allow specifying the merge-base when --stdin is passed
Kyle Zhao [Fri, 11 Nov 2022 23:45:14 +0000 (23:45 +0000)] 
merge-tree.c: allow specifying the merge-base when --stdin is passed

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>
3 years agomerge-tree.c: add --merge-base=<commit> option
Kyle Zhao [Fri, 11 Nov 2022 23:45:13 +0000 (23:45 +0000)] 
merge-tree.c: add --merge-base=<commit> option

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>
3 years agotests(scalar): tighten the stale `scalar.repo` test some
Johannes Schindelin [Thu, 10 Nov 2022 07:28:47 +0000 (07:28 +0000)] 
tests(scalar): tighten the stale `scalar.repo` test some

As pointed out by Stolee, the previous incarnation of this test case was
not stringent enough: we want to verify that _only_ the stale entries
are removed (previously, the test case would have succeeded even if all
entries had been removed).

Let's rectify this and verify that the other entries are left intact.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agorepository-version.txt: partialClone casing change
Kousik Sanagavarapu [Thu, 10 Nov 2022 16:05:56 +0000 (21:35 +0530)] 
repository-version.txt: partialClone casing change

Remotes are considered "promisor" if extensions.partialClone and some
other configuration variables are set. The casing for this in
Documentation/technical/repository-version.txt is not proper and may
cause confusion. This change corrects this casing.

Signed-off-by: Kousik Sanagavarapu <five231003@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoMakefile: don't create a ".build/.build/" for cocci, fix output
Ævar Arnfjörð Bjarmason [Thu, 10 Nov 2022 16:14:18 +0000 (17:14 +0100)] 
Makefile: don't create a ".build/.build/" for cocci, fix output

Fix a couple of issues in the recently merged 0f3c55d4c2b (Merge
branch 'ab/coccicheck-incremental' into next, 2022-11-08):

In copying over the "contrib/coccinelle/" rules to
".build/contrib/coccinelle/" we inadvertently ended up with a
".build/.build/contrib/coccinelle/" as well. We'd generate the
per-file patches in the former, and keep the rule and overall result
in the latter. E.g. running:

make contrib/coccinelle/free.cocci.patch COCCI_SOURCES="attr.c grep.c"

Would, per "tree -a .build" yield the following result:

.build
├── .build
│   └── contrib
│       └── coccinelle
│           └── free.cocci.patch
│               ├── attr.c
│               ├── attr.c.log
│               ├── grep.c
│               └── grep.c.log
└── contrib
    └── coccinelle
        ├── FOUND_H_SOURCES
        ├── free.cocci
        └── free.cocci.patch

Now we'll instead generate all of our files in
".build/contrib/coccinelle/". Fixing this required renaming the
directory where we keep our per-file patches, as we'd otherwise
conflict with the result.

Now the per-file patch directory is named e.g. "free.cocci.d". And the
end result will now be:

.build
└── contrib
    └── coccinelle
        ├── FOUND_H_SOURCES
        ├── free.cocci
        ├── free.cocci.d
        │   ├── attr.c.patch
        │   ├── attr.c.patch.log
        │   ├── grep.c.patch
        │   └── grep.c.patch.log
        └── free.cocci.patch

The per-file patches now have a ".patch" file suffix, which fixes
another issue reported against 0f3c55d4c2b: The summary output was
confusing. Before for the "make" command above we'd emit:

[...]
MKDIR -p .build/contrib/coccinelle
CP contrib/coccinelle/free.cocci .build/contrib/coccinelle/free.cocci
GEN .build/contrib/coccinelle/FOUND_H_SOURCES
MKDIR -p .build/.build/contrib/coccinelle/free.cocci.patch
SPATCH .build/.build/contrib/coccinelle/free.cocci.patch/grep.c
SPATCH .build/.build/contrib/coccinelle/free.cocci.patch/attr.c
SPATCH CAT $^ >.build/contrib/coccinelle/free.cocci.patch
CP .build/contrib/coccinelle/free.cocci.patch contrib/coccinelle/free.cocci.patch

But now we'll instead emit (identical output at the start omitted):

[...]
MKDIR -p .build/contrib/coccinelle/free.cocci.d
SPATCH grep.c >.build/contrib/coccinelle/free.cocci.d/grep.c.patch
SPATCH attr.c >.build/contrib/coccinelle/free.cocci.d/attr.c.patch
SPATCH CAT .build/contrib/coccinelle/free.cocci.d/**.patch >.build/contrib/coccinelle/free.cocci.patch
CP .build/contrib/coccinelle/free.cocci.patch contrib/coccinelle/free.cocci.patch

I.e. we have an "SPATCH" line that makes it clear that we're running
against the "{attr,grep}.c" file. The "SPATCH CAT" is then altered to
correspond to it, showing that we're concatenating the
"free.cocci.d/**.patch" files into one generated "free.cocci.patch" at
the end.

Reported-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoTurn `git bisect` into a full built-in
Johannes Schindelin [Thu, 10 Nov 2022 16:36:46 +0000 (23:36 +0700)] 
Turn `git bisect` into a full built-in

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>
3 years agobisect--helper: log: allow arbitrary number of arguments
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:45 +0000 (23:36 +0700)] 
bisect--helper: log: allow arbitrary number of arguments

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>
3 years agobisect--helper: handle states directly
Johannes Schindelin [Thu, 10 Nov 2022 16:36:44 +0000 (23:36 +0700)] 
bisect--helper: handle states directly

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>
3 years agobisect--helper: emit usage for "git bisect"
Ævar Arnfjörð Bjarmason [Thu, 10 Nov 2022 16:36:43 +0000 (23:36 +0700)] 
bisect--helper: emit usage for "git bisect"

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>
3 years agobisect test: test exit codes on bad usage
Ævar Arnfjörð Bjarmason [Thu, 10 Nov 2022 16:36:42 +0000 (23:36 +0700)] 
bisect test: test exit codes on bad usage

Address a test blindspot, the "log" command is the odd one out because
"git-bisect.sh" ignores any arguments it receives. Let's test both the
exit codes we expect, and the stderr and stdout we're emitting.

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>
3 years agobisect--helper: identify as bisect when report error
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:41 +0000 (23:36 +0700)] 
bisect--helper: identify as bisect when report error

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>
3 years agobisect-run: verify_good: account for non-negative exit status
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:40 +0000 (23:36 +0700)] 
bisect-run: verify_good: account for non-negative exit status

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>
3 years agobisect run: keep some of the post-v2.30.0 output
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:39 +0000 (23:36 +0700)] 
bisect run: keep some of the post-v2.30.0 output

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>
3 years agobisect: fix output regressions in v2.30.0
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:38 +0000 (23:36 +0700)] 
bisect: fix output regressions in v2.30.0

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>
3 years agobisect: refactor bisect_run() to match CodingGuidelines
Ævar Arnfjörð Bjarmason [Thu, 10 Nov 2022 16:36:37 +0000 (23:36 +0700)] 
bisect: refactor bisect_run() to match CodingGuidelines

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>
3 years agobisect tests: test for v2.30.0 "bisect run" regressions
Ævar Arnfjörð Bjarmason [Thu, 10 Nov 2022 16:36:36 +0000 (23:36 +0700)] 
bisect tests: test for v2.30.0 "bisect run" regressions

Add three failing tests which succeed on v2.29.0, but due to the topic
merged at [1] (specifically [2]) have been failing since then. We'll
address those regressions in subsequent commits.

There was also a "regression" where:

git bisect run ./missing-script.sh

Would count a non-existing script as "good", as the shell would exit
with 127. That edge case is a bit too insane to preserve, so let's not
add it to these regression tests.

There was another regression that 'git bisect' consumed some options
that was meant to passed down to program run with 'git bisect run'.
Since that regression is breaking user's expectation, it has been fixed
earlier without this patch queued.

1. 0a4cb1f1f2f (Merge branch 'mr/bisect-in-c-4', 2021-09-23)
2. d1bbbe45df8 (bisect--helper: reimplement `bisect_run` shell
   function in C, 2021-09-13)

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>
3 years agoMerge branch 'dd/bisect-helper-subcommand' into dd/git-bisect-builtin
Taylor Blau [Fri, 11 Nov 2022 22:05:43 +0000 (17:05 -0500)] 
Merge branch 'dd/bisect-helper-subcommand' into dd/git-bisect-builtin

* 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

3 years agobisect--helper: parse subcommand with OPT_SUBCOMMAND
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:22 +0000 (23:36 +0700)] 
bisect--helper: parse subcommand with OPT_SUBCOMMAND

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>
3 years agobisect--helper: move all subcommands into their own functions
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:21 +0000 (23:36 +0700)] 
bisect--helper: move all subcommands into their own functions

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>
3 years agobisect--helper: remove unused options
Đoàn Trần Công Danh [Thu, 10 Nov 2022 16:36:20 +0000 (23:36 +0700)] 
bisect--helper: remove unused options

'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>
3 years agochainlint: prefix annotated test definition with line numbers
Eric Sunshine [Fri, 11 Nov 2022 07:34:54 +0000 (07:34 +0000)] 
chainlint: prefix annotated test definition with line numbers

When chainlint detects problems in a test, it prints out the name of the
test script, the name of the problematic test, and a copy of the test
definition with "?!FOO?!" annotations inserted at the locations where
problems were detected. Taken together this information is sufficient
for the test author to identify the problematic code in the original
test definition. However, in a lengthy script or a lengthy test
definition, the author may still end up using the editor's search
feature to home in on the exact problem location.

To further assist the test author, display line numbers along with the
annotated test definition, thus allowing the author to jump directly to
each problematic line.

Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agochainlint: latch line numbers at which each token starts and ends
Eric Sunshine [Fri, 11 Nov 2022 07:34:53 +0000 (07:34 +0000)] 
chainlint: latch line numbers at which each token starts and ends

When chainlint detects problems in a test, it prints out the name of the
test script, the name of the problematic test, and a copy of the test
definition with "?!FOO?!" annotations inserted at the locations where
problems were detected. Taken together this information is sufficient
for the test author to identify the problematic code in the original
test definition. However, in a lengthy script or a lengthy test
definition, the author may still end up using the editor's search
feature to home in on the exact problem location.

To further assist the test author, an upcoming change will display line
numbers along with the annotated test definition, thus allowing the
author to jump directly to each problematic line. As preparation,
upgrade Lexer to latch the line numbers at which each token starts and
ends, and return that information with the token itself.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agochainlint: sidestep impoverished macOS "terminfo"
Eric Sunshine [Fri, 11 Nov 2022 07:34:52 +0000 (07:34 +0000)] 
chainlint: sidestep impoverished macOS "terminfo"

Although the macOS Terminal.app is "xterm"-compatible, its corresponding
"terminfo" entries -- such as "xterm", "xterm-256color", and
"xterm-new"[1] -- neglect to mention capabilities which Terminal.app
actually supports (such as "dim text"). This oversight on Apple's part
ends up penalizing users of "good citizen" console programs which
consult "terminfo" to tailor their output based upon reported terminal
capabilities (as opposed to programs which assume that the terminal
supports ANSI codes). The same problem is present in other Apple
"terminfo" entries, such as "nsterm"[2], with which macOS Terminal.app
may be configured.

Sidestep this Apple problem by imbuing get_colors() with specific
knowledge of capabilities common to "xterm" and "nsterm", rather than
trusting "terminfo" to report them correctly. Although hard-coding such
knowledge is ugly, "xterm" support is nearly ubiquitous these days, and
Git itself sets precedence by assuming support for ANSI color codes. For
other terminal types, fall back to querying "terminfo" via `tput` as
usual.

FOOTNOTES

[1] iTerm2 FAQ suggests "xterm-new": https://iterm2.com/faq.html

[2] Neovim documentation recommends terminal type "nsterm" with
    Terminal.app: https://neovim.io/doc/user/term.html#terminfo

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agosequencer: tighten label lookups
Phillip Wood [Thu, 10 Nov 2022 16:43:41 +0000 (16:43 +0000)] 
sequencer: tighten label lookups

The `label` command creates a ref refs/rewritten/<label> that the
`reset` and `merge` commands resolve by calling lookup_label(). That
uses lookup_commit_reference_by_name() to look up the label ref. As
lookup_commit_reference_by_name() uses the dwim rules when looking up
the label it will look for a branch named
refs/heads/refs/rewritten/<label> and return that instead of an error if
the branch exists and the label does not. Fix this by using read_ref()
followed by lookup_commit_object() when looking up labels.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agosequencer: unify label lookup
Phillip Wood [Thu, 10 Nov 2022 16:43:40 +0000 (16:43 +0000)] 
sequencer: unify label lookup

The arguments to the `reset` and `merge` commands may be a label created
with a `label` command or an arbitrary commit name. The `merge` command
uses the lookup_label() function to lookup its arguments but `reset` has
a slightly different version of that function in do_reset(). Reduce this
code duplication by calling lookup_label() from do_reset() as well.

This change improves the behavior of `reset` when the argument is a
tree.  Previously `reset` would accept a tree only for the rebase to
fail with

       update_ref failed for ref 'HEAD': cannot update ref 'HEAD': trying to write non-commit object da5497437fd67ca928333aab79c4b4b55036ea66 to branch 'HEAD'

Using lookup_label() means do_reset() will now error out straight away
if its argument is not a commit.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agorebase: use 'skip_cache_tree_update' option
Victoria Dye [Thu, 10 Nov 2022 19:06:05 +0000 (19:06 +0000)] 
rebase: use 'skip_cache_tree_update' option

Enable the 'skip_cache_tree_update' option in both 'do_reset()'
('sequencer.c') and 'reset_head()' ('reset.c'). Both of these callers invoke
'prime_cache_tree()' after 'unpack_trees()', so we can remove an unnecessary
cache tree rebuild by skipping 'cache_tree_update()'.

When testing with 'p3400-rebase.sh' and 'p3404-rebase-interactive.sh', the
performance change of this update was negligible, likely due to the
operation being dominated by more expensive operations (like checking out
trees). However, since the change doesn't harm performance, it's worth
keeping this 'unpack_trees()' usage consistent with others that subsequently
invoke 'prime_cache_tree()'.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
3 years agoread-tree: use 'skip_cache_tree_update' option
Victoria Dye [Thu, 10 Nov 2022 19:06:04 +0000 (19:06 +0000)] 
read-tree: use 'skip_cache_tree_update' option

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>
3 years agoreset: use 'skip_cache_tree_update' option
Victoria Dye [Thu, 10 Nov 2022 19:06:03 +0000 (19:06 +0000)] 
reset: use 'skip_cache_tree_update' option

Enable the 'skip_cache_tree_update' option in the variants that call
'prime_cache_tree()' after 'unpack_trees()' (specifically, 'git reset
--mixed' and 'git reset --hard'). This avoids redundantly rebuilding the
cache tree in both 'cache_tree_update()' at the end of 'unpack_trees()' and
in 'prime_cache_tree()', resulting in a small (but consistent) performance
improvement. From the newly-added 'p7102-reset.sh' test:

Test                         before            after
--------------------------------------------------------------------
7102.1: reset --hard (...)   2.11(0.40+1.54)   1.97(0.38+1.47) -6.6%

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>