]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
23 months agoMerge branch 'jc/all-negative-pathspec'
Junio C Hamano [Tue, 7 Jun 2022 21:10:59 +0000 (14:10 -0700)] 
Merge branch 'jc/all-negative-pathspec'

A git subcommand like "git add -p" spawns a separate git process
while relaying its command line arguments.  A pathspec with only
negative elements was mistakenly passed with an empty string, which
has been corrected.

* jc/all-negative-pathspec:
  pathspec: correct an empty string used as a pathspec element

23 months agoMerge branch 'js/scalar-diagnose'
Junio C Hamano [Tue, 7 Jun 2022 21:10:57 +0000 (14:10 -0700)] 
Merge branch 'js/scalar-diagnose'

Implementation of "scalar diagnose" subcommand.

* js/scalar-diagnose:
  scalar: teach `diagnose` to gather loose objects information
  scalar: teach `diagnose` to gather packfile info
  scalar diagnose: include disk space information
  scalar: implement `scalar diagnose`
  scalar: validate the optional enlistment argument
  archive --add-virtual-file: allow paths containing colons
  archive: optionally add "virtual" files

23 months agoMerge branch 'rs/document-archive-prefix'
Junio C Hamano [Tue, 7 Jun 2022 21:10:57 +0000 (14:10 -0700)] 
Merge branch 'rs/document-archive-prefix'

The documentation on the interaction between "--add-file" and
"--prefix" options of "git archive" has been improved.

* rs/document-archive-prefix:
  archive: improve documentation of --prefix

23 months agoMerge branch 'fh/transport-push-leakfix'
Junio C Hamano [Tue, 7 Jun 2022 21:10:57 +0000 (14:10 -0700)] 
Merge branch 'fh/transport-push-leakfix'

Leakfix.

* fh/transport-push-leakfix:
  transport: free local and remote refs in transport_push()
  transport: unify return values and exit point from transport_push()
  transport: remove unnecessary indenting in transport_push()

23 months agoMerge branch 'js/ci-github-workflow-markup'
Junio C Hamano [Tue, 7 Jun 2022 21:10:57 +0000 (14:10 -0700)] 
Merge branch 'js/ci-github-workflow-markup'

Update the GitHub workflow support to make it quicker to get to the
failing test.

* js/ci-github-workflow-markup:
  ci: call `finalize_test_case_output` a little later
  ci(github): mention where the full logs can be found
  ci: use `--github-workflow-markup` in the GitHub workflow
  ci(github): avoid printing test case preamble twice
  ci(github): skip the logs of the successful test cases
  ci: optionally mark up output in the GitHub workflow
  ci/run-build-and-tests: add some structure to the GitHub workflow output
  ci: make it easier to find failed tests' logs in the GitHub workflow
  ci/run-build-and-tests: take a more high-level view
  test(junit): avoid line feeds in XML attributes
  tests: refactor --write-junit-xml code
  ci: fix code style

23 months agoMerge branch 'ab/plug-leak-in-revisions'
Junio C Hamano [Tue, 7 Jun 2022 21:10:56 +0000 (14:10 -0700)] 
Merge branch 'ab/plug-leak-in-revisions'

Plug the memory leaks from the trickiest API of all, the revision
walker.

* ab/plug-leak-in-revisions: (27 commits)
  revisions API: add a TODO for diff_free(&revs->diffopt)
  revisions API: have release_revisions() release "topo_walk_info"
  revisions API: have release_revisions() release "date_mode"
  revisions API: call diff_free(&revs->pruning) in revisions_release()
  revisions API: release "reflog_info" in release revisions()
  revisions API: clear "boundary_commits" in release_revisions()
  revisions API: have release_revisions() release "prune_data"
  revisions API: have release_revisions() release "grep_filter"
  revisions API: have release_revisions() release "filter"
  revisions API: have release_revisions() release "cmdline"
  revisions API: have release_revisions() release "mailmap"
  revisions API: have release_revisions() release "commits"
  revisions API users: use release_revisions() for "prune_data" users
  revisions API users: use release_revisions() with UNLEAK()
  revisions API users: use release_revisions() in builtin/log.c
  revisions API users: use release_revisions() in http-push.c
  revisions API users: add "goto cleanup" for release_revisions()
  stash: always have the owner of "stash_info" free it
  revisions API users: use release_revisions() needing REV_INFO_INIT
  revision.[ch]: document and move code declared around "init"
  ...

23 months agoMerge branch 'yw/cmake-updates'
Junio C Hamano [Tue, 7 Jun 2022 21:10:56 +0000 (14:10 -0700)] 
Merge branch 'yw/cmake-updates'

CMake updates.

* yw/cmake-updates:
  cmake: remove (_)UNICODE def on Windows in CMakeLists.txt
  cmake: add pcre2 support
  cmake: fix CMakeLists.txt on Linux

2 years agoSeventh batch
Junio C Hamano [Fri, 3 Jun 2022 21:30:45 +0000 (14:30 -0700)] 
Seventh batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'tb/cruft-packs'
Junio C Hamano [Fri, 3 Jun 2022 21:30:37 +0000 (14:30 -0700)] 
Merge branch 'tb/cruft-packs'

A mechanism to pack unreachable objects into a "cruft pack",
instead of ejecting them into loose form to be reclaimed later, has
been introduced.

* tb/cruft-packs:
  sha1-file.c: don't freshen cruft packs
  builtin/gc.c: conditionally avoid pruning objects via loose
  builtin/repack.c: add cruft packs to MIDX during geometric repack
  builtin/repack.c: use named flags for existing_packs
  builtin/repack.c: allow configuring cruft pack generation
  builtin/repack.c: support generating a cruft pack
  builtin/pack-objects.c: --cruft with expiration
  reachable: report precise timestamps from objects in cruft packs
  reachable: add options to add_unseen_recent_objects_to_traversal
  builtin/pack-objects.c: --cruft without expiration
  builtin/pack-objects.c: return from create_object_entry()
  t/helper: add 'pack-mtimes' test-tool
  pack-mtimes: support writing pack .mtimes files
  chunk-format.h: extract oid_version()
  pack-write: pass 'struct packing_data' to 'stage_tmp_packfiles'
  pack-mtimes: support reading .mtimes files
  Documentation/technical: add cruft-packs.txt

2 years agoMerge branch 'kl/setup-in-unreadable-worktree'
Junio C Hamano [Fri, 3 Jun 2022 21:30:36 +0000 (14:30 -0700)] 
Merge branch 'kl/setup-in-unreadable-worktree'

Disable the "do not remove the directory the user started Git in"
logic when Git cannot tell where that directory is.  Earlier we
refused to run in such a case.

* kl/setup-in-unreadable-worktree:
  setup: don't die if realpath(3) fails on getcwd(3)

2 years agoMerge branch 'jx/l10n-workflow-change'
Junio C Hamano [Fri, 3 Jun 2022 21:30:36 +0000 (14:30 -0700)] 
Merge branch 'jx/l10n-workflow-change'

A workflow change for translators are being proposed.

* jx/l10n-workflow-change:
  l10n: Document the new l10n workflow
  Makefile: add "po-init" rule to initialize po/XX.po
  Makefile: add "po-update" rule to update po/XX.po
  po/git.pot: don't check in result of "make pot"
  po/git.pot: this is now a generated file
  Makefile: remove duplicate and unwanted files in FOUND_SOURCE_FILES
  i18n CI: stop allowing non-ASCII source messages in po/git.pot
  Makefile: have "make pot" not "reset --hard"
  Makefile: generate "po/git.pot" from stable LOCALIZED_C
  Makefile: sort source files before feeding to xgettext

2 years agoMerge branch 'tb/geom-repack-with-keep-and-max'
Junio C Hamano [Fri, 3 Jun 2022 21:30:36 +0000 (14:30 -0700)] 
Merge branch 'tb/geom-repack-with-keep-and-max'

Teach "git repack --geometric" work better with "--keep-pack" and
avoid corrupting the repository when packsize limit is used.

* tb/geom-repack-with-keep-and-max:
  builtin/repack.c: ensure that `names` is sorted
  t7703: demonstrate object corruption with pack.packSizeLimit
  repack: respect --keep-pack with geometric repack

2 years agoMerge branch 'ds/sparse-sparse-checkout'
Junio C Hamano [Fri, 3 Jun 2022 21:30:35 +0000 (14:30 -0700)] 
Merge branch 'ds/sparse-sparse-checkout'

"sparse-checkout" learns to work well with the sparse-index
feature.

* ds/sparse-sparse-checkout:
  sparse-checkout: integrate with sparse index
  p2000: add test for 'git sparse-checkout [add|set]'
  sparse-index: complete partial expansion
  sparse-index: partially expand directories
  sparse-checkout: --no-sparse-index needs a full index
  cache-tree: implement cache_tree_find_path()
  sparse-index: introduce partially-sparse indexes
  sparse-index: create expand_index()
  t1092: stress test 'git sparse-checkout set'
  t1092: refactor 'sparse-index contents' test

2 years agoMerge branch 'tb/midx-race-in-pack-objects'
Junio C Hamano [Fri, 3 Jun 2022 21:30:35 +0000 (14:30 -0700)] 
Merge branch 'tb/midx-race-in-pack-objects'

The multi-pack-index code did not protect the packfile it is going
to depend on from getting removed while in use, which has been
corrected.

* tb/midx-race-in-pack-objects:
  builtin/pack-objects.c: ensure pack validity from MIDX bitmap objects
  builtin/pack-objects.c: ensure included `--stdin-packs` exist
  builtin/pack-objects.c: avoid redundant NULL check
  pack-bitmap.c: check preferred pack validity when opening MIDX bitmap

2 years agoMerge branch 'ds/object-file-unpack-loose-header-fix'
Junio C Hamano [Fri, 3 Jun 2022 21:30:35 +0000 (14:30 -0700)] 
Merge branch 'ds/object-file-unpack-loose-header-fix'

Coding style fix.

* ds/object-file-unpack-loose-header-fix:
  object-file: convert 'switch' back to 'if'

