]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
3 months agoMerge branch 'la/trailer-cleanups' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:09 +0000 (16:22 -0800)] 
Merge branch 'la/trailer-cleanups' into maint-2.43

Code clean-up.

* la/trailer-cleanups:
  trailer: use offsets for trailer_start/trailer_end
  trailer: find the end of the log message
  commit: ignore_non_trailer computes number of bytes to ignore

3 months agoMerge branch 'jc/retire-cas-opt-name-constant' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:09 +0000 (16:22 -0800)] 
Merge branch 'jc/retire-cas-opt-name-constant' into maint-2.43

Code clean-up.

* jc/retire-cas-opt-name-constant:
  remote.h: retire CAS_OPT_NAME

3 months agoMerge branch 'rs/rebase-use-strvec-pushf' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:09 +0000 (16:22 -0800)] 
Merge branch 'rs/rebase-use-strvec-pushf' into maint-2.43

Code clean-up.

* rs/rebase-use-strvec-pushf:
  rebase: use strvec_pushf() for format-patch revisions

3 months agoMerge branch 'rs/t6300-compressed-size-fix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:08 +0000 (16:22 -0800)] 
Merge branch 'rs/t6300-compressed-size-fix' into maint-2.43

Test fix.

* rs/t6300-compressed-size-fix:
  t6300: avoid hard-coding object sizes

3 months agoMerge branch 'sp/test-i18ngrep' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:08 +0000 (16:22 -0800)] 
Merge branch 'sp/test-i18ngrep' into maint-2.43

Error message fix in the test framework.

* sp/test-i18ngrep:
  test-lib-functions.sh: fix test_grep fail message wording

3 months agoMerge branch 'jc/doc-misspelt-refs-fix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:08 +0000 (16:22 -0800)] 
Merge branch 'jc/doc-misspelt-refs-fix' into maint-2.43

Doc update.

* jc/doc-misspelt-refs-fix:
  doc: format.notes specify a ref under refs/notes/ hierarchy

3 months agoMerge branch 'jc/doc-most-refs-are-not-that-special' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:08 +0000 (16:22 -0800)] 
Merge branch 'jc/doc-most-refs-are-not-that-special' into maint-2.43

Doc updates.

* jc/doc-most-refs-are-not-that-special:
  docs: MERGE_AUTOSTASH is not that special
  docs: AUTO_MERGE is not that special
  refs.h: HEAD is not that special
  git-bisect.txt: BISECT_HEAD is not that special
  git.txt: HEAD is not that special

3 months agoMerge branch 'es/add-doc-list-short-form-of-all-in-synopsis' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:07 +0000 (16:22 -0800)] 
Merge branch 'es/add-doc-list-short-form-of-all-in-synopsis' into maint-2.43

Doc update.

* es/add-doc-list-short-form-of-all-in-synopsis:
  git-add.txt: add missing short option -A to synopsis

3 months agoMerge branch 'ps/chainlint-self-check-update' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:07 +0000 (16:22 -0800)] 
Merge branch 'ps/chainlint-self-check-update' into maint-2.43

Test framework update.

* ps/chainlint-self-check-update:
  tests: adjust whitespace in chainlint expectations

3 months agoMerge branch 'ps/reftable-fixes' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:07 +0000 (16:22 -0800)] 
Merge branch 'ps/reftable-fixes' into maint-2.43

Bunch of small fix-ups to the reftable code.

* ps/reftable-fixes:
  reftable/block: reuse buffer to compute record keys
  reftable/block: introduce macro to initialize `struct block_iter`
  reftable/merged: reuse buffer to compute record keys
  reftable/stack: fix use of unseeded randomness
  reftable/stack: fix stale lock when dying
  reftable/stack: reuse buffers when reloading stack
  reftable/stack: perform auto-compaction with transactional interface
  reftable/stack: verify that `reftable_stack_add()` uses auto-compaction
  reftable: handle interrupted writes
  reftable: handle interrupted reads
  reftable: wrap EXPECT macros in do/while

3 months agoMerge branch 'jk/config-cleanup' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:07 +0000 (16:22 -0800)] 
Merge branch 'jk/config-cleanup' into maint-2.43

Code clean-up around use of configuration variables.

* jk/config-cleanup:
  sequencer: simplify away extra git_config_string() call
  gpg-interface: drop pointless config_error_nonbool() checks
  push: drop confusing configset/callback redundancy
  config: use git_config_string() for core.checkRoundTripEncoding
  diff: give more detailed messages for bogus diff.* config
  config: use config_error_nonbool() instead of custom messages
  imap-send: don't use git_die_config() inside callback
  git_xmerge_config(): prefer error() to die()
  config: reject bogus values for core.checkstat

3 months agoMerge branch 'rs/incompatible-options-messages' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:06 +0000 (16:22 -0800)] 
Merge branch 'rs/incompatible-options-messages' into maint-2.43

Clean-up code that handles combinations of incompatible options.

* rs/incompatible-options-messages:
  worktree: simplify incompatibility message for --orphan and commit-ish
  worktree: standardize incompatibility messages
  clean: factorize incompatibility message
  revision, rev-parse: factorize incompatibility messages about - -exclude-hidden
  revision: use die_for_incompatible_opt3() for - -graph/--reverse/--walk-reflogs
  repack: use die_for_incompatible_opt3() for -A/-k/--cruft
  push: use die_for_incompatible_opt4() for - -delete/--tags/--all/--mirror

3 months agoMerge branch 'mk/doc-gitfile-more' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:06 +0000 (16:22 -0800)] 
Merge branch 'mk/doc-gitfile-more' into maint-2.43

Doc update.

* mk/doc-gitfile-more:
  doc: make the gitfile syntax easier to discover

3 months agoMerge branch 'ps/ref-tests-update-more' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:06 +0000 (16:22 -0800)] 
Merge branch 'ps/ref-tests-update-more' into maint-2.43

Tests update.

* ps/ref-tests-update-more:
  t6301: write invalid object ID via `test-tool ref-store`
  t5551: stop writing packed-refs directly
  t5401: speed up creation of many branches
  t4013: simplify magic parsing and drop "failure"
  t3310: stop checking for reference existence via `test -f`
  t1417: make `reflog --updateref` tests backend agnostic
  t1410: use test-tool to create empty reflog
  t1401: stop treating FETCH_HEAD as real reference
  t1400: split up generic reflog tests from the reffile-specific ones
  t0410: mark tests to require the reffiles backend

3 months agoMerge branch 'rs/column-leakfix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:06 +0000 (16:22 -0800)] 
Merge branch 'rs/column-leakfix' into maint-2.43

Leakfix.

* rs/column-leakfix:
  column: release strbuf and string_list after use

3 months agoMerge branch 'rs/i18n-cannot-be-used-together' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:05 +0000 (16:22 -0800)] 
Merge branch 'rs/i18n-cannot-be-used-together' into maint-2.43

Clean-up code that handles combinations of incompatible options.

* rs/i18n-cannot-be-used-together:
  i18n: factorize even more 'incompatible options' messages

3 months agoMerge branch 'jb/reflog-expire-delete-dry-run-options' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:05 +0000 (16:22 -0800)] 
Merge branch 'jb/reflog-expire-delete-dry-run-options' into maint-2.43

Command line parsing fix for "git reflog".

* jb/reflog-expire-delete-dry-run-options:
  builtin/reflog.c: fix dry-run option short name

3 months agoMerge branch 'js/packfile-h-typofix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:05 +0000 (16:22 -0800)] 
Merge branch 'js/packfile-h-typofix' into maint-2.43

Typofix.

* js/packfile-h-typofix:
  packfile.c: fix a typo in `each_file_in_pack_dir_fn()`'s declaration

3 months agoMerge branch 'jk/commit-graph-slab-clear-fix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:05 +0000 (16:22 -0800)] 
Merge branch 'jk/commit-graph-slab-clear-fix' into maint-2.43

Clearing in-core repository (happens during e.g., "git fetch
--recurse-submodules" with commit graph enabled) made in-core
commit object in an inconsistent state by discarding the necessary
data from commit-graph too early, which has been corrected.

* jk/commit-graph-slab-clear-fix:
  commit-graph: retain commit slab when closing NULL commit_graph

3 months agoMerge branch 'cp/git-flush-is-an-env-bool' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:04 +0000 (16:22 -0800)] 
Merge branch 'cp/git-flush-is-an-env-bool' into maint-2.43

Unlike other environment variables that took the usual
true/false/yes/no as well as 0/1, GIT_FLUSH only understood 0/1,
which has been corrected.

