45 hours agoGit 2.31-rc0 master v2.31.0-rc0
Junio C Hamano [Fri, 26 Feb 2021 00:34:59 +0000 (16:34 -0800)] 
Git 2.31-rc0

Signed-off-by: Junio C Hamano <>
45 hours agoMerge branch 'jc/push-delete-nothing'
Junio C Hamano [Fri, 26 Feb 2021 00:43:32 +0000 (16:43 -0800)] 
Merge branch 'jc/push-delete-nothing'

"git push $there --delete ''" should have been diagnosed as an
error, but instead turned into a matching push, which has been

* jc/push-delete-nothing:
  push: do not turn --delete '' into a matching push

45 hours agoMerge branch 'sh/mergetools-vimdiff1'
Junio C Hamano [Fri, 26 Feb 2021 00:43:32 +0000 (16:43 -0800)] 
Merge branch 'sh/mergetools-vimdiff1'

Mergetools update.

* sh/mergetools-vimdiff1:
  mergetools/vimdiff: add vimdiff1 merge tool variant

45 hours agoMerge branch 'dl/doc-config-camelcase'
Junio C Hamano [Fri, 26 Feb 2021 00:43:32 +0000 (16:43 -0800)] 
Merge branch 'dl/doc-config-camelcase'

A handful of multi-word configuration variable names in
documentation that are spelled in all lowercase have been corrected
to use the more canonical camelCase.

* dl/doc-config-camelcase:
  index-format doc: camelCase core.excludesFile
  blame-options.txt: camelcase blame.blankBoundary
  i18n.txt: camel case and monospace "i18n.commitEncoding"

45 hours agoMerge branch 'js/params-vs-args'
Junio C Hamano [Fri, 26 Feb 2021 00:43:32 +0000 (16:43 -0800)] 
Merge branch 'js/params-vs-args'

Messages update.

* js/params-vs-args:
  replace "parameters" by "arguments" in error messages

45 hours agoMerge branch 'ug/doc-commit-approxidate'
Junio C Hamano [Fri, 26 Feb 2021 00:43:32 +0000 (16:43 -0800)] 
Merge branch 'ug/doc-commit-approxidate'

Doc update.

* ug/doc-commit-approxidate:
  doc: mention approxidates for git-commit --date

45 hours agoMerge branch 'es/maintenance-of-bare-repositories'
Junio C Hamano [Fri, 26 Feb 2021 00:43:32 +0000 (16:43 -0800)] 
Merge branch 'es/maintenance-of-bare-repositories'

The "git maintenance register" command had trouble registering bare
repositories, which had been corrected.

* es/maintenance-of-bare-repositories:
  maintenance: fix incorrect `maintenance.repo` path with bare repository

45 hours agoMerge branch 'mt/add-chmod-fixes'
Junio C Hamano [Fri, 26 Feb 2021 00:43:31 +0000 (16:43 -0800)] 
Merge branch 'mt/add-chmod-fixes'

Various fixes on "git add --chmod".

* mt/add-chmod-fixes:
  add: propagate --chmod errors to exit status
  add: mark --chmod error string for translation
  add --chmod: don't update index when --dry-run is used

45 hours agoMerge branch 'ds/merge-base-independent'
Junio C Hamano [Fri, 26 Feb 2021 00:43:31 +0000 (16:43 -0800)] 
Merge branch 'ds/merge-base-independent'

The code to implement "git merge-base --independent" was poorly
done and was kept from the very beginning of the feature.

* ds/merge-base-independent:
  commit-reach: stale commits may prune generation further
  commit-reach: use heuristic in remove_redundant()
  commit-reach: move compare_commits_by_gen
  commit-reach: use one walk in remove_redundant()
  commit-reach: reduce requirements for remove_redundant()

45 hours agoMerge branch 'ah/rebase-no-fork-point-config'
Junio C Hamano [Fri, 26 Feb 2021 00:43:31 +0000 (16:43 -0800)] 
Merge branch 'ah/rebase-no-fork-point-config'

"git rebase --[no-]fork-point" gained a configuration variable
rebase.forkPoint so that users do not have to keep specifying a
non-default setting.

* ah/rebase-no-fork-point-config:
  rebase: add a config option for --no-fork-point

45 hours agoMerge branch 'mt/grep-sparse-checkout'
Junio C Hamano [Fri, 26 Feb 2021 00:43:31 +0000 (16:43 -0800)] 
Merge branch 'mt/grep-sparse-checkout'

"git grep" has been tweaked to be limited to the sparse checkout

* mt/grep-sparse-checkout:
  grep: honor sparse-checkout on working tree searches

45 hours agoMerge branch 'ah/commit-graph-leakplug'
Junio C Hamano [Fri, 26 Feb 2021 00:43:31 +0000 (16:43 -0800)] 
Merge branch 'ah/commit-graph-leakplug'

Plug a minor memory leak.

* ah/commit-graph-leakplug:
  commit-graph: avoid leaking topo_levels slab in write_commit_graph()

45 hours agoMerge branch 'zh/difftool-skip-to'
Junio C Hamano [Fri, 26 Feb 2021 00:43:31 +0000 (16:43 -0800)] 
Merge branch 'zh/difftool-skip-to'

"git difftool" learned "--skip-to=<path>" option to restart an
interrupted session from an arbitrary path.

* zh/difftool-skip-to:
  difftool.c: learn a new way start at specified file

45 hours agoMerge branch 'cw/pack-config-doc'
Junio C Hamano [Fri, 26 Feb 2021 00:43:30 +0000 (16:43 -0800)] 
Merge branch 'cw/pack-config-doc'

Doc update.

* cw/pack-config-doc:
  doc: mention bigFileThreshold for packing

45 hours agoMerge branch 'jc/maint-column-doc-typofix'
Junio C Hamano [Fri, 26 Feb 2021 00:43:30 +0000 (16:43 -0800)] 
Merge branch 'jc/maint-column-doc-typofix'

Doc update.

* jc/maint-column-doc-typofix:
  Documentation: typofix --column description

45 hours agoMerge branch 'ma/doc-markup-fix'
Junio C Hamano [Fri, 26 Feb 2021 00:43:30 +0000 (16:43 -0800)] 
Merge branch 'ma/doc-markup-fix'


* ma/doc-markup-fix:
  gitmailmap.txt: fix rendering of e-mail addresses
  git.txt: fix monospace rendering
  rev-list-options.txt: fix rendering of bonus paragraph

45 hours agoMerge branch 'jc/diffcore-rotate'
Junio C Hamano [Fri, 26 Feb 2021 00:43:30 +0000 (16:43 -0800)] 
Merge branch 'jc/diffcore-rotate'

"git {diff,log} --{skip,rotate}-to=<path>" allows the user to
discard diff output for early paths or move them to the end of the

* jc/diffcore-rotate:
  diff: --{rotate,skip}-to=<path>

45 hours agoMerge branch 'mt/checkout-index-corner-cases'
Junio C Hamano [Fri, 26 Feb 2021 00:43:30 +0000 (16:43 -0800)] 
Merge branch 'mt/checkout-index-corner-cases'

The error codepath around the "--temp/--prefix" feature of "git
checkout-index" has been improved.

* mt/checkout-index-corner-cases:
  checkout-index: omit entries with no tempname from --temp output
  write_entry(): fix misuses of `path` in error messages

45 hours agoMerge branch 'js/doc-proto-v2-response-end'
Junio C Hamano [Fri, 26 Feb 2021 00:43:30 +0000 (16:43 -0800)] 
Merge branch 'js/doc-proto-v2-response-end'


* js/doc-proto-v2-response-end:
  doc: fix naming of response-end-pkt

45 hours agoMerge branch 'rs/blame-optim'
Junio C Hamano [Fri, 26 Feb 2021 00:43:29 +0000 (16:43 -0800)] 
Merge branch 'rs/blame-optim'

Optimization in "git blame"

* rs/blame-optim:
  blame: remove unnecessary use of get_commit_info()

45 hours agoMerge branch 'mz/doc-notes-are-not-anchors'
Junio C Hamano [Fri, 26 Feb 2021 00:43:29 +0000 (16:43 -0800)] 
Merge branch 'mz/doc-notes-are-not-anchors'

