]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
2 years agobuiltin/grep.c: integrate with sparse index
Shaoxuan Yuan [Fri, 23 Sep 2022 04:18:42 +0000 (21:18 -0700)] 
builtin/grep.c: integrate with sparse index

Turn on sparse index and remove ensure_full_index().

Before this patch, `git-grep` utilizes the ensure_full_index() method to
expand the index and search all the entries. Because this method
requires walking all the trees and constructing the index, it is the
slow part within the whole command.

To achieve better performance, this patch uses grep_tree() to search the
sparse directory entries and get rid of the ensure_full_index() method.

Why grep_tree() is a better choice over ensure_full_index()?

1) grep_tree() is as correct as ensure_full_index(). grep_tree() looks
   into every sparse-directory entry (represented by a tree) recursively
   when looping over the index, and the result of doing so matches the
   result of expanding the index.

2) grep_tree() utilizes pathspecs to limit the scope of searching.
   ensure_full_index() always expands the index, which means it will
   always walk all the trees and blobs in the repo without caring if
   the user only wants a subset of the content, i.e. using a pathspec.
   On the other hand, grep_tree() will only search the contents that
   match the pathspec, and thus possibly walking fewer trees.

3) grep_tree() does not construct and copy back a new index, while
   ensure_full_index() does. This also saves some time.

----------------
Performance test

- Summary:

p2000 tests demonstrate a ~71% execution time reduction for
`git grep --cached bogus -- "f2/f1/f1/*"` using tree-walking logic.
However, notice that this result varies depending on the pathspec
given. See below "Command used for testing" for more details.

Test                              HEAD~   HEAD
-------------------------------------------------------
2000.78: git grep ... (full-v3)   0.35    0.39 (≈)
2000.79: git grep ... (full-v4)   0.36    0.30 (≈)
2000.80: git grep ... (sparse-v3) 0.88    0.23 (-73.8%)
2000.81: git grep ... (sparse-v4) 0.83    0.26 (-68.6%)

- Command used for testing:

git grep --cached bogus -- "f2/f1/f1/*"

The reason for specifying a pathspec is that, if we don't specify a
pathspec, then grep_tree() will walk all the trees and blobs to find the
pattern, and the time consumed doing so is not too different from using
the original ensure_full_index() method, which also spends most of the
time walking trees. However, when a pathspec is specified, this latest
logic will only walk the area of trees enclosed by the pathspec, and the
time consumed is reasonably a lot less.

Generally speaking, because the performance gain is acheived by walking
less trees, which are specified by the pathspec, the HEAD time v.s.
HEAD~ time in sparse-v[3|4], should be proportional to
"pathspec enclosed area" v.s. "all area", respectively. Namely, the
wider the <pathspec> is encompassing, the less the performance
difference between HEAD~ and HEAD, and vice versa.

That is, if we don't specify a pathspec, the performance difference [1]
is indistinguishable: both methods walk all the trees and take generally
same amount of time (even with the index construction time included for
ensure_full_index()).

[1] Performance test result without pathspec (hence walking all trees):

Command used:

git grep --cached bogus

Test                                HEAD~  HEAD
---------------------------------------------------
2000.78: git grep ... (full-v3)     6.17   5.19 (≈)
2000.79: git grep ... (full-v4)     6.19   5.46 (≈)
2000.80: git grep ... (sparse-v3)   6.57   6.44 (≈)
2000.81: git grep ... (sparse-v4)   6.65   6.28 (≈)

--------------------------
NEEDSWORK about submodules

There are a few NEEDSWORKs that belong to improvements beyond this
topic. See the NEEDSWORK in builtin/grep.c::grep_submodule() for
more context. The other two NEEDSWORKs in t1092 are also relative.

Suggested-by: Derrick Stolee <derrickstolee@github.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Helped-by: Victoria Dye <vdye@github.com>
Helped-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoSync with 'maint'
Junio C Hamano [Fri, 26 Aug 2022 18:14:11 +0000 (11:14 -0700)] 
Sync with 'maint'

2 years agoA handful more topics from the 'master' front for 2.37.3
Junio C Hamano [Thu, 25 Aug 2022 21:57:38 +0000 (14:57 -0700)] 
A handful more topics from the 'master' front for 2.37.3

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'po/doc-add-renormalize' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:13 +0000 (11:13 -0700)] 
Merge branch 'po/doc-add-renormalize' into maint

Documentation for "git add --renormalize" has been improved.
source: <20220810144450.470-2-philipoakley@iee.email>

* po/doc-add-renormalize:
  doc add: renormalize is not idempotent for CRCRLF

2 years agoMerge branch 'vd/sparse-reset-checkout-fixes' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:12 +0000 (11:13 -0700)] 
Merge branch 'vd/sparse-reset-checkout-fixes' into maint

Fixes to sparse index compatibility work for "reset" and "checkout"
commands.
source: <pull.1312.v3.git.1659985672.gitgitgadget@gmail.com>

* vd/sparse-reset-checkout-fixes:
  unpack-trees: unpack new trees as sparse directories
  cache.h: create 'index_name_pos_sparse()'
  oneway_diff: handle removed sparse directories
  checkout: fix nested sparse directory diff in sparse index

2 years agoMerge branch 'jk/fsck-tree-mode-bits-fix' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:12 +0000 (11:13 -0700)] 
Merge branch 'jk/fsck-tree-mode-bits-fix' into maint

"git fsck" reads mode from tree objects but canonicalizes the mode
before passing it to the logic to check object sanity, which has
hid broken tree objects from the checking logic.  This has been
corrected, but to help exiting projects with broken tree objects
that they cannot fix retroactively, the severity of anomalies this
code detects has been demoted to "info" for now.
source: <YvQcNpizy9uOZiAz@coredump.intra.peff.net>

* jk/fsck-tree-mode-bits-fix:
  fsck: downgrade tree badFilemode to "info"
  fsck: actually detect bad file modes in trees
  tree-walk: add a mechanism for getting non-canonicalized modes

2 years agoMerge branch 'fc/vimdiff-layout-vimdiff3-fix' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:12 +0000 (11:13 -0700)] 
Merge branch 'fc/vimdiff-layout-vimdiff3-fix' into maint

"vimdiff3" regression fix.
source: <20220810154618.307275-1-felipe.contreras@gmail.com>

* fc/vimdiff-layout-vimdiff3-fix:
  mergetools: vimdiff: simplify tabfirst
  mergetools: vimdiff: fix single window layouts
  mergetools: vimdiff: rework tab logic
  mergetools: vimdiff: fix for diffopt
  mergetools: vimdiff: silence annoying messages
  mergetools: vimdiff: make vimdiff3 actually work
  mergetools: vimdiff: fix comment

2 years agoMerge branch 'js/safe-directory-plus' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:12 +0000 (11:13 -0700)] 
Merge branch 'js/safe-directory-plus' into maint

Platform-specific code that determines if a directory is OK to use
as a repository has been taught to report more details, especially
on Windows.
source: <pull.1286.v2.git.1659965270.gitgitgadget@gmail.com>

* js/safe-directory-plus:
  mingw: handle a file owned by the Administrators group correctly
  mingw: be more informative when ownership check fails on FAT32
  mingw: provide details about unsafe directories' ownership
  setup: prepare for more detailed "dubious ownership" messages
  setup: fix some formatting

2 years agoMerge branch 'pw/use-glibc-tunable-for-malloc-optim' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:12 +0000 (11:13 -0700)] 
Merge branch 'pw/use-glibc-tunable-for-malloc-optim' into maint

Avoid repeatedly running getconf to ask libc version in the test
suite, and instead just as it once per script.
source: <pull.1311.git.1659620305757.gitgitgadget@gmail.com>

* pw/use-glibc-tunable-for-malloc-optim:
  tests: cache glibc version check

2 years agoMerge branch 'ab/hooks-regression-fix' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:12 +0000 (11:13 -0700)] 
Merge branch 'ab/hooks-regression-fix' into maint

A follow-up fix to a fix for a regression in 2.36.
source: <patch-1.1-2450e3e65cf-20220805T141402Z-avarab@gmail.com>

* ab/hooks-regression-fix:
  hook API: don't segfault on strbuf_addf() to NULL "out"

2 years agoMerge branch 'gc/git-reflog-doc-markup' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:11 +0000 (11:13 -0700)] 
Merge branch 'gc/git-reflog-doc-markup' into maint

Doc mark-up fix.
source: <pull.1304.git.git.1659387885711.gitgitgadget@gmail.com>

* gc/git-reflog-doc-markup:
  Documentation/git-reflog: remove unneeded \ from \{

2 years agoMerge branch 'js/ort-clean-up-after-failed-merge' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:11 +0000 (11:13 -0700)] 
Merge branch 'js/ort-clean-up-after-failed-merge' into maint

