]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
4 years agoMerge branch 'hk/ci-checkwhitespace-commentfix'
Junio C Hamano [Fri, 10 Dec 2021 22:35:12 +0000 (14:35 -0800)] 
Merge branch 'hk/ci-checkwhitespace-commentfix'

Comment fix.

* hk/ci-checkwhitespace-commentfix:
  ci(check-whitespace): update stale file top comments

4 years agoMerge branch 'vd/sparse-reset'
Junio C Hamano [Fri, 10 Dec 2021 22:35:12 +0000 (14:35 -0800)] 
Merge branch 'vd/sparse-reset'

Various operating modes of "git reset" have been made to work
better with the sparse index.

* vd/sparse-reset:
  unpack-trees: improve performance of next_cache_entry
  reset: make --mixed sparse-aware
  reset: make sparse-aware (except --mixed)
  reset: integrate with sparse index
  reset: expand test coverage for sparse checkouts
  sparse-index: update command for expand/collapse test
  reset: preserve skip-worktree bit in mixed reset
  reset: rename is_missing to !is_in_reset_tree

4 years agoMerge branch 'tl/midx-docfix'
Junio C Hamano [Fri, 10 Dec 2021 22:35:11 +0000 (14:35 -0800)] 
Merge branch 'tl/midx-docfix'

Doc mark-up fix.

* tl/midx-docfix:
  midx: fix a formatting issue in "multi-pack-index.txt"

4 years agoMerge branch 'po/size-t-for-vs'
Junio C Hamano [Fri, 10 Dec 2021 22:35:10 +0000 (14:35 -0800)] 
Merge branch 'po/size-t-for-vs'

On platforms where ulong is shorter than size_t, code paths that
shifted 1 or 1U to the left lacked the necessary cast to size_t,
which have been corrected.

* po/size-t-for-vs:
  object-file.c: LLP64 compatibility, upcast unity for left shift
  diffcore-delta.c: LLP64 compatibility, upcast unity for left shift
  repack.c: LLP64 compatibility, upcast unity for left shift

4 years agoMerge branch 'rs/mergesort'
Junio C Hamano [Fri, 10 Dec 2021 22:35:10 +0000 (14:35 -0800)] 
Merge branch 'rs/mergesort'

Bitop fix for platforms whose "long" is 32-bit.

* rs/mergesort:
  mergesort: avoid left shift overflow

4 years agoMerge branch 'ah/advice-pull-has-no-preference-between-rebase-and-merge'
Junio C Hamano [Fri, 10 Dec 2021 22:35:09 +0000 (14:35 -0800)] 
Merge branch 'ah/advice-pull-has-no-preference-between-rebase-and-merge'

The advice message given by "git pull" when the user hasn't made a
choice between merge and rebase still said that the merge is the
default, which no longer is the case.  This has been corrected.

* ah/advice-pull-has-no-preference-between-rebase-and-merge:
  pull: don't say that merge is "the default strategy"

4 years agoMerge branch 'ab/checkout-branch-info-leakfix'
Junio C Hamano [Fri, 10 Dec 2021 22:35:09 +0000 (14:35 -0800)] 
Merge branch 'ab/checkout-branch-info-leakfix'

Leakfix.

* ab/checkout-branch-info-leakfix:
  checkout: fix "branch info" memory leaks

4 years agoMerge branch 'jk/t5319-midx-corruption-test-deflake'
Junio C Hamano [Fri, 10 Dec 2021 22:35:08 +0000 (14:35 -0800)] 
Merge branch 'jk/t5319-midx-corruption-test-deflake'

Test fix.

* jk/t5319-midx-corruption-test-deflake:
  t5319: corrupt more bytes of the midx checksum

4 years agoMerge branch 'js/trace2-avoid-recursive-errors'
Junio C Hamano [Fri, 10 Dec 2021 22:35:08 +0000 (14:35 -0800)] 
Merge branch 'js/trace2-avoid-recursive-errors'

trace2 error code path fix.

* js/trace2-avoid-recursive-errors:
  trace2: disable tr2_dst before warning on write errors

4 years agoMerge branch 'jt/pack-header-lshift-overflow'
Junio C Hamano [Fri, 10 Dec 2021 22:35:08 +0000 (14:35 -0800)] 
Merge branch 'jt/pack-header-lshift-overflow'

The code to decode the length of packed object size has been
corrected.

* jt/pack-header-lshift-overflow:
  packfile: avoid overflowing shift during decode

4 years agoMerge branch 'jk/jump-merge-with-pathspec'
Junio C Hamano [Fri, 10 Dec 2021 22:35:08 +0000 (14:35 -0800)] 
Merge branch 'jk/jump-merge-with-pathspec'

The "merge" subcommand of "git jump" (in contrib/) silently ignored
pathspec and other parameters.

* jk/jump-merge-with-pathspec:
  git-jump: pass "merge" arguments to ls-files

4 years agoMerge branch 'jk/test-bitmap-fix'
Junio C Hamano [Fri, 10 Dec 2021 22:35:08 +0000 (14:35 -0800)] 
Merge branch 'jk/test-bitmap-fix'

Tighten code for testing pack-bitmap.

* jk/test-bitmap-fix:
  test_bitmap_hashes(): handle repository without bitmaps

4 years agoMerge branch 'ab/generate-command-list'
Junio C Hamano [Fri, 10 Dec 2021 22:35:08 +0000 (14:35 -0800)] 
Merge branch 'ab/generate-command-list'

Build optimization.

* ab/generate-command-list:
  generate-cmdlist.sh: don't parse command-list.txt thrice
  generate-cmdlist.sh: replace "grep' invocation with a shell version
  generate-cmdlist.sh: do not shell out to "sed"
  generate-cmdlist.sh: stop sorting category lines
  generate-cmdlist.sh: replace for loop by printf's auto-repeat feature
  generate-cmdlist.sh: run "grep | sort", not "sort | grep"
  generate-cmdlist.sh: don't call get_categories() from category_list()
  generate-cmdlist.sh: spawn fewer processes
  generate-cmdlist.sh: trivial whitespace change
  command-list.txt: sort with "LC_ALL=C sort"

4 years agoMerge branch 'tw/var-default-branch'
Junio C Hamano [Fri, 10 Dec 2021 22:35:07 +0000 (14:35 -0800)] 
Merge branch 'tw/var-default-branch'

"git var GIT_DEFAULT_BRANCH" is a way to see what name is used for
the newly created branch if "git init" is run.

* tw/var-default-branch:
  var: add GIT_DEFAULT_BRANCH variable

4 years agoMerge branch 'jk/strbuf-addftime-seconds-since-epoch'
Junio C Hamano [Fri, 10 Dec 2021 22:35:07 +0000 (14:35 -0800)] 
Merge branch 'jk/strbuf-addftime-seconds-since-epoch'

The "--date=format:<strftime>" gained a workaround for the lack of
system support for a non-local timezone to handle "%s" placeholder.

* jk/strbuf-addftime-seconds-since-epoch:
  strbuf_addftime(): handle "%s" manually

4 years agoMerge branch 'js/ci-no-directional-formatting'
Junio C Hamano [Fri, 10 Dec 2021 22:35:06 +0000 (14:35 -0800)] 
Merge branch 'js/ci-no-directional-formatting'

CI has been taught to catch some Unicode directional formatting
sequence that can be used in certain mischief.

* js/ci-no-directional-formatting:
  ci: disallow directional formatting

4 years agoMerge branch 'jc/fix-first-object-walk'
Junio C Hamano [Fri, 10 Dec 2021 22:35:05 +0000 (14:35 -0800)] 
Merge branch 'jc/fix-first-object-walk'

Doc update.

* jc/fix-first-object-walk:
  docs: add headers in MyFirstObjectWalk
  docs: fix places that break compilation in MyFirstObjectWalk

4 years agoMerge branch 'if/redact-packfile-uri'
Junio C Hamano [Fri, 10 Dec 2021 22:35:04 +0000 (14:35 -0800)] 
Merge branch 'if/redact-packfile-uri'

Redact the path part of packfile URI that appears in the trace output.

* if/redact-packfile-uri:
  http-fetch: redact url on die() message
  fetch-pack: redact packfile urls in traces

4 years agoMerge branch 'ja/doc-cleanup'
Junio C Hamano [Fri, 10 Dec 2021 22:35:03 +0000 (14:35 -0800)] 
Merge branch 'ja/doc-cleanup'

Doc update.

* ja/doc-cleanup:
  init doc: --shared=0xxx does not give umask but perm bits
  doc: git-init: clarify file modes in octal.
  doc: git-http-push: describe the refs as pattern pairs
  doc: uniformize <URL> placeholders' case
  doc: use three dots for indicating repetition instead of star
  doc: git-ls-files: express options as optional alternatives
  doc: use only hyphens as word separators in placeholders
  doc: express grammar placeholders between angle brackets
  doc: split placeholders as individual tokens
  doc: fix git credential synopsis

4 years agoMerge branch 'gc/remote-with-fewer-static-global-variables'
Junio C Hamano [Fri, 10 Dec 2021 22:35:02 +0000 (14:35 -0800)] 
Merge branch 'gc/remote-with-fewer-static-global-variables'

Code clean-up to eventually allow information on remotes defined
for an arbitrary repository to be read.

* gc/remote-with-fewer-static-global-variables:
  remote: die if branch is not found in repository
  remote: remove the_repository->remote_state from static methods
  remote: use remote_state parameter internally
  remote: move static variables into per-repository struct
  t5516: add test case for pushing remote refspecs