Objects that lost references can be pruned away, even when they
have notes attached to it (and these notes will become dangling,
which in turn can be pruned with "git notes prune").  This has been
clarified in the documentation.

* mz/doc-notes-are-not-anchors:
  docs: clarify that refs/notes/ do not keep the attached objects alive

45 hours agoMerge branch 'ab/detox-gettext-tests'
Junio C Hamano [Fri, 26 Feb 2021 00:43:29 +0000 (16:43 -0800)] 
Merge branch 'ab/detox-gettext-tests'

Removal of GIT_TEST_GETTEXT_POISON continues.

* ab/detox-gettext-tests:
  tests: remove most uses of test_i18ncmp
  tests: remove last uses of C_LOCALE_OUTPUT
  tests: remove most uses of C_LOCALE_OUTPUT
  tests: remove last uses of GIT_TEST_GETTEXT_POISON=false

45 hours agoMerge branch 'jk/rev-list-disk-usage'
Junio C Hamano [Fri, 26 Feb 2021 00:43:28 +0000 (16:43 -0800)] 
Merge branch 'jk/rev-list-disk-usage'

"git rev-list" command learned "--disk-usage" option.

* jk/rev-list-disk-usage:
  docs/rev-list: add some examples of --disk-usage
  docs/rev-list: add an examples section
  rev-list: add --disk-usage option for calculating disk usage
  t: add --no-tag option to test_commit

2 days agoindex-format doc: camelCase core.excludesFile
Junio C Hamano [Wed, 24 Feb 2021 20:26:41 +0000 (12:26 -0800)] 
index-format doc: camelCase core.excludesFile

Signed-off-by: Junio C Hamano <>
2 days agoblame-options.txt: camelcase blame.blankBoundary
Junio C Hamano [Wed, 24 Feb 2021 20:26:40 +0000 (12:26 -0800)] 
blame-options.txt: camelcase blame.blankBoundary

All other references to blame.* configuration variables are
camelCased already.  Update this one to match.

Signed-off-by: Junio C Hamano <>
2 days agoi18n.txt: camel case and monospace "i18n.commitEncoding"
Denton Liu [Wed, 24 Feb 2021 20:26:39 +0000 (12:26 -0800)] 
i18n.txt: camel case and monospace "i18n.commitEncoding"

In 95791be750 (doc: camelCase the i18n config variables to improve
readability, 2017-07-17), the other i18n config variables were
camel cased. However, this one instance was missed.

Camel case and monospace "i18n.commitEncoding" so that it matches the
surrounding text.

Signed-off-by: Denton Liu <>
[jc: fixed 3 other mistakes that are exactly the same]
Signed-off-by: Junio C Hamano <>
3 days agoadd: propagate --chmod errors to exit status
Matheus Tavares [Tue, 23 Feb 2021 01:10:35 +0000 (22:10 -0300)] 
add: propagate --chmod errors to exit status

If `add` encounters an error while applying the --chmod changes, it
prints a message to stderr, but exits with a success code. This might
have been an oversight, as the command does exit with a non-zero code in
other situations where it cannot (or refuses to) update all of the
requested paths (e.g. when some of the given paths are ignored). So make
the exit behavior more consistent by also propagating --chmod errors to
the exit status.

Note: the test "all statuses changed in folder if . is given" uses paths
added by previous test cases, some of which might be symbolic links.
Because `git add --chmod` will now fail with such paths, this test would
depend on whether all the previous tests were executed, or only some
of them. Avoid that by running the test on a fresh repo with only
regular files.

Signed-off-by: Matheus Tavares <>
Reviewed-by: Taylor Blau <>
Signed-off-by: Junio C Hamano <>
3 days agoadd: mark --chmod error string for translation
Matheus Tavares [Tue, 23 Feb 2021 01:10:34 +0000 (22:10 -0300)] 
add: mark --chmod error string for translation

This error message is intended for humans, so mark it for translation.
Also use error() instead of fprintf(stderr, ...), to make the
corresponding line a bit cleaner, and to display the "error:" prefix,
which helps classifying the nature/severity of the message.

Signed-off-by: Matheus Tavares <>
Reviewed-by: Taylor Blau <>
Signed-off-by: Junio C Hamano <>
3 days agoadd --chmod: don't update index when --dry-run is used
Matheus Tavares [Tue, 23 Feb 2021 01:10:33 +0000 (22:10 -0300)] 
add --chmod: don't update index when --dry-run is used

`git add --chmod` applies the mode changes even when `--dry-run` is
used. Fix that and add some tests for this option combination.

Helped-by: Junio C Hamano <>
Signed-off-by: Matheus Tavares <>
Reviewed-by: Taylor Blau <>
Signed-off-by: Junio C Hamano <>
3 days agorebase: add a config option for --no-fork-point
Alex Henrie [Tue, 23 Feb 2021 07:18:40 +0000 (00:18 -0700)] 
rebase: add a config option for --no-fork-point

Some users (myself included) would prefer to have this feature off by
default because it can silently drop commits.

Signed-off-by: Alex Henrie <>
Signed-off-by: Junio C Hamano <>
3 days agopush: do not turn --delete '' into a matching push
Junio C Hamano [Tue, 23 Feb 2021 23:13:32 +0000 (15:13 -0800)] 
push: do not turn --delete '' into a matching push

When we added a syntax sugar "git push remote --delete <ref>" to
"git push" as a synonym to the canonical "git push remote :<ref>"
syntax at f517f1f2 (builtin-push: add --delete as syntactic sugar
for :foo, 2009-12-30), we weren't careful enough to make sure that
<ref> is not empty.

Blindly rewriting "--delete <ref>" to ":<ref>" means that an empty
string <ref> results in refspec ":", which is the syntax to ask for
"matching" push that does not delete anything.

Worse yet, if there were matching refs that can be fast-forwarded,
they would have been published prematurely, even if the user feels
that they are not ready yet to be pushed out, which would be a real

Noticed-by: Tilman Vogel <>
Signed-off-by: Junio C Hamano <>
4 days agodoc: mention approxidates for git-commit --date
Jeff King [Tue, 23 Feb 2021 20:50:58 +0000 (15:50 -0500)] 
doc: mention approxidates for git-commit --date

We describe the more strict date formats accepted by GIT_COMMITTER_DATE,
etc, but the --date option also allows the looser approxidate formats,
as well. Unfortunately we don't have a good or complete reference for
this format, but let's at least mention that it _is_ looser, and give a
few examples.

If we ever write separate, more complete date-format documentation, we
should refer to it from here.

Based-on-a-patch-by: Utku Gultopu <>
Signed-off-by: Jeff King <>
Signed-off-by: Junio C Hamano <>
4 days agoreplace "parameters" by "arguments" in error messages
Johannes Sixt [Tue, 23 Feb 2021 21:11:32 +0000 (22:11 +0100)] 
replace "parameters" by "arguments" in error messages

When an error message informs the user about an incorrect command
invocation, it should refer to "arguments", not "parameters".

Signed-off-by: Johannes Sixt <>
Signed-off-by: Junio C Hamano <>
4 days agomergetools/vimdiff: add vimdiff1 merge tool variant
Seth House [Sun, 14 Feb 2021 02:28:40 +0000 (19:28 -0700)] 
mergetools/vimdiff: add vimdiff1 merge tool variant

This adds yet another vimdiff/gvimdiff variant and presents conflicts as
a two-way diff between 'LOCAL' and 'REMOTE'. 'MERGED' is not opened
which deviates from the norm so usage text is echoed as a Vim message on
startup that instructs the user with how to proceed and how to abort.

Vimdiff is well-suited to two-way diffs so this is an option for a more
simple, more streamlined conflict resolution. For example: it is
difficult to communicate differences across more than two files using
only syntax highlighting; default vimdiff commands to get and put
changes between buffers do not need the user to manually specify
a source or destination buffer when only using two buffers.

Like other merge tools that directly compare 'LOCAL' with 'REMOTE', this
tool will benefit when paired with the new `mergetool.hideResolved`