Plug memory leaks in the failure code path in the "merge-ort" merge
strategy backend.
source: <pull.1307.v2.git.1659114727.gitgitgadget@gmail.com>

* js/ort-clean-up-after-failed-merge:
  merge-ort: do leave trace2 region even if checkout fails
  merge-ort: clean up after failed merge

2 years agoMerge branch 'jk/struct-zero-init-with-older-gcc' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:10 +0000 (11:13 -0700)] 
Merge branch 'jk/struct-zero-init-with-older-gcc' into maint

Older gcc with -Wall complains about the universal zero initializer
"struct s = { 0 };" idiom, which makes developers' lives
inconvenient (as -Werror is enabled by DEVELOPER=YesPlease).  The
build procedure has been tweaked to help these compilers.
source: <YuQ60ZUPBHAVETD7@coredump.intra.peff.net>

* jk/struct-zero-init-with-older-gcc:
  config.mak.dev: squelch -Wno-missing-braces for older gcc

2 years agoMerge branch 'js/lstat-mingw-enotdir-fix' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:10 +0000 (11:13 -0700)] 
Merge branch 'js/lstat-mingw-enotdir-fix' into maint

Fix to lstat() emulation on Windows.
source: <pull.1291.v3.git.1659089152877.gitgitgadget@gmail.com>

* js/lstat-mingw-enotdir-fix:
  lstat(mingw): correctly detect ENOTDIR scenarios

2 years agoMerge branch 'js/mingw-with-python' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:10 +0000 (11:13 -0700)] 
Merge branch 'js/mingw-with-python' into maint

Conditionally allow building Python interpreter on Windows
source: <pull.1306.v2.git.1659109272.gitgitgadget@gmail.com>

* js/mingw-with-python:
  mingw: remove unneeded `NO_CURL` directive
  mingw: remove unneeded `NO_GETTEXT` directive
  windows: include the Python bits when building Git for Windows

2 years agoMerge branch 'ca/unignore-local-installation-on-windows' into maint
Junio C Hamano [Fri, 26 Aug 2022 18:13:10 +0000 (11:13 -0700)] 
Merge branch 'ca/unignore-local-installation-on-windows' into maint

Fix build procedure for Windows that uses CMake so that it can pick
up the shell interpreter from local installation location.
source: <pull.1304.git.1658912756815.gitgitgadget@gmail.com>

* ca/unignore-local-installation-on-windows:
  cmake: support local installations of git

2 years agoThe fifteenth batch
Junio C Hamano [Thu, 25 Aug 2022 21:20:06 +0000 (14:20 -0700)] 
The fifteenth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'vd/scalar-generalize-diagnose'
Junio C Hamano [Thu, 25 Aug 2022 21:42:32 +0000 (14:42 -0700)] 
Merge branch 'vd/scalar-generalize-diagnose'

The "diagnose" feature to create a zip archive for diagnostic
material has been lifted from "scalar" and made into a feature of
"git bugreport".

* vd/scalar-generalize-diagnose:
  scalar: update technical doc roadmap
  scalar-diagnose: use 'git diagnose --mode=all'
  builtin/bugreport.c: create '--diagnose' option
  builtin/diagnose.c: add '--mode' option
  builtin/diagnose.c: create 'git diagnose' builtin
  diagnose.c: add option to configure archive contents
  scalar-diagnose: move functionality to common location
  scalar-diagnose: move 'get_disk_info()' to 'compat/'
  scalar-diagnose: add directory to archiver more gently
  scalar-diagnose: avoid 32-bit overflow of size_t
  scalar-diagnose: use "$GIT_UNZIP" in test

2 years agoMerge branch 'jk/pipe-command-nonblock'
Junio C Hamano [Thu, 25 Aug 2022 21:42:31 +0000 (14:42 -0700)] 
Merge branch 'jk/pipe-command-nonblock'

Fix deadlocks between main Git process and subprocess spawned via
the pipe_command() API, that can kill "git add -p" that was
reimplemented in C recently.

* jk/pipe-command-nonblock:
  pipe_command(): mark stdin descriptor as non-blocking
  pipe_command(): handle ENOSPC when writing to a pipe
  pipe_command(): avoid xwrite() for writing to pipe
  git-compat-util: make MAX_IO_SIZE define globally available
  nonblock: support Windows
  compat: add function to enable nonblocking pipes

2 years agoMerge branch 'js/fetch-negotiation-trace'
Junio C Hamano [Thu, 25 Aug 2022 21:42:31 +0000 (14:42 -0700)] 
Merge branch 'js/fetch-negotiation-trace'

The common ancestor negotiation exchange during a "git fetch"
session now leaves trace log.

* js/fetch-negotiation-trace:
  fetch-pack: add tracing for negotiation rounds

2 years agoMerge branch 'jk/is-promisor-object-keep-tree-in-use'
Junio C Hamano [Thu, 25 Aug 2022 21:42:31 +0000 (14:42 -0700)] 
Merge branch 'jk/is-promisor-object-keep-tree-in-use'

An earlier optimization discarded a tree-object buffer that is
still in use, which has been corrected.

* jk/is-promisor-object-keep-tree-in-use:
  is_promisor_object(): fix use-after-free of tree buffer

2 years agoMerge branch 'en/submodule-merge-messages-fixes'
Junio C Hamano [Thu, 25 Aug 2022 21:42:29 +0000 (14:42 -0700)] 
Merge branch 'en/submodule-merge-messages-fixes'

Further update the help messages given while merging submodules.

* en/submodule-merge-messages-fixes:
  merge-ort: provide helpful submodule update message when possible
  merge-ort: avoid surprise with new sub_flag variable
  merge-ort: remove translator lego in new "submodule conflict suggestion"
  submodule merge: update conflict error message

2 years agoThe fourteenth batch
Junio C Hamano [Thu, 18 Aug 2022 19:46:40 +0000 (12:46 -0700)] 
The fourteenth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'll/disk-usage-humanise'
Junio C Hamano [Thu, 18 Aug 2022 20:07:05 +0000 (13:07 -0700)] 
Merge branch 'll/disk-usage-humanise'

"git rev-list --disk-usage" learned to take an optional value
"human" to show the reported value in human-readable format, like
"3.40MiB".

* ll/disk-usage-humanise:
  rev-list: support human-readable output for `--disk-usage`

2 years agoMerge branch 'sy/sparse-rm'
Junio C Hamano [Thu, 18 Aug 2022 20:07:05 +0000 (13:07 -0700)] 
Merge branch 'sy/sparse-rm'

"git rm" has become more aware of the sparse-index feature.

* sy/sparse-rm:
  rm: integrate with sparse-index
  rm: expand the index only when necessary
  pathspec.h: move pathspec_needs_expanded_index() from reset.c to here
  t1092: add tests for `git-rm`

2 years agoMerge branch 'vd/sparse-reset-checkout-fixes'
Junio C Hamano [Thu, 18 Aug 2022 20:07:04 +0000 (13:07 -0700)] 
Merge branch 'vd/sparse-reset-checkout-fixes'

Fixes to sparse index compatibility work for "reset" and "checkout"
commands.

* vd/sparse-reset-checkout-fixes:
  unpack-trees: unpack new trees as sparse directories
  cache.h: create 'index_name_pos_sparse()'
  oneway_diff: handle removed sparse directories
  checkout: fix nested sparse directory diff in sparse index

2 years agoMerge branch 'ds/bundle-uri-more'
Junio C Hamano [Thu, 18 Aug 2022 20:07:04 +0000 (13:07 -0700)] 
Merge branch 'ds/bundle-uri-more'

The "bundle URI" design gets documented.

* ds/bundle-uri-more:
  bundle-uri: add example bundle organization
  docs: document bundle URI standard

2 years agoMerge branch 'jk/fsck-tree-mode-bits-fix'
Junio C Hamano [Thu, 18 Aug 2022 20:07:04 +0000 (13:07 -0700)] 
Merge branch 'jk/fsck-tree-mode-bits-fix'

"git fsck" reads mode from tree objects but canonicalizes the mode
before passing it to the logic to check object sanity, which has
hid broken tree objects from the checking logic.  This has been
corrected, but to help exiting projects with broken tree objects
that they cannot fix retroactively, the severity of anomalies this
code detects has been demoted to "info" for now.

* jk/fsck-tree-mode-bits-fix:
  fsck: downgrade tree badFilemode to "info"
  fsck: actually detect bad file modes in trees
  tree-walk: add a mechanism for getting non-canonicalized modes

2 years agoMerge branch 'fc/vimdiff-layout-vimdiff3-fix'
Junio C Hamano [Thu, 18 Aug 2022 20:07:04 +0000 (13:07 -0700)] 
Merge branch 'fc/vimdiff-layout-vimdiff3-fix'