4 years agoMerge branch 'vd/sparse-sparsity-fix-on-read'
Junio C Hamano [Fri, 10 Dec 2021 22:35:01 +0000 (14:35 -0800)] 
Merge branch 'vd/sparse-sparsity-fix-on-read'

Ensure that the sparseness of the in-core index matches the
index.sparse configuration specified by the repository immediately
after the on-disk index file is read.

* vd/sparse-sparsity-fix-on-read:
  sparse-index: update do_read_index to ensure correct sparsity
  sparse-index: add ensure_correct_sparsity function
  sparse-index: avoid unnecessary cache tree clearing
  test-read-cache.c: prepare_repo_settings after config init

4 years agoMerge branch 'cw/protocol-v2-doc-fix'
Junio C Hamano [Fri, 10 Dec 2021 22:35:00 +0000 (14:35 -0800)] 
Merge branch 'cw/protocol-v2-doc-fix'

Doc update.

* cw/protocol-v2-doc-fix:
  protocol-v2.txt: align delim-pkt spec with usage

4 years agossh signing: verify ssh-keygen in test prereq
Fabian Stelzer [Thu, 9 Dec 2021 08:52:49 +0000 (09:52 +0100)] 
ssh signing: verify ssh-keygen in test prereq

Do a full ssh signing, find-principals and verify operation in the test
prereq's to make sure ssh-keygen works as expected. Only generating the
keys and verifying its presence is not sufficient in some situations.
One example was ssh-keygen creating unusable ssh keys in cygwin because
of unsafe default permissions for the key files. The other a broken
openssh 8.7 that segfaulted on any find-principals operation. This
extended prereq check avoids future test breakages in case ssh-keygen or
any environment behaviour changes.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agossh signing: make fmt-merge-msg consider key lifetime
Fabian Stelzer [Thu, 9 Dec 2021 08:52:48 +0000 (09:52 +0100)] 
ssh signing: make fmt-merge-msg consider key lifetime

Set the payload_type for check_signature() when generating merge messages to
verify merged tags signatures key lifetimes.
Implements the same tests as for verify-commit.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agossh signing: make verify-tag consider key lifetime
Fabian Stelzer [Thu, 9 Dec 2021 08:52:47 +0000 (09:52 +0100)] 
ssh signing: make verify-tag consider key lifetime

Set the payload_type for check_signature() when calling verify-tag.
Implements the same tests as for verify-commit.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agossh signing: make git log verify key lifetime
Fabian Stelzer [Thu, 9 Dec 2021 08:52:46 +0000 (09:52 +0100)] 
ssh signing: make git log verify key lifetime

Set the payload_type for check_signature() when calling git log.
Implements the same tests as for verify-commit.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agossh signing: make verify-commit consider key lifetime
Fabian Stelzer [Thu, 9 Dec 2021 08:52:45 +0000 (09:52 +0100)] 
ssh signing: make verify-commit consider key lifetime

If valid-before/after dates are configured for this signatures key in the
allowedSigners file then the verification should check if the key was valid at
the time the commit was made. This allows for graceful key rollover and
revoking keys without invalidating all previous commits.
This feature needs openssh > 8.8. Older ssh-keygen versions will simply
ignore this flag and use the current time.
Strictly speaking this feature is available in 8.7, but since 8.7 has a
bug that makes it unusable in another needed call we require 8.8.

Timestamp information is present on most invocations of check_signature.
However signer ident is not. We will need the signer email / name to be able
to implement "Trust on first use" functionality later.
Since the payload contains all necessary information we can parse it
from there. The caller only needs to provide us some info about the
payload by setting payload_type in the signature_check struct.

 - Add payload_type field & enum and payload_timestamp to struct
   signature_check
 - Populate the timestamp when not already set if we know about the
   payload type
 - Pass -Overify-time={payload_timestamp} in the users timezone to all
   ssh-keygen verification calls
 - Set the payload type when verifying commits
 - Add tests for expired, not yet valid and keys having a commit date
   outside of key validity as well as within

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agossh signing: add key lifetime test prereqs
Fabian Stelzer [Thu, 9 Dec 2021 08:52:44 +0000 (09:52 +0100)] 
ssh signing: add key lifetime test prereqs

if ssh-keygen supports -Overify-time, add test keys marked as expired,
not yet valid and valid both within the test_tick timeframe and outside of it.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agossh signing: use sigc struct to pass payload
Fabian Stelzer [Thu, 9 Dec 2021 08:52:43 +0000 (09:52 +0100)] 
ssh signing: use sigc struct to pass payload

To be able to extend the payload metadata with things like its creation
timestamp or the creators ident we remove the payload parameters to
check_signature() and use the already existing sigc->payload field
instead, only adding the length field to the struct. This also allows
us to get rid of the xmemdupz() calls in the verify functions. Since
sigc is now used to input data as well as output the result move it to
the front of the function list.

 - Add payload_length to struct signature_check
 - Populate sigc.payload/payload_len on all call sites
 - Remove payload parameters to check_signature()
 - Remove payload parameters to internal verify_* functions and use sigc
   instead
 - Remove xmemdupz() used for verbose output since payload is now already
   populated.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot/fmt-merge-msg: make gpgssh tests more specific
Fabian Stelzer [Thu, 9 Dec 2021 08:52:42 +0000 (09:52 +0100)] 
t/fmt-merge-msg: make gpgssh tests more specific

Some GPGSSH fmt-merge-msg tests were only grepping for failed/successful
signature validation and not checking for the tag in the resulting merge
message. Add the missing grep for it.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot/fmt-merge-msg: do not redirect stderr
Fabian Stelzer [Thu, 9 Dec 2021 08:52:41 +0000 (09:52 +0100)] 
t/fmt-merge-msg: do not redirect stderr

All the GPG and GPGSSH tests are redirecing stdout as well as stderr
to `actual` and grep for success/failure over the resulting file.
However, no output is printed on stderr and we do not need to
include it in the grep.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot/lib-pager: use sane_unset() to avoid breaking &&-chain
Eric Sunshine [Thu, 9 Dec 2021 05:10:57 +0000 (00:10 -0500)] 
t/lib-pager: use sane_unset() to avoid breaking &&-chain

This test intentionally breaks the &&-chain following `unset` since it
doesn't know if `unset` will succeed or fail and doesn't want a local
`unset` failure to abort the test overall. We can do better by using
sane_unset() which can be linked into the &&-chain as usual.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot2501: simplify the tests since we can now assume desired behavior
Elijah Newren [Thu, 9 Dec 2021 05:08:35 +0000 (05:08 +0000)] 
t2501: simplify the tests since we can now assume desired behavior

We no longer are dealing with a mixture of previous and desired
behavior, so simplify the tests a bit.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodir: new flag to remove_dir_recurse() to spare the original_cwd
Elijah Newren [Thu, 9 Dec 2021 05:08:34 +0000 (05:08 +0000)] 
dir: new flag to remove_dir_recurse() to spare the original_cwd