Signed-off-by: Seth House <>
Tested-by: David Aguilar <>
Signed-off-by: Junio C Hamano <>
4 days agomaintenance: fix incorrect `maintenance.repo` path with bare repository
Eric Sunshine [Tue, 23 Feb 2021 07:31:07 +0000 (02:31 -0500)] 
maintenance: fix incorrect `maintenance.repo` path with bare repository

The periodic maintenance tasks configured by `git maintenance start`
invoke `git for-each-repo` to run `git maintenance run` on each path
specified by the multi-value global configuration variable
`maintenance.repo`. Because `git for-each-repo` will likely be run
outside of the repositories which require periodic maintenance, it is
mandatory that the repository paths specified by `maintenance.repo` are

Unfortunately, however, `git maintenance register` does nothing to
ensure that the paths it assigns to `maintenance.repo` are indeed
absolute, and may in fact -- especially in the case of a bare repository
-- assign a relative path to `maintenance.repo` instead. Fix this
problem by converting all paths to absolute before assigning them to

While at it, also fix `git maintenance unregister` to convert paths to
absolute, as well, in order to ensure that it can correctly remove from
`maintenance.repo` a path assigned via `git maintenance register`.

Reported-by: Clement Moyroud <>
Signed-off-by: Eric Sunshine <>
Signed-off-by: Junio C Hamano <>
4 days agoThe tenth batch
Junio C Hamano [Tue, 23 Feb 2021 00:09:36 +0000 (16:09 -0800)] 
The tenth batch

Signed-off-by: Junio C Hamano <>
4 days agoMerge branch 'ab/test-lib'
Junio C Hamano [Tue, 23 Feb 2021 00:12:43 +0000 (16:12 -0800)] 
Merge branch 'ab/test-lib'

Test framework clean-up.

* ab/test-lib:
  test-lib-functions: assert correct parameter count
  test-lib-functions: remove bug-inducing "diagnostics" helper param
  test libs: rename "diff-lib" to "lib-diff"
  t/.gitattributes: sort lines
  test-lib-functions: move function to
  test libs: rename to
  test libs: rename bundle helper to ""
  test-lib-functions: remove generate_zero_bytes() wrapper
  test-lib-functions: move test_set_index_version() to its user
  test lib: change "error" to "BUG" as appropriate
  test-lib: remove check_var_migration

4 days agoMerge branch 'ab/diff-deferred-free'
Junio C Hamano [Tue, 23 Feb 2021 00:12:43 +0000 (16:12 -0800)] 
Merge branch 'ab/diff-deferred-free'

A small memleak in "diff -I<regexp>" has been corrected.

* ab/diff-deferred-free:
  diff: plug memory leak from regcomp() on {log,diff} -I
  diff: add an API for deferred freeing

4 days agoMerge branch 'ab/pager-exit-log'
Junio C Hamano [Tue, 23 Feb 2021 00:12:43 +0000 (16:12 -0800)] 
Merge branch 'ab/pager-exit-log'

When a pager spawned by us exited, the trace log did not record its
exit status correctly, which has been corrected.

* ab/pager-exit-log:
  pager: properly log pager exit code when signalled
  run-command: add braces for "if" block in wait_or_whine()
  pager: test for exit code with and without SIGPIPE
  pager: refactor wait_for_pager() function

4 days agoMerge branch 'ta/hash-function-transition-doc'
Junio C Hamano [Tue, 23 Feb 2021 00:12:43 +0000 (16:12 -0800)] 
Merge branch 'ta/hash-function-transition-doc'

Update formatting and grammar of the hash transition plan
documentation, plus some updates.

* ta/hash-function-transition-doc:
  doc: use https links
  doc hash-function-transition: move rationale upwards
  doc hash-function-transition: fix incomplete sentence
  doc hash-function-transition: use upper case consistently
  doc hash-function-transition: use SHA-1 and SHA-256 consistently
  doc hash-function-transition: fix asciidoc output

4 days agoMerge branch 'bc/signed-objects-with-both-hashes'
Junio C Hamano [Tue, 23 Feb 2021 00:12:42 +0000 (16:12 -0800)] 
Merge branch 'bc/signed-objects-with-both-hashes'

Signed commits and tags now allow verification of objects, whose
two object names (one in SHA-1, the other in SHA-256) are both

* bc/signed-objects-with-both-hashes:
  gpg-interface: remove other signature headers before verifying
  ref-filter: hoist signature parsing
  commit: allow parsing arbitrary buffers with headers
  gpg-interface: improve interface for parsing tags
  commit: ignore additional signatures when parsing signed commits
  ref-filter: switch some uses of unsigned long to size_t

4 days agoMerge branch 'dl/stash-cleanup'
Junio C Hamano [Tue, 23 Feb 2021 00:12:42 +0000 (16:12 -0800)] 
Merge branch 'dl/stash-cleanup'

Documentation, code and test clean-up around "git stash".

* dl/stash-cleanup:
  stash: declare ref_stash as an array
  t3905: use test_cmp() to check file contents
  t3905: replace test -s with test_file_not_empty
  t3905: remove nested git in command substitution
  t3905: move all commands into test cases
  t3905: remove spaces after redirect operators
  git-stash.txt: be explicit about subcommand options

5 days agocommit-graph: avoid leaking topo_levels slab in write_commit_graph()
Andrzej Hunt [Fri, 19 Feb 2021 20:13:10 +0000 (20:13 +0000)] 
commit-graph: avoid leaking topo_levels slab in write_commit_graph()

write_commit_graph initialises topo_levels using init_topo_level_slab(),
next it calls compute_topological_levels() which can cause the slab to
grow, we therefore need to clear the slab again using
clear_topo_level_slab() when we're done.

First introduced in 72a2bfca (commit-graph: add a slab to store
topological levels, 2021-01-16).

LeakSanitizer output:

==1026==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 8 byte(s) in 1 object(s) allocated from:
    #0 0x498ae9 in realloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:164:3
    #1 0xafbed8 in xrealloc /src/git/wrapper.c:126:8
    #2 0x7966d1 in topo_level_slab_at_peek /src/git/commit-graph.c:71:1
    #3 0x7965e0 in topo_level_slab_at /src/git/commit-graph.c:71:1
    #4 0x78fbf5 in compute_topological_levels /src/git/commit-graph.c:1472:12
    #5 0x78c5c3 in write_commit_graph /src/git/commit-graph.c:2456:2
    #6 0x535c5f in graph_write /src/git/builtin/commit-graph.c:299:6
    #7 0x5350ca in cmd_commit_graph /src/git/builtin/commit-graph.c:337:11
    #8 0x4cddb1 in run_builtin /src/git/git.c:453:11
    #9 0x4cabe2 in handle_builtin /src/git/git.c:704:3
    #10 0x4cd084 in run_argv /src/git/git.c:771:4
    #11 0x4ca424 in cmd_main /src/git/git.c:902:19
    #12 0x707fb6 in main /src/git/common-main.c:52:11
    #13 0x7fee4249383f in __libc_start_main (/lib/x86_64-linux-gnu/

Indirect leak of 524256 byte(s) in 1 object(s) allocated from:
    #0 0x498942 in calloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:154:3
    #1 0xafc088 in xcalloc /src/git/wrapper.c:140:8
    #2 0x796870 in topo_level_slab_at_peek /src/git/commit-graph.c:71:1
    #3 0x7965e0 in topo_level_slab_at /src/git/commit-graph.c:71:1
    #4 0x78fbf5 in compute_topological_levels /src/git/commit-graph.c:1472:12
    #5 0x78c5c3 in write_commit_graph /src/git/commit-graph.c:2456:2
    #6 0x535c5f in graph_write /src/git/builtin/commit-graph.c:299:6
    #7 0x5350ca in cmd_commit_graph /src/git/builtin/commit-graph.c:337:11
    #8 0x4cddb1 in run_builtin /src/git/git.c:453:11
    #9 0x4cabe2 in handle_builtin /src/git/git.c:704:3
    #10 0x4cd084 in run_argv /src/git/git.c:771:4
    #11 0x4ca424 in cmd_main /src/git/git.c:902:19
    #12 0x707fb6 in main /src/git/common-main.c:52:11
    #13 0x7fee4249383f in __libc_start_main (/lib/x86_64-linux-gnu/

SUMMARY: AddressSanitizer: 524264 byte(s) leaked in 2 allocation(s).