* cp/git-flush-is-an-env-bool:
  write-or-die: make GIT_FLUSH a Boolean environment variable

3 months agoMerge branch 'jc/sparse-checkout-set-default-fix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:04 +0000 (16:22 -0800)] 
Merge branch 'jc/sparse-checkout-set-default-fix' into maint-2.43

"git sparse-checkout set" added default patterns even when the
patterns are being fed from the standard input, which has been
corrected.

* jc/sparse-checkout-set-default-fix:
  sparse-checkout: use default patterns for 'set' only !stdin

3 months agoMerge branch 'jc/archive-list-with-extra-args' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:04 +0000 (16:22 -0800)] 
Merge branch 'jc/archive-list-with-extra-args' into maint-2.43

"git archive --list extra garbage" silently ignored excess command
line parameters, which has been corrected.

* jc/archive-list-with-extra-args:
  archive: "--list" does not take further options

3 months agoMerge branch 'rj/status-bisect-while-rebase' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:04 +0000 (16:22 -0800)] 
Merge branch 'rj/status-bisect-while-rebase' into maint-2.43

"git status" is taught to show both the branch being bisected and
being rebased when both are in effect at the same time.
cf. <xmqqil76kyov.fsf@gitster.g>

* rj/status-bisect-while-rebase:
  status: fix branch shown when not only bisecting

3 months agoMerge branch 'sh/completion-with-reftable' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:04 +0000 (16:22 -0800)] 
Merge branch 'sh/completion-with-reftable' into maint-2.43

Command line completion script (in contrib/) learned to work better
with the reftable backend.

* sh/completion-with-reftable:
  completion: support pseudoref existence checks for reftables
  completion: refactor existence checks for pseudorefs

3 months agoMerge branch 'jx/fetch-atomic-error-message-fix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:03 +0000 (16:22 -0800)] 
Merge branch 'jx/fetch-atomic-error-message-fix' into maint-2.43

"git fetch --atomic" issued an unnecessary empty error message,
which has been corrected.
cf. <ZX__e7VjyLXIl-uV@tanuki>

* jx/fetch-atomic-error-message-fix:
  fetch: no redundant error message for atomic fetch
  t5574: test porcelain output of atomic fetch

3 months agoMerge branch 'jk/mailinfo-iterative-unquote-comment' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:03 +0000 (16:22 -0800)] 
Merge branch 'jk/mailinfo-iterative-unquote-comment' into maint-2.43

The code to parse the From e-mail header has been updated to avoid
recursion.

* jk/mailinfo-iterative-unquote-comment:
  mailinfo: avoid recursion when unquoting From headers
  t5100: make rfc822 comment test more careful
  mailinfo: fix out-of-bounds memory reads in unquote_quoted_pair()

3 months agoMerge branch 'rs/show-ref-incompatible-options' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:03 +0000 (16:22 -0800)] 
Merge branch 'rs/show-ref-incompatible-options' into maint-2.43

Code clean-up for sanity checking of command line options for "git
show-ref".

* rs/show-ref-incompatible-options:
  show-ref: use die_for_incompatible_opt3()

3 months agoMerge branch 'jk/implicit-true' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:03 +0000 (16:22 -0800)] 
Merge branch 'jk/implicit-true' into maint-2.43

Some codepaths did not correctly parse configuration variables
specified with valueless "true", which has been corrected.

* jk/implicit-true:
  fsck: handle NULL value when parsing message config
  trailer: handle NULL value when parsing trailer-specific config
  submodule: handle NULL value when parsing submodule.*.branch
  help: handle NULL value for alias.* config
  trace2: handle NULL values in tr2_sysenv config callback
  setup: handle NULL value when parsing extensions
  config: handle NULL value when parsing non-bools

3 months agoMerge branch 'jk/bisect-reset-fix' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:02 +0000 (16:22 -0800)] 
Merge branch 'jk/bisect-reset-fix' into maint-2.43

"git bisect reset" has been taught to clean up state files and refs
even when BISECT_START file is gone.

* jk/bisect-reset-fix:
  bisect: always clean on reset

3 months agoMerge branch 'jk/end-of-options' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:02 +0000 (16:22 -0800)] 
Merge branch 'jk/end-of-options' into maint-2.43

"git $cmd --end-of-options --rev -- --path" for some $cmd failed
to interpret "--rev" as a rev, and "--path" as a path.  This was
fixed for many programs like "reset" and "checkout".

* jk/end-of-options:
  parse-options: decouple "--end-of-options" and "--"

3 months agoMerge branch 'jc/revision-parse-int' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:02 +0000 (16:22 -0800)] 
Merge branch 'jc/revision-parse-int' into maint-2.43

The command line parser for the "log" family of commands was too
loose when parsing certain numbers, e.g., silently ignoring the
extra 'q' in "git log -n 1q" without complaining, which has been
tightened up.

* jc/revision-parse-int:
  revision: parse integer arguments to --max-count, --skip, etc., more carefully

3 months agoMerge branch 'jp/use-diff-index-in-pre-commit-sample' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:02 +0000 (16:22 -0800)] 
Merge branch 'jp/use-diff-index-in-pre-commit-sample' into maint-2.43

The sample pre-commit hook that tries to catch introduction of new
paths that use potentially non-portable characters did not notice
an existing path getting renamed to such a problematic path, when
rename detection was enabled.

* jp/use-diff-index-in-pre-commit-sample:
  hooks--pre-commit: detect non-ASCII when renaming

3 months agoMerge branch 'jh/trace2-redact-auth' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:01 +0000 (16:22 -0800)] 
Merge branch 'jh/trace2-redact-auth' into maint-2.43

trace2 streams used to record the URLs that potentially embed
authentication material, which has been corrected.

* jh/trace2-redact-auth:
  t0212: test URL redacting in EVENT format
  t0211: test URL redacting in PERF format
  trace2: redact passwords from https:// URLs by default
  trace2: fix signature of trace2_def_param() macro

3 months agoMerge branch 'js/update-urls-in-doc-and-comment' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:01 +0000 (16:22 -0800)] 
Merge branch 'js/update-urls-in-doc-and-comment' into maint-2.43

Stale URLs have been updated to their current counterparts (or
archive.org) and HTTP links are replaced with working HTTPS links.

* js/update-urls-in-doc-and-comment:
  doc: refer to internet archive
  doc: update links for andre-simon.de
  doc: switch links to https
  doc: update links to current pages

3 months agoMerge branch 'ps/commit-graph-less-paranoid' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:01 +0000 (16:22 -0800)] 
Merge branch 'ps/commit-graph-less-paranoid' into maint-2.43

Earlier we stopped relying on commit-graph that (still) records
information about commits that are lost from the object store,
which has negative performance implications.  The default has been
flipped to disable this pessimization.

* ps/commit-graph-less-paranoid:
  commit-graph: disable GIT_COMMIT_GRAPH_PARANOIA by default

3 months agoMerge branch 'tz/send-email-negatable-options' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:00 +0000 (16:22 -0800)] 
Merge branch 'tz/send-email-negatable-options' into maint-2.43

Newer versions of Getopt::Long started giving warnings against our
(ab)use of it in "git send-email".  Bump the minimum version
requirement for Perl to 5.8.1 (from September 2002) to allow
simplifying our implementation.

* tz/send-email-negatable-options:
  send-email: avoid duplicate specification warnings
  perl: bump the required Perl version to 5.8.1 from 5.8.0

3 months agoMerge branch 'js/ci-discard-prove-state' into maint-2.43
Junio C Hamano [Fri, 9 Feb 2024 00:22:00 +0000 (16:22 -0800)] 
Merge branch 'js/ci-discard-prove-state' into maint-2.43

The way CI testing used "prove" could lead to running the test
suite twice needlessly, which has been corrected.

* js/ci-discard-prove-state:
  ci: avoid running the test suite _twice_
  ci: add support for GitLab CI
  ci: install test dependencies for linux-musl
  ci: squelch warnings when testing with unusable Git repo
  ci: unify setup of some environment variables
  ci: split out logic to set up failed test artifacts
  ci: group installation of Docker dependencies
  ci: make grouping setup more generic
  ci: reorder definitions for grouping functions

4 months agocommit-graph: retain commit slab when closing NULL commit_graph
Jeff King [Fri, 5 Jan 2024 05:41:42 +0000 (00:41 -0500)] 
commit-graph: retain commit slab when closing NULL commit_graph

This fixes a regression introduced in ac6d45d11f (commit-graph: move
slab-clearing to close_commit_graph(), 2023-10-03), in which running:

  git -c fetch.writeCommitGraph=true fetch --recurse-submodules