remove_dir_recurse(), and its non-static wrapper called
remove_dir_recursively(), both take flags for modifying its behavior.
As with the previous commits, we would generally like to protect
the original_cwd, but we want to forced user commands (e.g. 'git rm -rf
...') or other special cases to remove it.  Add a flag for this purpose.
After reading through every caller of remove_dir_recursively() in the
current codebase, there was only one that should be adjusted and that
one only in a very unusual circumstance.  Add a pair of new testcases to
highlight that very specific case involving submodules && --git-dir &&
--work-tree.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodir: avoid incidentally removing the original_cwd in remove_path()
Elijah Newren [Thu, 9 Dec 2021 05:08:33 +0000 (05:08 +0000)] 
dir: avoid incidentally removing the original_cwd in remove_path()

Modern git often tries to avoid leaving empty directories around when
removing files.  Originally, it did not bother.  This behavior started
with commit 80e21a9ed809 (merge-recursive::removeFile: remove empty
directories, 2005-11-19), stating the reason simply as:

    When the last file in a directory is removed as the result of a
    merge, try to rmdir the now-empty directory.

This was reimplemented in C and renamed to remove_path() in commit
e1b3a2cad7 ("Build-in merge-recursive", 2008-02-07), but was still
internal to merge-recursive.

This trend towards removing leading empty directories continued with
commit d9b814cc97f1 (Add builtin "git rm" command, 2006-05-19), which
stated the reasoning as:

    The other question is what to do with leading directories. The old
    "git rm" script didn't do anything, which is somewhat inconsistent.
    This one will actually clean up directories that have become empty
    as a result of removing the last file, but maybe we want to have a
    flag to decide the behaviour?

remove_path() in dir.c was added in 4a92d1bfb784 (Add remove_path: a
function to remove as much as possible of a path, 2008-09-27), because
it was noted that we had two separate implementations of the same idea
AND both were buggy.  It described the purpose of the function as

    a function to remove as much as possible of a path

Why remove as much as possible?  Well, at the time we probably would
have said something like:

  * removing leading directories makes things feel tidy
  * removing leading directories doesn't hurt anything so long as they
    had no files in them.

But I don't believe those reasons hold when the empty directory happens
to be the current working directory we inherited from our parent
process.  Leaving the parent process in a deleted directory can cause
user confusion when subsequent processes fail: any git command, for
example, will immediately fail with

    fatal: Unable to read current working directory: No such file or directory

Other commands may similarly get confused.  Modify remove_path() so that
the empty leading directories it also deletes does not include the
current working directory we inherited from our parent process.  I have
looked through every caller of remove_path() in the current codebase to
make sure that all should take this change.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agostash: do not attempt to remove startup_info->original_cwd
Elijah Newren [Thu, 9 Dec 2021 05:08:32 +0000 (05:08 +0000)] 
stash: do not attempt to remove startup_info->original_cwd

Since stash spawns a `clean` subprocess, make sure we run that from the
startup_info->original_cwd directory, so that the `clean` processs knows
to protect that directory.  Also, since the `clean` command might no
longer run from the toplevel, pass the ':/' magic pathspec to ensure we
still clean from the toplevel.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agorebase: do not attempt to remove startup_info->original_cwd
Elijah Newren [Thu, 9 Dec 2021 05:08:31 +0000 (05:08 +0000)] 
rebase: do not attempt to remove startup_info->original_cwd

Since rebase spawns a `checkout` subprocess, make sure we run that from
the startup_info->original_cwd directory, so that the checkout process
knows to protect that directory.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoclean: do not attempt to remove startup_info->original_cwd
Elijah Newren [Thu, 9 Dec 2021 05:08:30 +0000 (05:08 +0000)] 
clean: do not attempt to remove startup_info->original_cwd

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agosymlinks: do not include startup_info->original_cwd in dir removal
Elijah Newren [Thu, 9 Dec 2021 05:08:29 +0000 (05:08 +0000)] 
symlinks: do not include startup_info->original_cwd in dir removal

symlinks has a pair of schedule_dir_for_removal() and
remove_scheduled_dirs() functions that ensure that directories made
empty by removing other files also themselves get removed.  However, we
want to exclude startup_info->original_cwd and leave it around.  This
avoids the user getting confused by subsequent git commands (and non-git
commands) that would otherwise report confusing messages about being
unable to read the current working directory.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agounpack-trees: add special cwd handling
Elijah Newren [Thu, 9 Dec 2021 05:08:28 +0000 (05:08 +0000)] 
unpack-trees: add special cwd handling

When running commands such as `git reset --hard` from a subdirectory, if
that subdirectory is in the way of adding needed files, bail with an
error message.

Note that this change looks kind of like it duplicates the new lines of
code from the previous commit in verify_clean_subdirectory().  However,
when we are preserving untracked files, we would rather any error
messages about untracked files being in the way take precedence over
error messages about a subdirectory that happens to be the_original_cwd
being in the way.  But in the UNPACK_RESET_OVERWRITE_UNTRACKED case,
there is no untracked checking to be done, so we simply add a special
case near the top of verify_absent_1.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agounpack-trees: refuse to remove startup_info->original_cwd
Elijah Newren [Thu, 9 Dec 2021 05:08:27 +0000 (05:08 +0000)] 
unpack-trees: refuse to remove startup_info->original_cwd

In the past, when a directory needs to be removed to make room for a
file, we have always errored out when that directory contains any
untracked (but not ignored) files.  Add an extra condition on that: also
error out if the directory is the current working directory we inherited
from our parent process.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agosetup: introduce startup_info->original_cwd
Elijah Newren [Thu, 9 Dec 2021 05:08:26 +0000 (05:08 +0000)] 
setup: introduce startup_info->original_cwd

Removing the current working directory causes all subsequent git
commands run from that directory to get confused and fail with a message
about being unable to read the current working directory:

    $ git status
    fatal: Unable to read current working directory: No such file or directory

Non-git commands likely have similar warnings or even errors, e.g.

    $ bash -c 'echo hello'
    shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
    hello

This confuses end users, particularly since the command they get the
error from is not the one that caused the problem; the problem came from
the side-effect of some previous command.

We would like to avoid removing the current working directory of our
parent process; towards this end, introduce a new variable,
startup_info->original_cwd, that tracks the current working directory
that we inherited from our parent process.  For convenience of later
comparisons, we prefer that this new variable store a path relative to
the toplevel working directory (thus much like 'prefix'), except without
the trailing slash.

Subsequent commits will make use of this new variable.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot2501: add various tests for removing the current working directory
Elijah Newren [Thu, 9 Dec 2021 05:08:25 +0000 (05:08 +0000)] 
t2501: add various tests for removing the current working directory

Numerous commands will remove directories left empty as a "convenience"
after removing files within them.  That is normally fine, but removing
the current working directory can be rather inconvenient since it can
cause confusion for the user when they run subsequent commands.  For
example, after one git process has removed the current working
directory, git status/log/diff will all abort with the message:

    fatal: Unable to read current working directory: No such file or directory

We also have code paths that, when a file needs to be placed where a
directory is (due to e.g. checkout, merge, reset, whatever), will check
if this is okay and error out if not.  These rules include:
  * all tracked files under that directory are intended to be removed by
    the operation
  * none of the tracked files under that directory have uncommitted
    modification
  * there are no untracked files under that directory
However, if we end up remove the current working directory, we can cause
user confusion when they run subsequent commands, so we would prefer if
there was a fourth rule added to this list: avoid removing the current
working directory.

Since there are several code paths that can result in the current
working directory being removed, add several tests of various different
codepaths.  To make it clearer what the difference between the current
behavior and the behavior at the end of the series, code both of them
into the tests and have the appropriate behavior be selected by a flag.
Subsequent commits will toggle the flag from current to desired
behavior.

Also add a few tests suggested during the review of earlier rounds of
this patch series.

Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: intern strings
Phillip Wood [Thu, 9 Dec 2021 10:30:09 +0000 (10:30 +0000)] 
diff --color-moved: intern strings

Taking inspiration from xdl_classify_record() assign an id to each
addition and deletion such that lines that match for the current
--color-moved-ws mode share the same unique id. This reduces the
number of hash lookups a little (calculating the ids still involves
one hash lookup per line) but the main benefit is that when growing
blocks of potentially moved lines we can replace string comparisons
which involve chasing a pointer with a simple integer comparison. On a
large diff this commit reduces the time to run 'diff --color-moved' by
37% compared to the previous commit and 31% compared to master, for
'diff --color-moved-ws=allow-indentation-change' the reduction is 28%
compared to the previous commit and 96% compared to master. There is
little change in the performance of 'git log --patch' as the diffs are
smaller.

Test                                                                  HEAD^              HEAD
---------------------------------------------------------------------------------------------------------------
4002.1: diff --no-color-moved --no-color-moved-ws large change        0.38(0.33+0.05)    0.38(0.33+0.05)  +0.0%
4002.2: diff --color-moved --no-color-moved-ws large change           0.88(0.81+0.06)    0.55(0.50+0.04) -37.5%
4002.3: diff --color-moved-ws=allow-indentation-change large change   0.85(0.79+0.06)    0.61(0.54+0.06) -28.2%
4002.4: log --no-color-moved --no-color-moved-ws                      1.16(1.07+0.08)    1.15(1.09+0.05)  -0.9%
4002.5: log --color-moved --no-color-moved-ws                         1.31(1.22+0.08)    1.29(1.19+0.09)  -1.5%
4002.6: log --color-moved-ws=allow-indentation-change                 1.32(1.24+0.08)    1.31(1.18+0.13)  -0.8%

Test                                                                  master             HEAD
---------------------------------------------------------------------------------------------------------------
4002.1: diff --no-color-moved --no-color-moved-ws large change        0.38 (0.33+0.05)   0.38(0.33+0.05)  +0.0%
4002.2: diff --color-moved --no-color-moved-ws large change           0.80 (0.75+0.04)   0.55(0.50+0.04) -31.2%
4002.3: diff --color-moved-ws=allow-indentation-change large change  14.20(14.15+0.05)   0.61(0.54+0.06) -95.7%
4002.4: log --no-color-moved --no-color-moved-ws                      1.15 (1.05+0.09)   1.15(1.09+0.05)  +0.0%
4002.5: log --color-moved --no-color-moved-ws                         1.30 (1.19+0.11)   1.29(1.19+0.09)  -0.8%
4002.6: log --color-moved-ws=allow-indentation-change                 1.70 (1.63+0.06)   1.31(1.18+0.13) -22.9%

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff: use designated initializers for emitted_diff_symbol
Phillip Wood [Thu, 9 Dec 2021 10:30:08 +0000 (10:30 +0000)] 
diff: use designated initializers for emitted_diff_symbol

This makes it clearer which fields are being explicitly initialized
and will simplify the next commit where we add a new field to the
struct.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved-ws=allow-indentation-change: improve hash lookups
Phillip Wood [Thu, 9 Dec 2021 10:30:07 +0000 (10:30 +0000)] 
diff --color-moved-ws=allow-indentation-change: improve hash lookups

As libxdiff does not have a whitespace flag to ignore the indentation
the code for --color-moved-ws=allow-indentation-change uses
XDF_IGNORE_WHITESPACE and then filters out any hash lookups where
there are non-indentation changes. This filtering is inefficient as
we have to perform another string comparison.

By using the offset data that we have already computed to skip the
indentation we can avoid using XDF_IGNORE_WHITESPACE and safely remove
the extra checks which improves the performance by 11% and paves the
way for the elimination of string comparisons in the next commit.

This change slightly increases the run time of other --color-moved
modes. This could be avoided by using different comparison functions
for the different modes but after the next two commits there is no
measurable benefit in doing so.

There is a change in behavior for lines that begin with a form-feed or
vertical-tab character. Since b46054b374 ("xdiff: use
git-compat-util", 2019-04-11) xdiff does not treat '\f' or '\v' as
whitespace characters. This means that lines starting with those
characters are never considered to be blank and never match a line
that does not start with the same character. After this patch a line
matching "^[\f\v\r]*[ \t]*$" is considered to be blank by
--color-moved-ws=allow-indentation-change and lines beginning
"^[\f\v\r]*[ \t]*" can match another line if the suffixes match. This
changes the output of git show for d18f76dccf ("compat/regex: use the
regex engine from gawk for compat", 2010-08-17) as some lines in the
pre-image before a moved block that contain '\f' are now considered
moved as well as they match a blank line before the moved lines in the
post-image. This commit updates one of the tests to reflect this
change.

Test                                                                  HEAD^             HEAD
--------------------------------------------------------------------------------------------------------------
4002.1: diff --no-color-moved --no-color-moved-ws large change        0.38(0.33+0.05)   0.38(0.33+0.05)  +0.0%
4002.2: diff --color-moved --no-color-moved-ws large change           0.86(0.82+0.04)   0.88(0.84+0.04)  +2.3%
4002.3: diff --color-moved-ws=allow-indentation-change large change   0.97(0.94+0.03)   0.86(0.81+0.05) -11.3%
4002.4: log --no-color-moved --no-color-moved-ws                      1.16(1.07+0.09)   1.16(1.06+0.09)  +0.0%
4002.5: log --color-moved --no-color-moved-ws                         1.32(1.26+0.06)   1.33(1.27+0.05)  +0.8%
4002.6: log --color-moved-ws=allow-indentation-change                 1.35(1.29+0.06)   1.33(1.24+0.08)  -1.5%

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: stop clearing potential moved blocks
Phillip Wood [Thu, 9 Dec 2021 10:30:06 +0000 (10:30 +0000)] 
diff --color-moved: stop clearing potential moved blocks

moved_block_clear() was introduced in 74d156f4a1 ("diff
--color-moved-ws: fix double free crash", 2018-10-04) to free the
memory that was allocated when initializing a potential moved
block. However since 21536d077f ("diff --color-moved-ws: modify
allow-indentation-change", 2018-11-23) initializing a potential moved
block no longer allocates any memory. Up until the last commit we were
relying on moved_block_clear() to set the `match` pointer to NULL when
a block stopped matching, but since that commit we do not clear a
moved block that does not match so it does not make sense to clear
them elsewhere.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: shrink potential moved blocks as we go
Phillip Wood [Thu, 9 Dec 2021 10:30:05 +0000 (10:30 +0000)] 
diff --color-moved: shrink potential moved blocks as we go

Rather than setting `match` to NULL and then looping over the list of
potential matched blocks for a second time to remove blocks with no
matches just filter out the blocks with no matches as we go.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: unify moved block growth functions
Phillip Wood [Thu, 9 Dec 2021 10:30:04 +0000 (10:30 +0000)] 
diff --color-moved: unify moved block growth functions

After the last two commits pmb_advance_or_null() and
pmb_advance_or_null_multi_match() differ only in the comparison they
perform. Lets simplify the code by combining them into a single
function.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: call comparison function directly
Phillip Wood [Thu, 9 Dec 2021 10:30:03 +0000 (10:30 +0000)] 
diff --color-moved: call comparison function directly

This change will allow us to easily combine pmb_advance_or_null() and
pmb_advance_or_null_multi_match() in the next commit. Calling
xdiff_compare_lines() directly rather than using a function pointer
from the hash map has little effect on the run time.

Test                                                                  HEAD^             HEAD
-------------------------------------------------------------------------------------------------------------
4002.1: diff --no-color-moved --no-color-moved-ws large change        0.38(0.35+0.03)   0.38(0.32+0.06) +0.0%
4002.2: diff --color-moved --no-color-moved-ws large change           0.87(0.83+0.04)   0.87(0.80+0.06) +0.0%
4002.3: diff --color-moved-ws=allow-indentation-change large change   0.97(0.92+0.04)   0.97(0.93+0.04) +0.0%
4002.4: log --no-color-moved --no-color-moved-ws                      1.17(1.06+0.10)   1.16(1.10+0.05) -0.9%
4002.5: log --color-moved --no-color-moved-ws                         1.32(1.24+0.08)   1.31(1.22+0.09) -0.8%
4002.6: log --color-moved-ws=allow-indentation-change                 1.36(1.25+0.10)   1.35(1.25+0.10) -0.7%

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved-ws=allow-indentation-change: simplify and optimize
Phillip Wood [Thu, 9 Dec 2021 10:30:02 +0000 (10:30 +0000)] 
diff --color-moved-ws=allow-indentation-change: simplify and optimize

If we already have a block of potentially moved lines then as we move
down the diff we need to check if the next line of each potentially
moved line matches the current line of the diff. The implementation of
--color-moved-ws=allow-indentation-change was needlessly performing
this check on all the lines in the diff that matched the current line
rather than just the current line. To exacerbate the problem finding
all the other lines in the diff that match the current line involves a
fuzzy lookup so we were wasting even more time performing a second
comparison to filter out the non-matching lines. Fixing this reduces
time to run
  git diff --color-moved-ws=allow-indentation-change v2.28.0 v2.29.0
by 93% compared to master and simplifies the code.

Test                                                                  HEAD^              HEAD
---------------------------------------------------------------------------------------------------------------
4002.1: diff --no-color-moved --no-color-moved-ws large change        0.38 (0.35+0.03)   0.38(0.35+0.03)  +0.0%
4002.2: diff --color-moved --no-color-moved-ws large change           0.86 (0.80+0.06)   0.87(0.83+0.04)  +1.2%
4002.3: diff --color-moved-ws=allow-indentation-change large change  19.01(18.93+0.06)   0.97(0.92+0.04) -94.9%
4002.4: log --no-color-moved --no-color-moved-ws                      1.16 (1.06+0.09)   1.17(1.06+0.10)  +0.9%
4002.5: log --color-moved --no-color-moved-ws                         1.32 (1.25+0.07)   1.32(1.24+0.08)  +0.0%
4002.6: log --color-moved-ws=allow-indentation-change                 1.71 (1.64+0.06)   1.36(1.25+0.10) -20.5%

Test                                                                  master             HEAD
---------------------------------------------------------------------------------------------------------------
4002.1: diff --no-color-moved --no-color-moved-ws large change        0.38 (0.33+0.05)   0.38(0.35+0.03)  +0.0%
4002.2: diff --color-moved --no-color-moved-ws large change           0.80 (0.75+0.04)   0.87(0.83+0.04)  +8.7%
4002.3: diff --color-moved-ws=allow-indentation-change large change  14.20(14.15+0.05)   0.97(0.92+0.04) -93.2%
4002.4: log --no-color-moved --no-color-moved-ws                      1.15 (1.05+0.09)   1.17(1.06+0.10)  +1.7%
4002.5: log --color-moved --no-color-moved-ws                         1.30 (1.19+0.11)   1.32(1.24+0.08)  +1.5%
4002.6: log --color-moved-ws=allow-indentation-change                 1.70 (1.63+0.06)   1.36(1.25+0.10) -20.0%

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff: simplify allow-indentation-change delta calculation
Phillip Wood [Thu, 9 Dec 2021 10:30:01 +0000 (10:30 +0000)] 
diff: simplify allow-indentation-change delta calculation

Now that we reliably end a block when the sign changes we don't need
the whitespace delta calculation to rely on the sign.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: avoid false short line matches and bad zebra coloring
Phillip Wood [Thu, 9 Dec 2021 10:30:00 +0000 (10:30 +0000)] 
diff --color-moved: avoid false short line matches and bad zebra coloring

When marking moved lines it is possible for a block of potential
matched lines to extend past a change in sign when there is a sequence
of added lines whose text matches the text of a sequence of deleted
and added lines. Most of the time either `match` will be NULL or
`pmb_advance_or_null()` will fail when the loop encounters a change of
sign but there are corner cases where `match` is non-NULL and
`pmb_advance_or_null()` successfully advances the moved block despite
the change in sign.

One consequence of this is highlighting a short line as moved when it
should not be. For example

-moved line  # Correctly highlighted as moved
+short line  # Wrongly highlighted as moved
 context
+moved line  # Correctly highlighted as moved
+short line
 context
-short line

The other consequence is coloring a moved addition following a moved
deletion in the wrong color. In the example below the first "+moved
line 3" should be highlighted as newMoved not newMovedAlternate.

-moved line 1 # Correctly highlighted as oldMoved
-moved line 2 # Correctly highlighted as oldMovedAlternate
+moved line 3 # Wrongly highlighted as newMovedAlternate
 context      # Everything else is highlighted correctly
+moved line 2
+moved line 3
 context
+moved line 1
-moved line 3

These false matches are more likely when using --color-moved-ws with
the exception of --color-moved-ws=allow-indentation-change which ties
the sign of the current whitespace delta to the sign of the line to
avoid this problem. The fix is to check that the sign of the new line
being matched is the same as the sign of the line that started the
block of potential matches.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved=zebra: fix alternate coloring
Phillip Wood [Thu, 9 Dec 2021 10:29:59 +0000 (10:29 +0000)] 
diff --color-moved=zebra: fix alternate coloring

b0a2ba4776 ("diff --color-moved=zebra: be stricter with color
alternation", 2018-11-23) sought to avoid using the alternate colors
unless there are two adjacent moved blocks of the same
sign. Unfortunately it contains two bugs that prevented it from fixing
the problem properly. Firstly `last_symbol` is reset at the start of
each iteration of the loop losing the symbol of the last line and
secondly when deciding whether to use the alternate color it should be
checking if the current line is the same sign of the last line, not a
different sign. The combination of the two errors means that we still
use the alternate color when we should do but we also use it when we
shouldn't. This is most noticable when using
--color-moved-ws=allow-indentation-change with hunks like

-this line gets indented
+    this line gets indented

where the post image is colored with newMovedAlternate rather than
newMoved. While this does not matter much, the next commit will change
the coloring to be correct in this case, so lets fix the bug here to
make it clear why the output is changing and add a regression test.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: rewind when discarding pmb
Phillip Wood [Thu, 9 Dec 2021 10:29:58 +0000 (10:29 +0000)] 
diff --color-moved: rewind when discarding pmb

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: factor out function
Phillip Wood [Thu, 9 Dec 2021 10:29:57 +0000 (10:29 +0000)] 
diff --color-moved: factor out function

This code is quite heavily indented and having it in its own function
simplifies an upcoming change.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: clear all flags on blocks that are too short
Phillip Wood [Thu, 9 Dec 2021 10:29:56 +0000 (10:29 +0000)] 
diff --color-moved: clear all flags on blocks that are too short

If a block of potentially moved lines is not long enough then the
DIFF_SYMBOL_MOVED_LINE flag is cleared on the matching lines so they
are not marked as moved. To avoid problems when we start rewinding
after an unsuccessful match in a couple of commits time make sure all
the move related flags are cleared, not just DIFF_SYMBOL_MOVED_LINE.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff --color-moved: add perf tests
Phillip Wood [Thu, 9 Dec 2021 10:29:55 +0000 (10:29 +0000)] 
diff --color-moved: add perf tests

Add some tests so we can monitor changes to the performance of the
move detection code. The tests record the performance --color-moved
and --color-moved-ws=allow-indentation-change for a large diff and a
sequence of smaller diffs. The range of commits used for the large
diff can be customized by exporting TEST_REV_A and TEST_REV_B when
running the test.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoflex-array: simplify compiler-specific workaround
Junio C Hamano [Thu, 9 Dec 2021 01:39:39 +0000 (17:39 -0800)] 
flex-array: simplify compiler-specific workaround

We use "type array[];" syntax for the flex-array member at the end
of a struct under C99 or later, except when we are building with
older SUNPRO_C compilers.  As we find more vendor compilers that
claim to grok C99 but not understand the flex-array syntax, the
existing "If we are using C99, but not with these compilers..."
conditional will keep growing.

Make it more manageable by listing vendor-specific exceptions
earlier, with the expectation that new exceptions will not be
combined into existing ones to make the condition longer, and
instead will be implemented as a new "#elif" in the cascade of
similar to old SUNPRO_C, we can just add a single line

    #elif defined(_MSC_VER)

immediately before "#elif defined(__GNUC__)" to cause us to fallback
to the safer but a bit wasteful version.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotmp-objdir: disable ref updates when replacing the primary odb
Neeraj Singh [Mon, 6 Dec 2021 22:05:05 +0000 (22:05 +0000)] 
tmp-objdir: disable ref updates when replacing the primary odb

When creating a subprocess with a temporary ODB, we set the
GIT_QUARANTINE_ENVIRONMENT env var to tell child Git processes not
to update refs, since the tmp-objdir may go away.

Introduce a similar mechanism for in-process temporary ODBs when
we call tmp_objdir_replace_primary_odb. Now both mechanisms set
the disable_ref_updates flag on the odb, which is queried by
the ref_transaction_prepare function.

Peff's test case [1] was invoking ref updates via the cachetextconv
setting. That particular code silently does nothing when a ref
update is forbidden. See the call to notes_cache_put in
fill_textconv where errors are ignored.

[1] https://lore.kernel.org/git/YVOn3hDsb5pnxR53@coredump.intra.peff.net/

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Neeraj Singh <neerajsi@microsoft.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotmp-objdir: new API for creating temporary writable databases
Neeraj Singh [Mon, 6 Dec 2021 22:05:04 +0000 (22:05 +0000)] 
tmp-objdir: new API for creating temporary writable databases

The tmp_objdir API provides the ability to create temporary object
directories, but was designed with the goal of having subprocesses
access these object stores, followed by the main process migrating
objects from it to the main object store or just deleting it.  The
subprocesses would view it as their primary datastore and write to it.

Here we add the tmp_objdir_replace_primary_odb function that replaces
the current process's writable "main" object directory with the
specified one. The previous main object directory is restored in either
tmp_objdir_migrate or tmp_objdir_destroy.

For the --remerge-diff usecase, add a new `will_destroy` flag in `struct
object_database` to mark ephemeral object databases that do not require
fsync durability.

Add 'git prune' support for removing temporary object databases, and
make sure that they have a name starting with tmp_ and containing an
operation-specific name.

Based-on-patch-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Neeraj Singh <neerajsi@microsoft.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoconfig.mak.dev: specify -std=gnu99 for gcc/clang
Jeff King [Wed, 8 Dec 2021 19:50:54 +0000 (14:50 -0500)] 
config.mak.dev: specify -std=gnu99 for gcc/clang

The point of DEVELOPER=1 is to turn up the warnings so we can catch
portability or correctness mistakes at the compiler level. But since
modern compilers tend to default to modern standards like gnu17, we
might miss warnings about older standards, even though we expect Git to
build with compilers that use them.

So it's helpful for developer builds to set the -std argument to our
lowest-common denominator. Traditionally this was c89, but since we're
moving to assuming c99 in 7bc341e21b (git-compat-util: add a test
balloon for C99 support, 2021-12-01) that seems like a good spot to
land. And as explained in that commit, we want "gnu99" because we still
want to take advantage of some extensions when they're available.

The new argument kicks in only for clang and gcc (which we know to
support "-std=" and "gnu" standards). And only for compiler versions
which default to a newer standard. That will avoid accidentally
silencing any build problems that non-developers would run into on older
compilers that default to c89.

My digging found that the default switched to gnu11 in gcc 5.1.0.
Clang's documentation is less clear, but has done so since at least
clang-7. So that's what I put in the conditional here. It's OK to err on
the side of not-enabling this for older compilers. Most developers (as
well as CI) are using much more recent versions, so any warnings will
eventually surface.

A concrete example is anonymous unions, which became legal in c11.
Without this patch, "gcc -pedantic" will not complain about them, but
will if we add in "-std=gnu99".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoMerge branch 'bc/require-c99' into jk/limit-developers-to-gnu99
Junio C Hamano [Wed, 8 Dec 2021 21:16:32 +0000 (13:16 -0800)] 
Merge branch 'bc/require-c99' into jk/limit-developers-to-gnu99

* bc/require-c99:
  git-compat-util: add a test balloon for C99 support

4 years agopull, fetch: fix segfault in --set-upstream option
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 22:04:30 +0000 (23:04 +0100)] 
pull, fetch: fix segfault in --set-upstream option

Fix a segfault in the --set-upstream option added in
24bc1a12926 (pull, fetch: add --set-upstream option, 2019-08-19) added
in v2.24.0.

The code added there did not do the same checking we do for "git
branch" itself since 8efb8899cfe (branch: segfault fixes and
validation, 2013-02-23), which in turn fixed the same sort of segfault
I'm fixing now in "git branch --set-upstream-to", see
6183d826ba6 (branch: introduce --set-upstream-to, 2012-08-20).

The warning message I'm adding here is an amalgamation of the error
added for "git branch" in 8efb8899cfe, and the error output
install_branch_config() itself emits, i.e. it trims "refs/heads/" from
the name and says "branch X on remote", not "branch refs/heads/X on
remote".

I think it would make more sense to simply die() here, but in the
other checks for --set-upstream added in 24bc1a12926 we issue a
warning() instead. Let's do the same here for consistency for now.

There was an earlier submitted alternate way of fixing this in [1],
due to that patch breaking threading with the original report at [2] I
didn't notice it before authoring this version. I think the more
detailed warning message here is better, and we should also have tests
for this behavior.

The --no-rebase option to "git pull" is needed as of the recently
merged 7d0daf3f12f (Merge branch 'en/pull-conflicting-options',
2021-08-30).

1. https://lore.kernel.org/git/20210706162238.575988-1-clemens@endorphin.org/
2. https://lore.kernel.org/git/CAG6gW_uHhfNiHGQDgGmb1byMqBA7xa8kuH1mP-wAPEe5Tmi2Ew@mail.gmail.com/

Reported-by: Clemens Fruhwirth <clemens@endorphin.org>
Reported-by: Jan Pokorný <poki@fnusa.cz>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agocbtree: remove broken and unused cb_unlink
Eric Wong [Tue, 7 Dec 2021 18:38:10 +0000 (18:38 +0000)] 
cbtree: remove broken and unused cb_unlink

cb_unlink is broken once a node is no longer self-referential
due to subsequent insertions.  This is a consequence of an
intrusive implementation and I'm not sure if it's easily fixable
while retaining our cache-friendly intrusive property (I've
tried for several hours in another project).

In any case, we're not using cb_unlink anywhere in our codebase,
just get rid of it to avoid misleading future readers.

Signed-off-by: Eric Wong <e@80x24.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoconfig API: use get_error_routine(), not vreportf()
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 18:26:34 +0000 (19:26 +0100)] 
config API: use get_error_routine(), not vreportf()

Change the git_die_config() function added in 5a80e97c827 (config: add
`git_die_config()` to the config-set API, 2014-08-07) to use the
public callbacks in the usage.[ch] API instead of the the underlying
vreportf() function.

In preceding commits the rest of the vreportf() users outside of
usage.c was migrated to die_message(), so we can now make it "static".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agousage.c + gc: add and use a die_message_errno()
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 18:26:33 +0000 (19:26 +0100)] 
usage.c + gc: add and use a die_message_errno()

Change the "error: " output when we exit with 128 due to gc.log errors
to use a "fatal: " prefix instead. To do this add a
die_message_errno() a sibling function to the die_errno() added in a
preceding commit.

Before this we'd expect report_last_gc_error() to return -1 from
error_errno() in this case. It already treated a status of 0 and 1
specially. Let's just document that anything that's not 0 or 1 should
be returned.

We could also retain the "ret < 0" behavior here without hardcoding
128 by returning -128, and having the caller do a "return -ret", but I
think this makes more sense, and preserves the path from
die_message*()'s return value to the "return" without hardcoding
"128".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agogc: return from cmd_gc(), don't call exit()
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 18:26:32 +0000 (19:26 +0100)] 
gc: return from cmd_gc(), don't call exit()

A minor code cleanup. Let's "return" from cmd_gc() instead of calling
exit(). See 338abb0f045 (builtins + test helpers: use return instead
of exit() in cmd_*, 2021-06-08) for other such cases.

While we're at it add a \n to separate the variable declaration from
the rest of the code in this block. Both of these changes make a
subsequent change smaller and easier to read.

This change isn't really needed for that subsequent change, but now
someone viewing that future behavior change won't need to wonder why
we're either still calling exit() here, or fixing it while we're at
it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agousage.c API users: use die_message() for error() + exit 128
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 18:26:31 +0000 (19:26 +0100)] 
usage.c API users: use die_message() for error() + exit 128