2 years agoMerge branch 'pb/use-freebsd-12.3-in-cirrus-ci'
Junio C Hamano [Fri, 3 Jun 2022 21:30:34 +0000 (14:30 -0700)] 
Merge branch 'pb/use-freebsd-12.3-in-cirrus-ci'

Update the version of FreeBSD image used in Cirrus CI.

* pb/use-freebsd-12.3-in-cirrus-ci:
  ci: update Cirrus-CI image to FreeBSD 12.3

2 years agoMerge branch 'ds/bundle-uri'
Junio C Hamano [Fri, 3 Jun 2022 21:30:34 +0000 (14:30 -0700)] 
Merge branch 'ds/bundle-uri'

Preliminary code refactoring around transport and bundle code.

* ds/bundle-uri:
  bundle.h: make "fd" version of read_bundle_header() public
  remote: allow relative_url() to return an absolute url
  remote: move relative_url()
  http: make http_get_file() external
  fetch-pack: move --keep=* option filling to a function
  fetch-pack: add a deref_without_lazy_fetch_extended()
  dir API: add a generalized path_match_flags() function
  connect.c: refactor sending of agent & object-format

2 years agoMerge branch 'ns/batch-fsync'
Junio C Hamano [Fri, 3 Jun 2022 21:30:34 +0000 (14:30 -0700)] 
Merge branch 'ns/batch-fsync'

Introduce a filesystem-dependent mechanism to optimize the way the
bits for many loose object files are ensured to hit the disk
platter.

* ns/batch-fsync:
  core.fsyncmethod: performance tests for batch mode
  t/perf: add iteration setup mechanism to perf-lib
  core.fsyncmethod: tests for batch mode
  test-lib-functions: add parsing helpers for ls-files and ls-tree
  core.fsync: use batch mode and sync loose objects by default on Windows
  unpack-objects: use the bulk-checkin infrastructure
  update-index: use the bulk-checkin infrastructure
  builtin/add: add ODB transaction around add_files_to_cache
  cache-tree: use ODB transaction around writing a tree
  core.fsyncmethod: batched disk flushes for loose-objects
  bulk-checkin: rebrand plug/unplug APIs as 'odb transactions'
  bulk-checkin: rename 'state' variable and separate 'plugged' boolean

2 years agoMerge branch 'en/sparse-cone-becomes-default'
Junio C Hamano [Fri, 3 Jun 2022 21:30:33 +0000 (14:30 -0700)] 
Merge branch 'en/sparse-cone-becomes-default'

Deprecate non-cone mode of the sparse-checkout feature.

* en/sparse-cone-becomes-default:
  Documentation: some sparsity wording clarifications
  git-sparse-checkout.txt: mark non-cone mode as deprecated
  git-sparse-checkout.txt: flesh out pattern set sections a bit
  git-sparse-checkout.txt: add a new EXAMPLES section
  git-sparse-checkout.txt: shuffle some sections and mark as internal
  git-sparse-checkout.txt: update docs for deprecation of 'init'
  git-sparse-checkout.txt: wording updates for the cone mode default
  sparse-checkout: make --cone the default
  tests: stop assuming --no-cone is the default mode for sparse-checkout

2 years agoSixth batch
Junio C Hamano [Wed, 1 Jun 2022 02:10:00 +0000 (19:10 -0700)] 
Sixth batch

Fast-tracking GitHub CI Windows build fixes.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'jc/http-clear-finished-pointer'
Junio C Hamano [Wed, 1 Jun 2022 02:10:35 +0000 (19:10 -0700)] 
Merge branch 'jc/http-clear-finished-pointer'

Meant to go with js/ci-gcc-12-fixes.

* jc/http-clear-finished-pointer:
  http.c: clear the 'finished' member once we are done with it

2 years agoMerge branch 'js/ci-gcc-12-fixes'
Junio C Hamano [Wed, 1 Jun 2022 02:10:35 +0000 (19:10 -0700)] 
Merge branch 'js/ci-gcc-12-fixes'

Fixes real problems noticed by gcc 12 and works around false
positives.

* js/ci-gcc-12-fixes:
  dir.c: avoid "exceeds maximum object size" error with GCC v12.x
  nedmalloc: avoid new compile error
  compat/win32/syslog: fix use-after-realloc

2 years agoFifth batch
Junio C Hamano [Tue, 31 May 2022 06:24:12 +0000 (23:24 -0700)] 
Fifth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'js/use-builtin-add-i'
Junio C Hamano [Tue, 31 May 2022 06:24:03 +0000 (23:24 -0700)] 
Merge branch 'js/use-builtin-add-i'

"git add -i" was rewritten in C some time ago and has been in
testing; the reimplementation is now exposed to general public by
default.

* js/use-builtin-add-i:
  add -i: default to the built-in implementation
  t2016: require the PERL prereq only when necessary

2 years agoMerge branch 'jc/t6424-failing-merge-preserve-local-changes'
Junio C Hamano [Tue, 31 May 2022 06:24:03 +0000 (23:24 -0700)] 
Merge branch 'jc/t6424-failing-merge-preserve-local-changes'

The tests that ensured merges stop when interfering local changes
are present did not make sure that local changes are preserved; now
they do.

* jc/t6424-failing-merge-preserve-local-changes:
  t6424: make sure a failed merge preserves local changes

2 years agoMerge branch 'cc/http-curlopt-resolve'
Junio C Hamano [Tue, 31 May 2022 06:24:02 +0000 (23:24 -0700)] 
Merge branch 'cc/http-curlopt-resolve'

With the new http.curloptResolve configuration, the CURLOPT_RESOLVE
mechanism that allows cURL based applications to use pre-resolved
IP addresses for the requests is exposed to the scripts.

* cc/http-curlopt-resolve:
  http: add custom hostname to IP address resolutions

2 years agoscalar: teach `diagnose` to gather loose objects information
Matthew John Cheetham [Sat, 28 May 2022 23:11:18 +0000 (16:11 -0700)] 
scalar: teach `diagnose` to gather loose objects information

When operating at the scale that Scalar wants to support, certain data
shapes are more likely to cause undesirable performance issues, such as
large numbers of loose objects.

By including statistics about this, `scalar diagnose` now makes it
easier to identify such scenarios.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar: teach `diagnose` to gather packfile info
Matthew John Cheetham [Sat, 28 May 2022 23:11:17 +0000 (16:11 -0700)] 
scalar: teach `diagnose` to gather packfile info

It's helpful to see if there are other crud files in the pack
directory. Let's teach the `scalar diagnose` command to gather
file size information about pack files.

While at it, also enumerate the pack files in the alternate
object directories, if any are registered.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar diagnose: include disk space information
Johannes Schindelin [Sat, 28 May 2022 23:11:16 +0000 (16:11 -0700)] 
scalar diagnose: include disk space information

When analyzing problems with large worktrees/repositories, it is useful
to know how close to a "full disk" situation Scalar/Git operates. Let's
include this information.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar: implement `scalar diagnose`
Johannes Schindelin [Sat, 28 May 2022 23:11:15 +0000 (16:11 -0700)] 
scalar: implement `scalar diagnose`

Over the course of Scalar's development, it became obvious that there is
a need for a command that can gather all kinds of useful information
that can help identify the most typical problems with large
worktrees/repositories.

The `diagnose` command is the culmination of this hard-won knowledge: it
gathers the installed hooks, the config, a couple statistics describing
the data shape, among other pieces of information, and then wraps
everything up in a tidy, neat `.zip` archive.

Note: originally, Scalar was implemented in C# using the .NET API, where
we had the luxury of a comprehensive standard library that includes
basic functionality such as writing a `.zip` file. In the C version, we
lack such a commodity. Rather than introducing a dependency on, say,
libzip, we slightly abuse Git's `archive` machinery: we write out a
`.zip` of the empty try, augmented by a couple files that are added via
the `--add-file*` options. We are careful trying not to modify the
current repository in any way lest the very circumstances that required
`scalar diagnose` to be run are changed by the `diagnose` run itself.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoscalar: validate the optional enlistment argument
Johannes Schindelin [Sat, 28 May 2022 23:11:14 +0000 (16:11 -0700)] 
scalar: validate the optional enlistment argument

The `scalar` command needs a Scalar enlistment for many subcommands, and
looks in the current directory for such an enlistment (traversing the
parent directories until it finds one).

These is subcommands can also be called with an optional argument
specifying the enlistment. Here, too, we traverse parent directories as
needed, until we find an enlistment.

However, if the specified directory does not even exist, or is not a
directory, we should stop right there, with an error message.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoarchive --add-virtual-file: allow paths containing colons
Johannes Schindelin [Sat, 28 May 2022 23:11:13 +0000 (16:11 -0700)] 
archive --add-virtual-file: allow paths containing colons

By allowing the path to be enclosed in double-quotes, we can avoid
the limitation that paths cannot contain colons.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoarchive: optionally add "virtual" files
Johannes Schindelin [Sat, 28 May 2022 23:11:12 +0000 (16:11 -0700)] 
archive: optionally add "virtual" files

With the `--add-virtual-file=<path>:<content>` option, `git archive` now
supports use cases where relatively trivial files need to be added that
do not exist on disk.

This will allow us to generate `.zip` files with generated content,
without having to add said content to the object database and without
having to write it out to disk.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
[jc: tweaked <path> handling]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopathspec: correct an empty string used as a pathspec element
Junio C Hamano [Sun, 29 May 2022 22:39:51 +0000 (15:39 -0700)] 
pathspec: correct an empty string used as a pathspec element

Pathspecs with only negative elements did not work with some
commands that pass the pathspec along to a subprocess.  For
instance,

    $ git add -p -- ':!*.txt'

should add everything except for paths ending in ".txt", but it gets
complaint from underlying "diff-index" and aborts.