multiple times in a freshly cloned repository causes a segfault. What
happens in the second (and subsequent) runs is this:

  1. We make a "struct commit" for any ref tips which we're storing
     (even if we already have them, they still go into FETCH_HEAD).

     Because the first run will have created a commit graph, we'll find
     those commits in the graph.

     The commit struct is therefore created with a NULL "maybe_tree"
     entry, because we can load its oid from the graph later. But to do
     that we need to remember that we got the commit from the graph,
     which is recorded in a global commit_graph_data_slab object.

  2. Because we're using --recurse-submodules, we'll try to fetch each
     of the possible submodules. That implies creating a separate
     "struct repository" in-process for each submodule, which will
     require a later call to repo_clear().

     The call to repo_clear() calls raw_object_store_clear(), which in
     turn calls close_object_store(), which in turn calls
     close_commit_graph(). And the latter frees the commit graph data
     slab.

  3. Later, when trying to write out a new commit graph, we'll ask for
     their tree oid via get_commit_tree_oid(), which will see that the
     object is parsed but with a NULL maybe_tree field. We'd then
     usually pull it from the graph file, but because the slab was
     cleared, we don't realize that we can do so! We end up returning
     NULL and segfaulting.

     (It seems questionable that we'd write a graph entry for such a
     commit anyway, since we know we already have one. I didn't
     double-check, but that may simply be another side effect of having
     cleared the slab).

The bug is in step (2) above. We should not be clearing the slab when
cleaning up the submodule repository structs. Prior to ac6d45d11f, we
did not do so because it was done inside a helper function that returned
early when it saw NULL. So the behavior change from that commit is that
we'll now _always_ clear the slab via repo_clear(), even if the
repository being closed did not have a commit graph (and thus would have
a NULL commit_graph struct).

The most immediate fix is to add in a NULL check in close_commit_graph(),
making it a true noop when passed in an object_store with a NULL
commit_graph (it's OK to just return early, since the rest of its code
is already a noop when passed NULL). That restores the pre-ac6d45d11f
behavior. And that's what this patch does, along with a test that
exercises it (we already have a test that uses submodules along with
fetch.writeCommitGraph, but the bug only triggers when there is a
subsequent fetch and when that fetch uses --recurse-submodules).

So that fixes the regression in the least-risky way possible.

I do think there's some fragility here that we might want to follow up
on. We have a global commit_graph_data_slab that contains graph
positions, and our global commit structs depend on the that slab
remaining valid. But close_commit_graph() is just about closing _one_
object store's graph. So it's dangerous to call that function and clear
the slab without also throwing away any "struct commit" we might have
parsed that depends on it.

Which at first glance seems like a bug we could already trigger. In the
situation described here, there is no commit graph in the submodule
repository, so our commit graph is NULL (in fact, in our test script
there is no submodule repo at all, so we immediately return from
repo_init() and call repo_clear() only to free up memory). But what
would happen if there was one? Wouldn't we see a non-NULL commit_graph
entry, and then clear the global slab anyway?

The answer is "no", but for very bizarre reasons. Remember that
repo_clear() calls raw_object_store_clear(), which then calls
close_object_store() and thus close_commit_graph(). But before it does
so, raw_object_store_clear() does something else: it frees the commit
graph and sets it to NULL! So by this code path we'll _never_ see a
non-NULL commit_graph struct, and thus never clear the slab.

So it happens to work out. But it still seems questionable to me that we
would clear a global slab (which might still be in use) when closing the
commit graph. This clearing comes from 957ba814bf (commit-graph: when
closing the graph, also release the slab, 2021-09-08), and was fixing a
case where we really did need it to be closed (and in that case we
presumably call close_object_store() more directly).

So I suspect there may still be a bug waiting to happen there, as any
object loaded before the call to close_object_store() may be stranded
with a bogus maybe_tree entry (and thus looking at it after the call
might cause an error). But I'm not sure how to trigger it, nor what the
fix should look like (you probably would need to "unparse" any objects
pulled from the graph). And so this patch punts on that for now in favor
of fixing the recent regression in the most direct way, which should not
have any other fallouts.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agowrite-or-die: make GIT_FLUSH a Boolean environment variable
Chandra Pratap [Thu, 4 Jan 2024 10:20:17 +0000 (10:20 +0000)] 
write-or-die: make GIT_FLUSH a Boolean environment variable

Among Git's environment variables, the ones marked as "Boolean"
accept values in a way similar to Boolean configuration variables,
i.e. values like 'yes', 'on', 'true' and positive numbers are
taken as "on" and values like 'no', 'off', 'false' are taken as
"off".

GIT_FLUSH can be used to force Git to use non-buffered I/O when
writing to stdout. It can only accept two values, '1' which causes
Git to flush more often and '0' which makes all output buffered.
Make GIT_FLUSH accept more values besides '0' and '1' by turning it
into a Boolean environment variable, modifying the required logic.
Update the related documentation.

Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agosparse-checkout: use default patterns for 'set' only !stdin
Junio C Hamano [Thu, 21 Dec 2023 06:59:24 +0000 (22:59 -0800)] 
sparse-checkout: use default patterns for 'set' only !stdin

"git sparse-checkout set ---no-cone" uses default patterns when none
is given from the command line, but it should do so ONLY when
--stdin is not being used.  Right now, add_patterns_from_input()
called when reading from the standard input is sloppy and does not
check if there are extra command line parameters that the command
will silently ignore, but that will change soon and not setting this
unnecessary and unused default patterns start to matter when it gets
fixed.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoarchive: "--list" does not take further options
Junio C Hamano [Thu, 21 Dec 2023 18:13:58 +0000 (10:13 -0800)] 
archive: "--list" does not take further options

"git archive --list blah" should notice an extra command line
parameter that goes unused.  Make it so.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agotrailer: use offsets for trailer_start/trailer_end
Linus Arver [Fri, 20 Oct 2023 19:01:35 +0000 (19:01 +0000)] 
trailer: use offsets for trailer_start/trailer_end

Previously these fields in the trailer_info struct were of type "const
char *" and pointed to positions in the input string directly (to the
start and end positions of the trailer block).

Use offsets to make the intended usage less ambiguous. We only need to
reference the input string in format_trailer_info(), so update that
function to take a pointer to the input.

While we're at it, rename trailer_start to trailer_block_start to be
more explicit about these offsets (that they are for the entire trailer
block including other trailers). Ditto for trailer_end.

Reported-by: Glen Choo <glencbz@gmail.com>
Signed-off-by: Linus Arver <linusa@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agotrailer: find the end of the log message
Linus Arver [Fri, 20 Oct 2023 19:01:34 +0000 (19:01 +0000)] 
trailer: find the end of the log message

Previously, trailer_info_get() computed the trailer block end position
by

(1) checking for the opts->no_divider flag and optionally calling
    find_patch_start() to find the "patch start" location (patch_start), and
(2) calling find_trailer_end() to find the end of the trailer block
    using patch_start as a guide, saving the return value into
    "trailer_end".

The logic in (1) was awkward because the variable "patch_start" is
misleading if there is no patch in the input. The logic in (2) was
misleading because it could be the case that no trailers are in the
input (yet we are setting a "trailer_end" variable before even searching
for trailers, which happens later in find_trailer_start()). The name
"find_trailer_end" was misleading because that function did not look for
any trailer block itself --- instead it just computed the end position
of the log message in the input where the end of the trailer block (if
it exists) would be (because trailer blocks must always come after the
end of the log message).

Combine the logic in (1) and (2) together into find_patch_start() by
renaming it to find_end_of_log_message(). The end of the log message is
the starting point which find_trailer_start() needs to start searching
backward to parse individual trailers (if any).

Helped-by: Jonathan Tan <jonathantanmy@google.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Linus Arver <linusa@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agorebase: use strvec_pushf() for format-patch revisions
René Scharfe [Tue, 19 Dec 2023 07:42:18 +0000 (08:42 +0100)] 
rebase: use strvec_pushf() for format-patch revisions

In run_am(), a strbuf is used to create a revision argument that is then
added to the argument list for git format-patch using strvec_push().
Use strvec_pushf() to add it directly instead, simplifying the code
and plugging a small leak on the error code path.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agocompletion: support pseudoref existence checks for reftables
Stan Hu [Tue, 19 Dec 2023 22:14:18 +0000 (14:14 -0800)] 
completion: support pseudoref existence checks for reftables