"vimdiff3" regression fix.

* fc/vimdiff-layout-vimdiff3-fix:
  mergetools: vimdiff: simplify tabfirst
  mergetools: vimdiff: fix single window layouts
  mergetools: vimdiff: rework tab logic
  mergetools: vimdiff: fix for diffopt
  mergetools: vimdiff: silence annoying messages
  mergetools: vimdiff: make vimdiff3 actually work
  mergetools: vimdiff: fix comment

2 years agoMerge branch 'po/doc-add-renormalize'
Junio C Hamano [Thu, 18 Aug 2022 20:07:03 +0000 (13:07 -0700)] 
Merge branch 'po/doc-add-renormalize'

Documentation for "git add --renormalize" has been improved.

* po/doc-add-renormalize:
  doc add: renormalize is not idempotent for CRCRLF

2 years agomerge-ort: provide helpful submodule update message when possible
Elijah Newren [Thu, 18 Aug 2022 07:15:27 +0000 (07:15 +0000)] 
merge-ort: provide helpful submodule update message when possible

In commit 4057523a40 ("submodule merge: update conflict error message",
2022-08-04), a more detailed message was provided when submodules
conflict, in order to help users know how to resolve those conflicts.
There were a couple situations for which a different message would be
more appropriate, but that commit left handling those for future work.
Unfortunately, that commit would check if any submodules were of the
type that it didn't know how to explain, and, if so, would avoid
providing the more detailed explanation even for the submodules it did
know how to explain.

Change this to have the code print the helpful messages for the subset
of submodules it knows how to explain.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomerge-ort: avoid surprise with new sub_flag variable
Elijah Newren [Thu, 18 Aug 2022 07:15:26 +0000 (07:15 +0000)] 
merge-ort: avoid surprise with new sub_flag variable

Commit 4057523a40 ("submodule merge: update conflict error message",
2022-08-04) added a sub_flag variable that is used to store a value from
enum conflict_and_info_types, but initializes it with a value of -1 that
does not correspond to any of the conflict_and_info_types.  The code may
never set it to a valid value and yet still use it, which can be
surprising when reading over the code at first.  Initialize it instead
to the generic CONFLICT_SUBMODULE_FAILED_TO_MERGE value, which is still
distinct from the two values we need to special case.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomerge-ort: remove translator lego in new "submodule conflict suggestion"
Elijah Newren [Thu, 18 Aug 2022 07:15:25 +0000 (07:15 +0000)] 
merge-ort: remove translator lego in new "submodule conflict suggestion"

In commit 4057523a40 ("submodule merge: update conflict error message",
2022-08-04), the new "submodule conflict suggestion" code was
translating 6 different pieces of the new message and then used
carefully crafted logic to allow stitching it back together with special
formatting.  Keep the components of the message together as much as
possible, so that:
  * we reduce the number of things translators have to translate
  * translators have more control over the format of the output
  * the code is much easier for developers to understand too

Also, reformat some comments running beyond the 80th column while at it.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopipe_command(): mark stdin descriptor as non-blocking
Jeff King [Wed, 17 Aug 2022 06:10:22 +0000 (02:10 -0400)] 
pipe_command(): mark stdin descriptor as non-blocking

Our pipe_command() helper lets you both write to and read from a child
process on its stdin/stdout. It's supposed to work without deadlocks
because we use poll() to check when descriptors are ready for reading or
writing. But there's a bug: if both the data to be written and the data
to be read back exceed the pipe buffer, we'll deadlock.

The issue is that the code assumes that if you have, say, a 2MB buffer
to write and poll() tells you that the pipe descriptor is ready for
writing, that calling:

  write(cmd->in, buf, 2*1024*1024);

will do a partial write, filling the pipe buffer and then returning what
it did write. And that is what it would do on a socket, but not for a
pipe. When writing to a pipe, at least on Linux, it will block waiting
for the child process to read() more. And now we have a potential
deadlock, because the child may be writing back to us, waiting for us to
read() ourselves.

An easy way to trigger this is:

  git -c add.interactive.useBuiltin=true \
      -c interactive.diffFilter=cat \
      checkout -p HEAD~200

The diff against HEAD~200 will be big, and the filter wants to write all
of it back to us (obviously this is a dummy filter, but in the real
world something like diff-highlight would similarly stream back a big
output).

If you set add.interactive.useBuiltin to false, the problem goes away,
because now we're not using pipe_command() anymore (instead, that part
happens in perl). But this isn't a bug in the interactive code at all.
It's the underlying pipe_command() code which is broken, and has been
all along.

We presumably didn't notice because most calls only do input _or_
output, not both. And the few that do both, like gpg calls, may have
large inputs or outputs, but never both at the same time (e.g., consider
signing, which has a large payload but a small signature comes back).

The obvious fix is to put the descriptor into non-blocking mode, and
indeed, that makes the problem go away. Callers shouldn't need to
care, because they never see the descriptor (they hand us a buffer to
feed into it).

The included test fails reliably on Linux without this patch. Curiously,
it doesn't fail in our Windows CI environment, but has been reported to
do so for individual developers. It should pass in any environment after
this patch (courtesy of the compat/ layers added in the last few
commits).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopipe_command(): handle ENOSPC when writing to a pipe
Jeff King [Wed, 17 Aug 2022 06:09:42 +0000 (02:09 -0400)] 
pipe_command(): handle ENOSPC when writing to a pipe

When write() to a non-blocking pipe fails because the buffer is full,
POSIX says we should see EAGAIN. But our mingw_write() compat layer on
Windows actually returns ENOSPC for this case. This is probably
something we want to correct, but given that we don't plan to use
non-blocking descriptors in a lot of places, we can work around it by
just catching ENOSPC alongside EAGAIN. If we ever do fix mingw_write(),
then this patch can be reverted.

We don't actually use a non-blocking pipe yet, so this is still just
preparation.

Helped-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopipe_command(): avoid xwrite() for writing to pipe
Jeff King [Wed, 17 Aug 2022 06:08:06 +0000 (02:08 -0400)] 
pipe_command(): avoid xwrite() for writing to pipe

If xwrite() sees an EAGAIN response, it will loop forever until the
write succeeds (or encounters a real error). This is due to ef1cf0167a
(xwrite: poll on non-blocking FDs, 2016-06-26), with the idea that we
won't be surprised by a descriptor unexpectedly set as non-blocking.

But that will make things awkward when we do want a non-blocking
descriptor, and a future patch will switch pipe_command() to using one.
In that case, looping on EAGAIN is bad, because the process on the other
end of the pipe may be waiting on us before doing another read() on the
pipe, which would mean we deadlock.

In practice we're not supposed to ever see EAGAIN here, since poll()
will have just told us the descriptor is ready for writing. But our
Windows emulation of poll() will always return "ready" for writing to a
pipe descriptor! This is due to 94f4d01932 (mingw: workaround for hangs
when sending STDIN, 2020-02-17).

Our best bet in that case is to keep handling other descriptors, as any
read() we do may allow the child command to make forward progress (i.e.,
its write() finishes, and then it read()s from its stdin, freeing up
space in the pipe buffer). This means we might busy-loop between poll()
and write() on Windows if the child command is slow to read our input,
but it's much better than the alternative of deadlocking.

In practice, this busy-looping should be rare:

  - for small inputs, we'll just write the whole thing in a single
    write() anyway, non-blocking or not

  - for larger inputs where the child reads input and then processes it
    before writing (e.g., gpg verifying a signature), we may make a few
    extra write() calls that get EAGAIN during the initial write, but
    once it has taken in the whole input, we'll correctly block waiting
    to read back the data.

  - for larger inputs where the child process is streaming output back
    (like a diff filter), we'll likewise see some extra EAGAINs, but
    most of them will be followed immediately by a read(), which will
    let the child command make forward progress.

Of course it won't happen at all for now, since we don't yet use a
non-blocking pipe. This is just preparation for when we do.

Helped-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agogit-compat-util: make MAX_IO_SIZE define globally available
Jeff King [Wed, 17 Aug 2022 06:06:58 +0000 (02:06 -0400)] 
git-compat-util: make MAX_IO_SIZE define globally available

We define MAX_IO_SIZE within wrapper.c, but it's useful for any code
that wants to do a raw write() for whatever reason (say, because they
want different EAGAIN handling). Let's make it available everywhere.

The alternative would be adding xwrite_foo() variants to give callers
more options. But there's really no reason MAX_IO_SIZE needs to be
abstracted away, so this give callers the most flexibility.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agononblock: support Windows
René Scharfe [Wed, 17 Aug 2022 06:05:25 +0000 (02:05 -0400)] 
nonblock: support Windows