Continue the migration of code that printed a message and exited with
128. In this case the caller used "error()", so we'll be changing the
output from "error: " to "fatal: ". This change is intentional and
desired.

This code is dying, so it should emit "fatal", the only reason it
didn't do so was because before the existence of "die_message()" it
would have needed to craft its own "fatal: " message.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agousage.c API users: use die_message() for "fatal :" + exit 128
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 18:26:30 +0000 (19:26 +0100)] 
usage.c API users: use die_message() for "fatal :" + exit 128

Change code that printed its own "fatal: " message and exited with a
status code of 128 to use the die_message() function added in a
preceding commit.

This change also demonstrates why the return value of
die_message_routine() needed to be that of "report_fn". We have
callers such as the run-command.c::child_err_spew() which would like
to replace its error routine with the return value of
"get_die_message_routine()".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agousage.c: add a die_message() routine
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 18:26:29 +0000 (19:26 +0100)] 
usage.c: add a die_message() routine

We have code in various places that would like to call die(), but
wants to defer the exit(128) it would invoke, e.g. to print an
additional message, or adjust the exit code. Add a die_message()
helper routine to bridge this gap in the API.

Functionally this behaves just like the error() routine, except it'll
print a "fatal: " prefix, and it will return with 128 instead of -1,
this is so that caller can pass the return value to "exit()", instead
of having to hardcode "exit(128)".