In contrib/completion/git-completion.bash, there are a bunch of
instances where we read pseudorefs, such as HEAD, MERGE_HEAD,
REVERT_HEAD, and others via the filesystem. However, the upcoming
reftable refs backend won't use '.git/HEAD' at all but instead will
write an invalid refname as placeholder for backwards compatibility,
which will break the git-completion script.

Update the '__git_pseudoref_exists' function to:

1. Recognize the placeholder '.git/HEAD' written by the reftable
   backend (its content is specified in the reftable specs).
2. If reftable is in use, use 'git rev-parse' to determine whether the
    given ref exists.
3. Otherwise, continue to use 'test -f' to check for the ref's filename.

Signed-off-by: Stan Hu <stanhu@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agocompletion: refactor existence checks for pseudorefs
Stan Hu [Tue, 19 Dec 2023 22:14:17 +0000 (14:14 -0800)] 
completion: refactor existence checks for pseudorefs

In preparation for the reftable backend, this commit introduces a
'__git_pseudoref_exists' function that continues to use 'test -f' to
determine whether a given pseudoref exists in the local filesystem.

Signed-off-by: Stan Hu <stanhu@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoremote.h: retire CAS_OPT_NAME
Junio C Hamano [Tue, 19 Dec 2023 19:26:25 +0000 (11:26 -0800)] 
remote.h: retire CAS_OPT_NAME

When the "--force-with-lease" option was introduced in 28f5d176
(remote.c: add command line option parser for "--force-with-lease",
2013-07-08), the design discussion revolved around the concept of
"compare-and-swap", and it can still be seen in the name used for
variables and helper functions.  The end-user facing option name
ended up to be a bit different, so during the development iteration
of the feature, we used this C preprocessor macro to make it easier
to rename it later.

All of that happened more than 10 years ago, and the flexibility
afforded by the CAS_OPT_NAME macro outlived its usefulness.  Inline
the constant string for the option name, like all other option names
in the code.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agodoc: format.notes specify a ref under refs/notes/ hierarchy
Junio C Hamano [Fri, 15 Dec 2023 22:28:00 +0000 (14:28 -0800)] 
doc: format.notes specify a ref under refs/notes/ hierarchy

There is no 'ref/notes/' hierarchy.  '[format] notes = foo' uses notes
that are found in 'refs/notes/foo'.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agotest-lib-functions.sh: fix test_grep fail message wording
Shreyansh Paliwal [Sun, 3 Dec 2023 17:17:59 +0000 (22:47 +0530)] 
test-lib-functions.sh: fix test_grep fail message wording

In the recent commit 2e87fca189 (test framework: further deprecate
test_i18ngrep, 2023-10-31), the test_i18ngrep function was
deprecated, and all the callers were updated to call the test_grep
function instead.  But test_grep inherited an error message that
still refers to test_i18ngrep by mistake.  Correct it so that a
broken call to the test_grep will identify itself as such.

Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agofetch: no redundant error message for atomic fetch
Jiang Xin [Sun, 17 Dec 2023 14:11:34 +0000 (22:11 +0800)] 
fetch: no redundant error message for atomic fetch

If an error occurs during an atomic fetch, a redundant error message
will appear at the end of do_fetch(). It was introduced in b3a804663c
(fetch: make `--atomic` flag cover backfilling of tags, 2022-02-17).

Because a failure message is displayed before setting retcode in the
function do_fetch(), calling error() on the err message at the end of
this function may result in redundant or empty error message to be
displayed.

We can remove the redundant error() function, because we know that
the function ref_transaction_abort() never fails. While we can find a
common pattern for calling ref_transaction_abort() by running command
"git grep -A1 ref_transaction_abort", e.g.:

    if (ref_transaction_abort(transaction, &error))
        error("abort: %s", error.buf);

Following this pattern, we can tolerate the return value of the function
ref_transaction_abort() being changed in the future. We also delay the
output of the err message to the end of do_fetch() to reduce redundant
code. With these changes, the test case "fetch porcelain output
(atomic)" in t5574 will also be fixed.

Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agot5574: test porcelain output of atomic fetch
Jiang Xin [Sun, 17 Dec 2023 14:11:33 +0000 (22:11 +0800)] 
t5574: test porcelain output of atomic fetch

The test case "fetch porcelain output" checks output of the fetch
command. The error output must be empty with the follow assertion:

    test_must_be_empty stderr

But this assertion fails if using atomic fetch. Refactor this test case
to use different fetch options by splitting it into three test cases.

  1. "setup for fetch porcelain output".

  2. "fetch porcelain output": for non-atomic fetch.

  3. "fetch porcelain output (atomic)": for atomic fetch.

Add new command "test_commit ..." in the first test case, so that if we
run these test cases individually (--run=4-6), "git rev-parse HEAD~"
command will work properly. Run the above test cases, we can find that
one test case has a known breakage, as shown below:

    ok 4 - setup for fetch porcelain output
    ok 5 - fetch porcelain output  # TODO known breakage vanished
    not ok 6 - fetch porcelain output (atomic) # TODO known breakage

The failed test case has an error message with only the error prompt but
no message body, as follows:

    'stderr' is not empty, it contains:
    error:

In a later commit, we will fix this issue.

Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agodocs: MERGE_AUTOSTASH is not that special
Junio C Hamano [Fri, 15 Dec 2023 20:32:45 +0000 (12:32 -0800)] 
docs: MERGE_AUTOSTASH is not that special

A handful of manual pages called MERGE_AUTOSTASH a "special ref",
but there is nothing special about it.  It merely is yet another
pseudoref.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agodocs: AUTO_MERGE is not that special
Junio C Hamano [Fri, 15 Dec 2023 20:32:44 +0000 (12:32 -0800)] 
docs: AUTO_MERGE is not that special

A handful of manual pages called AUTO_MERGE a "special ref", but
there is nothing special about it.  It merely is yet another
pseudoref.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agorefs.h: HEAD is not that special
Junio C Hamano [Fri, 15 Dec 2023 20:32:43 +0000 (12:32 -0800)] 
refs.h: HEAD is not that special

In-code comment explains pseudorefs but used a wrong nomenclature
"special ref".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agogit-bisect.txt: BISECT_HEAD is not that special
Junio C Hamano [Fri, 15 Dec 2023 20:32:42 +0000 (12:32 -0800)] 
git-bisect.txt: BISECT_HEAD is not that special

The description of "git bisect --no-checkout" called BISECT_HEAD a
"special ref", but there is nothing special about it.  It merely is
yet another pseudoref.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agogit.txt: HEAD is not that special
Junio C Hamano [Fri, 15 Dec 2023 20:32:41 +0000 (12:32 -0800)] 
git.txt: HEAD is not that special

The introductory text in "git help git" that describes HEAD called
it "a special ref".  It is special compared to the more regular refs
like refs/heads/master and refs/tags/v1.0.0, but not that special,
unlike truly special ones like FETCH_HEAD.

Rewrite a few sentences to also introduce the distinction between a
regular ref that contain the object name and a symbolic ref that
contain the name of another ref.  Update the description of HEAD
that point at the current branch to use the more correct term, a
"symbolic ref".

This was found as part of auditing the documentation and in-code
comments for uses of "special ref" that refer merely a "pseudo ref".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agogit-add.txt: add missing short option -A to synopsis
Eric Sunshine [Fri, 15 Dec 2023 20:43:33 +0000 (15:43 -0500)] 
git-add.txt: add missing short option -A to synopsis

With one exception, the synopsis for `git add` consistently lists the
short counterpart alongside the long-form of each option (for instance,
"[--edit | -e]"). The exception is that -A is not mentioned alongside
--all. Fix this inconsistency

Reported-by: Benjamin Lehmann <ben.lehmann@gmail.com>
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agotests: adjust whitespace in chainlint expectations
Patrick Steinhardt [Fri, 15 Dec 2023 06:42:47 +0000 (07:42 +0100)] 
tests: adjust whitespace in chainlint expectations

The "check-chainlint" target runs automatically when running tests and
performs self-checks to verify that the chainlinter itself produces the
expected output. Originally, the chainlinter was implemented via sed,
but the infrastructure has been rewritten in fb41727b7e (t: retire
unused chainlint.sed, 2022-09-01) to use a Perl script instead.

The rewrite caused some slight whitespace changes in the output that are
ultimately not of much importance. In order to be able to assert that
the actual chainlinter errors match our expectations we thus have to
ignore whitespace characters when diffing them. As the `-w` flag is not
in POSIX we try to use `git diff -w --no-index` before we fall back to
`diff -w -u`.