Implement enable_pipe_nonblock() using the Windows API. This works only
for pipes, but that is sufficient for this limited interface. Despite
the API calls used, it handles both "named" and anonymous pipes from our
pipe() emulation.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocompat: add function to enable nonblocking pipes
Jeff King [Wed, 17 Aug 2022 06:04:55 +0000 (02:04 -0400)] 
compat: add function to enable nonblocking pipes

We'd like to be able to make some of our pipes nonblocking so that
poll() can be used effectively, but O_NONBLOCK isn't portable. Let's
introduce a compat wrapper so this can be abstracted for each platform.

The interface is as narrow as possible to let platforms do what's
natural there (rather than having to implement fcntl() and a fake
O_NONBLOCK for example, or having to handle other types of descriptors).

The next commit will add Windows support, at which point we should be
covering all platforms in practice. But if we do find some other
platform without O_NONBLOCK, we'll return ENOSYS. Arguably we could just
trigger a build-time #error in this case, which would catch the problem
earlier. But since we're not planning to use this compat wrapper in many
code paths, a seldom-seen runtime error may be friendlier for such a
platform than blocking compilation completely. Our test suite would
still notice it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agofetch-pack: add tracing for negotiation rounds
Josh Steadmon [Tue, 2 Aug 2022 22:04:05 +0000 (15:04 -0700)] 
fetch-pack: add tracing for negotiation rounds

Currently, negotiation for V0/V1/V2 fetch have trace2 regions covering
the entire negotiation process. However, we'd like additional data, such
as timing for each round of negotiation or the number of "haves" in each
round. Additionally, "independent negotiation" (AKA push negotiation)
has no tracing at all. Having this data would allow us to compare the
performance of the various negotation implementations, and to debug
unexpectedly slow fetch & push sessions.

Add per-round trace2 regions for all negotiation implementations (V0+V1,
V2, and independent negotiation), as well as an overall region for
independent negotiation. Add trace2 data logging for the number of haves
and "in vain" objects for each round, and for the total number of rounds
once negotiation completes.  Finally, add a few checks into various
tests to verify that the number of rounds is logged as expected.

Signed-off-by: Josh Steadmon <steadmon@google.com>
Acked-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoThe thirteenth batch
Junio C Hamano [Mon, 15 Aug 2022 01:33:58 +0000 (18:33 -0700)] 
The thirteenth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'js/safe-directory-plus'
Junio C Hamano [Mon, 15 Aug 2022 06:19:28 +0000 (23:19 -0700)] 
Merge branch 'js/safe-directory-plus'

Platform-specific code that determines if a directory is OK to use
as a repository has been taught to report more details, especially
on Windows.

* js/safe-directory-plus:
  mingw: handle a file owned by the Administrators group correctly
  mingw: be more informative when ownership check fails on FAT32
  mingw: provide details about unsafe directories' ownership
  setup: prepare for more detailed "dubious ownership" messages
  setup: fix some formatting

2 years agoMerge branch 'pw/use-glibc-tunable-for-malloc-optim'
Junio C Hamano [Mon, 15 Aug 2022 06:19:28 +0000 (23:19 -0700)] 
Merge branch 'pw/use-glibc-tunable-for-malloc-optim'

Avoid repeatedly running getconf to ask libc version in the test
suite, and instead just as it once per script.

* pw/use-glibc-tunable-for-malloc-optim:
  tests: cache glibc version check

2 years agoMerge branch 'ab/tech-docs-to-help'
Junio C Hamano [Mon, 15 Aug 2022 06:19:27 +0000 (23:19 -0700)] 
Merge branch 'ab/tech-docs-to-help'

Expose a lot of "tech docs" via "git help" interface.

* ab/tech-docs-to-help:
  docs: move http-protocol docs to man section 5
  docs: move cruft pack docs to gitformat-pack
  docs: move pack format docs to man section 5
  docs: move signature docs to man section 5
  docs: move index format docs to man section 5
  docs: move protocol-related docs to man section 5
  docs: move commit-graph format docs to man section 5
  git docs: add a category for file formats, protocols and interfaces
  git docs: add a category for user-facing file, repo and command UX
  git help doc: use "<doc>" instead of "<guide>"
  help.c: remove common category behavior from drop_prefix() behavior
  help.c: refactor drop_prefix() to use a "switch" statement"

2 years agoMerge branch 'jc/rerere-autoupdate-doc'
Junio C Hamano [Mon, 15 Aug 2022 06:19:27 +0000 (23:19 -0700)] 
Merge branch 'jc/rerere-autoupdate-doc'

Update documentation on the "--[no-]rerere-autoupdate" option.

* jc/rerere-autoupdate-doc:
  doc: clarify rerere-autoupdate
  doc: consolidate --rerere-autoupdate description

2 years agoMerge branch 'ab/hooks-regression-fix'
Junio C Hamano [Mon, 15 Aug 2022 06:19:27 +0000 (23:19 -0700)] 
Merge branch 'ab/hooks-regression-fix'

A follow-up fix to a fix for a regression in 2.36.

* ab/hooks-regression-fix:
  hook API: don't segfault on strbuf_addf() to NULL "out"

2 years agois_promisor_object(): fix use-after-free of tree buffer
Jeff King [Sun, 14 Aug 2022 06:29:15 +0000 (02:29 -0400)] 
is_promisor_object(): fix use-after-free of tree buffer

Since commit fcc07e980b (is_promisor_object(): free tree buffer after
parsing, 2021-04-13), we'll always free the buffers attached to a
"struct tree" after searching them for promisor links. But there's an
important case where we don't want to do so: if somebody else is already
using the tree!

This can happen during a "rev-list --missing=allow-promisor" traversal
in a partial clone that is missing one or more trees or blobs. The
backtrace for the free looks like this:

      #1 free_tree_buffer tree.c:147
      #2 add_promisor_object packfile.c:2250
      #3 for_each_object_in_pack packfile.c:2190
      #4 for_each_packed_object packfile.c:2215
      #5 is_promisor_object packfile.c:2272
      #6 finish_object__ma builtin/rev-list.c:245
      #7 finish_object builtin/rev-list.c:261
      #8 show_object builtin/rev-list.c:274
      #9 process_blob list-objects.c:63
      #10 process_tree_contents list-objects.c:145
      #11 process_tree list-objects.c:201
      #12 traverse_trees_and_blobs list-objects.c:344
      [...]

We're in the middle of walking through the entries of a tree object via
process_tree_contents(). We see a blob (or it could even be another tree
entry) that we don't have, so we call is_promisor_object() to check it.
That function loops over all of the objects in the promisor packfile,
including the tree we're currently walking. When we're done with it
there, we free the tree buffer. But as we return to the walk in
process_tree_contents(), it's still holding on to a pointer to that
buffer, via its tree_desc iterator, and it accesses the freed memory.

Even a trivial use of "--missing=allow-promisor" triggers this problem,
as the included test demonstrates (it's just a vanilla --blob:none
clone).

We can detect this case by only freeing the tree buffer if it was
allocated on our behalf. This is a little tricky since that happens
inside parse_object(), and it doesn't tell us whether the object was
already parsed, or whether it allocated the buffer itself. But by
checking for an already-parsed tree beforehand, we can distinguish the
two cases.

That feels a little hacky, and does incur an extra lookup in the
object-hash table. But that cost is fairly minimal compared to actually
loading objects (and since we're iterating the whole pack here, we're
likely to be loading most objects, rather than reusing cached results).

It may also be a good direction for this function in general, as there
are other possible optimizations that rely on doing some analysis before
parsing:

  - we could detect blobs and avoid reading their contents; they can't
    link to other objects, but parse_object() doesn't know that we don't
    care about checking their hashes.

  - we could avoid allocating object structs entirely for most objects
    (since we really only need them in the oidset), which would save
    some memory.

  - promisor commits could use the commit-graph rather than loading the
    object from disk

This commit doesn't do any of those optimizations, but I think it argues
that this direction is reasonable, rather than relying on parse_object()
and trying to teach it to give us more information about whether it
parsed.

The included test fails reliably under SANITIZE=address just when
running "rev-list --missing=allow-promisor". Checking the output isn't
strictly necessary to detect the bug, but it seems like a reasonable
addition given the general lack of coverage for "allow-promisor" in the
test suite.

Reported-by: Andrew Olsen <andrew.olsen@koordinates.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar: update technical doc roadmap
Victoria Dye [Fri, 12 Aug 2022 20:10:19 +0000 (20:10 +0000)] 
scalar: update technical doc roadmap