Note that as with the other routines the "die_message_builtin" needs
to return "void" and otherwise conform to the "report_fn"
signature.

As we'll see in a subsequent commit callers will want to replace
e.g. their default "die_routine" with a "die_message_routine".

For now we're just adding the routine and making die_builtin() in
usage.c itself use it. In order to do that we need to add a
get_die_message_routine() function, which works like the other
get_*_routine() functions in usage.c. There is no
set_die_message_rotine(), as it hasn't been needed yet. We can add it
if we ever need it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot1430: create valid symrefs using test-helper
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:20 +0000 (13:38 +0000)] 
t1430: create valid symrefs using test-helper

This still leaves some other direct filesystem access. Currently, the files
backend does not allow invalidly named symrefs. Fixes for this are currently in
the 'seen' branch

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot1430: remove refs using test-tool
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:19 +0000 (13:38 +0000)] 
t1430: remove refs using test-tool

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agorefs: introduce REF_SKIP_REFNAME_VERIFICATION flag
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:18 +0000 (13:38 +0000)] 
refs: introduce REF_SKIP_REFNAME_VERIFICATION flag

Use this flag with the test-helper in t1430, to avoid direct writes to the ref
database.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agorefs: introduce REF_SKIP_OID_VERIFICATION flag
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:17 +0000 (13:38 +0000)] 
refs: introduce REF_SKIP_OID_VERIFICATION flag