To accomodate for cases where the host system has no Git installation we
use the locally-compiled version of Git. This can result in problems
though when the Git project's repository is using extensions that the
locally-compiled version of Git doesn't understand. It will refuse to
run and thus cause the checks to fail.

Instead of improving the detection logic, fix our ".expect" files so
that we do not need any post-processing at all anymore. This allows us
to drop the `-w` flag when diffing so that we can always use diff(1)
now.

Note that we keep some of the post-processing of `chainlint.pl` output
intact to strip leading line numbers generated by the script. Having
these would cause a rippling effect whenever we add a new test that
sorts into the middle of existing tests and would require us to
renumerate all subsequent lines, which seems rather pointless.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agomailinfo: avoid recursion when unquoting From headers
Jeff King [Thu, 14 Dec 2023 21:48:59 +0000 (16:48 -0500)] 
mailinfo: avoid recursion when unquoting From headers

Our unquote_comment() function is recursive; when it sees a comment
within a comment, like:

  (this is an (embedded) comment)

it recurses to handle the inner comment. This is fine for practical use,
but it does mean that you can easily run out of stack space with a
malicious header. For example:

  perl -e 'print "From: ", "(" x 2**18;' |
  git mailinfo /dev/null /dev/null

segfaults on my system. And since mailinfo is likely to be fed untrusted
input from the Internet (if not by human users, who might recognize a
garbage header, but certainly there are automated systems that apply
patches from a list) it may be possible for an attacker to trigger the
problem.

That said, I don't think there's an interesting security vulnerability
here. All an attacker can do is make it impossible to parse their email
and apply their patch, and there are lots of ways to generate bogus
emails. So it's more of an annoyance than anything.

But it's pretty easy to fix it. The recursion is not helping us preserve
any particular state from each level. The only flag in our parsing is
take_next_literally, and we can never recurse when it is set (since the
start of a new comment implies it was not backslash-escaped). So it is
really only useful for finding the end of the matched pair of
parentheses. We can do that easily with a simple depth counter.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agot5100: make rfc822 comment test more careful
Jeff King [Thu, 14 Dec 2023 21:47:46 +0000 (16:47 -0500)] 
t5100: make rfc822 comment test more careful

When processing "From" headers in an email, mailinfo "unquotes" quoted
strings and rfc822 parenthesized comments. For quoted strings, we
actually remove the double-quotes, so:

  From: "A U Thor" <someone@example.com>

become:

  Author: A U Thor
  Email: someone@example.com

But for comments, we leave the outer parentheses in place, so:

  From: A U (this is a comment) Thor <someone@example.com>

becomes:

  Author: A U (this is a comment) Thor
  Email: someone@example.com

So what is the comment "unquoting" actually doing? In our code, being in
a comment section has exactly two effects:

  1. We'll unquote backslash-escaped characters inside a comment
     section.

  2. We _won't_ unquote double-quoted strings inside a comment section.

Our test for comments in t5100 checks this:

  From: "A U Thor" <somebody@example.com> (this is \(really\) a comment (honestly))

So it is covering (1), but not (2). Let's add in a quoted string to
cover this.

Moreover, because the comment appears at the end of the From header,
there's nothing to confirm that we correctly found the end of the
comment section (and not just the end-of-string). Let's instead move it
to the beginning of the header, which means we can confirm that the
existing quoted string is detected (which will only happen if we know
we've left the comment block).

As expected, the test continues to pass, but this will give us more
confidence as we refactor the code in the next patch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agot6300: avoid hard-coding object sizes
René Scharfe [Tue, 12 Dec 2023 17:04:55 +0000 (18:04 +0100)] 
t6300: avoid hard-coding object sizes

f4ee22b526 (ref-filter: add tests for objectsize:disk, 2018-12-24)
hard-coded the expected object sizes.  Coincidentally the size of commit
and tag is the same with zlib at the default compression level.

1f5f8f3e85 (t6300: abstract away SHA-1-specific constants, 2020-02-22)
encoded the sizes as a single value, which coincidentally also works
with sha256.

Different compression libraries like zlib-ng may arrive at different
values.  Get them from the file system instead of hard-coding them to
make switching the compression library (or changing the compression
level) easier.

Reported-by: Ondrej Pohorelsky <opohorel@redhat.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agomailinfo: fix out-of-bounds memory reads in unquote_quoted_pair()
Jeff King [Tue, 12 Dec 2023 22:12:43 +0000 (17:12 -0500)] 
mailinfo: fix out-of-bounds memory reads in unquote_quoted_pair()

When processing a header like a "From" line, mailinfo uses
unquote_quoted_pair() to handle double-quotes and rfc822 parenthesized
comments. It takes a NUL-terminated string on input, and loops over the
"in" pointer until it sees the NUL. When it finds the start of an
interesting block, it delegates to helper functions which also increment
"in", and return the updated pointer.

But there's a bug here: the helpers find the NUL with a post-increment
in the loop condition, like:

   while ((c = *in++) != 0)

So when they do see a NUL (rather than the correct termination of the
quote or comment section), they return "in" as one _past_ the NUL
terminator. And thus the outer loop in unquote_quoted_pair() does not
realize we hit the NUL, and keeps reading past the end of the buffer.

We should instead make sure to return "in" positioned at the NUL, so
that the caller knows to stop their loop, too. A hacky way to do this is
to return "in - 1" after leaving the inner loop. But a slightly cleaner
solution is to avoid incrementing "in" until we are sure it contained a
non-NUL byte (i.e., doing it inside the loop body).

The two tests here show off the problem. Since we check the output,
they'll _usually_ report a failure in a normal build, but it depends on
what garbage bytes are found after the heap buffer. Building with
SANITIZE=address reliably notices the problem. The outcome (both the
exit code and the exact bytes) are just what Git happens to produce for
these cases today, and shouldn't be taken as an endorsement. It might be
reasonable to abort on an unterminated string, for example. The priority
for this patch is fixing the out-of-bounds memory access.

Reported-by: Carlos Andrés Ramírez Cataño <antaigroupltda@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/block: reuse buffer to compute record keys
Patrick Steinhardt [Mon, 11 Dec 2023 09:08:12 +0000 (10:08 +0100)] 
reftable/block: reuse buffer to compute record keys

When iterating over entries in the block iterator we compute the key of
each of the entries and write it into a buffer. We do not reuse the
buffer though and thus re-allocate it on every iteration, which is
wasteful.

Refactor the code to reuse the buffer.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/block: introduce macro to initialize `struct block_iter`
Patrick Steinhardt [Mon, 11 Dec 2023 09:08:07 +0000 (10:08 +0100)] 
reftable/block: introduce macro to initialize `struct block_iter`

There are a bunch of locations where we initialize members of `struct
block_iter`, which makes it harder than necessary to expand this struct
to have additional members. Unify the logic via a new `BLOCK_ITER_INIT`
macro that initializes all members.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/merged: reuse buffer to compute record keys
Patrick Steinhardt [Mon, 11 Dec 2023 09:08:03 +0000 (10:08 +0100)] 
reftable/merged: reuse buffer to compute record keys

When iterating over entries in the merged iterator's queue, we compute
the key of each of the entries and write it into a buffer. We do not
reuse the buffer though and thus re-allocate it on every iteration,
which is wasteful given that we never transfer ownership of the
allocated bytes outside of the loop.

Refactor the code to reuse the buffer. This also fixes a potential
memory leak when `merged_iter_advance_subiter()` returns an error.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/stack: fix use of unseeded randomness
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:59 +0000 (10:07 +0100)] 
reftable/stack: fix use of unseeded randomness

When writing a new reftable stack, Git will first create the stack with
a random suffix so that concurrent updates will not try to write to the
same file. This random suffix is computed via a call to rand(3P). But we
never seed the function via srand(3P), which means that the suffix is in
fact always the same.

Fix this bug by using `git_rand()` instead, which does not need to be
initialized. While this function is likely going to be slower depending
on the platform, this slowness should not matter in practice as we only
use it when writing a new reftable stack.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/stack: fix stale lock when dying
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:54 +0000 (10:07 +0100)] 
reftable/stack: fix stale lock when dying

When starting a transaction via `reftable_stack_init_addition()`, we
create a lockfile for the reftable stack itself which we'll write the
new list of tables to. But if we terminate abnormally e.g. via a call to
`die()`, then we do not remove the lockfile. Subsequent executions of
Git which try to modify references will thus fail with an out-of-date
error.

Fix this bug by registering the lock as a `struct tempfile`, which
ensures automatic cleanup for us.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/stack: reuse buffers when reloading stack
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:50 +0000 (10:07 +0100)] 
reftable/stack: reuse buffers when reloading stack