Signed-off-by: Andrzej Hunt <>
Signed-off-by: Junio C Hamano <>
5 days agodifftool.c: learn a new way start at specified file
ZheNing Hu [Fri, 19 Feb 2021 12:53:54 +0000 (12:53 +0000)] 
difftool.c: learn a new way start at specified file

`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the middle,
we will have to traverse list again to get the file diff which
we want to see. Therefore,teach the command an option
`--skip-to=<path>` to allow the user to say that diffs for earlier
paths are not interesting (because they were already seen in an
earlier session) and start this session with the named path.

Signed-off-by: ZheNing Hu <>
Signed-off-by: Junio C Hamano <>
5 days agocommit-reach: stale commits may prune generation further
Derrick Stolee [Fri, 19 Feb 2021 12:34:10 +0000 (12:34 +0000)] 
commit-reach: stale commits may prune generation further

The remove_redundant_with_gen() algorithm performs a depth-first-search
to find commits in the 'array' list, starting at the parents of each
commit in 'array'. The result is that commits in 'array' are marked
STALE when they are reachable from another commit in 'array'.

This depth-first-search is fast when commits lie on or near the
first-parent history of the higher commits. The search terminates early
if all but one commit becomes marked STALE.

However, it is possible that there are two independent commits with high
generation number. In that case, the depth-first-search might languish
by searching in lower generations due to the fixed min_generation used
throughout the method.

With the expectation that commits with lower generation are expected to
become STALE more often, we can optimize further by increasing that
min_generation boundary upon discovery of the commit with minimum

We must first sort the commits in 'array' by generation. We cannot sort
'array' itself since it must preserve relative order among the returned
results (see revision.c:mark_redundant_parents() for an example).

This simplifies the initialization of min_generation, but it also allows
us to increase the new min_generation when we find the commit with
smallest generation remaining.

This requires more than two commits in order to test, so I used the
Linux kernel repository with a few commits that are slightly off of the
first-parent history. I timed the following command:

  git merge-base --independent 2ecedd756908 d2360a398f0b \
1253935ad801 160bab43419e 0e2209629fec 1d0e16ac1a9e

The first two commits have similar generation and are near the v5.10
tag. Commit 160bab43419e is off of the first-parent history behind v5.5,
while the others are scattered somewhere reachable from v5.9. This is
designed to demonstrate the optimization, as that commit within v5.5
would normally cause a lot of extra commit walking.

Since remove_redundant_with_alg() is called only when at least one of
the input commits has a finite generation number, this algorithm is
tested with a commit-graph generated starting at a number of different
tags, the earliest being v5.5.

commit-graph at v5.5:

 | Method                | Time  |
 | *_no_gen()            | 864ms |
 | *_with_gen() (before) | 858ms |
 | *_with_gen() (after)  | 810ms |

commit-graph at v5.7:

 | Method                | Time  |
 | *_no_gen()            | 625ms |
 | *_with_gen() (before) | 572ms |
 | *_with_gen() (after)  | 517ms |

commit-graph at v5.9:

 | Method                | Time  |
 | *_no_gen()            | 268ms |
 | *_with_gen() (before) | 224ms |
 | *_with_gen() (after)  | 202ms |

commit-graph at v5.10:

 | Method                | Time  |
 | *_no_gen()            |  72ms |
 | *_with_gen() (before) |  37ms |
 | *_with_gen() (after)  |   9ms |

Note that these are only modest improvements for the case where the two
independent commits are not in the commit-graph (not until v5.10). All
algorithms get faster as more commits are indexed, which is not a
surprise. However, the cost of walking extra commits is more and more
prevalent in relative terms as more commits are indexed. Finally, the
last case allows us to jump to the minimum generation between the last
two commits (that are actually independent) so we greatly reduce the
cost in that case.

Signed-off-by: Derrick Stolee <>
Signed-off-by: Junio C Hamano <>
5 days agocommit-reach: use heuristic in remove_redundant()
Derrick Stolee [Fri, 19 Feb 2021 12:34:09 +0000 (12:34 +0000)] 
commit-reach: use heuristic in remove_redundant()

Reachability algorithms in commit-reach.c frequently benefit from using
the first-parent history as a heuristic for satisfying reachability
queries. The most obvious example was implemented in 4fbcca4e
(commit-reach: make can_all_from_reach... linear, 2018-07-20).

Update the walk in remove_redundant() to use this same heuristic. Here,
we are walking starting at the parents of the input commits. Sort those
parents and walk from the highest generation to lower. Each time, use
the heuristic of searching the first parent history before continuing to
expand the walk.

The order in which we explore the commits matters, so update
compare_commits_by_gen to break generation number ties with commit date.
This has no effect when the commits are in a commit-graph file with
corrected commit dates computed, but it will assist when the commits are
in the region "above" the commit-graph with "infinite" generation
number. Note that we cannot shift to use
compare_commits_by_gen_then_commit_date as the method prototype is
different. We use compare_commits_by_gen for QSORT() as opposed to as a
priority function.

The important piece is to ensure we short-circuit the walk when we find
that there is a single non-redundant commit. This happens frequently
when looking for merge-bases or comparing several tags with 'git
merge-base --independent'. Use a new count 'count_still_independent' and
if that hits 1 we can stop walking.

To update 'count_still_independent' properly, we add use of the RESULT
flag on the input commits. Then we can detect when we reach one of these
commits and decrease the count. We need to remove the RESULT flag at
that moment because we might re-visit that commit when popping the

We use the STALE flag to mark parents that have been added to the new
walk_start list, but we need to clear that flag before we start walking
so those flags don't halt our depth-first-search walk.

On my copy of the Linux kernel repository, the performance of 'git
merge-base --independent <all-tags>' goes from 1.1 seconds to 0.11

Signed-off-by: Derrick Stolee <>
Signed-off-by: Junio C Hamano <>
5 days agocommit-reach: move compare_commits_by_gen
Derrick Stolee [Fri, 19 Feb 2021 12:34:08 +0000 (12:34 +0000)] 
commit-reach: move compare_commits_by_gen

Move this earlier in the file so it can be used by more methods.

Signed-off-by: Derrick Stolee <>
Signed-off-by: Junio C Hamano <>
5 days agocommit-reach: use one walk in remove_redundant()
Derrick Stolee [Fri, 19 Feb 2021 12:34:07 +0000 (12:34 +0000)] 
commit-reach: use one walk in remove_redundant()

The current implementation of remove_redundant() uses several calls to
paint_down_to_common() to determine that commits are independent of each
other. This leads to quadratic behavior when many inputs are passed to
commands such as 'git merge-base'.

For example, in the Linux kernel repository, I tested the performance
by passing all tags:

 git merge-base --independent $(git for-each-ref refs/tags --format="$(refname)")

(Note: I had to delete the tags v2.6.11-tree and v2.6.11 as they do
not point to commits.)

Here is the performance improvement introduced by this change:

 Before: 16.4s
  After:  1.1s

This performance improvement requires the commit-graph file to be
present. We keep the old algorithm around as remove_redundant_no_gen()
and use it when generation_numbers_enabled() is false. This is similar
to other algorithms within commit-reach.c. The new algorithm is
implemented in remove_redundant_with_gen().

The basic approach is to do one commit walk instead of many. First, scan
all commits in the list and mark their _parents_ with the STALE flag.
This flag will indicate commits that are reachable from one of the
inputs, except not including themselves. Then, walk commits until
covering all commits up to the minimum generation number pushing the
STALE flag throughout.

At the end, we need to clear the STALE bit from all of the commits
we walked. We move the non-stale commits in 'array' to the beginning of
the list, and this might overwrite stale commits. However, we store an
array of commits that started the walk, and use clear_commit_marks() on
each of those starting commits. That method will walk the reachable
commits with the STALE bit and clear them all. This makes the algorithm
safe for re-entry or for other uses of those commits after this walk.

This logic is covered by tests in, so the behavior
does not change. This is tested both in the case with a commit-graph and

Signed-off-by: Derrick Stolee <>
Signed-off-by: Junio C Hamano <>
5 days agodoc: mention bigFileThreshold for packing
Christian Walther [Sun, 21 Feb 2021 13:23:57 +0000 (13:23 +0000)] 
doc: mention bigFileThreshold for packing

Knowing about the core.bigFileThreshold configuration variable is
helpful when examining pack file size differences between repositories.
Add a reference to it to the manpages a user is likely to read in this

Capitalize CONFIGURATION for consistency with other pages having such a

Signed-off-by: Christian Walther <>
Signed-off-by: Junio C Hamano <>
7 days agoDocumentation: typofix --column description
Junio C Hamano [Sat, 20 Feb 2021 02:44:05 +0000 (18:44 -0800)] 
Documentation: typofix --column description

f4ed0af6 (Merge branch 'nd/columns', 2012-05-03) brought in three
cut-and-pasted copies of malformatted descriptions.  Let's fix them
all the same way by marking the configuration variable names up as
monospace just like the command line option `--column` is typeset.

While we are at it, correct a missing space after the full stop that
ends the sentence.

Signed-off-by: Junio C Hamano <>
9 days agogitmailmap.txt: fix rendering of e-mail addresses
Martin Ågren [Wed, 17 Feb 2021 19:56:06 +0000 (20:56 +0100)] 
gitmailmap.txt: fix rendering of e-mail addresses

Both AsciiDoc and Asciidoctor are eager to pick up the e-mail addresses
in this document and turn them into references at the bottom of the
manpage / clickable links. We don't really need that for these dummy
addresses. Spell "@" as "&#64;" to make them not do this. In the open
block, we can instead avoid this by indenting the contents, similar to
the earlier blocks.

Fix a backtick which should have been a single quote mark. With all the
quoting that is going on around here, this mistake trips up the parsing
and rendering quite a bit.

Before this commit, we have the same failure mode with AsciiDoc 8.6.10
and Asciidoctor 1.5.5, and this change makes both of them happy.

Signed-off-by: Martin Ågren <>
Acked-by: Ævar Arnfjörð Bjarmason <>
Signed-off-by: Junio C Hamano <>
9 days agogit.txt: fix monospace rendering
Martin Ågren [Wed, 17 Feb 2021 19:56:05 +0000 (20:56 +0100)] 
git.txt: fix monospace rendering

When we write `<name>`s with the "s" tucked on to the closing backtick,
we end up rendering the backticks literally. Rephrase this sentence
slightly to render this as monospace.

Signed-off-by: Martin Ågren <>
Signed-off-by: Junio C Hamano <>
9 days agoThe ninth batch
Junio C Hamano [Thu, 18 Feb 2021 00:39:59 +0000 (16:39 -0800)] 
The ninth batch

Signed-off-by: Junio C Hamano <>
9 days agoMerge branch 'ak/config-bad-bool-error'
Junio C Hamano [Thu, 18 Feb 2021 01:21:43 +0000 (17:21 -0800)] 
Merge branch 'ak/config-bad-bool-error'

The error message given when a configuration variable that is
expected to have a boolean value has been improved.

* ak/config-bad-bool-error:
  config: improve error message for boolean config

9 days agoMerge branch 'js/reflog-expire-stale-fix'
Junio C Hamano [Thu, 18 Feb 2021 01:21:43 +0000 (17:21 -0800)] 
Merge branch 'js/reflog-expire-stale-fix'

"git reflog expire --stale-fix" can be used to repair the reflog by
removing entries that refer to objects that have been pruned away,
but was not careful to tolerate missing objects.

* js/reflog-expire-stale-fix:
  reflog expire --stale-fix: be generous about missing objects

9 days agoMerge branch 'js/commit-graph-warning'
Junio C Hamano [Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)] 
Merge branch 'js/commit-graph-warning'

When certain features (e.g. grafts) used in the repository are
incompatible with the use of the commit-graph, we used to silently
turned commit-graph off; we now tell the user what we are doing.

* js/commit-graph-warning:
  commit-graph: when incompatible with graphs, indicate why

9 days agoMerge branch 'ew/rev-parse-since-test'
Junio C Hamano [Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)] 
Merge branch 'ew/rev-parse-since-test'

Test to make sure "git rev-parse one-thing one-thing" gives
the same thing twice (when one-thing is --since=X).

* ew/rev-parse-since-test:
  t1500: ensure current --since= behavior remains

9 days agoMerge branch 'ds/maintenance-pack-refs'
Junio C Hamano [Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)] 
Merge branch 'ds/maintenance-pack-refs'

"git maintenance" tool learned a new "pack-refs" maintenance task.

* ds/maintenance-pack-refs:
  maintenance: incremental strategy runs pack-refs weekly
  maintenance: add pack-refs task

9 days agoMerge branch 'jx/t5411-unique-filenames'
Junio C Hamano [Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)] 
Merge branch 'jx/t5411-unique-filenames'

Avoid individual tests in t5411 from getting affected by each other
by forcing them to use separate output files during the test.

* jx/t5411-unique-filenames:
  t5411: refactor check of refs using test_cmp_refs
  t5411: use different out file to prevent overwriting

9 days agoMerge branch 'js/fsck-name-objects-fix'
Junio C Hamano [Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)] 
Merge branch 'js/fsck-name-objects-fix'

Fix "git fsck --name-objects" which apparently has not been used by
anybody who is motivated enough to report breakage.

* js/fsck-name-objects-fix:
  fsck --name-objects: be more careful parsing generation numbers
  t1450: robustify `remove_object()`

9 days agoMerge branch 'jk/mailmap-only-at-root'
Junio C Hamano [Thu, 18 Feb 2021 01:21:41 +0000 (17:21 -0800)] 
Merge branch 'jk/mailmap-only-at-root'

The .mailmap is documented to be read only from the root level of a
working tree, but a stray file in a bare repository also was read
by accident, which has been corrected.

* jk/mailmap-only-at-root:
  mailmap: only look for .mailmap in work tree

9 days agoMerge branch 'mt/grep-cached-untracked'
Junio C Hamano [Thu, 18 Feb 2021 01:21:41 +0000 (17:21 -0800)] 
Merge branch 'mt/grep-cached-untracked'

"git grep --untracked" is meant to be "let's ALSO find in these
files on the filesystem" when looking for matches in the working
tree files, and does not make any sense if the primary search is
done against the index, or the tree objects.  The "--cached" and
"--untracked" options have been marked as mutually incompatible.

* mt/grep-cached-untracked:
  grep: error out if --untracked is used with --cached

9 days agoMerge branch 'sh/mergetool-hideresolved'
Junio C Hamano [Thu, 18 Feb 2021 01:21:41 +0000 (17:21 -0800)] 
Merge branch 'sh/mergetool-hideresolved'

"git mergetool" feeds three versions (base, local and remote) of
a conflicted path unmodified.  The command learned to optionally
prepare these files with unconflicted parts already resolved.

* sh/mergetool-hideresolved:
  mergetool: add per-tool support and overrides for the hideResolved flag
  mergetool: break setup_tool out into separate initialization function
  mergetool: add hideResolved configuration

9 days agoMerge branch 'jt/trace2-BUG'
Junio C Hamano [Thu, 18 Feb 2021 01:21:41 +0000 (17:21 -0800)] 
Merge branch 'jt/trace2-BUG'

Even though invocations of "die()" were logged to the trace2
system, "BUG()"s were not, which has been corrected.

* jt/trace2-BUG:
  usage: trace2 BUG() invocations

9 days agoMerge branch 'js/range-diff-one-side-only'
Junio C Hamano [Thu, 18 Feb 2021 01:21:41 +0000 (17:21 -0800)] 
Merge branch 'js/range-diff-one-side-only'

The "git range-diff" command learned "--(left|right)-only" option
to show only one side of the compared range.

* js/range-diff-one-side-only:
  range-diff: offer --left-only/--right-only options
  range-diff: move the diffopt initialization down one layer
  range-diff: combine all options in a single data structure
  range-diff: simplify code spawning `git log`
  range-diff: libify the read_patches() function again
  range-diff: avoid leaking memory in two error code paths

9 days agoMerge branch 'js/range-diff-wo-dotdot'
Junio C Hamano [Thu, 18 Feb 2021 01:21:41 +0000 (17:21 -0800)] 
Merge branch 'js/range-diff-wo-dotdot'

There are other ways than ".." for a single token to denote a
"commit range", namely "<rev>^!" and "<rev>^-<n>", but "git
range-diff" did not understand them.

* js/range-diff-wo-dotdot:
  range-diff(docs): explain how to specify commit ranges
  range-diff/format-patch: handle commit ranges other than A..B
  range-diff/format-patch: refactor check for commit range

9 days agoMerge branch 'jt/clone-unborn-head'
Junio C Hamano [Thu, 18 Feb 2021 01:21:40 +0000 (17:21 -0800)] 
Merge branch 'jt/clone-unborn-head'

"git clone" tries to locally check out the branch pointed at by
HEAD of the remote repository after it is done, but the protocol
did not convey the information necessary to do so when copying an
empty repository.  The protocol v2 learned how to do so.

* jt/clone-unborn-head:
  clone: respect remote unborn HEAD
  connect, transport: encapsulate arg in struct
  ls-refs: report unborn targets of symrefs

9 days agoMerge branch 'mr/bisect-in-c-4'
Junio C Hamano [Thu, 18 Feb 2021 01:21:40 +0000 (17:21 -0800)] 
Merge branch 'mr/bisect-in-c-4'

Piecemeal of rewrite of "git bisect" in C continues.

* mr/bisect-in-c-4:
  bisect--helper: retire `--check-and-set-terms` subcommand
  bisect--helper: reimplement `bisect_skip` shell function in C
  bisect--helper: retire `--bisect-auto-next` subcommand
  bisect--helper: use `res` instead of return in BISECT_RESET case option
  bisect--helper: retire `--bisect-write` subcommand
  bisect--helper: reimplement `bisect_replay` shell function in C
  bisect--helper: reimplement `bisect_log` shell function in C

9 days agoMerge branch 'ds/commit-graph-genno-fix'
Junio C Hamano [Thu, 18 Feb 2021 01:21:40 +0000 (17:21 -0800)] 
Merge branch 'ds/commit-graph-genno-fix'

Fix incremental update of commit-graph file around corrected commit
date data.

* ds/commit-graph-genno-fix:
  commit-graph: prepare commit graph
  commit-graph: be extra careful about mixed generations
  commit-graph: compute generations separately
  commit-graph: validate layers for generation data
  commit-graph: always parse before commit_graph_data_at()
  commit-graph: use repo_parse_commit

9 days agoMerge branch 'ak/corrected-commit-date'
Junio C Hamano [Thu, 18 Feb 2021 01:21:40 +0000 (17:21 -0800)] 
Merge branch 'ak/corrected-commit-date'

The commit-graph learned to use corrected commit dates instead of
the generation number to help topological revision traversal.

* ak/corrected-commit-date:
  doc: add corrected commit date info
  commit-reach: use corrected commit dates in paint_down_to_common()
  commit-graph: use generation v2 only if entire chain does
  commit-graph: implement generation data chunk
  commit-graph: implement corrected commit date
  commit-graph: return 64-bit generation number
  commit-graph: add a slab to store topological levels
  t6600-test-reach: generalize *_three_modes
  commit-graph: consolidate fill_commit_graph_info
  revision: parse parent in indegree_walk_step()
  commit-graph: fix regression when computing Bloom filters

9 days agodoc: fix naming of response-end-pkt
Joey Salazar [Thu, 18 Feb 2021 00:11:22 +0000 (00:11 +0000)] 
doc: fix naming of response-end-pkt

Git Protocol version 2[1] defines 0002 as a Message Packet that indicates
the end of a response for stateless connections.

Change the naming of the 0002 Packet to 'Response End' to match the
parsing introduced in Wireshark's MR !1922 for consistency. A subsequent
MR in Wireshark will address additional mismatches.


Signed-off-by: Joey Salazar <>
Reviewed-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
9 days agodocs/rev-list: add some examples of --disk-usage
Jeff King [Wed, 17 Feb 2021 23:35:33 +0000 (18:35 -0500)] 
docs/rev-list: add some examples of --disk-usage

It's not immediately obvious why --disk-usage might be a useful thing.
These examples show off a few of the real-world cases I've used it for.

Signed-off-by: Jeff King <>
Signed-off-by: Junio C Hamano <>
9 days agodocs/rev-list: add an examples section
Jeff King [Wed, 17 Feb 2021 23:34:21 +0000 (18:34 -0500)] 
docs/rev-list: add an examples section

We currently don't show any examples of using git-rev-list at all. Let's
add some pretty elementary examples. They likely seem obvious to anybody
who has worked with the tool for a while, but my purpose here is

  - they may be enlightening to people who haven't used the tool a lot
    to give a general flavor of how it is meant to be used

  - they can serve as a starting point for adding more interesting
    examples (we can do that without the basic ones, of course, but I
    think it makes sense to show off the building blocks)

This set is far from exhaustive, but again, the purpose is to be a
starting point for further additions.

Signed-off-by: Jeff King <>
Signed-off-by: Junio C Hamano <>
10 days agorev-list-options.txt: fix rendering of bonus paragraph
Martin Ågren [Wed, 17 Feb 2021 19:56:04 +0000 (20:56 +0100)] 
rev-list-options.txt: fix rendering of bonus paragraph

In git-log(1) -- but not in git-shortlog(1) or git-rev-list(1) -- we
include a bonus paragraph in the description of `--first-parent`. But
we forgot to add a lone "+" for a list continuation, and we shouldn't
be indenting this second paragraph. As a result, we get a different
indentation and the `backticks` render literally.

Signed-off-by: Martin Ågren <>
Signed-off-by: Junio C Hamano <>
10 days agoblame: remove unnecessary use of get_commit_info()
Rafael Silva [Wed, 17 Feb 2021 14:54:43 +0000 (15:54 +0100)] 
blame: remove unnecessary use of get_commit_info()

When `git blame --color-by-age`, the determine_line_heat() is called to
select how to color the output based on the commit's author date.  It
uses the get_commit_info() to parse the information into a `commit_info`
structure, however, this is actually unnecessary because the
determine_line_heat() caller also does the same.

Instead, let's change the determine_line_heat() to take a `commit_info`
structure and remove the internal call to get_commit_info() thus
cleaning up and optimizing the code path.

Enabling Git's trace2 API in order to record the execution time for
every call to determine_line_heat() function:

   + trace2_region_enter("blame", "determine_line_heat", the_repository);
     determine_line_heat(ent, &default_color);
   + trace2_region_enter("blame", "determine_line_heat", the_repository);

Then, running `git blame` for "kernel/fork.c" in linux.git and summing
all the execution time for every call (around 1.3k calls) resulted in
2.6x faster execution (best out 3):

   git built from 328c109303 (The eighth batch, 2021-02-12) = 42ms
   git built from 328c109303 + this change                  = 16ms

Signed-off-by: Rafael Silva <>
Reviewed-by: Taylor Blau <>
Signed-off-by: Junio C Hamano <>
11 days agocheckout-index: omit entries with no tempname from --temp output
Matheus Tavares [Tue, 16 Feb 2021 14:06:52 +0000 (11:06 -0300)] 
checkout-index: omit entries with no tempname from --temp output

With --temp (or --stage=all, which implies --temp), checkout-index
writes a list to stdout associating temporary file names to the entries'
names. But if it fails to write an entry, and the failure happens before
even assigning a temporary filename to that entry, we get an odd output
line. This can be seen when trying to check out a symlink whose blob is

$ missing_blob=$(git hash-object --stdin </dev/null)
$ git update-index --add --cacheinfo 120000,$missing_blob,foo
$ git checkout-index --temp foo
error: unable to read sha1 file of foo (e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)

The 'TAB foo' line is not much useful and it might break scripts that
expect the 'tempname TAB foo' output. So let's omit such entries from
the stdout list (but leaving the error message on stderr).

We could also consider omitting _all_ failed entries from the output
list, but that's probably not a good idea as the associated tempfiles
may have been created even when checkout failed, so scripts may want to
use the output list for cleanup.

Signed-off-by: Matheus Tavares <>
Signed-off-by: Junio C Hamano <>
11 days agowrite_entry(): fix misuses of `path` in error messages
Matheus Tavares [Tue, 16 Feb 2021 14:06:51 +0000 (11:06 -0300)] 
write_entry(): fix misuses of `path` in error messages

The variables `path` and `ce->name`, at write_entry(), usually have the
same contents, but that's not the case when using a checkout prefix or
writing to a tempfile. (In fact, `path` will be either empty or dirty
when writing to a tempfile.) Therefore, these variables cannot be used
interchangeably. In this sense, fix wrong uses of `path` in error
messages where it should really be `ce->name`, and add some regression
tests. (Note: there doesn't seem to be any misuse in the other way

Signed-off-by: Matheus Tavares <>
Signed-off-by: Junio C Hamano <>
11 days agodiff: --{rotate,skip}-to=<path>
Junio C Hamano [Thu, 11 Feb 2021 19:57:50 +0000 (11:57 -0800)] 
diff: --{rotate,skip}-to=<path>

In the implementation of "git difftool", there is a case where the
user wants to start viewing the diffs at a specific path and
continue on to the rest, optionally wrapping around to the
beginning.  Since it is somewhat cumbersome to implement such a
feature as a post-processing step of "git diff" output, let's
support it internally with two new options.

 - "git diff --rotate-to=C", when the resulting patch would show
   paths A B C D E without the option, would "rotate" the paths to
   shows patch to C D E A B instead.  It is an error when there is
   no patch for C is shown.

 - "git diff --skip-to=C" would instead "skip" the paths before C,
   and shows patch to C D E.  Again, it is an error when there is no
   patch for C is shown.

 - "git log [-p]" also accepts these two options, but it is not an
   error if there is no change to the specified path.  Instead, the
   set of output paths are rotated or skipped to the specified path
   or the first path that sorts after the specified path.

Signed-off-by: Junio C Hamano <>
2 weeks agoThe eighth batch
Junio C Hamano [Fri, 12 Feb 2021 22:13:40 +0000 (14:13 -0800)] 
The eighth batch

Signed-off-by: Junio C Hamano <>
2 weeks agoMerge branch 'tb/precompose-prefix-too'
Junio C Hamano [Fri, 12 Feb 2021 22:21:04 +0000 (14:21 -0800)] 
Merge branch 'tb/precompose-prefix-too'

When commands are started from a subdirectory, they may have to
compare the path to the subdirectory (called prefix and found out
from $(pwd)) with the tracked paths.  On macOS, $(pwd) and
readdir() yield decomposed path, while the tracked paths are
usually normalized to the precomposed form, causing mismatch.  This
has been fixed by taking the same approach used to normalize the
command line arguments.

* tb/precompose-prefix-too:
  MacOS: precompose_argv_prefix()

2 weeks agoMerge branch 'jk/complete-branch-force-delete'
Junio C Hamano [Fri, 12 Feb 2021 22:21:04 +0000 (14:21 -0800)] 
Merge branch 'jk/complete-branch-force-delete'

The command line completion (in contrib/) completed "git branch -d"
with branch names, but "git branch -D" offered tagnames in addition,
which has been corrected.  "git branch -M" had the same problem.

* jk/complete-branch-force-delete:
  doc/git-branch: fix awkward wording for "-c"
  completion: handle other variants of "branch -m"
  completion: treat "branch -D" the same way as "branch -d"

2 weeks agoMerge branch 'jv/upload-pack-filter-spec-quotefix'
Junio C Hamano [Fri, 12 Feb 2021 22:21:04 +0000 (14:21 -0800)] 
Merge branch 'jv/upload-pack-filter-spec-quotefix'

Fix in passing custom args from "git clone" to "upload-pack" on the
other side.

* jv/upload-pack-filter-spec-quotefix:
  t5544: clarify 'hook works with partial clone' test
  upload-pack.c: fix filter spec quoting bug

2 weeks agoMerge branch 'tb/pack-revindex-on-disk'
Junio C Hamano [Fri, 12 Feb 2021 22:21:04 +0000 (14:21 -0800)] 
Merge branch 'tb/pack-revindex-on-disk'

Introduce an on-disk file to record revindex for packdata, which
traditionally was always created on the fly and only in-core.

* tb/pack-revindex-on-disk:
  t5325: check both on-disk and in-memory reverse index
  pack-revindex: ensure that on-disk reverse indexes are given precedence
  t: prepare for GIT_TEST_WRITE_REV_INDEX
  Documentation/config/pack.txt: advertise 'pack.writeReverseIndex'
  builtin/pack-objects.c: respect 'pack.writeReverseIndex'
  builtin/index-pack.c: write reverse indexes
  builtin/index-pack.c: allow stripping arbitrary extensions
  pack-write.c: prepare to write 'pack-*.rev' files
  packfile: prepare for the existence of '*.rev' files

2 weeks agoMerge branch 'ab/tests-various-fixup'
Junio C Hamano [Fri, 12 Feb 2021 22:21:04 +0000 (14:21 -0800)] 
Merge branch 'ab/tests-various-fixup'

Various test updates.

* ab/tests-various-fixup:
  rm tests: actually test for SIGPIPE in SIGPIPE test
  archive tests: use a cheaper "zipinfo -h" invocation to get header
  upload-pack tests: avoid a non-zero "grep" exit status
  git-svn tests: rewrite brittle tests to use "--[no-]merges".
  git svn mergeinfo tests: refactor "test -z" to use test_must_be_empty
  git svn mergeinfo tests: modernize redirection & quoting style
  cache-tree tests: explicitly test HEAD and index differences
  cache-tree tests: use a sub-shell with less indirection
  cache-tree tests: remove unused $2 parameter
  cache-tree tests: refactor for modern test style

2 weeks agotest-lib-functions: assert correct parameter count
Ævar Arnfjörð Bjarmason [Fri, 12 Feb 2021 13:29:42 +0000 (14:29 +0100)] 
test-lib-functions: assert correct parameter count

Add assertions of the correct parameter count of various functions, in
particularly the wrappers for the shell "test" built-in.

In an earlier commit we fixed a bug with an incorrect number of
arguments being passed to "test_path_is_{file,missing}". Let's also
guard other similar functions from the same sort of misuse.

Signed-off-by: Ævar Arnfjörð Bjarmason <>
Signed-off-by: Junio C Hamano <>
2 weeks agotest-lib-functions: remove bug-inducing "diagnostics" helper param
Ævar Arnfjörð Bjarmason [Fri, 12 Feb 2021 13:29:41 +0000 (14:29 +0100)] 
test-lib-functions: remove bug-inducing "diagnostics" helper param

Remove the optional "diagnostics" parameter of the
test_path_is_{file,dir,missing} functions.

We have a lot of uses of these functions, but the only legitimate use
of the diagnostics parameter is from when the functions themselves
were introduced in 2caf20c52b7 (test-lib: user-friendly alternatives
to test [-d|-f|-e], 2010-08-10).

But as the the rest of this diff demonstrates its presence did more to
silently introduce bugs in our tests. Fix such bugs in the tests added
in ae4e89e549b (gc: add --keep-largest-pack option, 2018-04-15), and
c04ba51739a (t6046: testcases checking whether updates can be skipped
in a merge, 2018-04-19).

Let's also assert that those functions are called with exactly one
parameter, a follow-up commit will add similar asserts to other
functions in that we didn't have existing misuse

Signed-off-by: Ævar Arnfjörð Bjarmason <>
Signed-off-by: Junio C Hamano <>
2 weeks agotest libs: rename "diff-lib" to "lib-diff"
Ævar Arnfjörð Bjarmason [Fri, 12 Feb 2021 13:29:40 +0000 (14:29 +0100)] 
test libs: rename "diff-lib" to "lib-diff"

Rename the "diff-lib" to "lib-diff". With this rename and preceding
commits there is no remaining t/*lib* which doesn't follow the
convention of being called t/lib-*.

Signed-off-by: Ævar Arnfjörð Bjarmason <>
Signed-off-by: Junio C Hamano <>
2 weeks agoSync with maint
Junio C Hamano [Thu, 11 Feb 2021 21:58:52 +0000 (13:58 -0800)] 
Sync with maint

2 weeks agoMerge branch 'en/merge-ort-perf'
Junio C Hamano [Thu, 11 Feb 2021 21:58:43 +0000 (13:58 -0800)] 
Merge branch 'en/merge-ort-perf'

The "ort" merge strategy.

* en/merge-ort-perf:
  merge-ort: begin performance work; instrument with trace2_region_* calls
  merge-ort: ignore the directory rename split conflict for now
  merge-ort: fix massive leak

2 weeks agoMerge branch 'en/ort-directory-rename'
Junio C Hamano [Thu, 11 Feb 2021 21:58:43 +0000 (13:58 -0800)] 
Merge branch 'en/ort-directory-rename'

ORT merge strategy learns to infer "renamed directory" while

* en/ort-directory-rename:
  merge-ort: fix a directory rename detection bug
  merge-ort: process_renames() now needs more defensiveness
  merge-ort: implement apply_directory_rename_modifications()
  merge-ort: add a new toplevel_dir field
  merge-ort: implement handle_path_level_conflicts()
  merge-ort: implement check_for_directory_rename()
  merge-ort: implement apply_dir_rename() and check_dir_renamed()
  merge-ort: implement compute_collisions()
  merge-ort: modify collect_renames() for directory rename handling
  merge-ort: implement handle_directory_level_conflicts()
  merge-ort: implement compute_rename_counts()
  merge-ort: copy get_renamed_dir_portion() from merge-recursive.c
  merge-ort: add outline of get_provisional_directory_renames()
  merge-ort: add outline for computing directory renames
  merge-ort: collect which directories are removed in dirs_removed
  merge-ort: initialize and free new directory rename data structures
  merge-ort: add new data structures for directory rename detection

2 weeks agoMerge branch 'tb/ci-run-cocci-with-18.04' into maint maint
Junio C Hamano [Thu, 11 Feb 2021 21:57:36 +0000 (13:57 -0800)] 
Merge branch 'tb/ci-run-cocci-with-18.04' into maint

* tb/ci-run-cocci-with-18.04:
  .github/workflows/main.yml: run static-analysis on bionic

2 weeks agoconfig: improve error message for boolean config
Andrew Klotz [Thu, 11 Feb 2021 20:30:53 +0000 (20:30 +0000)] 
config: improve error message for boolean config

Currently invalid boolean config values return messages about 'bad
numeric', which is slightly misleading when the error was due to a
boolean value. We can improve the developer experience by returning a
boolean error message when we know the value is neither a bool text or

before with an invalid boolean value of `non-boolean`, its unclear what
numeric is referring to:
  fatal: bad numeric config value 'non-boolean' for 'commit.gpgsign': invalid unit

now the error message mentions `non-boolean` is a bad boolean value:
  fatal: bad boolean config value 'non-boolean' for 'commit.gpgsign'

Signed-off-by: Andrew Klotz <>
Signed-off-by: Junio C Hamano <>
2 weeks agostash: declare ref_stash as an array
Denton Liu [Tue, 9 Feb 2021 07:28:53 +0000 (23:28 -0800)] 
stash: declare ref_stash as an array

Save sizeof(const char *) bytes by declaring ref_stash as an array
instead of having a redundant pointer to an array.

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agot3905: use test_cmp() to check file contents
Denton Liu [Tue, 9 Feb 2021 07:28:52 +0000 (23:28 -0800)] 
t3905: use test_cmp() to check file contents

Modernize the script by doing file content comparisons using test_cmp()
instead of `test x = "$(cat file)"`.

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agot3905: replace test -s with test_file_not_empty
Denton Liu [Tue, 9 Feb 2021 07:28:51 +0000 (23:28 -0800)] 
t3905: replace test -s with test_file_not_empty

In order to modernize the test script, replace `test -s` with
test_file_not_empty(), which provides better diagnostic output in the
case of failure.

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agot3905: remove nested git in command substitution
Denton Liu [Tue, 9 Feb 2021 07:28:50 +0000 (23:28 -0800)] 
t3905: remove nested git in command substitution

If a git command in a nested command substitution fails, it will be
silently ignored since only the return code of the outer command
substitutions is reported. Factor out nested command substitutions so
that the error codes of those commands are reported.

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agot3905: move all commands into test cases
Denton Liu [Tue, 9 Feb 2021 07:28:49 +0000 (23:28 -0800)] 
t3905: move all commands into test cases

In order to modernize the tests, move commands that currently run
outside of test cases into a test case. Where possible, clean up files
that are produced using test_when_finished() but in the case where files
persist over multiple test cases, create a new test case to perform

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agot3905: remove spaces after redirect operators
Denton Liu [Tue, 9 Feb 2021 07:28:48 +0000 (23:28 -0800)] 
t3905: remove spaces after redirect operators

For shell scripts, the usual convention is for there to be no space
after redirection operators, (e.g. `>file`, not `> file`). Remove these
spaces wherever they appear.

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agogit-stash.txt: be explicit about subcommand options
Denton Liu [Tue, 9 Feb 2021 07:28:47 +0000 (23:28 -0800)] 
git-stash.txt: be explicit about subcommand options

Currently, the options for the `list` and `show` subcommands are just
listed as `<options>`. This seems to imply, from a cursory glance at the
summary, that they take the stash options listed below. However, reading
more carefully, we see that they take log options and diff options

Make it more obvious that they take log and diff options by explicitly
stating this in the subcommand summary.

Signed-off-by: Denton Liu <>
Signed-off-by: Junio C Hamano <>
2 weeks agorev-list: add --disk-usage option for calculating disk usage
Jeff King [Tue, 9 Feb 2021 10:53:50 +0000 (05:53 -0500)] 
rev-list: add --disk-usage option for calculating disk usage

It can sometimes be useful to see which refs are contributing to the
overall repository size (e.g., does some branch have a bunch of objects
not found elsewhere in history, which indicates that deleting it would
shrink the size of a clone).

You can find that out by generating a list of objects, getting their
sizes from cat-file, and then summing them, like:

    git rev-list --objects --no-object-names main..branch
    git cat-file --batch-check='%(objectsize:disk)' |
    perl -lne '$total += $_; END { print $total }'

Though note that the caveats from git-cat-file(1) apply here. We "blame"
base objects more than their deltas, even though the relationship could
easily be flipped. Still, it can be a useful rough measure.

But one problem is that it's slow to run. Teaching rev-list to sum up
the sizes can be much faster for two reasons:

  1. It skips all of the piping of object names and sizes.

  2. If bitmaps are in use, for objects that are in the
     bitmapped packfile we can skip the oid_object_info()
     lookup entirely, and just ask the revindex for the
     on-disk size.

This patch implements a --disk-usage option which produces the same
answer in a fraction of the time. Here are some timings using a clone of

  [rev-list piped to cat-file, no bitmaps]
  $ time git rev-list --objects --no-object-names --all |
    git cat-file --buffer --batch-check='%(objectsize:disk)' |
    perl -lne '$total += $_; END { print $total }'
  real 0m29.635s
  user 0m38.003s
  sys 0m1.093s

  [internal, no bitmaps]
  $ time git rev-list --disk-usage --objects --all
  real 0m31.262s
  user 0m30.885s
  sys 0m0.376s

Even though the wall-clock time is slightly worse due to parallelism,
notice the CPU savings between the two. We saved 21% of the CPU just by
avoiding the pipes.

But the real win is with bitmaps. If we use them without the new option:

  [rev-list piped to cat-file, bitmaps]
  $ time git rev-list --objects --no-object-names --all --use-bitmap-index |
    git cat-file --batch-check='%(objectsize:disk)' |
    perl -lne '$total += $_; END { print $total }'
  real 0m6.244s
  user 0m8.452s
  sys 0m0.311s

then we're faster to generate the list of objects, but we still spend a
lot of time piping and looking things up. But if we do both together:

  [internal, bitmaps]
  $ time git rev-list --disk-usage --objects --all --use-bitmap-index
  real 0m0.219s
  user 0m0.169s
  sys 0m0.049s

then we get the same answer much faster.

For "--all", that answer will correspond closely to "du objects/pack",
of course. But we're actually checking reachability here, so we're still
fast when we ask for more interesting things:

  $ time git rev-list --disk-usage --use-bitmap-index v5.0..v5.10
  real 0m0.429s
  user 0m0.356s
  sys 0m0.072s

Signed-off-by: Jeff King <>
Signed-off-by: Junio C Hamano <>