Update the Scalar roadmap to reflect the completion of generalizing 'scalar
diagnose' into 'git diagnose' and 'git bugreport --diagnose'.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar-diagnose: use 'git diagnose --mode=all'
Victoria Dye [Fri, 12 Aug 2022 20:10:18 +0000 (20:10 +0000)] 
scalar-diagnose: use 'git diagnose --mode=all'

Replace implementation of 'scalar diagnose' with an internal invocation of
'git diagnose --mode=all'. This simplifies the implementation of
'cmd_diagnose' by making it a direct alias of 'git diagnose' and removes
some code in 'scalar.c' that is duplicated in 'builtin/diagnose.c'. The
simplicity of the alias also sets up a clean deprecation path for 'scalar
diagnose' (in favor of 'git diagnose'), if that is desired in the future.

This introduces one minor change to the output of 'scalar diagnose', which
is that the prefix of the created zip archive is changed from 'scalar_' to
'git-diagnostics-'.

Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/bugreport.c: create '--diagnose' option
Victoria Dye [Fri, 12 Aug 2022 20:10:17 +0000 (20:10 +0000)] 
builtin/bugreport.c: create '--diagnose' option

Create a '--diagnose' option for 'git bugreport' to collect additional
information about the repository and write it to a zipped archive.

The '--diagnose' option behaves effectively as an alias for simultaneously
running 'git bugreport' and 'git diagnose'. In the documentation, users are
explicitly recommended to attach the diagnostics alongside a bug report to
provide additional context to readers, ideally reducing some back-and-forth
between reporters and those debugging the issue.

Note that '--diagnose' may take an optional string arg (either 'stats' or
'all'). If specified without the arg, the behavior corresponds to running
'git diagnose' without '--mode'. As with 'git diagnose', this default is
intended to help reduce unintentional leaking of sensitive information).
Users can also explicitly specify '--diagnose=(stats|all)' to generate the
respective archive created by 'git diagnose --mode=(stats|all)'.

Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/diagnose.c: add '--mode' option
Victoria Dye [Fri, 12 Aug 2022 20:10:16 +0000 (20:10 +0000)] 
builtin/diagnose.c: add '--mode' option

Create '--mode=<mode>' option in 'git diagnose' to allow users to optionally
select non-default diagnostic information to include in the output archive.
Additionally, document the currently-available modes, emphasizing the
importance of not sharing a '--mode=all' archive publicly due to the
presence of sensitive information.

Note that the option parsing callback - 'option_parse_diagnose()' - is added
to 'diagnose.c' rather than 'builtin/diagnose.c' so that it may be reused in
future callers configuring a diagnostics archive.

Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/diagnose.c: create 'git diagnose' builtin
Victoria Dye [Fri, 12 Aug 2022 20:10:15 +0000 (20:10 +0000)] 
builtin/diagnose.c: create 'git diagnose' builtin

Create a 'git diagnose' builtin to generate a standalone zip archive of
repository diagnostics.

The "diagnose" functionality was originally implemented for Scalar in
aa5c79a331 (scalar: implement `scalar diagnose`, 2022-05-28). However, the
diagnostics gathered are not specific to Scalar-cloned repositories and
can be useful when diagnosing issues in any Git repository.

Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agodiagnose.c: add option to configure archive contents
Victoria Dye [Fri, 12 Aug 2022 20:10:14 +0000 (20:10 +0000)] 
diagnose.c: add option to configure archive contents

Update 'create_diagnostics_archive()' to take an argument 'mode'. When
archiving diagnostics for a repository, 'mode' is used to selectively
include/exclude information based on its value. The initial options for
'mode' are:

* DIAGNOSE_NONE: do not collect any diagnostics or create an archive
  (no-op).
* DIAGNOSE_STATS: collect basic repository metadata (Git version, repo path,
  filesystem available space) as well as sizing and count statistics for the
  repository's objects and packfiles.
* DIAGNOSE_ALL: collect basic repository metadata, sizing/count statistics,
  and copies of the '.git', '.git/hooks', '.git/info', '.git/logs', and
  '.git/objects/info' directories.

These modes are introduced to provide users the option to collect
diagnostics without the sensitive information included in copies of '.git'
dir contents. At the moment, only 'scalar diagnose' uses
'create_diagnostics_archive()' (with a hardcoded 'DIAGNOSE_ALL' mode to
match existing functionality), but more callers will be introduced in
subsequent patches.

Finally, refactor from a hardcoded set of 'add_directory_to_archiver()'
calls to iterative invocations gated by 'DIAGNOSE_ALL'. This allows for
easier future modification of the set of directories to archive and improves
error reporting when 'add_directory_to_archiver()' fails.

Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar-diagnose: move functionality to common location
Victoria Dye [Fri, 12 Aug 2022 20:10:13 +0000 (20:10 +0000)] 
scalar-diagnose: move functionality to common location

Move the core functionality of 'scalar diagnose' into a new 'diagnose.[c,h]'
library to prepare for new callers in the main Git tree generating
diagnostic archives. These callers will be introduced in subsequent patches.

While this patch appears large, it is mostly made up of moving code out of
'scalar.c' and into 'diagnose.c'. Specifically, the functions

- dir_file_stats_objects()
- dir_file_stats()
- count_files()
- loose_objs_stats()
- add_directory_to_archiver()

are all copied verbatim from 'scalar.c'. The 'create_diagnostics_archive()'
function is a mostly identical (partial) copy of 'cmd_diagnose()', with the
primary changes being that 'zip_path' is an input and "Enlistment root" is
corrected to "Repository root" in the archiver log.

Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar-diagnose: move 'get_disk_info()' to 'compat/'
Victoria Dye [Fri, 12 Aug 2022 20:10:12 +0000 (20:10 +0000)] 
scalar-diagnose: move 'get_disk_info()' to 'compat/'

Move 'get_disk_info()' function into 'compat/'. Although Scalar-specific
code is generally not part of the main Git tree, 'get_disk_info()' will be
used in subsequent patches by additional callers beyond 'scalar diagnose'.
This patch prepares for that change, at which point this platform-specific
code should be part of 'compat/' as a matter of convention.

The function is copied *mostly* verbatim, with two exceptions:

* '#ifdef WIN32' is replaced with '#ifdef GIT_WINDOWS_NATIVE' to allow
  'statvfs' to be used with Cygwin.
* the 'struct strbuf buf' and 'int res' (as well as their corresponding
  cleanup & return) are moved outside of the '#ifdef' block.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar-diagnose: add directory to archiver more gently
Victoria Dye [Fri, 12 Aug 2022 20:10:11 +0000 (20:10 +0000)] 
scalar-diagnose: add directory to archiver more gently

If a directory added to the 'scalar diagnose' archiver does not exist, warn
and return 0 from 'add_directory_to_archiver()' rather than failing with a
fatal error. This handles a failure edge case where the '.git/logs' has not
yet been created when running 'scalar diagnose', but extends to any
situation where a directory may be missing in the '.git' dir.

Now, when a directory is missing a warning is captured in the diagnostic
logs. This provides a user with more complete information than if 'scalar
diagnose' simply failed with an error.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar-diagnose: avoid 32-bit overflow of size_t
Victoria Dye [Fri, 12 Aug 2022 20:10:10 +0000 (20:10 +0000)] 
scalar-diagnose: avoid 32-bit overflow of size_t

Avoid 32-bit size_t overflow when reporting the available disk space in
'get_disk_info' by casting the block size and available block count to
'off_t' before multiplying them. Without this change, 'st_mult' would
(correctly) report a size_t overflow on 32-bit systems at or exceeding 2^32
bytes of available space.

Note that 'off_t' is a 64-bit integer even on 32-bit systems due to the
inclusion of '#define _FILE_OFFSET_BITS 64' in 'git-compat-util.h' (see
b97e911643 (Support for large files on 32bit systems., 2007-02-17)).

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar-diagnose: use "$GIT_UNZIP" in test
Victoria Dye [Fri, 12 Aug 2022 20:10:09 +0000 (20:10 +0000)] 
scalar-diagnose: use "$GIT_UNZIP" in test

Use the "$GIT_UNZIP" test variable rather than verbatim 'unzip' to unzip the
'scalar diagnose' archive. Using "$GIT_UNZIP" is needed to run the Scalar
tests on systems where 'unzip' is not in the system path.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoThe twelfth batch
Junio C Hamano [Fri, 12 Aug 2022 18:46:05 +0000 (11:46 -0700)] 
The twelfth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'ab/plug-revisions-leak'
Junio C Hamano [Fri, 12 Aug 2022 20:19:08 +0000 (13:19 -0700)] 
Merge branch 'ab/plug-revisions-leak'

Plug a bit more leaks in the revisions API.