In `reftable_stack_reload_once()` we iterate over all the tables added
to the stack in order to figure out whether any of the tables needs to
be reloaded. We use a set of buffers in this context to compute the
paths of these tables, but discard those buffers on every iteration.
This is quite wasteful given that we do not need to transfer ownership
of the allocated buffer outside of the loop.

Refactor the code to instead reuse the buffers to reduce the number of
allocations we need to do. Note that we do not have to manually reset
the buffer because `stack_filename()` does this for us already.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/stack: perform auto-compaction with transactional interface
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:46 +0000 (10:07 +0100)] 
reftable/stack: perform auto-compaction with transactional interface

Whenever updating references or reflog entries in the reftable stack, we
need to add a new table to the stack, thus growing the stack's length by
one. The stack can grow to become quite long rather quickly, leading to
performance issues when trying to read records. But besides performance
issues, this can also lead to exhaustion of file descriptors very
rapidly as every single table requires a separate descriptor when
opening the stack.

While git-pack-refs(1) fixes this issue for us by merging the tables, it
runs too irregularly to keep the length of the stack within reasonable
limits. This is why the reftable stack has an auto-compaction mechanism:
`reftable_stack_add()` will call `reftable_stack_auto_compact()` after
its added the new table, which will auto-compact the stack as required.

But while this logic works alright for `reftable_stack_add()`, we do not
do the same in `reftable_addition_commit()`, which is the transactional
equivalent to the former function that allows us to write multiple
updates to the stack atomically. Consequentially, we will easily run
into file descriptor exhaustion in code paths that use many separate
transactions like e.g. non-atomic fetches.

Fix this issue by calling `reftable_stack_auto_compact()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable/stack: verify that `reftable_stack_add()` uses auto-compaction
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:42 +0000 (10:07 +0100)] 
reftable/stack: verify that `reftable_stack_add()` uses auto-compaction

While we have several tests that check whether we correctly perform
auto-compaction when manually calling `reftable_stack_auto_compact()`,
we don't have any tests that verify whether `reftable_stack_add()` does
call it automatically. Add one.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable: handle interrupted writes
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:38 +0000 (10:07 +0100)] 
reftable: handle interrupted writes

There are calls to write(3P) where we don't properly handle interrupts.
Convert them to use `write_in_full()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable: handle interrupted reads
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:34 +0000 (10:07 +0100)] 
reftable: handle interrupted reads

There are calls to pread(3P) and read(3P) where we don't properly handle
interrupts. Convert them to use `pread_in_full()` and `read_in_full()`,
respectively.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoreftable: wrap EXPECT macros in do/while
Patrick Steinhardt [Mon, 11 Dec 2023 09:07:29 +0000 (10:07 +0100)] 
reftable: wrap EXPECT macros in do/while

The `EXPECT` macros used by the reftable test framework are all using a
single `if` statement with the actual condition. This results in weird
syntax when using them in if/else statements like the following:

```
if (foo)
EXPECT(foo == 2)
else
EXPECT(bar == 2)
```

Note that there need not be a trailing semicolon. Furthermore, it is not
immediately obvious whether the else now belongs to the `if (foo)` or
whether it belongs to the expanded `if (foo == 2)` from the macro.

Fix this by wrapping the macros in a do/while loop.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoshow-ref: use die_for_incompatible_opt3()
René Scharfe [Mon, 11 Dec 2023 08:09:28 +0000 (09:09 +0100)] 
show-ref: use die_for_incompatible_opt3()

Use the standard message for reporting the use of multiple mutually
exclusive options by calling die_for_incompatible_opt3() instead of
rolling our own.  This has the benefits of showing only the actually
given options, reducing the number of strings to translate and making
the UI slightly more consistent.

Adjust the test to no longer insist on a specific order of the
reported options, as this implementation detail does not affect the
usefulness of the error message.

Reported-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agorevision: parse integer arguments to --max-count, --skip, etc., more carefully
Junio C Hamano [Fri, 8 Dec 2023 22:35:23 +0000 (07:35 +0900)] 
revision: parse integer arguments to --max-count, --skip, etc., more carefully

The "rev-list" and other commands in the "log" family, being the
oldest part of the system, use their own custom argument parsers,
and integer values of some options are parsed with atoi(), which
allows a non-digit after the number (e.g., "1q") to be silently
ignored.  As a natural consequence, an argument that does not begin
with a digit (e.g., "q") silently becomes zero, too.

Switch to use strtol_i() and parse_timestamp() appropriately to
catch bogus input.

Note that one may naïvely expect that --max-count, --skip, etc., to
only take non-negative values, but we must allow them to also take
negative values, as an escape hatch to countermand a limit set by an
earlier option on the command line; the underlying variables are
initialized to (-1) and "--max-count=-1", for example, is a
legitimate way to reinitialize the limit.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agosequencer: simplify away extra git_config_string() call
Jeff King [Thu, 7 Dec 2023 07:26:42 +0000 (02:26 -0500)] 
sequencer: simplify away extra git_config_string() call

In our config callback, we call git_config_string() to copy the incoming
value string into a local string. But we don't modify or store that
string; we just look at it and then free it. We can make the code
simpler by just looking at the value passed into the callback.

Note that we do need to check for NULL, which is the one bit of logic
git_config_string() did for us. And I could even see an argument that we
are abstracting any error-checking of the value behind the
git_config_string() layer. But in practice no other callbacks behave
this way; it is standard to check for NULL and then just look at the
string directly.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agogpg-interface: drop pointless config_error_nonbool() checks
Jeff King [Thu, 7 Dec 2023 07:26:31 +0000 (02:26 -0500)] 
gpg-interface: drop pointless config_error_nonbool() checks

Config callbacks which use git_config_string() or git_config_pathname()
have no need to check for a NULL value. This is handled automatically
by those helpers.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agopush: drop confusing configset/callback redundancy
Jeff King [Thu, 7 Dec 2023 07:26:22 +0000 (02:26 -0500)] 
push: drop confusing configset/callback redundancy

We parse push config by calling git_config() with our git_push_config()
callback. But inside that callback, when we see "push.gpgsign", we
ignore the value passed into the callback and instead make a new call to
git_config_get_value().

This is unnecessary at best, and slightly wrong at worst (if there are
multiple instances, get_value() only returns one; both methods end up
with last-one-wins, but we'd fail to report errors if earlier
incarnations were bogus).

The call was added by 68c757f219 (push: add a config option push.gpgSign
for default signed pushes, 2015-08-19). That commit doesn't give any
reason to deviate from the usual strategy here; it was probably just
somebody unfamiliar with our config API and its conventions.

It also added identical code to builtin/send-pack.c, which also handles
push.gpgsign.

And then the same issue spread to its neighbor in b33a15b081 (push: add
recurseSubmodules config option, 2015-11-17), presumably via
cargo-culting.

This patch fixes all three to just directly use the value provided to
the callback. While I was adjusting the code to do so, I noticed that
push.gpgsign is overly careful about a NULL value. After
git_parse_maybe_bool() has returned anything besides 1, we know that the
value cannot be NULL (if it were, it would be an implicit "true", and
many callers of maybe_bool rely on that). Here that lets us shorten "if
(v && !strcasecmp(v, ...))" to just "if (!strcasecmp(v, ...))".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoconfig: use git_config_string() for core.checkRoundTripEncoding
Jeff King [Thu, 7 Dec 2023 07:26:11 +0000 (02:26 -0500)] 
config: use git_config_string() for core.checkRoundTripEncoding

Since this code path was recently converted to check for a NULL value,
it now behaves exactly like git_config_string(). We can shorten the code
a bit by using that helper.

Note that git_config_string() takes a const pointer, but our storage
variable is non-const. We're better off making this "const", though,
since the default value points to a string literal (and thus it would be
an error if anybody tried to write to it).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agodiff: give more detailed messages for bogus diff.* config
Jeff King [Thu, 7 Dec 2023 07:25:23 +0000 (02:25 -0500)] 
diff: give more detailed messages for bogus diff.* config

The config callbacks for a few diff.* variables simply return -1 when we
encounter an error. The message you get mentions the offending location,
like:

  fatal: bad config variable 'diff.algorithm' in file '.git/config' at line 7

but is vague about "bad" (as it must be, since the message comes from
the generic config code). Most callbacks add their own messages here, so
let's do the same. E.g.:

  error: unknown value for config 'diff.algorithm': foo
  fatal: bad config variable 'diff.algorithm' in file '.git/config' at line 7