This lets the ref-store test helper write non-existent or unparsable objects
into the ref storage.

Use this to make t1006 and t3800 independent of the files storage backend.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agorefs: update comment.
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:16 +0000 (13:38 +0000)] 
refs: update comment.

REF_IS_PRUNING is right below this comment, so it clearly does not belong in
this comment. This was apparently introduced in commit 5ac95fee (Nov 5, 2017
"refs: tidy up and adjust visibility of the `ref_update` flags").

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotest-ref-store: plug memory leak in cmd_delete_refs
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:15 +0000 (13:38 +0000)] 
test-ref-store: plug memory leak in cmd_delete_refs

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotest-ref-store: parse symbolic flag constants
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:14 +0000 (13:38 +0000)] 
test-ref-store: parse symbolic flag constants

This lets tests use REF_XXXX constants instead of hardcoded integers. The flag
names should be separated by a ','.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotest-ref-store: remove force-create argument for create-reflog
Han-Wen Nienhuys [Tue, 7 Dec 2021 13:38:13 +0000 (13:38 +0000)] 
test-ref-store: remove force-create argument for create-reflog

Nobody uses force_create=0, so this flag is unnecessary.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoMerge branch 'hn/create-reflog-simplify' into hn/reftable-coverity-fixes
Junio C Hamano [Tue, 7 Dec 2021 20:45:15 +0000 (12:45 -0800)] 
Merge branch 'hn/create-reflog-simplify' into hn/reftable-coverity-fixes

* hn/create-reflog-simplify:
  refs: drop force_create argument of create_reflog API

4 years agoMerge branch 'hn/reftable' into hn/reftable-coverity-fixes
Junio C Hamano [Tue, 7 Dec 2021 20:44:49 +0000 (12:44 -0800)] 
Merge branch 'hn/reftable' into hn/reftable-coverity-fixes

* hn/reftable:
  Add "test-tool dump-reftable" command.
  reftable: add dump utility
  reftable: implement stack, a mutable database of reftable files.
  reftable: implement refname validation
  reftable: add merged table view
  reftable: add a heap-based priority queue for reftable records
  reftable: reftable file level tests
  reftable: read reftable files
  reftable: generic interface to tables
  reftable: write reftable files
  reftable: a generic binary tree implementation
  reftable: reading/writing blocks
  Provide zlib's uncompress2 from compat/zlib-compat.c
  reftable: (de)serialization for the polymorphic record type.
  reftable: add blocksource, an abstraction for random access reads
  reftable: utility functions
  reftable: add error related functionality
  reftable: add LICENSE
  hash.h: provide constants for the hash IDs

4 years agoobject.c: use BUG(...) no die("BUG: ...") in lookup_object_by_type()
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 11:05:54 +0000 (12:05 +0100)] 
object.c: use BUG(...) no die("BUG: ...") in lookup_object_by_type()

Adjust code added in 7463064b280 (object.h: add
lookup_object_by_type() function, 2021-06-22) to use the BUG()
function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agopathspec: use BUG(...) not die("BUG:%s:%d....", <file>, <line>)
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 11:05:53 +0000 (12:05 +0100)] 
pathspec: use BUG(...) not die("BUG:%s:%d....", <file>, <line>)

Change code that was added in 8f4f8f4579f (guard against new pathspec
magic in pathspec matching code, 2013-07-14) to use the BUG() macro
instead of emitting a "fatal" message with the "__FILE__"-name and
"__LINE__"-numbers.

The original code predated the existence of the BUG() function, which
was added in d8193743e08 (usage.c: add BUG() function, 2017-05-12).

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agostrbuf.h: use BUG(...) not die("BUG: ...")
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 11:05:52 +0000 (12:05 +0100)] 
strbuf.h: use BUG(...) not die("BUG: ...")

In 7141efab248 (strbuf: clarify assertion in strbuf_setlen(),
2011-04-27) this 'die("BUG: "' invocation was added with the rationale
that strbuf.c had existing users doing the same, but those users were
later changed to use BUG() in 033abf97fcb (Replace all die("BUG: ...")
calls by BUG() ones, 2018-05-02). Let's do the same here.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agopack-objects: use BUG(...) not die("BUG: ...")
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 11:05:51 +0000 (12:05 +0100)] 
pack-objects: use BUG(...) not die("BUG: ...")

Change this code added in da93d12b004 (pack-objects: be incredibly
anal about stdio semantics, 2006-04-02) to use BUG() instead.

See 1a07e59c3e2 (Update messages in preparation for i18n, 2018-07-21)
for when the "BUG: " prefix was added, and [1] for background on the
Solaris behavior that prompted the exhaustive error checking in this
fgets() loop.

1. https://lore.kernel.org/git/824.1144007555@lotus.CS.Berkeley.EDU/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agocommon-main.c: call exit(), don't return
Ævar Arnfjörð Bjarmason [Tue, 7 Dec 2021 10:13:51 +0000 (11:13 +0100)] 
common-main.c: call exit(), don't return

Change the main() function to call "exit()" instead of ending with a
"return" statement. The "exit()" function is our own wrapper that
calls trace2_cmd_exit_fl() for us, from git-compat-util.h:

#define exit(code) exit(trace2_cmd_exit_fl(__FILE__, __LINE__, (code)))

That "exit()" wrapper has been in use ever since ee4512ed481 (trace2:
create new combined trace facility, 2019-02-22).

This changes nothing about how we "exit()", as we'd invoke
"trace2_cmd_exit_fl()" in both cases due to the wrapper, this change
makes it easier to reason about this code, as we're now always
obviously relying on our "exit()" wrapper.

There is already code immediately downstream of our "main()" which has
a hard reliance on that, e.g. the various "exit()" calls downstream of
"cmd_main()" in "git.c".

We even had a comment in "t/helper/test-trace2.c" that seemed to be
confused about how the "exit()" wrapper interacted with uses of
"return", even though it was introduced in the same trace2 series in
a15860dca3f (trace2: t/helper/test-trace2, t0210.sh, t0211.sh,
t0212.sh, 2019-02-22), after the aforementioned ee4512ed481. Perhaps
it pre-dated the "exit()" wrapper?