We used to error out when a pathspec with only negative elements in
it, like the one in the above example.  Later, 859b7f1d (pathspec:
don't error out on all-exclusionary pathspec patterns, 2017-02-07)
updated the logic to add an empty string as an extra element.  The
intention was to let the extra element to match everything and let
the negative ones given by the user to subtract from it.

At around the same time, we were migrating from "an empty string is
a valid pathspec element that matches everything" to "either a dot
or ":/" is used to match all, and an empty string is rejected",
between d426430e (pathspec: warn on empty strings as pathspec,
2016-06-22) and 9e4e8a64 (pathspec: die on empty strings as
pathspec, 2017-06-06).  I think 9e4e8a64, which happened long after
859b7f1d happened, was not careful enough to turn the empty string
859b7f1d added to either a dot or ":/".

A care should be taken as the definition of "everything" depends on
subcommand.  For the purpose of "add -p", adding a "." to add
everything in the current directory is the right thing to do.  But
for some other commands, ":/" (i.e. really really everything, even
things outside the current subdirectory) is the right choice.

We would break commands in a big way if we get this wrong, so add a
handful of test pieces to make sure the resulting code still
excludes the paths that are expected and includes "everything" else.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'rs/document-archive-prefix' into js/scalar-diagnose
Junio C Hamano [Sat, 28 May 2022 17:38:06 +0000 (10:38 -0700)] 
Merge branch 'rs/document-archive-prefix' into js/scalar-diagnose

* rs/document-archive-prefix:
  archive: improve documentation of --prefix

2 years agoarchive: improve documentation of --prefix
René Scharfe [Sat, 28 May 2022 06:57:46 +0000 (08:57 +0200)] 
archive: improve documentation of --prefix

Document the interaction between --add-file and --prefix by giving an
example.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agohttp.c: clear the 'finished' member once we are done with it
Junio C Hamano [Thu, 26 May 2022 19:37:31 +0000 (12:37 -0700)] 
http.c: clear the 'finished' member once we are done with it

In http.c, the run_active_slot() function allows the given "slot" to
make progress by calling step_active_slots() in a loop repeatedly,
and the loop is not left until the request held in the slot
completes.

Ages ago, we used to use the slot->in_use member to get out of the
loop, which misbehaved when the request in "slot" completes (at
which time, the result of the request is copied away from the slot,
and the in_use member is cleared, making the slot ready to be
reused), and the "slot" gets reused to service a different request
(at which time, the "slot" becomes in_use again, even though it is
for a different request).  The loop terminating condition mistakenly
thought that the original request has yet to be completed.

Today's code, after baa7b67d (HTTP slot reuse fixes, 2006-03-10)
fixed this issue, uses a separate "slot->finished" member that is
set in run_active_slot() to point to an on-stack variable, and the
code that completes the request in finish_active_slot() clears the
on-stack variable via the pointer to signal that the particular
request held by the slot has completed.  It also clears the in_use
member (as before that fix), so that the slot itself can safely be
reused for an unrelated request.

One thing that is not quite clean in this arrangement is that,
unless the slot gets reused, at which point the finished member is
reset to NULL, the member keeps the value of &finished, which
becomes a dangling pointer into the stack when run_active_slot()
returns.  Clear the finished member before the control leaves the
function, which has a side effect of unconfusing compilers like
recent GCC 12 that is over-eager to warn against such an assignment.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agotransport: free local and remote refs in transport_push()
Frantisek Hrbata [Fri, 20 May 2022 12:49:52 +0000 (14:49 +0200)] 
transport: free local and remote refs in transport_push()

Fix memory leaks in transport_push(), where remote_refs and local_refs
are never freed.

116 bytes in 1 blocks are definitely lost in loss record 56 of 103
   at 0x484486F: malloc (vg_replace_malloc.c:381)
   by 0x4938D7E: strdup (strdup.c:42)
   by 0x628418: xstrdup (wrapper.c:39)
   by 0x4FD454: process_capabilities (connect.c:232)
   by 0x4FD454: get_remote_heads (connect.c:354)
   by 0x610A38: handshake (transport.c:333)
   by 0x612B02: transport_push (transport.c:1302)
   by 0x4803D6: push_with_options (push.c:357)
   by 0x4811D6: do_push (push.c:414)
   by 0x4811D6: cmd_push (push.c:650)
   by 0x405210: run_builtin (git.c:465)
   by 0x405210: handle_builtin (git.c:719)
   by 0x406363: run_argv (git.c:786)
   by 0x406363: cmd_main (git.c:917)
   by 0x404F17: main (common-main.c:56)

5,912 (388 direct, 5,524 indirect) bytes in 2 blocks are definitely lost in loss record 98 of 103
   at 0x4849464: calloc (vg_replace_malloc.c:1328)
   by 0x628705: xcalloc (wrapper.c:150)
   by 0x5C216D: alloc_ref_with_prefix (remote.c:975)
   by 0x5C232A: alloc_ref (remote.c:983)
   by 0x5C232A: one_local_ref (remote.c:2299)
   by 0x5C232A: one_local_ref (remote.c:2289)
   by 0x5BDB03: do_for_each_repo_ref_iterator (iterator.c:418)
   by 0x5B4C4F: do_for_each_ref (refs.c:1486)
   by 0x5B4C4F: refs_for_each_ref (refs.c:1492)
   by 0x5B4C4F: for_each_ref (refs.c:1497)
   by 0x5C6ADF: get_local_heads (remote.c:2310)
   by 0x612A85: transport_push (transport.c:1286)
   by 0x4803D6: push_with_options (push.c:357)
   by 0x4811D6: do_push (push.c:414)
   by 0x4811D6: cmd_push (push.c:650)
   by 0x405210: run_builtin (git.c:465)
   by 0x405210: handle_builtin (git.c:719)
   by 0x406363: run_argv (git.c:786)
   by 0x406363: cmd_main (git.c:917)

Signed-off-by: Frantisek Hrbata <frantisek@hrbata.com>
Reviewed-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agotransport: unify return values and exit point from transport_push()
Frantisek Hrbata [Fri, 20 May 2022 12:49:51 +0000 (14:49 +0200)] 
transport: unify return values and exit point from transport_push()

It seems there is no reason to return 1 instead of -1 when push_refs()
is not set in transport vtable. Let's unify the error return values and
use the done label as a single exit point from transport_push().

Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Frantisek Hrbata <frantisek@hrbata.com>
Reviewed-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agotransport: remove unnecessary indenting in transport_push()
Frantisek Hrbata [Fri, 20 May 2022 12:49:50 +0000 (14:49 +0200)] 
transport: remove unnecessary indenting in transport_push()

Remove the big indented block for transport_push() check in transport vtable
and let's just return error immediately. Hopefully this makes the code
more readable.

Signed-off-by: Frantisek Hrbata <frantisek@hrbata.com>
Reviewed-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agosha1-file.c: don't freshen cruft packs
Taylor Blau [Fri, 20 May 2022 23:18:17 +0000 (19:18 -0400)] 
sha1-file.c: don't freshen cruft packs

We don't bother to freshen objects stored in a cruft pack individually
by updating the `.mtimes` file. This is because we can't portably `mmap`
and write into the middle of a file (i.e., to update the mtime of just
one object). Instead, we would have to rewrite the entire `.mtimes` file
which may incur some wasted effort especially if there a lot of cruft
objects and they are freshened infrequently.

Instead, force the freshening code to avoid an optimizing write by
writing out the object loose and letting it pick up a current mtime.

This works because we prefer the mtime of the loose copy of an object
when both a loose and packed one exist (whether or not the packed copy
comes from a cruft pack or not).

This could certainly do with a test and/or be included earlier in this
series/PR, but I want to wait until after I have a chance to clean up
the overly-repetitive nature of the cruft pack tests in general.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/gc.c: conditionally avoid pruning objects via loose
Taylor Blau [Fri, 20 May 2022 23:18:14 +0000 (19:18 -0400)] 
builtin/gc.c: conditionally avoid pruning objects via loose

Expose the new `git repack --cruft` mode from `git gc` via a new opt-in
flag. When invoked like `git gc --cruft`, `git gc` will avoid exploding
unreachable objects as loose ones, and instead create a cruft pack and
`.mtimes` file.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/repack.c: add cruft packs to MIDX during geometric repack
Taylor Blau [Fri, 20 May 2022 23:18:11 +0000 (19:18 -0400)] 
builtin/repack.c: add cruft packs to MIDX during geometric repack

When using cruft packs, the following race can occur when a geometric
repack that writes a MIDX bitmap takes place afterwords:

  - First, create an unreachable object and do an all-into-one cruft
    repack which stores that object in the repository's cruft pack.
  - Then make that object reachable.
  - Finally, do a geometric repack and write a MIDX bitmap.

Assuming that we are sufficiently unlucky as to select a commit from the
MIDX which reaches that object for bitmapping, then the `git
multi-pack-index` process will complain that that object is missing.

The reason is because we don't include cruft packs in the MIDX when
doing a geometric repack. Since the "make that object reachable" doesn't
necessarily mean that we'll create a new copy of that object in one of
the packs that will get rolled up as part of a geometric repack, it's
possible that the MIDX won't see any copies of that now-reachable
object.

Of course, it's desirable to avoid including cruft packs in the MIDX
because it causes the MIDX to store a bunch of objects which are likely
to get thrown away. But excluding that pack does open us up to the above
race.

This patch demonstrates the bug, and resolves it by including cruft
packs in the MIDX even when doing a geometric repack.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/repack.c: use named flags for existing_packs
Taylor Blau [Fri, 20 May 2022 23:18:08 +0000 (19:18 -0400)] 
builtin/repack.c: use named flags for existing_packs

We use the `util` pointer for items in the `existing_packs` string list
to indicate which packs are going to be deleted. Since that has so far
been the only use of that `util` pointer, we just set it to 0 or 1.

But we're going to add an additional state to this field in the next
patch, so prepare for that by adding a #define for the first bit so we
can more expressively inspect the flags state.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/repack.c: allow configuring cruft pack generation
Taylor Blau [Fri, 20 May 2022 23:18:06 +0000 (19:18 -0400)] 
builtin/repack.c: allow configuring cruft pack generation

In servers which set the pack.window configuration to a large value, we
can wind up spending quite a lot of time finding new bases when breaking
delta chains between reachable and unreachable objects while generating
a cruft pack.

Introduce a handful of `repack.cruft*` configuration variables to
control the parameters used by pack-objects when generating a cruft
pack.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/repack.c: support generating a cruft pack
Taylor Blau [Fri, 20 May 2022 23:18:03 +0000 (19:18 -0400)] 
builtin/repack.c: support generating a cruft pack

Expose a way to split the contents of a repository into a main and cruft
pack when doing an all-into-one repack with `git repack --cruft -d`, and
a complementary configuration variable.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/pack-objects.c: --cruft with expiration
Taylor Blau [Fri, 20 May 2022 23:18:00 +0000 (19:18 -0400)] 
builtin/pack-objects.c: --cruft with expiration

In a previous patch, pack-objects learned how to generate a cruft pack
so long as no objects are dropped.

This patch teaches pack-objects to handle the case where a non-never
`--cruft-expiration` value is passed. This case is slightly more
complicated than before, because we want pack-objects to save
unreachable objects which would have been pruned when there is another
recent (i.e., non-prunable) unreachable object which reaches the other.
We'll call these objects "unreachable but reachable-from-recent".

Here is how pack-objects handles `--cruft-expiration`:

  - Instead of adding all objects outside of the kept pack(s) into the
    packing list, only handle the ones whose mtime is within the grace
    period.

  - Construct a reachability traversal whose tips are the
    unreachable-but-recent objects.

  - Then, walk along that traversal, stopping if we reach an object in
    the kept pack. At each step along the traversal, we add the object
    we are visiting to the packing list.

In the majority of these cases, any object we visit in this traversal
will already be in our packing list. But we will sometimes encounter
reachable-from-recent cruft objects, which we want to retain even if
they aged out of the grace period.

The most subtle point of this process is that we actually don't need to
bother to update the rescued object's mtime. Even though we will write
an .mtimes file with a value that is older than the expiration window,
it will continue to survive cruft repacks so long as any objects which
reach it haven't aged out.

That is, a future repack will also exclude that object from the initial
packing list, only to discover it later on when doing the reachability
traversal.

Finally, stopping early once an object is found in a kept pack is safe
to do because the kept packs ordinarily represent which packs will
survive after repacking. Assuming that it _isn't_ safe to halt a
traversal early would mean that there is some ancestor object which is
missing, which implies repository corruption (i.e., the complete set of
reachable objects isn't present).

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoreachable: report precise timestamps from objects in cruft packs
Taylor Blau [Fri, 20 May 2022 23:17:57 +0000 (19:17 -0400)] 
reachable: report precise timestamps from objects in cruft packs

When generating a cruft pack, the caller within pack-objects will want
to know the precise timestamps of cruft objects (i.e., their
corresponding values in the .mtimes table) rather than the mtime of the
cruft pack itself.

Teach add_recent_packed() to lookup each object's precise mtime from the
.mtimes file if one exists (indicated by the is_cruft bit on the
packed_git structure).

A couple of small things worth noting here:

  - load_pack_mtimes() needs to be called before asking for
    nth_packed_mtime(), and that call is done lazily here. That function
    exits early if the .mtimes file has already been opened and parsed,
    so only the first call is slow.

  - Checking the is_cruft bit can be done without any extra work on the
    caller's behalf, since it is set up for us automatically as a
    side-effect of calling add_packed_git() (just like the 'pack_keep'
    and 'pack_promisor' bits).

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoreachable: add options to add_unseen_recent_objects_to_traversal
Taylor Blau [Fri, 20 May 2022 23:17:54 +0000 (19:17 -0400)] 
reachable: add options to add_unseen_recent_objects_to_traversal

This function behaves very similarly to what we will need in
pack-objects in order to implement cruft packs with expiration. But it
is lacking a couple of things. Namely, it needs:

  - a mechanism to communicate the timestamps of individual recent
    objects to some external caller

  - and, in the case of packed objects, our future caller will also want
    to know the originating pack, as well as the offset within that pack
    at which the object can be found

  - finally, it needs a way to skip over packs which are marked as kept
    in-core.

To address the first two, add a callback interface in this patch which
reports the time of each recent object, as well as a (packed_git,
off_t) pair for packed objects.

Likewise, add a new option to the packed object iterators to skip over
packs which are marked as kept in core. This option will become
implicitly tested in a future patch.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/pack-objects.c: --cruft without expiration
Taylor Blau [Fri, 20 May 2022 23:17:52 +0000 (19:17 -0400)] 
builtin/pack-objects.c: --cruft without expiration

Teach `pack-objects` how to generate a cruft pack when no objects are
dropped (i.e., `--cruft-expiration=never`). Later patches will teach
`pack-objects` how to generate a cruft pack that prunes objects.

When generating a cruft pack which does not prune objects, we want to
collect all unreachable objects into a single pack (noting and updating
their mtimes as we accumulate them). Ordinary use will pass the result
of a `git repack -A` as a kept pack, so when this patch says "kept
pack", readers should think "reachable objects".

Generating a non-expiring cruft packs works as follows:

  - Callers provide a list of every pack they know about, and indicate
    which packs are about to be removed.

  - All packs which are going to be removed (we'll call these the
    redundant ones) are marked as kept in-core.

    Any packs the caller did not mention (but are known to the
    `pack-objects` process) are also marked as kept in-core. Packs not
    mentioned by the caller are assumed to be unknown to them, i.e.,
    they entered the repository after the caller decided which packs
    should be kept and which should be discarded.

    Since we do not want to include objects in these "unknown" packs
    (because we don't know which of their objects are or aren't
    reachable), these are also marked as kept in-core.

  - Then, we enumerate all objects in the repository, and add them to
    our packing list if they do not appear in an in-core kept pack.

This results in a new cruft pack which contains all known objects that
aren't included in the kept packs. When the kept pack is the result of
`git repack -A`, the resulting pack contains all unreachable objects.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/pack-objects.c: return from create_object_entry()
Taylor Blau [Fri, 20 May 2022 23:17:49 +0000 (19:17 -0400)] 
builtin/pack-objects.c: return from create_object_entry()

A new caller in the next commit will want to immediately modify the
object_entry structure created by create_object_entry(). Instead of
forcing that caller to wastefully look-up the entry we just created,
return it from create_object_entry() instead.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agot/helper: add 'pack-mtimes' test-tool
Taylor Blau [Fri, 20 May 2022 23:17:46 +0000 (19:17 -0400)] 
t/helper: add 'pack-mtimes' test-tool

In the next patch, we will implement and test support for writing a
cruft pack via a special mode of `git pack-objects`. To make sure that
objects are written with the correct timestamps, and a new test-tool
that can dump the object names and corresponding timestamps from a given
`.mtimes` file.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopack-mtimes: support writing pack .mtimes files
Taylor Blau [Fri, 20 May 2022 23:17:43 +0000 (19:17 -0400)] 
pack-mtimes: support writing pack .mtimes files

Now that the `.mtimes` format is defined, supplement the pack-write API
to be able to conditionally write an `.mtimes` file along with a pack by
setting an additional flag and passing an oidmap that contains the
timestamps corresponding to each object in the pack.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agochunk-format.h: extract oid_version()
Taylor Blau [Fri, 20 May 2022 23:17:41 +0000 (19:17 -0400)] 
chunk-format.h: extract oid_version()

There are three definitions of an identical function which converts
`the_hash_algo` into either 1 (for SHA-1) or 2 (for SHA-256). There is a
copy of this function for writing both the commit-graph and
multi-pack-index file, and another inline definition used to write the
.rev header.

Consolidate these into a single definition in chunk-format.h. It's not
clear that this is the best header to define this function in, but it
should do for now.

(Worth noting, the .rev caller expects a 4-byte unsigned, but the other
two callers work with a single unsigned byte. The consolidated version
uses the latter type, and lets the compiler widen it when required).

Another caller will be added in a subsequent patch.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopack-write: pass 'struct packing_data' to 'stage_tmp_packfiles'
Taylor Blau [Fri, 20 May 2022 23:17:38 +0000 (19:17 -0400)] 
pack-write: pass 'struct packing_data' to 'stage_tmp_packfiles'

This structure will be used to communicate the per-object mtimes when
writing a cruft pack. Here, we need the full packing_data structure
because the mtime information is stored in an array there, not on the
individual object_entry's themselves (to avoid paying the overhead in
structure width for operations which do not generate a cruft pack).

We haven't passed this information down before because one of the two
callers (in bulk-checkin.c) does not have a packing_data structure at
all. In that case (where no cruft pack will be generated), NULL is
passed instead.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopack-mtimes: support reading .mtimes files
Taylor Blau [Fri, 20 May 2022 23:17:35 +0000 (19:17 -0400)] 
pack-mtimes: support reading .mtimes files

To store the individual mtimes of objects in a cruft pack, introduce a
new `.mtimes` format that can optionally accompany a single pack in the
repository.

The format is defined in Documentation/technical/pack-format.txt, and
stores a 4-byte network order timestamp for each object in name (index)
order.

This patch prepares for cruft packs by defining the `.mtimes` format,
and introducing a basic API that callers can use to read out individual
mtimes.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoFourth batch
Junio C Hamano [Thu, 26 May 2022 21:51:40 +0000 (14:51 -0700)] 
Fourth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'ac/remote-v-with-object-list-filters'
Junio C Hamano [Thu, 26 May 2022 21:51:32 +0000 (14:51 -0700)] 
Merge branch 'ac/remote-v-with-object-list-filters'

"git remote -v" now shows the list-objects-filter used during
fetching from the remote, if available.

* ac/remote-v-with-object-list-filters:
  builtin/remote.c: teach `-v` to list filters for promisor remotes

2 years agoMerge branch 'cb/path-owner-check-with-sudo'
Junio C Hamano [Thu, 26 May 2022 21:51:32 +0000 (14:51 -0700)] 
Merge branch 'cb/path-owner-check-with-sudo'

With a recent update to refuse access to repositories of other
people by default, "sudo make install" and "sudo git describe"
stopped working.  This series intends to loosen it while keeping
the safety.

* cb/path-owner-check-with-sudo:
  t0034: add negative tests and allow git init to mostly work under sudo
  git-compat-util: avoid failing dir ownership checks if running privileged
  t: regression git needs safe.directory when using sudo

2 years agoMerge branch 'cg/tools-for-git-doc'
Junio C Hamano [Thu, 26 May 2022 21:51:31 +0000 (14:51 -0700)] 
Merge branch 'cg/tools-for-git-doc'

A new doc that lists tips for tools to work with Git's codebase.

* cg/tools-for-git-doc:
  Documentation/ToolsForGit.txt: Tools for developing Git

2 years agoMerge branch 'tk/simple-autosetupmerge'
Junio C Hamano [Thu, 26 May 2022 21:51:30 +0000 (14:51 -0700)] 
Merge branch 'tk/simple-autosetupmerge'

"git -c branch.autosetupmerge=simple branch $A $B" will set the $B
as $A's upstream only when $A and $B shares the same name, and "git
-c push.default=simple" on branch $A would push to update the
branch $A at the remote $B came from.  Also more places use the
sole remote, if exists, before defaulting to 'origin'.

* tk/simple-autosetupmerge:
  push: new config option "push.autoSetupRemote" supports "simple" push
  push: default to single remote even when not named origin
  branch: new autosetupmerge option 'simple' for matching branches

2 years agol10n: Document the new l10n workflow
Ævar Arnfjörð Bjarmason [Thu, 26 May 2022 14:50:35 +0000 (22:50 +0800)] 
l10n: Document the new l10n workflow

Change the "flow" of how translators interact with the l10n repository
at [1] to adjust it for a new workflow of not having a po/git.pot file
in-tree at all, and to not commit line numbers to the po/*.po files
that we do track in tree.

The current workflow was added in a combination of dce37b66fb0 (l10n:
initial git.pot for 1.7.10 upcoming release, 2012-02-13) and
271ce198cd0 (Update l10n guide, 2012-02-29).

As noted in preceding commits I think that it came about due to
technical debt I'd left behind in how the "po/git.pot" file was
created, and a mis-impression that the file:line comments were needed
as anything more than a transitory translation aid.

As the updated po/README.md shows the new workflow is substantially
the same, the difference is that translators no longer need to
initially pull from the l10n coordinator for a new po/git.pot, they
can simply use git.git's canonical source repository.

The l10n coordinator is still expected to announce a release to
translate, which presumably would always be Junio's latest release
tag. I'm not certain if this part of the process is actually
important. I.e. the delta translation-wise between that tag and
"master" is usually pretty small, so perhaps translators can just work
on "master" instead.

1. https://github.com/git-l10n/git-po/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMakefile: add "po-init" rule to initialize po/XX.po
Ævar Arnfjörð Bjarmason [Thu, 26 May 2022 14:50:34 +0000 (22:50 +0800)] 
Makefile: add "po-init" rule to initialize po/XX.po

The core translation is the minimum set of work that must be done for a
new language translation.

There are over 5000 messages in the template message file "po/git.pot"
that need to be translated. It is not a piece of cake for such a huge
workload. So we used to define a small set of messages called "core
translation" that a new l10n contributor must complete before sending
pull request to the l10n coordinator.

By pulling in some parts of the git-po-helper[^1] logic, we add a new
rule to create this core translation message "po/git-core.pot":

    make po/git-core.pot

To help new l10n contributors to initialized their "po/XX.pot" from
"po/git-core.pot", we also add new rules "po-init":

    make po-init PO_FILE=po/XX.po

[^1]: https://github.com/git-l10n/git-po-helper/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMakefile: add "po-update" rule to update po/XX.po
Jiang Xin [Thu, 26 May 2022 14:50:33 +0000 (22:50 +0800)] 
Makefile: add "po-update" rule to update po/XX.po

Since there is no longer a "po/git.pot" file in tree, a l10n team leader
has to run several commands to update their "po/XX.po" file:

    $ make pot
    $ msgmerge --add-location --backup=off -U po/XX.po po/git.pot

To make this process easier, add a new rule so that l10n team leaders
can update their "po/XX.po" with one command. E.g.:

    $ make po-update PO_FILE=po/zh_CN.po

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopo/git.pot: don't check in result of "make pot"
Ævar Arnfjörð Bjarmason [Thu, 26 May 2022 14:50:32 +0000 (22:50 +0800)] 
po/git.pot: don't check in result of "make pot"

Remove the "po/git.pot" file from being tracked, which started with
dce37b66fb0 (l10n: initial git.pot for 1.7.10 upcoming release,
2012-02-13).

The reason the po/git.pot started being checked in was because the
po/*.po files were changed a schema where we'd generate them from a
known-good snapshot of po/git.pot, instead of each translator running
"make pot" themselves.

This makes sense, but we don't need to carry this file in-tree just to
achieve that aim, and doing so has resulted in a significant amount of
"diff churn" since this method of doing it was introduced:

    $ git log -p --oneline -- po/git.pot|wc -l
    553743

We can instead let l10n contributors to generate "po/git.pot" in runtime
to update their own "po/XX.po", and the l10n coordinator can check
pull requests using CI pipeline.

This reverts to the schema introduced initially in cd5513a7168 (i18n:
Makefile: "pot" target to extract messages marked for translation,
2011-02-22).

The actual "git rm" of po/git.pot was in preceding commit to make this
change easier to review, and to preempt the mailing list from blocking
it due to it being too large.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopo/git.pot: this is now a generated file
Jiang Xin [Thu, 26 May 2022 14:50:31 +0000 (22:50 +0800)] 
po/git.pot: this is now a generated file

We no longer keep track of the contents of this file.

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMakefile: remove duplicate and unwanted files in FOUND_SOURCE_FILES
Jiang Xin [Thu, 26 May 2022 14:50:30 +0000 (22:50 +0800)] 
Makefile: remove duplicate and unwanted files in FOUND_SOURCE_FILES

We get source files saved in "$(FOUND_SOURCE_FILES)" by running the
command "git ls-files" or the command "find". We tried to have the
both commands return the same list of files, but apparently the "find"
command will return more files, such as the generated headers. We can
filter out these generated headers to get closer results.

In addition to this, "$(FOUND_SOURCE_FILES)" may contain duplicate
files. E.g. "git-ls-files" may have duplicate entries for the same file
in different staging areas if there are unresolved conflicts in the
working tree. For this case, we can reduce duplicate entries by passing
the option "--deduplicate" to git-ls-files.

Junio reported that when running "make" in a working tree with
unresolved conflicts, "make" may report warnings like below:

    Makefile:xxxx: target '.build/pot/po/FOO.c.po' given more than once
                   in the same rule

The duplicate targets are introduced by the following pattern rule we
added in the preceding commit for incremental build of "po/git.pot".

    $(LOCALIZED_C_GEN_PO): .build/pot/po/%.po: %

Although we have resolved this issue by sorting to create a unique
$(LOCALIZED_C), other targets may benefit from this. Such as: tags,
cscope.out, etc.

Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoi18n CI: stop allowing non-ASCII source messages in po/git.pot
Ævar Arnfjörð Bjarmason [Thu, 26 May 2022 14:50:29 +0000 (22:50 +0800)] 
i18n CI: stop allowing non-ASCII source messages in po/git.pot

In the preceding commit we moved away from using xgettext(1) to both
generate the po/git.pot, and to merge the incrementally generated
po/git.pot+ file as we sourced translations from C, shell and Perl.

Doing it this way, which dates back to my initial
implementation[1][2][3] was conflating two things: With xgettext(1)
the --from-code both controls what encoding is specified in the
po/git.pot's header, and what encoding we allow in source messages.

We don't ever want to allow non-ASCII in *source messages*, and doing
so has hid e.g. a buggy message introduced in
a6226fd772b (submodule--helper: convert the bulk of cmd_add() to C,
2021-08-10) from us, we'd warn about it before, but only when running
"make pot", but the operation would still succeed. Now we'll error out
on it when running "make pot".

Since the preceding Makefile changes made this easy: let's add a "make
check-pot" target with the same prerequisites as the "po/git.pot"
target, but without changing the file "po/git.pot". Running it as part
of the "static-analysis" CI target will ensure that we catch any such
issues in the future. E.g.:

    $ make check-pot
        XGETTEXT .build/pot/po/builtin/submodule--helper.c.po
    xgettext: Non-ASCII string at builtin/submodule--helper.c:3381.
              Please specify the source encoding through --from-code.
    make: *** [.build/pot/po/builtin/submodule--helper.c.po] Error 1

1. cd5513a7168 (i18n: Makefile: "pot" target to extract messages
   marked for translation, 2011-02-22)
2. adc3b2b2767 (Makefile: add xgettext target for *.sh files,
   2011-05-14)
3. 5e9637c6297 (i18n: add infrastructure for translating Git with
   gettext, 2011-11-18)

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMakefile: have "make pot" not "reset --hard"
Ævar Arnfjörð Bjarmason [Thu, 26 May 2022 14:50:28 +0000 (22:50 +0800)] 
Makefile: have "make pot" not "reset --hard"

Before commit fc0fd5b23b (Makefile: help gettext tools to cope with our
custom PRItime format, 2017-07-20), we'd consider source files as-is
with gettext, but because we need to understand PRItime in the same way
that gettext itself understands PRIuMAX, we'd first check if we had a
clean checkout, then munge all of the processed files in-place with
"sed", generate "po/git.pot", and then finally "reset --hard" to undo
our changes.

By generating "pot" snippets in ".build/pot/po" for each source file
and rewriting certain source files with PRItime macros to temporary
files in ".build/pot/po", we can avoid running "make pot" by altering
files in place and doing a "reset --hard" afterwards.

This speed of "make pot" is slower than before on an initial run,
because we run "xgettext" many times (once per source file), but it
can be boosted by parallelization. It is *much* faster for incremental
runs, and will allow us to implement related targets in subsequent
commits.

When the "pot" target was originally added in cd5513a7168 (i18n:
Makefile: "pot" target to extract messages marked for translation,
2011-02-22) it behaved like a "normal" target. I.e. we'd skip the
re-generation of the po/git.pot if nothing had to be done.

Then after po/git.pot was checked in in dce37b66fb0 (l10n: initial
git.pot for 1.7.10 upcoming release, 2012-02-13) the target was broken
until 1f31963e921 (i18n: treat "make pot" as an explicitly-invoked
target, 2014-08-22) when it was made to depend on "FORCE". I.e. the
Makefile's dependency resolution inherently can't handle incremental
building when the target file may be updated by git (or something else
external to "make"). But this case no longer applies, so FORCE is no
longer needed.

That out of the way, the main logic change here is getting rid of the
"reset --hard":

We'll generate intermediate ".build/pot/po/%.po" files from "%", which
is handy to see at a glance what strings (if any) in a given file are
marked for translation:

$ make .build/pot/po/pretty.c.po
[...]
$ cat .build/pot/po/pretty.c.po
#: pretty.c:1051
msgid "unable to parse --pretty format"
msgstr ""
$

For these C source files which contain the PRItime macros, we will
create temporary munged "*.c" files in a tree in ".build/pot/po"
corresponding to our source tree, and have "xgettext" consider those.
The rule needs to be careful to "(cd .build/pot/po && ...)", because
otherwise the comments in the po/git.pot file wouldn't refer to the
correct source locations (they'd be prefixed with ".build/pot/po").
These temporary munged "*.c” files will be removed immediately after
the corresponding po files are generated, because some development tools
cannot ignore the duplicate source files in the ".build" directory
according to the ".gitignore" file, and that may cause trouble.

The output of the generated po/git.pot file is changed in one minor
way: Because we're using msgcat(1) instead of xgettext(1) to
concatenate the output we'll now disambiguate where "TRANSLATORS"
comments come from, in cases where a message is the same in N files,
and either only one has a "TRANSLATORS" comment, or they're
different. E.g. for the "Your edited hunk[...]" message we'll now
apply this change (comment content elided):

+#. #-#-#-#-#  add-patch.c.po  #-#-#-#-#
 #. TRANSLATORS: do not translate [y/n]
[...]
+#. #-#-#-#-#  git-add--interactive.perl.po  #-#-#-#-#
 #. TRANSLATORS: do not translate [y/n]
[...]
 #: add-patch.c:1253 git-add--interactive.perl:1244
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""

There are six such changes, and they all make the context more
understandable, as msgcat(1) is better at handling these edge cases
than xgettext(1)'s previously used "--join-existing" flag.

But filenames in the above disambiguation lines of extracted-comments
have an extra ".po" extension compared to the filenames at the file
locations. While we could rename the intermediate ".build/pot/po/%.po"
files without the ".po" extension to use more intuitive filenames in
the disambiguation lines of extracted-comments, but that will confuse
developer tools with lots of invalid C or other source files in
".build/pot/po" directory.

The addition of "--omit-header" option for xgettext makes the "pot"
snippets in ".build/pot/po/*.po" smaller. But as we'll see in a
subsequent commit this header behavior has been hiding an
encoding-related bug from us, so let's carry it forward instead of
re-generating it with xgettext(1).

The "po/git.pot" file should have a header entry, because a proper
header entry will increase the speed of creating a new po file using
msginit and set a proper "POT-Creation-Date:" field in the header
entry of a "po/XX.po" file. We use xgettext to generate a separate
header file at ".build/pot/git.header" from "/dev/null", and use this
header to assemble "po/git.pot".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMakefile: generate "po/git.pot" from stable LOCALIZED_C
Jiang Xin [Thu, 26 May 2022 14:50:27 +0000 (22:50 +0800)] 
Makefile: generate "po/git.pot" from stable LOCALIZED_C

Different users may generate a different message template file
"po/git.pot". This is because the POT file is generated from
"$(LOCALIZED_C)", which is supposed to list all the sources that we
extract the strings to be translated from. But "$(LOCALIZED_C)"
includes "$(C_OBJ)", which only lists the source files used in the
current build for a specific platform and specific compiler
conditions.

Instead of using "$(C_OBJ)", we use "$(FOUND_C_SOURCES)", which lists
all source files we keep track of (or ship in a tarball extract), to
form a stable "LOCALIZED_C". We also add "$(SCALAR_SOURCES)", which
is part of "$(C_OBJ)" but not included in "$(FOUND_C_SOURCES)".

With this update, the newly generated "po/git.pot" will have 30 new
entries coming from the following C source files:

 * compat/fsmonitor/fsm-listen-win32.c
 * compat/mingw.c
 * compat/regex/regcomp.c
 * compat/simple-ipc/ipc-win32.c

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMakefile: sort source files before feeding to xgettext
Jiang Xin [Thu, 26 May 2022 14:50:26 +0000 (22:50 +0800)] 
Makefile: sort source files before feeding to xgettext

We will feed xgettext with more C source files and in different order
in subsequent commit. To generate a stable "po/git.pot" regardless of
the number and order of input source files, we sort the c, perl, and
shell source files in groups before feeding them to xgettext.

Ævar suggested that we should not pass the option "--sort-by-file" to
xgettext to sort the translatable strings, as it will mix the three
groups of source files (c, perl and shell) in the file "po/git.pot",
and change the order of translatable strings in the same line of a file.

With this update, the newly generated "po/git.pot" will have the same
entries while in a different order.

With the help of a custom diff driver as shown below,

    git config --global diff.gettext-fmt.textconv \
        "msgcat --no-location --sort-by-file"

and appending a new entry "*.pot diff=gettext-fmt" to git attributes,
we can see that there are no substantial changes in "po/git.pot".

We won't checkin the newly generated "po/git.pot", because we will
remove it from tree in a later commit.

Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoThird batch
Junio C Hamano [Wed, 25 May 2022 23:24:26 +0000 (16:24 -0700)] 
Third batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'tb/receive-pack-code-cleanup'
Junio C Hamano [Wed, 25 May 2022 23:42:49 +0000 (16:42 -0700)] 
Merge branch 'tb/receive-pack-code-cleanup'

Code clean-up.

* tb/receive-pack-code-cleanup:
  builtin/receive-pack.c: remove redundant 'if'

2 years agoMerge branch 'jc/avoid-redundant-submodule-fetch'
Junio C Hamano [Wed, 25 May 2022 23:42:49 +0000 (16:42 -0700)] 
Merge branch 'jc/avoid-redundant-submodule-fetch'

"git fetch --recurse-submodules" from multiple remotes (either from
a remote group, or "--all") used to make one extra "git fetch" in
the submodules, which has been corrected.

* jc/avoid-redundant-submodule-fetch:
  fetch: do not run a redundant fetch from submodule

2 years agoMerge branch 'os/fetch-check-not-current-branch'
Junio C Hamano [Wed, 25 May 2022 23:42:48 +0000 (16:42 -0700)] 
Merge branch 'os/fetch-check-not-current-branch'

The way "git fetch" without "--update-head-ok" ensures that HEAD in
no worktree points at any ref being updated was too wasteful, which
has been optimized a bit.

* os/fetch-check-not-current-branch:
  fetch: limit shared symref check only for local branches

2 years agoMerge branch 'pb/ggg-in-mfc-doc'
Junio C Hamano [Wed, 25 May 2022 23:42:48 +0000 (16:42 -0700)] 
Merge branch 'pb/ggg-in-mfc-doc'

Documentation update.

* pb/ggg-in-mfc-doc:
  MyFirstContribution: drop PR description for GGG single-patch contributions
  MyFirstContribution: reference "The cover letter" in GitGitGadget section
  MyFirstContribution: reference "The cover letter" in "Preparing Email"
  MyFirstContribution: add standalone section on cover letter
  MyFirstContribution: add "Anatomy of a Patch Series" section

2 years agoMerge branch 'jt/fetch-peek-optional-section'
Junio C Hamano [Wed, 25 May 2022 23:42:48 +0000 (16:42 -0700)] 
Merge branch 'jt/fetch-peek-optional-section'

"git fetch" unnecessarily failed when an unexpected optional
section appeared in the output, which has been corrected.

* jt/fetch-peek-optional-section:
  fetch-pack: make unexpected peek result non-fatal

2 years agoMerge branch 'jc/show-branch-g-current'
Junio C Hamano [Wed, 25 May 2022 23:42:47 +0000 (16:42 -0700)] 
Merge branch 'jc/show-branch-g-current'

The "--current" option of "git show-branch" should have been made
incompatible with the "--reflog" mode, but this was not enforced,
which has been corrected.

* jc/show-branch-g-current:
  show-branch: -g and --current are incompatible

2 years agoMerge branch 'ep/coverage-report-wants-test-to-have-run'
Junio C Hamano [Wed, 25 May 2022 23:42:47 +0000 (16:42 -0700)] 
Merge branch 'ep/coverage-report-wants-test-to-have-run'

"make coverage-report" without first running "make coverage" did
not produce any meaningful result, which has been corrected.

* ep/coverage-report-wants-test-to-have-run:
  Makefile: add a prerequisite to the coverage-report target

2 years agoci: update Cirrus-CI image to FreeBSD 12.3
Philippe Blain [Wed, 25 May 2022 12:51:12 +0000 (08:51 -0400)] 
ci: update Cirrus-CI image to FreeBSD 12.3

The FreeBSD CI build (on Cirrus-CI) has been failing in
't9001-send-email.sh' for quite some time, with an error from the
runtime linker relating to the Perl installation:

    $ GIT_SEND_EMAIL_NOTTY=1 git send-email \
    '--from=Example <from@example.com>' '--to=nobody@example.com' \
    '--smtp-server=/tmp/cirrus-ci-build/t/trash directory.t9001-send-email/fake.sendmail' \
    --compose '--subject=foo' 0001-Second.patch
    ld-elf.so.1: /usr/local/lib/perl5/5.32/mach/CORE/libperl.so.5.32: Undefined symbol "strerror_l@FBSD_1.6"

This first instance is in t9001.6 but it fails similarly in several tests
in this file.

The FreeBSD image we use is FreeBSD 12.2, which is unsupported since
March 31st, 2022 [1]. Switching to a supported version, 12.3,
makes this error disappear [2].

Change the image we use to FreeBSD 12.3.

[1] https://www.freebsd.org/security/unsupported/
[2] https://lore.kernel.org/git/9cc31276-ab78-fa8a-9fb4-b19266911211@gmail.com/

Reviewed-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agosetup: don't die if realpath(3) fails on getcwd(3)
Kevin Locke [Tue, 24 May 2022 19:20:12 +0000 (13:20 -0600)] 
setup: don't die if realpath(3) fails on getcwd(3)

Prior to Git 2.35.0, git could be run from an inaccessible working
directory so long as the git repository specified by options and/or
environment variables was accessible.  For example:

    git init repo
    mkdir -p a/b
    cd a/b
    chmod u-x ..
    git -C "${PWD%/a/b}/repo" status

If this example seems a bit contrived, consider running with the
repository owner as a substitute UID (e.g. with runuser(1) or sudo(8))
without ensuring the working directory is accessible by that user.

The code added by e6f8861bd4 ("setup: introduce
startup_info->original_cwd") to preserve the working directory attempts
to normalize the path using strbuf_realpath().  If that fails, as in the
case above, it is treated as a fatal error.

This commit treats strbuf_realpath() errors as non-fatal.  If an error
occurs, setup_original_cwd() will continue without applying removal
prevention for cwd, resulting in the pre-2.35.0 behavior.  The risk
should be minimal, since git will not operate on a repository with
inaccessible ancestors, this behavior is only known to occur when cwd is
a descendant of the repository, an ancestor of cwd is inaccessible, and
no ancestors of the repository are inaccessible.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocmake: remove (_)UNICODE def on Windows in CMakeLists.txt
Yuyi Wang [Tue, 24 May 2022 12:57:01 +0000 (12:57 +0000)] 
cmake: remove (_)UNICODE def on Windows in CMakeLists.txt

`UNICODE` and `_UNICODE` are not required when building git on Windows.
Actually, they should not be predefined at all.

There're 2 evidences that `(_)UNICODE` is supposed to be nonexist:

compat/win32/trace2_win32_process_info.c:83: It uses jw_array_string
which accepts pe32.szExeFile as const char*.

t/helper/test-drop-caches.c:16: Calling to GetCurrentDirectory with
Buffer as char*.

The autotools build system never defines `UNICODE` and `_UNICODE` and
builds on Windows well.

Signed-off-by: Yuyi Wang <Strawberry_Str@hotmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocmake: add pcre2 support
Yuyi Wang [Tue, 24 May 2022 06:38:48 +0000 (06:38 +0000)] 
cmake: add pcre2 support

Fix one of the TODOs listed in the CMakeLists.txt by adding support
for building with pcre2.

As pcre2 doesn't provide cmake find module, we find it with pkgconf.
This patch also works with vcpkg on Windows, with pkgconf and pcre2
installed.

Pkgconf and pcre2 is detected automatically just like curl, expat
and iconv. The output of CMake indicates whether pcre2 is found.

Signed-off-by: Yuyi Wang <Strawberry_Str@hotmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocmake: fix CMakeLists.txt on Linux
Yuyi Wang [Tue, 24 May 2022 06:38:47 +0000 (06:38 +0000)] 
cmake: fix CMakeLists.txt on Linux

CMakeLists.txt didn't follow the grammar of `set`, and it will fail when
setting `USE_VCPKG` off on non-Windows platforms.

When the platform is Linux, the Makefile adds `compat/linux/procinfo.o`
to `COMPAT_OBJS`, but the CMakeLists.txt didn't add
`compat/linux/procinfo.c` to `compat_SOURCES`. It would cause linkage
error.

Signed-off-by: Yuyi Wang <Strawberry_Str@hotmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agodir.c: avoid "exceeds maximum object size" error with GCC v12.x
Johannes Schindelin [Tue, 24 May 2022 00:23:06 +0000 (00:23 +0000)] 
dir.c: avoid "exceeds maximum object size" error with GCC v12.x

Technically, the pointer difference `end - start` _could_ be negative,
and when cast to an (unsigned) `size_t` that would cause problems. In
this instance, the symptom is:

dir.c: In function 'git_url_basename':
dir.c:3087:13: error: 'memchr' specified bound [9223372036854775808, 0]
       exceeds maximum object size 9223372036854775807
       [-Werror=stringop-overread]
    CC ewah/bitmap.o
 3087 |         if (memchr(start, '/', end - start) == NULL
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

While it is a bit far-fetched to think that `end` (which is defined as
`repo + strlen(repo)`) and `start` (which starts at `repo` and never
steps beyond the NUL terminator) could result in such a negative
difference, GCC has no way of knowing that.

See also https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783.

Let's just add a safety check, primarily for GCC's benefit.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agonedmalloc: avoid new compile error
Johannes Schindelin [Tue, 24 May 2022 00:23:04 +0000 (00:23 +0000)] 
nedmalloc: avoid new compile error

GCC v12.x complains thusly:

compat/nedmalloc/nedmalloc.c: In function 'DestroyCaches':
compat/nedmalloc/nedmalloc.c:326:12: error: the comparison will always
                              evaluate as 'true' for the address of 'caches'
                              will never be NULL [-Werror=address]
  326 |         if(p->caches)
      |            ^
compat/nedmalloc/nedmalloc.c:196:22: note: 'caches' declared here
  196 |         threadcache *caches[THREADCACHEMAXCACHES];
      |                      ^~~~~~

... and it is correct, of course.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agocompat/win32/syslog: fix use-after-realloc
Johannes Schindelin [Tue, 24 May 2022 00:23:03 +0000 (00:23 +0000)] 
compat/win32/syslog: fix use-after-realloc

Git for Windows' SDK recently upgraded to GCC v12.x which points out
that the `pos` variable might be used even after the corresponding
memory was `realloc()`ed and therefore potentially no longer valid.

Since a subset of this SDK is used in Git's CI/PR builds, we need to fix
this to continue to be able to benefit from the CI/PR runs.

Note: This bug has been with us since 2a6b149c64f6 (mingw: avoid using
strbuf in syslog, 2011-10-06), and while it looks tempting to replace
the hand-rolled string manipulation with a `strbuf`-based one, that
commit's message explains why we cannot do that: The `syslog()` function
is called as part of the function in `daemon.c` which is set as the
`die()` routine, and since `strbuf_grow()` can call that function if it
runs out of memory, this would cause a nasty infinite loop that we do
not want to re-introduce.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/pack-objects.c: ensure pack validity from MIDX bitmap objects
Taylor Blau [Tue, 24 May 2022 18:54:36 +0000 (14:54 -0400)] 
builtin/pack-objects.c: ensure pack validity from MIDX bitmap objects

When using a multi-pack bitmap, pack-objects will try to perform its
traversal using a call to `traverse_bitmap_commit_list()`, which calls
`add_object_entry_from_bitmap()` to add each object it finds to its
packing list.

This path can cause pack-objects to add objects from packs that don't
have open pack_fds on them, by avoiding a call to `is_pack_valid()`.
This is because we only call `is_pack_valid()` on the preferred pack (in
order to do verbatim reuse via `reuse_partial_packfile_from_bitmap()`)
and not others when loading a MIDX bitmap.

In this case, `add_object_entry_from_bitmap()` will check whether it
wants each object entry by calling `want_object_in_pack()`, which will
call `want_found_object` (since its caller already supplied a
`found_pack`). In most cases (particularly without `--local`, and when
`ignored_packed_keep_on_disk` and `ignored_packed_keep_in_core` are
both "0"), we'll take the entry from the pack contained in the MIDX
bitmap, all without an open pack_fd.

When we then try to use that entry later to assemble the actual pack,
we'll be susceptible to any simultaneous writers moving that pack out of
the way (e.g., due to a concurrent repack) without having an open file
descriptor, causing races that result in errors like:

    remote: Enumerating objects: 1498802, done.
    remote: fatal: packfile ./objects/pack/pack-e57d433b5a588daa37fbe946e2b28dfaec03a93e.pack cannot be accessed
    remote: aborting due to possible repository corruption on the remote side.

This race can happen even with multi-pack bitmaps, since we may open a
MIDX bitmap that is being rewritten long before its packs are actually
unlinked.

Work around this by calling `is_pack_valid()` from within
`want_found_object()`, matching the behavior in
`want_object_in_pack_one()` (which has an analogous call). Most calls to
`is_pack_valid()` should be basically no-ops, since only the first call
requires us to open a file (subsequent calls realize the file is already
open, and return immediately).

Importantly, when `want_object_in_pack()` is given a non-NULL
`*found_pack`, but `want_found_object()` rejects the copy of the object
in that pack, we must reset `*found_pack` and `*found_offset` to NULL
and 0, respectively. Failing to do so could lead to other checks in
`want_object_in_pack()` (such as `want_object_in_pack_one()`) using the
same (invalid) pack as `*found_pack`, meaning that we don't call
`is_pack_valid()` because `p == *found_pack`. This can lead the caller
to believe it can use a copy of an object from an invalid pack.

An alternative approach to closing this race would have been to call
`is_pack_valid()` on _all_ packs in a multi-pack bitmap on load. This
has a couple of problems:

  - it is unnecessarily expensive in the cases where we don't actually
    need to open any packs (e.g., in `git rev-list --use-bitmap-index
    --count`)

  - more importantly, it means any time we would have hit this race,
    we'll avoid using bitmaps altogether, leading to significant
    slowdowns by forcing a full object traversal

Co-authored-by: Victoria Dye <vdye@github.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/pack-objects.c: ensure included `--stdin-packs` exist
Taylor Blau [Tue, 24 May 2022 18:54:31 +0000 (14:54 -0400)] 
builtin/pack-objects.c: ensure included `--stdin-packs` exist

A subsequent patch will teach `want_object_in_pack()` to set its
`*found_pack` and `*found_offset` poitners to NULL when the provided
pack does not pass the `is_pack_valid()` check.

The `--stdin-packs` mode of `pack-objects` is not quite prepared to
handle this. To prepare it for this change, do the following two things:

  - Ensure provided packs pass the `is_pack_valid()` check when
    collecting the caller-provided packs into the "included" and
    "excluded" lists.

  - Gracefully handle any _invalid_ packs being passed to
    `want_object_in_pack()`.

Calling `is_pack_valid()` early on makes it substantially less likely
that we will have to deal with a pack going away, since we'll have an
open file descriptor on its contents much earlier.

But even packs with open descriptors can become invalid in the future if
we (a) hit our open descriptor limit, forcing us to close some open
packs, and (b) one of those just-closed packs has gone away in the
meantime.

`add_object_entry_from_pack()` depends on having a non-NULL
`*found_pack`, since it passes that pointer to `packed_object_info()`,
meaning that we would SEGV if the pointer became NULL (like we propose
to do in `want_object_in_pack()` in the following patch).

But avoiding calling `packed_object_info()` entirely is OK, too, since
its only purpose is to identify which objects in the included packs are
commits, so that they can form the tips of the advisory traversal used
to discover the object namehashes.

Failing to do this means that at worst we will produce lower-quality
deltas, but it does not prevent us from generating the pack as long as
we can find a copy of each object from the disappearing pack in some
other part of the repository.

Co-authored-by: Victoria Dye <vdye@github.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agobuiltin/pack-objects.c: avoid redundant NULL check
Taylor Blau [Tue, 24 May 2022 18:54:27 +0000 (14:54 -0400)] 
builtin/pack-objects.c: avoid redundant NULL check

Before calling `for_each_object_in_pack()`, the caller
`read_packs_list_from_stdin()` loops through each of the `include_packs`
and checks that its `->util` pointer (which is used to store the `struct
packed_git *` itself) is non-NULL.

This check is redundant, because `read_packs_list_from_stdin()` already
checks that the included packs are non-NULL earlier on in the same
function (and it does not add any new entries in between).

Remove this check, since it is not doing anything in the meantime.

Co-authored-by: Victoria Dye <vdye@github.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agopack-bitmap.c: check preferred pack validity when opening MIDX bitmap
Taylor Blau [Tue, 24 May 2022 18:54:22 +0000 (14:54 -0400)] 
pack-bitmap.c: check preferred pack validity when opening MIDX bitmap

When pack-objects adds an entry to its packing list, it marks the
packfile and offset containing the object, which we may later use during
verbatim reuse (c.f., `write_reused_pack_verbatim()`).

If the packfile in question is deleted in the background (e.g., due to a
concurrent `git repack`), we'll die() as a result of calling use_pack(),
unless we have an open file descriptor on the pack itself. 4c08018204
(pack-objects: protect against disappearing packs, 2011-10-14) worked
around this by opening the pack ahead of time before recording it as a
valid source for reuse.

4c08018204's treatment meant that we could tolerate disappearing packs,
since it ensures we always have an open file descriptor on any pack that
we mark as a valid source for reuse. This tightens the race to only
happen when we need to close an open pack's file descriptor (c.f., the
caller of `packfile.c::get_max_fd_limit()`) _and_ that pack was deleted,
in which case we'll complain that a pack could not be accessed and
die().

The pack bitmap code does this, too, since prior to dc1daacdcc
(pack-bitmap: check pack validity when opening bitmap, 2021-07-23) it
was vulnerable to the same race.

The MIDX bitmap code does not do this, and is vulnerable to the same
race. Apply the same treatment as dc1daacdcc to the routine responsible
for opening the multi-pack bitmap's preferred pack to close this race.

This patch handles the "preferred" pack (c.f., the section
"multi-pack-index reverse indexes" in
Documentation/technical/pack-format.txt) specially, since pack-objects
depends on reusing exact chunks of that pack verbatim in
reuse_partial_packfile_from_bitmap(). So if that pack cannot be loaded,
the utility of a bitmap is significantly diminished.

Similar to dc1daacdcc, we could technically just add this check in
reuse_partial_packfile_from_bitmap(), since it's possible to use a MIDX
.bitmap without needing to open any of its packs. But it's simpler to do
the check as early as possible, covering all direct uses of the
preferred pack. Note that doing this check early requires us to call
prepare_midx_pack() early, too, so move the relevant part of that loop
from load_reverse_index() into open_midx_bitmap_1().

Subsequent patches handle the non-preferred packs in a slightly
different fashion.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoSecond batch
Junio C Hamano [Mon, 23 May 2022 21:39:45 +0000 (14:39 -0700)] 
Second batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agoMerge branch 'jc/archive-add-file-normalize-mode'
Junio C Hamano [Mon, 23 May 2022 21:39:54 +0000 (14:39 -0700)] 
Merge branch 'jc/archive-add-file-normalize-mode'

"git archive --add-file=<path>" picked up the raw permission bits
from the path and propagated to zip output in some cases, without
normalization, which has been corrected (tar output did not have
this issue).

* jc/archive-add-file-normalize-mode:
  archive: do not let on-disk mode leak to zip archives

2 years agoMerge branch 'ab/valgrind-fixes'
Junio C Hamano [Mon, 23 May 2022 21:39:54 +0000 (14:39 -0700)] 
Merge branch 'ab/valgrind-fixes'

A bit of test framework fixes with a few fixes to issues found by
valgrind.

* ab/valgrind-fixes:
  commit-graph.c: don't assume that stat() succeeds
  object-file: fix a unpack_loose_header() regression in 3b6a8db3b03
  log test: skip a failing mkstemp() test under valgrind
  tests: using custom GIT_EXEC_PATH breaks --valgrind tests

2 years agoMerge branch 'ab/commit-plug-leaks'
Junio C Hamano [Mon, 23 May 2022 21:39:54 +0000 (14:39 -0700)] 
Merge branch 'ab/commit-plug-leaks'

Leakfix in the top-level called-once function.

* ab/commit-plug-leaks:
  commit: fix "author_ident" leak

2 years agosparse-checkout: integrate with sparse index
Derrick Stolee [Mon, 23 May 2022 13:48:46 +0000 (13:48 +0000)] 
sparse-checkout: integrate with sparse index

When modifying the sparse-checkout definition, the sparse-checkout
builtin calls update_sparsity() to modify the SKIP_WORKTREE bits of all
cache entries in the index. Before, we needed the index to be fully
expanded in order to ensure we had the full list of files necessary that
match the new patterns.

Insert a call to reset_sparse_directories() that expands sparse
directories that are within the new pattern list, but only far enough
that every necessary file path now exists as a cache entry. The
remaining logic within update_sparsity() will modify the SKIP_WORKTREE
bits appropriately.

This allows us to disable command_requires_full_index within the
sparse-checkout builtin. Add tests that demonstrate that we are not
expanding to a full index unnecessarily.

We can see the improved performance in the p2000 test script:

Test                           HEAD~1            HEAD
------------------------------------------------------------------------
2000.24: git ... (sparse-v3)   2.14(1.55+0.58)   1.57(1.03+0.53) -26.6%
2000.25: git ... (sparse-v4)   2.20(1.62+0.57)   1.58(0.98+0.59) -28.2%

These reductions of 26-28% are small compared to most examples, but the
time is dominated by writing a new copy of the base repository to the
worktree and then deleting it again. The fact that the previous index
expansion was such a large portion of the time is telling how important
it is to complete this sparse index integration.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agop2000: add test for 'git sparse-checkout [add|set]'
Derrick Stolee [Mon, 23 May 2022 13:48:45 +0000 (13:48 +0000)] 
p2000: add test for 'git sparse-checkout [add|set]'

The sparse-checkout builtin is almost completely integrated with the
sparse index, allowing the sparse-checkout boundary to be modified
without expanding a sparse index to a full one. Add a test to
p2000-sparse-operations.sh that adds a directory to the sparse-checkout
definition, then removes it. Using both operations is important to
ensure that the operation is doing the same work in each repetition as
well as leaving the test repo in a good state for later tests.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agosparse-index: complete partial expansion
Derrick Stolee [Mon, 23 May 2022 13:48:44 +0000 (13:48 +0000)] 
sparse-index: complete partial expansion

To complete the implementation of expand_to_pattern_list(), we need to
detect when a sparse directory entry should remain sparse. This avoids a
full expansion, so we now need to use the PARTIALLY_SPARSE mode to
indicate this state.

There still are no callers to this method, but we will add one in the
next change.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agosparse-index: partially expand directories
Derrick Stolee [Mon, 23 May 2022 13:48:43 +0000 (13:48 +0000)] 
sparse-index: partially expand directories

The expand_to_pattern_list() method expands sparse directory entries
to their list of contained files when either the pattern list is NULL or
the directory is contained in the new pattern list's cone mode patterns.

It is possible that the pattern list has a recursive match with a
directory 'A/B/C/' and so an existing sparse directory 'A/B/' would need
to be expanded. If there exists a directory 'A/B/D/', then that
directory should not be expanded and instead we can create a sparse
directory.

To implement this, we plug into the add_path_to_index() callback for the
call to read_tree_at(). Since we now need access to both the index we
are writing and the pattern list we are comparing, create a 'struct
modify_index_context' to use as a data transfer object. It is important
that we use the given pattern list since we will use this pattern list
to change the sparse-checkout patterns and cannot use
istate->sparse_checkout_patterns.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years agosparse-checkout: --no-sparse-index needs a full index
Derrick Stolee [Mon, 23 May 2022 13:48:42 +0000 (13:48 +0000)] 
sparse-checkout: --no-sparse-index needs a full index

When the --no-sparse-index option is supplied, the sparse-checkout
builtin should explicitly ask to expand a sparse index to a full one.
This is currently done implicitly due to the command_requires_full_index
protection, but that will be removed in an upcoming change.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>