I've written the string in a way that should be reusable for
translators, and matches another similar message in transport.c (there
doesn't yet seem to be a popular generic message to reuse here, so
hopefully this will get the ball rolling).

Note that in the case of diff.algorithm, our parse_algorithm_value()
helper does detect a NULL value string. But it's still worth detecting
it ourselves here, since we can give a more specific error message (and
which is the usual one for unexpected implicit-bool values).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoconfig: use config_error_nonbool() instead of custom messages
Jeff King [Thu, 7 Dec 2023 07:25:16 +0000 (02:25 -0500)] 
config: use config_error_nonbool() instead of custom messages

A few config callbacks use their own custom messages to report an
unexpected implicit bool like:

  [merge "foo"]
  driver

These should just use config_error_nonbool(), so the user sees
consistent messages.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoimap-send: don't use git_die_config() inside callback
Jeff King [Thu, 7 Dec 2023 07:24:58 +0000 (02:24 -0500)] 
imap-send: don't use git_die_config() inside callback

The point of git_die_config() is to let configset users mention the
file/line info for invalid config, like:

  if (!git_config_get_int("foo.bar", &value)) {
if (!is_ok(value))
git_die_config("foo.bar");
  }

Using it from within a config callback is unnecessary, because we can
simply return an error, at which point the config machinery will mention
the file/line of the offending variable. Worse, using git_die_config()
can actually produce the wrong location when the key is found in
multiple spots. For instance, with config like:

  [imap]
  host
  host = foo

we'll report the line number of the "host = foo" line, but the problem
is on the implicit-bool "host" line.

We can fix it by just returning an error code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agogit_xmerge_config(): prefer error() to die()
Jeff King [Thu, 7 Dec 2023 07:24:49 +0000 (02:24 -0500)] 
git_xmerge_config(): prefer error() to die()

When parsing merge config, a few code paths die on error. It's
preferable for us to call error() here, because the resulting error
message from the config parsing code contains much more detail.

For example, before:

  fatal: unknown style 'bogus' given for 'merge.conflictstyle'

and after:

  error: unknown style 'bogus' given for 'merge.conflictstyle'
  fatal: bad config variable 'merge.conflictstyle' in file '.git/config' at line 7

Since we're touching these lines, I also marked them for translation.
There's no reason they shouldn't behave like most other config-parsing
errors.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoconfig: reject bogus values for core.checkstat
Jeff King [Thu, 7 Dec 2023 07:24:04 +0000 (02:24 -0500)] 
config: reject bogus values for core.checkstat

If you feed nonsense config like:

  git -c core.checkstat=foobar status

we'll silently ignore the unknown value, rather than reporting an error.
This goes all the way back to c08e4d5b5c (Enable minimal stat checking,
2013-01-22).

Detecting and complaining now is technically a backwards-incompatible
change, but I don't think anybody has any reason to use an invalid value
here. There are no historical values we'd want to allow for backwards
compatibility or anything like that. We are better off loudly telling
the user that their config may not be doing what they expect.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agofsck: handle NULL value when parsing message config
Jeff King [Thu, 7 Dec 2023 07:11:35 +0000 (02:11 -0500)] 
fsck: handle NULL value when parsing message config

When parsing fsck.*, receive.fsck.*, or fetch.fsck.*, we don't check for
an implicit bool. So any of:

  [fsck]
  badTree
  [receive "fsck"]
  badTree
  [fetch "fsck"]
  badTree

will cause us to segfault. We can fix it with config_error_nonbool() in
the usual way, but we have to make a few more changes to get good error
messages. The problem is that all three spots do:

  if (skip_prefix(var, "fsck.", &var))

to match and parse the actual message id. But that means that "var" now
just says "badTree" instead of "receive.fsck.badTree", making the
resulting message confusing. We can fix that by storing the parsed
message id in its own separate variable.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agotrailer: handle NULL value when parsing trailer-specific config
Jeff King [Thu, 7 Dec 2023 07:11:32 +0000 (02:11 -0500)] 
trailer: handle NULL value when parsing trailer-specific config

When parsing the "key", "command", and "cmd" trailer config, we just
make a copy of the value string.  If we see an implicit bool like:

  [trailer "foo"]
  key

we'll segfault trying to copy a NULL pointer. We can fix this with the
usual config_error_nonbool() check.

I split this out from the other vanilla cases, because at first glance
it looks like a better fix here would be to move the NULL check out of
the switch statement. But it would change the behavior of other keys
like trailer.*.ifExists, where an implicit bool is interpreted as
EXISTS_DEFAULT.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agosubmodule: handle NULL value when parsing submodule.*.branch
Jeff King [Thu, 7 Dec 2023 07:11:29 +0000 (02:11 -0500)] 
submodule: handle NULL value when parsing submodule.*.branch

We record the submodule branch config value as a string, so config that
uses an implicit bool like:

  [submodule "foo"]
  branch

will cause us to segfault. Note that unlike most other config-parsing
bugs of this class, this can be triggered by parsing a bogus .gitmodules
file (which we might do after cloning a malicious repository).

I don't think the security implications are important, though. It's
always a strict NULL dereference, not an out-of-bounds read or write. So
we should reliably kill the process. That may be annoying, but the
impact is limited to the attacker preventing the victim from
successfully using "git clone --recurse-submodules", etc, on the
malicious repo.

The "branch" entry is the only one with this problem; other strings like
"path" and "url" already check for NULL.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agohelp: handle NULL value for alias.* config
Jeff King [Thu, 7 Dec 2023 07:11:27 +0000 (02:11 -0500)] 
help: handle NULL value for alias.* config

When showing all config with "git help --all", we print the list of
defined aliases. But our config callback to do so does not check for a
NULL value, meaning a config block like:

  [alias]
  foo

will cause us to segfault. We should detect and complain about this in
the usual way.

Since this command is purely informational (and we aren't trying to run
the alias), we could perhaps just generate a warning and continue. But
this sort of misconfiguration should be pretty rare, and the error
message we will produce points directly to the line of config that needs
to be fixed. So just generating the usual error should be OK.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agotrace2: handle NULL values in tr2_sysenv config callback
Jeff King [Thu, 7 Dec 2023 07:11:24 +0000 (02:11 -0500)] 
trace2: handle NULL values in tr2_sysenv config callback

If you have config with an implicit bool like:

  [trace2]
  envvars

we'll segfault, as we unconditionally try to xstrdup() the value. We
should instead detect and complain, as a boolean value has no meaning
here. The same is true for every variable in tr2_sysenv_settings (and
this patch covers them all, as we check them in a loop).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agosetup: handle NULL value when parsing extensions
Jeff King [Thu, 7 Dec 2023 07:11:21 +0000 (02:11 -0500)] 
setup: handle NULL value when parsing extensions

The "partialclone" extension config records a string, and hence it is an
error to have an implicit bool like:

  [extensions]
  partialclone

in your config. We should recognize and reject this, rather than
segfaulting (which is the current behavior). Note that it's OK to use
config_error_nonbool() here, even though the return value is an enum. We
explicitly document EXTENSION_ERROR as -1 for compatibility with
error(), etc.

This is the only extension value that has this problem. Most of the
others are bools that interpret this value naturally. The exception is
extensions.objectformat, which does correctly check for NULL.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoconfig: handle NULL value when parsing non-bools
Jeff King [Thu, 7 Dec 2023 07:11:14 +0000 (02:11 -0500)] 
config: handle NULL value when parsing non-bools

When the config parser sees an "implicit" bool like:

  [core]
  someVariable

it passes NULL to the config callback. Any callback code which expects a
string must check for NULL. This usually happens via helpers like
git_config_string(), etc, but some custom code forgets to do so and will
segfault.

These are all fairly vanilla cases where the solution is just the usual
pattern of:

  if (!value)
        return config_error_nonbool(var);

though note that in a few cases we have to split initializers like:

  int some_var = initializer();

into:

  int some_var;
  if (!value)
        return config_error_nonbool(var);
  some_var = initializer();

There are still some broken instances after this patch, which I'll
address on their own in individual patches after this one.

Reported-by: Carlos Andrés Ramírez Cataño <antaigroupltda@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agobisect: always clean on reset
Jeff King [Thu, 7 Dec 2023 06:53:41 +0000 (01:53 -0500)] 
bisect: always clean on reset

Usually "bisect reset" cleans up any refs/bisect/ refs, along with
meta-files like .git/BISECT_LOG. But it only does so after deciding that
a bisection is active, which it does by reading BISECT_START. This is
usually fine, but it's possible to get into a confusing state if the
BISECT_START file is gone, but other cruft is left (this might be due to
a bug, or a system crash, etc).