This change makes the "trace2_cmd_exit()" macro orphaned, we now
always use "trace2_cmd_exit_fl()" directly, but let's keep that
simpler example in place. Even if we're unlikely to get another
"main()" other than the one in our "common-main.c", there's some value
in having the API documentation and example discuss a simpler version
that doesn't require an "exit()" wrapper macro.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoblame: enable and test the sparse index
Lessley Dennington [Mon, 6 Dec 2021 15:56:01 +0000 (15:56 +0000)] 
blame: enable and test the sparse index

Enable the sparse index for the 'git blame' command. The index was already
not expanded with this command, so the most interesting thing to do is to
add tests that verify that 'git blame' behaves correctly when the sparse
index is enabled and that its performance improves. More specifically, these
cases are:

1. The index is not expanded for 'blame' when given paths in the sparse
checkout cone at multiple levels.

2. Performance measurably improves for 'blame' with sparse index when given
paths in the sparse checkout cone at multiple levels.

The `p2000` tests demonstrate a ~60% execution time reduction when running
'blame' for a file two levels deep and and a ~30% execution time reduction
for a file three levels deep.

Test                                         before  after
----------------------------------------------------------------
2000.62: git blame f2/f4/a (full-v3)         0.31    0.32 +3.2%
2000.63: git blame f2/f4/a (full-v4)         0.29    0.31 +6.9%
2000.64: git blame f2/f4/a (sparse-v3)       0.55    0.23 -58.2%
2000.65: git blame f2/f4/a (sparse-v4)       0.57    0.23 -59.6%
2000.66: git blame f2/f4/f3/a (full-v3)      0.77    0.85 +10.4%
2000.67: git blame f2/f4/f3/a (full-v4)      0.78    0.81 +3.8%
2000.68: git blame f2/f4/f3/a (sparse-v3)    1.07    0.72 -32.7%
2000.99: git blame f2/f4/f3/a (sparse-v4)    1.05    0.73 -30.5%

We do not include paths outside the sparse checkout cone because blame
does not support blaming files that are not present in the working
directory. This is true in both sparse and full checkouts.

Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff: enable and test the sparse index
Lessley Dennington [Mon, 6 Dec 2021 15:56:00 +0000 (15:56 +0000)] 
diff: enable and test the sparse index

Enable the sparse index within the 'git diff' command. Its implementation
already safely integrates with the sparse index because it shares code
with the 'git status' and 'git checkout' commands that were already
integrated.  For more details see:

d76723ee53 (status: use sparse-index throughout, 2021-07-14)
1ba5f45132 (checkout: stop expanding sparse indexes, 2021-06-29)

The most interesting thing to do is to add tests that verify that 'git
diff' behaves correctly when the sparse index is enabled. These cases are:

1. The index is not expanded for 'diff' and 'diff --staged'
2. 'diff' and 'diff --staged' behave the same in full checkout, sparse
checkout, and sparse index repositories in the following partially-staged
scenarios (i.e. the index, HEAD, and working directory differ at a given
path):
    1. Path is within sparse-checkout cone
    2. Path is outside sparse-checkout cone
    3. A merge conflict exists for paths outside sparse-checkout cone

The `p2000` tests demonstrate a ~44% execution time reduction for 'git
diff' and a ~86% execution time reduction for 'git diff --staged' using a
sparse index:

Test                                      before  after
-------------------------------------------------------------
2000.30: git diff (full-v3)               0.33    0.34 +3.0%
2000.31: git diff (full-v4)               0.33    0.35 +6.1%
2000.32: git diff (sparse-v3)             0.53    0.31 -41.5%
2000.33: git diff (sparse-v4)             0.54    0.29 -46.3%
2000.34: git diff --cached (full-v3)      0.07    0.07 +0.0%
2000.35: git diff --cached (full-v4)      0.07    0.08 +14.3%
2000.36: git diff --cached (sparse-v3)    0.28    0.04 -85.7%
2000.37: git diff --cached (sparse-v4)    0.23    0.03 -87.0%

Co-authored-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agodiff: replace --staged with --cached in t1092 tests
Lessley Dennington [Mon, 6 Dec 2021 15:55:59 +0000 (15:55 +0000)] 
diff: replace --staged with --cached in t1092 tests

Replace uses of the synonym --staged in t1092 tests with --cached (which
is the real and preferred option). This will allow consistency in the new
tests to be added with the upcoming change to enable the sparse index for
diff.

Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agorepo-settings: prepare_repo_settings only in git repos
Lessley Dennington [Mon, 6 Dec 2021 15:55:58 +0000 (15:55 +0000)] 
repo-settings: prepare_repo_settings only in git repos

Check whether git directory exists before adding any repo settings. If it
does not exist, BUG with the message that one cannot add settings for an
uninitialized repository. If it does exist, proceed with adding repo
settings.

Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotest-read-cache: set up repo after git directory
Lessley Dennington [Mon, 6 Dec 2021 15:55:57 +0000 (15:55 +0000)] 
test-read-cache: set up repo after git directory

Move repo setup to occur after git directory is set up. This will protect
against test failures in the upcoming change to BUG in
prepare_repo_settings if no git directory exists.

Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agocommit-graph: return if there is no git directory
Lessley Dennington [Mon, 6 Dec 2021 15:55:56 +0000 (15:55 +0000)] 
commit-graph: return if there is no git directory

Return early if git directory does not exist. This will protect against
test failures in the upcoming change to BUG in prepare_repo_settings if no
git directory exists.

Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agogit: ensure correct git directory setup with -h
Lessley Dennington [Mon, 6 Dec 2021 15:55:55 +0000 (15:55 +0000)] 
git: ensure correct git directory setup with -h

Ensure correct git directory setup when -h is passed with commands. This
specifically applies to repos with special help text configuration
variables and to commands run with -h outside a repository. This
will also protect against test failures in the upcoming change to BUG in
prepare_repo_settings if no git directory exists.

Note: this diff is better seen when ignoring whitespace changes.

Co-authored-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agounpack-trees: use traverse_path instead of name
Derrick Stolee [Mon, 6 Dec 2021 14:10:37 +0000 (14:10 +0000)] 
unpack-trees: use traverse_path instead of name

The sparse_dir_matches_path() method compares a cache entry that is a
sparse directory entry against a 'struct traverse_info *info' and a
'struct name_entry *p' to see if the cache entry has exactly the right
name for those other inputs.

This method was introduced in 523506d (unpack-trees: unpack sparse
directory entries, 2021-07-14), but included a significant mistake. The
path comparisons used 'info->name' instead of 'info->traverse_path'.
Since 'info->name' only stores a single tree entry name while
'info->traverse_path' stores the full path from root, this method does
not work when 'info' is in a subdirectory of a directory. Replacing the
right strings and their corresponding lengths make the method work
properly.

The previous change included a failing test that exposes this issue.
That test now passes. The critical detail is that as we go deep into
unpack_trees(), the logic for merging a sparse directory entry with a
tree entry during 'git checkout' relies on this
sparse_dir_matches_path() in order to avoid calling
traverse_trees_recursive() during unpack_callback() in this hunk:

if (!is_sparse_directory_entry(src[0], names, info) &&
    traverse_trees_recursive(n, dirmask, mask & ~dirmask,
    names, info) < 0) {
return -1;
}

For deep paths, the short-circuit never occurred and
traverse_trees_recursive() was being called incorrectly and that was
causing other strange issues. Specifically, the error message from the
now-passing test previously included this:

      error: Your local changes to the following files would be overwritten by checkout:
              deep/deeper1/deepest2/a
              deep/deeper1/deepest3/a
      Please commit your changes or stash them before you switch branches.
      Aborting

These messages occurred because the 'current' cache entry in
twoway_merge() was showing as NULL because the index did not contain
entries for the paths contained within the sparse directory entries. We
instead had 'oldtree' given as the entry at HEAD and 'newtree' as the
entry in the target tree. This led to reject_merge() listing these
paths.

Now that sparse_dir_matches_path() works the same for deep paths as it
does for shallow depths, the rest of the logic kicks in to properly
handle modifying the sparse directory entries as designed.

Reported-by: Gustave Granroth <gus.gran@gmail.com>
Reported-by: Mike Marcelais <michmarc@exchange.microsoft.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agot1092: add deeper changes during a checkout
Derrick Stolee [Mon, 6 Dec 2021 14:10:36 +0000 (14:10 +0000)] 
t1092: add deeper changes during a checkout

Extend the repository data in the setup of t1092 to include more
directories within two parent directories. This reproduces a bug found
by users of the sparse index feature with suitably-complicated
sparse-checkout definitions.

Add a failing test that fails in its first 'git checkout deepest' run in
the sparse index case with this error:

  error: Your local changes to the following files would be overwritten by checkout:
          deep/deeper1/deepest2/a
          deep/deeper1/deepest3/a
  Please commit your changes or stash them before you switch branches.
  Aborting

The next change will fix this error, and that fix will make it clear why
the extra depth is necessary for revealing this bug. The assignment of
the sparse-checkout definition to include deep/deeper1/deepest as a
sibling directory is important to ensure that deep/deeper1 is not a
sparse directory entry, but deep/deeper1/deepest2 is.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agogrep: clarify what `grep.patternType=default` means
Junio C Hamano [Sun, 5 Dec 2021 20:26:16 +0000 (12:26 -0800)] 
grep: clarify what `grep.patternType=default` means

We documented that with grep.patternType set to default, the "git
grep" command returns to "the default matching behavior" in 84befcd0
(grep: add a grep.patternType configuration setting, 2012-08-03).