* ab/plug-revisions-leak:
  revisions API: don't leak memory on argv elements that need free()-ing
  bisect.c: partially fix bisect_rev_setup() memory leak
  log: refactor "rev.pending" code in cmd_show()
  log: fix a memory leak in "git show <revision>..."
  test-fast-rebase helper: use release_revisions() (again)
  bisect.c: add missing "goto" for release_revisions()

2 years agoMerge branch 'ab/leak-check'
Junio C Hamano [Fri, 12 Aug 2022 20:19:08 +0000 (13:19 -0700)] 
Merge branch 'ab/leak-check'

Extend SANITIZE=leak checking and declare more tests "currently leak-free".

* ab/leak-check:
  CI: use "GIT_TEST_SANITIZE_LEAK_LOG=true" in linux-leaks
  upload-pack: fix a memory leak in create_pack_file()
  leak tests: mark passing SANITIZE=leak tests as leak-free
  leak tests: don't skip some tests under SANITIZE=leak
  test-lib: have the "check" mode for SANITIZE=leak consider leak logs
  test-lib: add a GIT_TEST_PASSING_SANITIZE_LEAK=check mode
  test-lib: simplify by removing test_external
  tests: move copy/pasted PERL + Test::More checks to a lib-perl.sh
  t/Makefile: don't remove test-results in "clean-except-prove-cache"
  test-lib: add a SANITIZE=leak logging mode
  t/README: reword the "GIT_TEST_PASSING_SANITIZE_LEAK" description
  test-lib: add a --invert-exit-code switch
  test-lib: fix GIT_EXIT_OK logic errors, use BAIL_OUT
  test-lib: don't set GIT_EXIT_OK before calling test_atexit_handler
  test-lib: use $1, not $@ in test_known_broken_{ok,failure}_

2 years agoMerge branch 'gc/git-reflog-doc-markup'
Junio C Hamano [Fri, 12 Aug 2022 20:19:08 +0000 (13:19 -0700)] 
Merge branch 'gc/git-reflog-doc-markup'

Doc mark-up fix.

* gc/git-reflog-doc-markup:
  Documentation/git-reflog: remove unneeded \ from \{

2 years agoMerge branch 'lt/symbolic-ref-sanity'
Junio C Hamano [Fri, 12 Aug 2022 20:19:07 +0000 (13:19 -0700)] 
Merge branch 'lt/symbolic-ref-sanity'

"git symbolic-ref symref non..sen..se" is now diagnosed as an error.

* lt/symbolic-ref-sanity:
  symbolic-ref: refuse to set syntactically invalid target

2 years agorev-list: support human-readable output for `--disk-usage`
Li Linchao [Thu, 11 Aug 2022 04:47:54 +0000 (04:47 +0000)] 
rev-list: support human-readable output for `--disk-usage`

The '--disk-usage' option for git-rev-list was introduced in 16950f8384
(rev-list: add --disk-usage option for calculating disk usage, 2021-02-09).
This is very useful for people inspect their git repo's objects usage
infomation, but the resulting number is quit hard for a human to read.

Teach git rev-list to output a human readable result when using
'--disk-usage'.

Signed-off-by: Li Linchao <lilinchao@oschina.cn>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoSync with Git 2.37.2
Junio C Hamano [Thu, 11 Aug 2022 04:54:33 +0000 (21:54 -0700)] 
Sync with Git 2.37.2

2 years agoGit 2.37.2 v2.37.2
Junio C Hamano [Thu, 11 Aug 2022 04:52:03 +0000 (21:52 -0700)] 
Git 2.37.2

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'jc/string-list-cleanup' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:36 +0000 (21:52 -0700)] 
Merge branch 'jc/string-list-cleanup' into maint

Code clean-up.
source: <xmqq7d471dns.fsf@gitster.g>

* jc/string-list-cleanup:
  builtin/remote.c: use the right kind of STRING_LIST_INIT

2 years agoMerge branch 'mt/pkt-line-comment-tweak' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:35 +0000 (21:52 -0700)] 
Merge branch 'mt/pkt-line-comment-tweak' into maint

In-code comment clarification.
source: <6a14443c101fa132498297af6d7a483520688d75.1658488203.git.matheus.bernardino@usp.br>

* mt/pkt-line-comment-tweak:
  pkt-line.h: move comment closer to the associated code

2 years agoMerge branch 'ma/t4200-update' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:35 +0000 (21:52 -0700)] 
Merge branch 'ma/t4200-update' into maint

Test fix.
source: <20220718154322.2177166-1-martin.agren@gmail.com>

* ma/t4200-update:
  t4200: drop irrelevant code

2 years agoMerge branch 'tb/commit-graph-genv2-upgrade-fix' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:34 +0000 (21:52 -0700)] 
Merge branch 'tb/commit-graph-genv2-upgrade-fix' into maint

There was a bug in the codepath to upgrade generation information
in commit-graph from v1 to v2 format, which has been corrected.
source: <cover.1657667404.git.me@ttaylorr.com>

* tb/commit-graph-genv2-upgrade-fix:
  commit-graph: fix corrupt upgrade from generation v1 to v2
  commit-graph: introduce `repo_find_commit_pos_in_graph()`
  t5318: demonstrate commit-graph generation v2 corruption

2 years agoMerge branch 'tk/untracked-cache-with-uall' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:34 +0000 (21:52 -0700)] 
Merge branch 'tk/untracked-cache-with-uall' into maint

Fix for a bug that makes write-tree to fail to write out a
non-existent index as a tree, introduced in 2.37.
source: <20220722212232.833188-1-martin.agren@gmail.com>

* tk/untracked-cache-with-uall:
  read-cache: make `do_read_index()` always set up `istate->repo`

2 years agoMerge branch 'mt/checkout-count-fix' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:33 +0000 (21:52 -0700)] 
Merge branch 'mt/checkout-count-fix' into maint

"git checkout" miscounted the paths it updated, which has been
corrected.
source: <cover.1657799213.git.matheus.bernardino@usp.br>

* mt/checkout-count-fix:
  checkout: fix two bugs on the final count of updated entries
  checkout: show bug about failed entries being included in final report
  checkout: document bug where delayed checkout counts entries twice

2 years agoMerge branch 'cl/rerere-train-with-no-sign' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:33 +0000 (21:52 -0700)] 
Merge branch 'cl/rerere-train-with-no-sign' into maint

"rerere-train" script (in contrib/) used to honor commit.gpgSign
while recreating the throw-away merges.
source: <PH7PR14MB5594A27B9295E95ACA4D6A69CE8F9@PH7PR14MB5594.namprd14.prod.outlook.com>

* cl/rerere-train-with-no-sign:
  contrib/rerere-train: avoid useless gpg sign in training

2 years agoMerge branch 'kk/p4-client-name-encoding-fix' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:33 +0000 (21:52 -0700)] 
Merge branch 'kk/p4-client-name-encoding-fix' into maint

"git p4" did not handle non-ASCII client name well, which has been
corrected.
source: <pull.1285.v3.git.git.1658394440.gitgitgadget@gmail.com>

* kk/p4-client-name-encoding-fix:
  git-p4: refactoring of p4CmdList()
  git-p4: fix bug with encoding of p4 client name

2 years agoMerge branch 'mb/p4-utf16-crlf' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:32 +0000 (21:52 -0700)] 
Merge branch 'mb/p4-utf16-crlf' into maint

"git p4" working on UTF-16 files on Windows did not implement
CRLF-to-LF conversion correctly, which has been corrected.
source: <pull.1294.v2.git.git.1658341065221.gitgitgadget@gmail.com>

* mb/p4-utf16-crlf:
  git-p4: fix CR LF handling for utf16 files

2 years agoMerge branch 'hx/lookup-commit-in-graph-fix' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:32 +0000 (21:52 -0700)] 
Merge branch 'hx/lookup-commit-in-graph-fix' into maint

A corner case bug where lazily fetching objects from a promisor
remote resulted in infinite recursion has been corrected.
source: <cover.1656593279.git.hanxin.hx@bytedance.com>

* hx/lookup-commit-in-graph-fix:
  t5330: remove run_with_limited_processses()
  commit-graph.c: no lazy fetch in lookup_commit_in_graph()

2 years agoMerge branch 'jc/resolve-undo' into maint
Junio C Hamano [Thu, 11 Aug 2022 04:52:32 +0000 (21:52 -0700)] 
Merge branch 'jc/resolve-undo' into maint

The resolve-undo information in the index was not protected against
GC, which has been corrected.
source: <xmqq35f7kzad.fsf@gitster.g>

* jc/resolve-undo:
  fsck: do not dereference NULL while checking resolve-undo data
  revision: mark blobs needed for resolve-undo as reachable

2 years agofsck: downgrade tree badFilemode to "info"
Jeff King [Wed, 10 Aug 2022 21:04:07 +0000 (17:04 -0400)] 
fsck: downgrade tree badFilemode to "info"