And since "bisect reset" refuses to do anything in this state, the user
has no easy way to clean up the leftover cruft. While another "bisect
start" would clear the state, in the interim it can be annoying, as
other tools (like our bash prompt code) think we are bisecting, and
for-each-ref output may be polluted with refs/bisect/ entries.

Further adding to the confusion is that running "bisect reset $some_ref"
skips the BISECT_START check. So it never realizes that there's no
bisection active and does the cleanup anyway!

So let's just make sure we always do the cleanup, whether we looked at
BISECT_START or not. If the user doesn't give us a commit to reset to,
we'll still say "We are not bisecting" and skip the call to "git
checkout".

Reported-by: Janik Haag <janik@aq0.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoparse-options: decouple "--end-of-options" and "--"
Jeff King [Wed, 6 Dec 2023 22:21:45 +0000 (17:21 -0500)] 
parse-options: decouple "--end-of-options" and "--"

When we added generic end-of-options support in 51b4594b40
(parse-options: allow --end-of-options as a synonym for "--",
2019-08-06), we made them true synonyms. They both stop option parsing,
and they are both returned in the resulting argv if the KEEP_DASHDASH
flag is used.

The hope was that this would work for all callers:

  - most generic callers would not pass KEEP_DASHDASH, and so would just
    do the right thing (stop parsing there) without needing to know
    anything more.

  - callers with KEEP_DASHDASH were generally going to rely on
    setup_revisions(), which knew to handle --end-of-options specially

But that turned out miss quite a few cases that pass KEEP_DASHDASH but
do their own manual parsing. For example, "git reset", "git checkout",
and so on want pass KEEP_DASHDASH so they can support:

  git reset $revs -- $paths

but of course aren't going to actually do a traversal, so they don't
call setup_revisions(). And those cases currently get confused by
--end-of-options being left in place, like:

   $ git reset --end-of-options HEAD
   fatal: option '--end-of-options' must come before non-option arguments

We could teach each of these callers to handle the leftover option
explicitly. But let's try to be a bit more clever and see if we can
solve it centrally in parse-options.c.

The bogus assumption here is that KEEP_DASHDASH tells us the caller
wants to see --end-of-options in the result. But really, the callers
which need to know that --end-of-options was reached are those that may
potentially parse more options from argv. In other words, those that
pass the KEEP_UNKNOWN_OPT flag.

If such a caller is aware of --end-of-options (e.g., because they call
setup_revisions() with the result), then this will continue to do the
right thing, treating anything after --end-of-options as a non-option.

And if the caller is not aware of --end-of-options, they are better off
keeping it intact, because either:

  1. They are just passing the options along to somebody else anyway, in
     which case that somebody would need to know about the
     --end-of-options marker.

  2. They are going to parse the remainder themselves, at which point
     choking on --end-of-options is much better than having it silently
     removed. The point is to avoid option injection from untrusted
     command line arguments, and bailing is better than quietly treating
     the untrusted argument as an option.

This fixes bugs with --end-of-options across several commands, but I've
focused on two in particular here:

  - t7102 confirms that "git reset --end-of-options --foo" now works.
    This checks two things. One, that we no longer barf on
    "--end-of-options" itself (which previously we did, even if the rev
    was something vanilla like "HEAD" instead of "--foo"). And two, that
    we correctly treat "--foo" as a revision rather than an option.

    This fix applies to any other cases which pass KEEP_DASHDASH but not
    KEEP_UNKNOWN_OPT, like "git checkout", "git check-attr", "git grep",
    etc, which would previously choke on "--end-of-options".

  - t9350 shows the opposite case: fast-export passed KEEP_UNKNOWN_OPT
    but not KEEP_DASHDASH, but then passed the result on to
    setup_revisions(). So it never saw --end-of-options, and would
    erroneously parse "fast-export --end-of-options --foo" as having a
    "--foo" option. This is now fixed.

Note that this does shut the door for callers which want to know if we
hit end-of-options, but don't otherwise need to keep unknown opts. The
obvious thing here is feeding it to the DWIM verify_filename()
machinery. And indeed, this is a problem even for commands which do
understand --end-of-options already. For example, without this patch,
you get:

  $ git log --end-of-options --foo
  fatal: option '--foo' must come before non-option arguments

because we refuse to accept "--foo" as a filename (because it starts
with a dash) even though we could know that we saw end-of-options. The
verify_filename() function simply doesn't accept this extra information.

So that is the status quo, and this patch doubles down further on that.
Commands like "git reset" have the same problem, but they won't even
know that parse-options saw --end-of-options! So even if we fixed
verify_filename(), they wouldn't have anything to pass to it.

But in practice I don't think this is a big deal. If you are being
careful enough to use --end-of-options, then you should also be using
"--" to disambiguate and avoid the DWIM behavior in the first place. In
other words, doing:

  git log --end-of-options --this-is-a-rev -- --this-is-a-path

works correctly, and will continue to do so. And likewise, with this
patch now:

  git reset --end-of-options --this-is-a-rev -- --this-is-a-path

will work, as well.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoworktree: simplify incompatibility message for --orphan and commit-ish
René Scharfe [Wed, 6 Dec 2023 11:52:01 +0000 (12:52 +0100)] 
worktree: simplify incompatibility message for --orphan and commit-ish

Use a single translatable string to report that the worktree add option
--orphan is incompatible with a commit-ish instead of having the
commit-ish in a separate translatable string.  This reduces the number
of strings to translate and gives translators the full context.

A similar message is used in builtin/describe.c, but with the plural of
commit-ish, and here we need the singular form.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoworktree: standardize incompatibility messages
René Scharfe [Wed, 6 Dec 2023 11:52:00 +0000 (12:52 +0100)] 
worktree: standardize incompatibility messages

Use the standard parameterized message for reporting incompatible
options for worktree add.  This reduces the number of strings to
translate and makes the UI slightly more consistent.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agoclean: factorize incompatibility message
René Scharfe [Wed, 6 Dec 2023 11:51:59 +0000 (12:51 +0100)] 
clean: factorize incompatibility message

Use the standard parameterized message for reporting incompatible
options to inform users that they can't use -x and -X together.  This
reduces the number of strings to translate and makes the UI slightly
more consistent.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agorevision, rev-parse: factorize incompatibility messages about - -exclude-hidden
René Scharfe [Wed, 6 Dec 2023 11:51:58 +0000 (12:51 +0100)] 
revision, rev-parse: factorize incompatibility messages about - -exclude-hidden

Use the standard parameterized message for reporting incompatible
options to report options that are not accepted in combination with
--exclude-hidden.  This reduces the number of strings to translate and
makes the UI a bit more consistent.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agorevision: use die_for_incompatible_opt3() for - -graph/--reverse/--walk-reflogs
René Scharfe [Wed, 6 Dec 2023 11:51:57 +0000 (12:51 +0100)] 
revision: use die_for_incompatible_opt3() for - -graph/--reverse/--walk-reflogs

The revision option --reverse is incompatible with --walk-reflogs and
--graph is incompatible with both --reverse and --walk-reflogs.  So they
are all incompatible with each other.

Use the function for checking three mutually incompatible options,
die_for_incompatible_opt3(), to perform this check in one place and
without repetition.  This is shorter and clearer.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agorepack: use die_for_incompatible_opt3() for -A/-k/--cruft
René Scharfe [Wed, 6 Dec 2023 11:51:56 +0000 (12:51 +0100)] 
repack: use die_for_incompatible_opt3() for -A/-k/--cruft

The repack option --keep-unreachable is incompatible with -A, --cruft is
incompatible with -A and -k, and -k is short for --keep-unreachable.  So
they are all incompatible with each other.

Use the function for checking three mutually incompatible options,
die_for_incompatible_opt3(), to perform this check in one place and
without repetition.  This is shorter and clearer.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 months agopush: use die_for_incompatible_opt4() for - -delete/--tags/--all/--mirror
René Scharfe [Wed, 6 Dec 2023 11:51:55 +0000 (12:51 +0100)] 
push: use die_for_incompatible_opt4() for - -delete/--tags/--all/--mirror

The push option --delete is incompatible with --all, --mirror, and
--tags; --tags is incompatible with --all and --mirror; --all is
incompatible with --mirror.  This means they are all incompatible with
each other.  And --branches is an alias for --all.

Use the function for checking four mutually incompatible options,
die_for_incompatible_opt4(), to perform this check in one place and
without repetition.  This is shorter and clearer.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>