The grep.extendedRegexp configuration variable was the only way to
configure the behavior before that, after b22520a3 (grep: allow -E
and -n to be turned on by default via configuration, 2011-03-30)
introduced it.

It is understandable that we referred to the behavior that honors
the older configuration variable as "the default matching"
behavior.  It is fairly clear in its log message:

    When grep.patternType is set to a value other than "default", the
    grep.extendedRegexp setting is ignored. The value of "default" restores
    the current default behavior, including the grep.extendedRegexp
    behavior.

But when the paragraph is read in isolation by a new person who is
not aware of that backstory (which is the synonym for "most users"),
the "default matching behavior" can be read as "how 'git grep'
behaves without any configuration variables or options", which is
"match the pattern as BRE".

Clarify what the passage means by elaborating what the phrase
"default matching behavior" wanted to mean.

Helped-by: Johannes Altmanninger <aclopte@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agotests: set GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME only when needed
Johannes Schindelin [Fri, 3 Dec 2021 09:39:13 +0000 (09:39 +0000)] 
tests: set GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME only when needed

A couple of test scripts have actually been adapted to accommodate for a
configurable default branch name, but they still overrode it via the
`GIT_TEST_*` variable. Let's drop that override where possible.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agosequencer: do not export GIT_DIR and GIT_WORK_TREE for 'exec'
Elijah Newren [Sat, 4 Dec 2021 05:36:59 +0000 (05:36 +0000)] 
sequencer: do not export GIT_DIR and GIT_WORK_TREE for 'exec'

Commands executed from `git rebase --exec` can give different behavior
from within that environment than they would outside of it, due to the
fact that sequencer.c exports both GIT_DIR and GIT_WORK_TREE.  For
example, if the relevant script calls something like

  git -C ../otherdir log --format=%H --no-walk

the user may be surprised to find that the command above does not show a
commit hash from ../otherdir, because $GIT_DIR prevents automatic gitdir
detection and makes the -C option useless.

This is a regression in behavior from the original legacy
implemented-in-shell rebase.  It is perhaps rare for it to cause
problems in practice, especially since most small problems that were
caused by this area of bugs has been fixed-up in the past in a way that
masked the particular bug observed without fixing the real underlying
problem.

An explanation of how we arrived at the current situation is perhaps
merited.  The setting of GIT_DIR and GIT_WORK_TREE done by sequencer.c
arose from a sequence of historical accidents:

* When rebase was implemented as a shell command, it would call
  git-sh-setup, which among other things would set GIT_DIR -- but not
  export it.  This meant that when rebase --exec commands were run via
      /bin/sh -c "$COMMAND"
  they would not inherit the GIT_DIR setting.  The fact that GIT_DIR
  was not set in the run $COMMAND is the behavior we'd like to restore.

* When the rebase--helper builtin was introduced to allow incrementally
  replacing shell with C code, we had an implementation that was half
  shell, half C.  In particular, commit 18633e1a22 ("rebase -i: use the
  rebase--helper builtin", 2017-02-09) added calls to
      exec git rebase--helper ...
  which caused rebase--helper to inherit the GIT_DIR environment
  variable from the shell.  git's setup would change the environment
  variable from an absolute path to a relative one (".git"), but would
  leave it set.  This meant that when rebase --exec commands were run
  via
      run_command_v_opt(...)
  they would inherit the GIT_DIR setting.

* In commit 09d7b6c6fa ("sequencer: pass absolute GIT_DIR to exec
  commands", 2017-10-31), it was noted that the GIT_DIR caused problems
  with some commands; e.g.
      git rebase --exec 'cd subdir && git describe' ...
  would have GIT_DIR=.git which was invalid due to the change to the
  subdirectory.  Instead of questioning why GIT_DIR was set, that commit
  instead made sequencer change GIT_DIR to be an absolute path and
  explicitly export it via
      argv_array_pushf(&child_env, "GIT_DIR=%s", absolute_path(get_git_dir()));
      run_command_v_opt_cd_env(..., child_env.argv)

* In commit ab5e67d751 ("sequencer: pass absolute GIT_WORK_TREE to exec
  commands", 2018-07-14), it was noted that when GIT_DIR is set but
  GIT_WORK_TREE is not, that we do not discover GIT_WORK_TREE but just
  assume it is '.'.  That is incorrect if trying to run commands from a
  subdirectory.  However, rather than question why GIT_DIR was set, that
  commit instead also added GIT_WORK_TREE to the list of things to
  export.

Each of the above problems would have been fixed automatically when
git-rebase became a full builtin, had it not been for the fact that
sequencer.c started exporting GIT_DIR and GIT_WORK_TREE in the interim.
Stop exporting them now.

Signed-off-by: Elijah Newren <newren@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Acked-by: Johannes Altmanninger <aclopte@gmail.com>
Acked-by: Phillip Wood <phillip.wood123@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoname-rev: prefer shorter names over following merges
Elijah Newren [Sat, 4 Dec 2021 05:35:52 +0000 (05:35 +0000)] 
name-rev: prefer shorter names over following merges

name-rev has a MERGE_TRAVERSAL_WEIGHT to say that traversing a second or
later parent of a merge should be 65535 times more expensive than a
first-parent traversal, as per ac076c29ae8d (name-rev: Fix non-shortest
description, 2007-08-27).  The point of this weight is to prefer names
like

    v2.32.0~1471^2

over names like

    v2.32.0~43^2~15^2~11^2~20^2~31^2

which are two equally valid names in git.git for the same commit.  Note
that the first follows 1472 parent traversals compared to a mere 125 for
the second.  Weighting all traversals equally would clearly prefer the
second name since it has fewer parent traversals, but humans aren't
going to be traversing commits and they tend to have an easier time
digesting names with fewer segments.  The fact that the former only has
two segments (~1471, ^2) makes it much simpler than the latter which has
six segments (~43, ^2, ~15, etc.).  Since name-rev is meant to "find
symbolic names suitable for human digestion", we prefer fewer segments.

However, the particular rule implemented in name-rev would actually
prefer

    v2.33.0-rc0~11^2~1

over

    v2.33.0-rc0~20^2

because both have precisely one second parent traversal, and it gives
the tie breaker to shortest number of total parent traversals.  Fewer
segments is more important for human consumption than number of hops, so
we'd rather see the latter which has one fewer segment.

Include the generation in is_better_name() and use a new
effective_distance() calculation so that we prefer fewer segments in
the printed name over fewer total parent traversals performed to get the
answer.

== Side-note on tie-breakers ==

When there are the same number of segments for two different names, we
actually use the name of an ancestor commit as a tie-breaker as well.
For example, for the commit cbdca289fb in the git.git repository, we
prefer the name v2.33.0-rc0~112^2~1 over v2.33.0-rc0~57^2~5.  This is
because:

  * cbdca289fb is the parent of 25e65b6dd5, which implies the name for
    cbdca289fb should be the first parent of the preferred name for
    25e65b6dd5
  * 25e65b6dd5 could be named either v2.33.0-rc0~112^2 or
    v2.33.0-rc0~57^2~4, but the former is preferred over the latter due
    to fewer segments
  * combine the two previous facts, and the name we get for cbdca289fb
    is "v2.33.0-rc0~112^2~1" rather than "v2.33.0-rc0~57^2~5".

Technically, we get this for free out of the implementation since we
only keep track of one name for each commit as we walk history (and
re-add parents to the queue if we find a better name for those parents),
but the first bullet point above ensures users get results that feel
more consistent.

== Alternative Ideas and Meanings Discussed ==

One suggestion that came up during review was that shortest
string-length might be easiest for users to consume.  However, such a
scheme would be rather computationally expensive (we'd have to track all
names for each commit as we traversed the graph) and would additionally
come with the possibly perplexing result that on a linear segment of
history we could rapidly swap back and forth on names:
   MYTAG~3^2     would     be preferred over   MYTAG~9998
   MYTAG~3^2~1   would NOT be preferred over   MYTAG~9999
   MYTAG~3^2~2   might     be preferred over   MYTAG~10000

Another item that came up was possible auxiliary semantic meanings for
name-rev results either before or after this patch.  The basic answer
was that the previous implementation had no known useful auxiliary
semantics, but that for many repositories (most in my experience), the
new scheme does.  In particular, the new name-rev output can often be
used to answer the question, "How or when did this commit get merged?"
Since that usefulness depends on how merges happen within the repository
and thus isn't universally applicable, details are omitted here but you
can see them at [1].

[1] https://lore.kernel.org/git/CABPp-BEeUM+3NLKDVdak90_UUeNghYCx=Dgir6=8ixvYmvyq3Q@mail.gmail.com/

Finally, it was noted that the algorithm could be improved by just
explicitly tracking the number of segments and using both it and
distance in the comparison, instead of giving a magic number that tries
to blend the two (and which therefore might give suboptimal results in
repositories with really huge numbers of commits that periodically merge
older code).  However, "[this patch] seems to give us a much better
results than the current code, so let's take it and leave further
futzing outside the scope."

Signed-off-by: Elijah Newren <newren@gmail.com>
Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 years agoxdiff: drop unused flags parameter from recs_match
Jeff King [Fri, 3 Dec 2021 05:12:01 +0000 (00:12 -0500)] 
xdiff: drop unused flags parameter from recs_match

Since 6b13bc3232 (xdiff: simplify comparison, 2021-11-17), we do not
call xdl_recmatch() from xdiffi.c's recs_match(), so we no longer need
the "flags" parameter. That in turn lets us drop the flags parameters
from the group-slide functions which call it.

There's no functional change here; it's just making these functions a
little simpler.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>