The previous commit un-broke the "badFileMode" check; before then it was
literally testing nothing. And as far as I can tell, it has been so
since the very initial version of fsck.

The current severity of "badFileMode" is just "warning". But in the
--strict mode used by transfer.fsckObjects, that is elevated to an
error. This will potentially cause hassle for users, because historical
objects with bad modes will suddenly start causing pushes to many server
operators to be rejected.

At the same time, these bogus modes aren't actually a big risk. Because
we canonicalize them everywhere besides fsck, they can't cause too much
mischief in the real world. The worst thing you can do is end up with
two almost-identical trees that have different hashes but are
interpreted the same. That will generally cause things to be inefficient
rather than wrong, and is a bug somebody working on a Git implementation
would want to fix, but probably not worth inconveniencing users by
refusing to push or fetch.

So let's downgrade this to "info" by default, which is our setting for
"mention this when fscking, but don't ever reject, even under strict
mode". If somebody really wants to be paranoid, they can still adjust
the level using config.

Suggested-by: Xavier Morel <xavier.morel@masklinn.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agofsck: actually detect bad file modes in trees
Jeff King [Wed, 10 Aug 2022 21:02:45 +0000 (17:02 -0400)] 
fsck: actually detect bad file modes in trees

We use the normal tree_desc code to iterate over trees in fsck, meaning
we only see the canonicalized modes it returns. And hence we'd never see
anything unexpected, since it will coerce literally any garbage into one
of our normal and accepted modes.

We can use the new RAW_MODES flag to see the real modes, and then use
the existing code to actually analyze them. The existing code is written
as allow-known-good, so there's not much point in testing a variety of
breakages. The one tested here should be S_IFREG but with nonsense
permissions.

Do note that the error-reporting here isn't great. We don't mention the
specific bad mode, but just that the tree has one or more broken modes.
But when you go to look at it with "git ls-tree", we'll report the
canonicalized mode! This isn't ideal, but given that this should come up
rarely, and that any number of other tree corruptions might force you
into looking at the binary bytes via "cat-file", it's not the end of the
world. And it's something we can improve on top later if we choose.

Reported-by: Xavier Morel <xavier.morel@masklinn.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agotree-walk: add a mechanism for getting non-canonicalized modes
Jeff King [Wed, 10 Aug 2022 21:01:17 +0000 (17:01 -0400)] 
tree-walk: add a mechanism for getting non-canonicalized modes

When using init_tree_desc() and tree_entry() to iterate over a tree, we
always canonicalize the modes coming out of the tree. This is a good
thing to prevent bugs or oddities in normal code paths, but it's
counter-productive for tools like fsck that want to see the exact
contents.

We can address this by adding an option to avoid the extra
canonicalization. A few notes on the implementation:

  - I've attached the new option to the tree_desc struct itself. The
    actual code change is in decode_tree_entry(), which is in turn
    called by the public update_tree_entry(), tree_entry(), and
    init_tree_desc() functions, plus their "gently" counterparts.

    By letting it ride along in the struct, we can avoid changing the
    signature of those functions, which are called many times. Plus it's
    conceptually simpler: you really want a particular iteration of a
    tree to be "raw" or not, rather than individual calls.

  - We still have to set the new option somewhere. The struct is
    initialized by init_tree_desc(). I added the new flags field only to
    the "gently" version. That avoids disturbing the much more numerous
    non-gentle callers, and it makes sense that anybody being careful
    about looking at raw modes would also be careful about bogus trees
    (i.e., the caller will be something like fsck in the first place).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobundle-uri: add example bundle organization
Derrick Stolee [Tue, 9 Aug 2022 13:12:41 +0000 (13:12 +0000)] 
bundle-uri: add example bundle organization

The previous change introduced the bundle URI design document. It
creates a flexible set of options that allow bundle providers many ways
to organize Git object data and speed up clones and fetches. It is
particularly important that we have flexibility so we can apply future
advancements as new ideas for efficiently organizing Git data are
discovered.

However, the design document does not provide even an example of how
bundles could be organized, and that makes it difficult to envision how
the feature should work at the end of the implementation plan.

Add a section that details how a bundle provider could work, including
using the Git server advertisement for multiple geo-distributed servers.
This organization is based on the GVFS Cache Servers which have
successfully used similar ideas to provide fast object access and
reduced server load for very large repositories.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agodocs: document bundle URI standard
Derrick Stolee [Tue, 9 Aug 2022 13:12:40 +0000 (13:12 +0000)] 
docs: document bundle URI standard

Introduce the idea of bundle URIs to the Git codebase through an
aspirational design document. This document includes the full design
intended to include the feature in its fully-implemented form. This will
take several steps as detailed in the Implementation Plan section.

By committing this document now, it can be used to motivate changes
necessary to reach these final goals. The design can still be altered as
new information is discovered.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: simplify tabfirst
Felipe Contreras [Wed, 10 Aug 2022 15:46:18 +0000 (10:46 -0500)] 
mergetools: vimdiff: simplify tabfirst

If we wrap the tabdo command there's no need for a separate command
call.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: fix single window layouts
Felipe Contreras [Wed, 10 Aug 2022 15:46:17 +0000 (10:46 -0500)] 
mergetools: vimdiff: fix single window layouts

Layouts with a single window other than "MERGED" do not work (e.g.
"LOCAL" or "MERGED+LOCAL").

This is because as the documentation of bufdo says:

    The last buffer (or where an error occurred) becomes the current
    buffer.

And we do always do bufdo the end.

Additionally, we do it only once, when it should be per tab.

Fix this by doing it once per tab right after it's created and before
any buffer is switched.

Cc: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: rework tab logic
Felipe Contreras [Wed, 10 Aug 2022 15:46:16 +0000 (10:46 -0500)] 
mergetools: vimdiff: rework tab logic

If we treat tabs especially, the logic becomes much simpler.

Cc: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: fix for diffopt
Felipe Contreras [Wed, 10 Aug 2022 15:46:15 +0000 (10:46 -0500)] 
mergetools: vimdiff: fix for diffopt

When diffopt has hiddenoff set and there's only one window (as is the
case in the single window mode) the diff mode is turned off.

We don't want that, so turn that option off.

Cc: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: silence annoying messages
Felipe Contreras [Wed, 10 Aug 2022 15:46:14 +0000 (10:46 -0500)] 
mergetools: vimdiff: silence annoying messages

When using the single window mode we are greeted with the following
warning:

  "./content_LOCAL_8975" 6L, 28B
  "./content_BASE_8975" 6 lines, 29 bytes
  "./content_REMOTE_8975" 6 lines, 29 bytes
  "content" 16 lines, 115 bytes
  Press ENTER or type command to continue

every time.

Silence that.

Suggested-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: make vimdiff3 actually work
Felipe Contreras [Wed, 10 Aug 2022 15:46:13 +0000 (10:46 -0500)] 
mergetools: vimdiff: make vimdiff3 actually work

When vimdiff3 was added in 7c147b77d3 (mergetools: add vimdiff3 mode,
2014-04-20), the description made clear the intention:

    It's similar to the default, except that the other windows are
    hidden.  This ensures that removed/added colors are still visible on
    the main merge window, but the other windows not visible.

However, in 0041797449 (vimdiff: new implementation with layout support,
2022-03-30) this was broken by generating a command that never creates
windows, and therefore vim never shows the diff.

The layout support implementation broke the whole purpose of vimdiff3,
and simply shows MERGED, which is no different from simply opening the
file with vim.

In order to show the diff, the windows need to be created first, and
then when they are hidden the diff remains (if hidenoff isn't set), but
by setting the `hidden` option the initial buffers are marked as hidden
thus making the feature work.

Suggested-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agomergetools: vimdiff: fix comment
Felipe Contreras [Wed, 10 Aug 2022 15:46:12 +0000 (10:46 -0500)] 
mergetools: vimdiff: fix comment

The name of the variable is wrong, and it can be set to anything, like
1.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Fernando Ramos <greenfoo@u92.eu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agodoc add: renormalize is not idempotent for CRCRLF
Philip Oakley [Wed, 10 Aug 2022 14:44:50 +0000 (15:44 +0100)] 
doc add: renormalize is not idempotent for CRCRLF

Bug report
 https://lore.kernel.org/git/AM0PR02MB56357CC96B702244F3271014E8DC9@AM0PR02MB5635.eurprd02.prod.outlook.com/
noted that a file containing /r/r/n needed renormalising twice.

This is by design. Lone CR characters, not paired with an LF, are left
unchanged. Note this limitation of the "clean" filter in the documentation.

Renormalize was introduced at 9472935d81e (add: introduce "--renormalize",
Torsten Bögershausen, 2017-11-16)

Signed-off-by: Philip Oakley <philipoakley@iee.email>
Reviewed-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agorm: integrate with sparse-index
Shaoxuan Yuan [Sun, 7 Aug 2022 04:13:35 +0000 (12:13 +0800)] 
rm: integrate with sparse-index

Enable the sparse index within the `git-rm` command.

The `p2000` tests demonstrate a ~92% execution time reduction for
'git rm' using a sparse index.

Test                              HEAD~1            HEAD
--------------------------------------------------------------------------
2000.74: git rm ... (full-v3)     0.41(0.37+0.05)   0.43(0.36+0.07) +4.9%
2000.75: git rm ... (full-v4)     0.38(0.34+0.05)   0.39(0.35+0.05) +2.6%
2000.76: git rm ... (sparse-v3)   0.57(0.56+0.01)   0.05(0.05+0.00) -91.2%
2000.77: git rm ... (sparse-v4)   0.57(0.55+0.02)   0.03(0.03+0.00) -94.7%

----
Also, normalize a behavioral difference of `git-rm` under sparse-index.
See related discussion [1].

`git-rm` a sparse-directory entry within a sparse-index enabled repo
behaves differently from a sparse directory within a sparse-checkout
enabled repo.

For example, in a sparse-index repo, where 'folder1' is a
sparse-directory entry, `git rm -r --sparse folder1` provides this:

        rm 'folder1/'

Whereas in a sparse-checkout repo *without* sparse-index, doing so
provides this:

        rm 'folder1/0/0/0'
        rm 'folder1/0/1'
        rm 'folder1/a'

Because `git rm` a sparse-directory entry does not need to expand the
index, therefore we should accept the current behavior, which is faster
than "expand the sparse-directory entry to match the sparse-checkout
situation".

Modify a previous test so such difference is not considered as an error.

[1] https://github.com/ffyuanda/git/pull/6#discussion_r934861398

Helped-by: Victoria Dye <vdye@github.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agorm: expand the index only when necessary
Shaoxuan Yuan [Sun, 7 Aug 2022 04:13:34 +0000 (12:13 +0800)] 
rm: expand the index only when necessary

Remove the `ensure_full_index()` method so `git-rm` does not always
expand the index when the expansion is unnecessary, i.e. when
<pathspec> does not have any possibilities to match anything outside
of sparse-checkout definition.

Expand the index when the <pathspec> needs an expanded index, i.e. the
<pathspec> contains wildcard that may need a full-index or the
<pathspec> is simply outside of sparse-checkout definition.

Notice that the test 'rm pathspec expands index when necessary' in
t1092 *is* testing this code change behavior, though it will be marked
as 'test_expect_success' only in the next patch, where we officially
mark `command_requires_full_index = 0`, so the index does not expand
unless we tell it to do so.

Notice that because we also want `ensure_full_index` to record the
stdout and stderr from Git command, a corresponding modification
is also included in this patch. The reason we want the "sparse-index-out"
and "sparse-index-err", is that we need to make sure there is no error
from Git command itself, so we can rely on the `test_region` result
and determine if the index is expanded or not.

Helped-by: Victoria Dye <vdye@github.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopathspec.h: move pathspec_needs_expanded_index() from reset.c to here
Shaoxuan Yuan [Sun, 7 Aug 2022 04:13:33 +0000 (12:13 +0800)] 
pathspec.h: move pathspec_needs_expanded_index() from reset.c to here

Method pathspec_needs_expanded_index() in reset.c from 4d1cfc1351
(reset: make --mixed sparse-aware, 2021-11-29) is reusable when we
need to verify if the index needs to be expanded when the command
is utilizing a pathspec rather than a literal path.

Move it to pathspec.h for reusability.

Add a few items to the function so it can better serve its purpose as
a standalone public function:

* Add a check in front so if the index is not sparse, return early since
  no expansion is needed.

* It now takes an arbitrary 'struct index_state' pointer instead of
  using `the_index` and `active_cache`.

* Add documentation to the function.

Helped-by: Victoria Dye <vdye@github.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agot1092: add tests for `git-rm`
Shaoxuan Yuan [Sun, 7 Aug 2022 04:13:32 +0000 (12:13 +0800)] 
t1092: add tests for `git-rm`

Add tests for `git-rm`, make sure it behaves as expected when
<pathspec> is both inside or outside of sparse-checkout definition.

Helped-by: Victoria Dye <vdye@github.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'vd/sparse-reset-checkout-fixes' into sy/sparse-rm
Junio C Hamano [Mon, 8 Aug 2022 20:23:06 +0000 (13:23 -0700)] 
Merge branch 'vd/sparse-reset-checkout-fixes' into sy/sparse-rm

* vd/sparse-reset-checkout-fixes:
  unpack-trees: unpack new trees as sparse directories
  cache.h: create 'index_name_pos_sparse()'
  oneway_diff: handle removed sparse directories
  checkout: fix nested sparse directory diff in sparse index

2 years agounpack-trees: unpack new trees as sparse directories
Victoria Dye [Mon, 8 Aug 2022 19:07:52 +0000 (19:07 +0000)] 
unpack-trees: unpack new trees as sparse directories

If 'unpack_single_entry()' is unpacking a new directory tree (that is, one
not already present in the index) into a sparse index, unpack the tree as a
sparse directory rather than traversing its contents and unpacking each file
individually. This helps keep the sparse index as collapsed as possible in
cases such as 'git reset --hard' restoring a outside-of-cone directory
removed with 'git rm -r --sparse'.

Without this patch, 'unpack_single_entry()' will only unpack a directory
into the index as a sparse directory (rather than traversing into it and
unpacking its files one-by-one) if an entry with the same name already
exists in the index. This patch allows sparse directory unpacking without a
matching index entry when the following conditions are met:

1. the directory's path is outside the sparse cone, and
2. there are no children of the directory in the index

If a directory meets these requirements (as determined by
'is_new_sparse_dir()'), 'unpack_single_entry()' unpacks the sparse directory
index entry and propagates the decision back up to 'unpack_callback()' to
prevent unnecessary tree traversal into the unpacked directory.

Reported-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocache.h: create 'index_name_pos_sparse()'
Victoria Dye [Mon, 8 Aug 2022 19:07:51 +0000 (19:07 +0000)] 
cache.h: create 'index_name_pos_sparse()'

Add 'index_name_pos_sparse()', which behaves the same as 'index_name_pos()',
except that it does not expand a sparse index to search for an entry inside
a sparse directory.

'index_entry_exists()' was originally implemented in 20ec2d034c (reset: make
sparse-aware (except --mixed), 2021-11-29) as an alternative to
'index_name_pos()' to allow callers to search for an index entry without
expanding a sparse index. However, that particular use case only required
knowing whether the requested entry existed, so 'index_entry_exists()' does
not return the index positioning information provided by 'index_name_pos()'.

This patch implements 'index_name_pos_sparse()' to accommodate callers that
need the positioning information of 'index_name_pos()', but do not want to
expand the index.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agooneway_diff: handle removed sparse directories
Victoria Dye [Mon, 8 Aug 2022 19:07:50 +0000 (19:07 +0000)] 
oneway_diff: handle removed sparse directories

Update 'do_oneway_diff()' to perform a 'diff_tree_oid()' on removed sparse
directories, as it does for added or modified sparse directories (see
9eb00af562 (diff-lib: handle index diffs with sparse dirs, 2021-07-14)).

At the moment, this update is unreachable code because 'unpack_trees()'
(currently the only way 'oneway_diff()' can be called, via 'diff_cache()')
will always traverse trees down to the individual removed files of a deleted
sparse directory. A subsequent patch will change this to better preserve a
sparse index in other uses of 'unpack_tree()', e.g. 'git reset --hard'.
However, making that change without this patch would result in (among other
issues) 'git status' printing only the name of a deleted sparse directory,
not its contents. To avoid introducing that bug, 'do_oneway_diff()' is
updated before modifying 'unpack_trees()'.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocheckout: fix nested sparse directory diff in sparse index
Victoria Dye [Mon, 8 Aug 2022 19:07:49 +0000 (19:07 +0000)] 
checkout: fix nested sparse directory diff in sparse index

Add the 'recursive' diff flag to the local changes reporting done by 'git
checkout' in 'show_local_changes()'. Without the flag enabled, unexpanded
sparse directories will not be recursed into to report the diff of each
file's contents, resulting in the reported local changes including
"modified" sparse directories.

The same issue was found and fixed for 'git status' in 2c521b0e49 (status:
fix nested sparse directory diff in sparse index, 2022-03-01)

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoThe eleventh batch
Junio C Hamano [Mon, 8 Aug 2022 19:57:28 +0000 (12:57 -0700)] 
The eleventh batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>