summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2022-01-10Merge branch 'ds/sparse-checkout-malformed-pattern-fix'Libravatar Junio C Hamano3-6/+42
Certain sparse-checkout patterns that are valid in non-cone mode led to segfault in cone mode, which has been corrected. * ds/sparse-checkout-malformed-pattern-fix: sparse-checkout: refuse to add to bad patterns sparse-checkout: fix OOM error with mixed patterns sparse-checkout: fix segfault on malformed patterns
2022-01-05The seventh batchLibravatar Junio C Hamano1-0/+49
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-05Merge branch 'rs/daemon-plug-leak'Libravatar Junio C Hamano1-1/+1
Plug a memory leak. * rs/daemon-plug-leak: daemon: plug memory leak on overlong path
2022-01-05Merge branch 'rs/pcre2-utf'Libravatar Junio C Hamano2-2/+8
"git grep --perl-regexp" failed to match UTF-8 characters with wildcard when the pattern consists only of ASCII letters, which has been corrected. * rs/pcre2-utf: grep/pcre2: factor out literal variable grep/pcre2: use PCRE2_UTF even with ASCII patterns
2022-01-05Merge branch 'jc/t4204-do-not-write-git-on-upstream-of-pipe'Libravatar Junio C Hamano1-12/+17
Test fixes. * jc/t4204-do-not-write-git-on-upstream-of-pipe: t4204 is not sanitizer clean at all
2022-01-05Merge branch 'rs/log-invert-grep-with-headers'Libravatar Junio C Hamano5-7/+42
"git log --invert-grep --author=<name>" used to exclude commits written by the given author, but now "--invert-grep" only affects the matches made by the "--grep=<pattern>" option. * rs/log-invert-grep-with-headers: log: let --invert-grep only invert --grep
2022-01-05Merge branch 'gh/gpg-doc-markup-fix'Libravatar Junio C Hamano1-1/+1
Doc markup fix. * gh/gpg-doc-markup-fix: docs: add missing colon to Documentation/config/gpg.txt
2022-01-05Merge branch 'rs/t4202-invert-grep-test-fix'Libravatar Junio C Hamano1-1/+1
Test fix. * rs/t4202-invert-grep-test-fix: t4202: fix patternType setting in --invert-grep test
2022-01-05Merge branch 'ds/repack-fixlets'Libravatar Junio C Hamano4-5/+55
Two fixes around "git repack". * ds/repack-fixlets: repack: make '--quiet' disable progress repack: respect kept objects with '--write-midx -b'
2022-01-05Merge branch 'jc/merge-detached-head-name'Libravatar Junio C Hamano7-5/+67
The default merge message prepared by "git merge" records the name of the current branch; the name can be overridden with a new option to allow users to pretend a merge is made on a different branch. * jc/merge-detached-head-name: merge: allow to pretend a merge is made into a different branch
2022-01-05Merge branch 'km/help-prompt-fix'Libravatar Junio C Hamano1-1/+1
Among some code paths that ask an yes/no question, only one place gave a prompt that looked different from the others, which has been updated to match what the others create. * km/help-prompt-fix: help: make auto-correction prompt more consistent
2022-01-05Merge branch 'jv/use-larger-buffer-in-upload-pack'Libravatar Junio C Hamano1-5/+12
"git upload-pack" (the other side of "git fetch") used a 8kB buffer but most of its payload came on 64kB "packets". The buffer size has been enlarged so that such a packet fits. * jv/use-larger-buffer-in-upload-pack: upload-pack.c: increase output buffer size
2022-01-05Merge branch 'jk/ssh-signing-doc-markup-fix'Libravatar Junio C Hamano1-1/+1
Docfix. * jk/ssh-signing-doc-markup-fix: doc/config: mark ssh allowedSigners example as literal
2022-01-05Merge branch 'pw/diff-color-moved-fix'Libravatar Junio C Hamano3-256/+437
Correctness and performance update to "diff --color-moved" feature. * pw/diff-color-moved-fix: diff --color-moved: intern strings diff: use designated initializers for emitted_diff_symbol diff --color-moved-ws=allow-indentation-change: improve hash lookups diff --color-moved: stop clearing potential moved blocks diff --color-moved: shrink potential moved blocks as we go diff --color-moved: unify moved block growth functions diff --color-moved: call comparison function directly diff --color-moved-ws=allow-indentation-change: simplify and optimize diff: simplify allow-indentation-change delta calculation diff --color-moved: avoid false short line matches and bad zebra coloring diff --color-moved=zebra: fix alternate coloring diff --color-moved: rewind when discarding pmb diff --color-moved: factor out function diff --color-moved: clear all flags on blocks that are too short diff --color-moved: add perf tests
2022-01-05Merge branch 'xw/am-empty'Libravatar Junio C Hamano6-16/+211
"git am" learns "--empty=(stop|drop|keep)" option to tweak what is done to a piece of e-mail without a patch in it. * xw/am-empty: am: support --allow-empty to record specific empty patches am: support --empty=<option> to handle empty patches doc: git-format-patch: describe the option --always
2022-01-05Merge branch 'en/keep-cwd'Libravatar Junio C Hamano13-22/+442
Many git commands that deal with working tree files try to remove a directory that becomes empty (i.e. "git switch" from a branch that has the directory to another branch that does not would attempt remove all files in the directory and the directory itself). This drops users into an unfamiliar situation if the command was run in a subdirectory that becomes subject to removal due to the command. The commands have been taught to keep an empty directory if it is the directory they were started in to avoid surprising users. * en/keep-cwd: t2501: simplify the tests since we can now assume desired behavior dir: new flag to remove_dir_recurse() to spare the original_cwd dir: avoid incidentally removing the original_cwd in remove_path() stash: do not attempt to remove startup_info->original_cwd rebase: do not attempt to remove startup_info->original_cwd clean: do not attempt to remove startup_info->original_cwd symlinks: do not include startup_info->original_cwd in dir removal unpack-trees: add special cwd handling unpack-trees: refuse to remove startup_info->original_cwd setup: introduce startup_info->original_cwd t2501: add various tests for removing the current working directory
2022-01-05Merge branch 'jc/flex-array-definition'Libravatar Junio C Hamano1-2/+11
The conditions to choose different definitions of the FLEX_ARRAY macro for vendor compilers has been simplified to make it easier to maintain. * jc/flex-array-definition: flex-array: simplify compiler-specific workaround
2022-01-05Merge branch 'jh/p4-rcs-expansion-in-bytestring'Libravatar Junio C Hamano2-39/+42
The RCS keyword substitution in "git p4" used to be done assuming that the contents are UTF-8 text, which can trigger decoding errors. We now treat the contents as a bytestring for robustness and correctness. * jh/p4-rcs-expansion-in-bytestring: git-p4: resolve RCS keywords in bytes not utf-8 git-p4: open temporary patch file for write only git-p4: add raw option to read_pipelines git-p4: pre-compile RCS keyword regexes git-p4: use with statements to close files after use in patchRCSKeywords
2022-01-03The sixth batchLibravatar Junio C Hamano1-0/+11
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-03Merge branch 'en/sparse-checkout-set'Libravatar Junio C Hamano5-97/+227
The "init" and "set" subcommands in "git sparse-checkout" have been unified for a better user experience and performance. * en/sparse-checkout-set: sparse-checkout: remove stray trailing space clone: avoid using deprecated `sparse-checkout init` Documentation: clarify/correct a few sparsity related statements git-sparse-checkout.txt: update to document init/set/reapply changes sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} sparse-checkout: enable `set` to initialize sparse-checkout mode sparse-checkout: split out code for tweaking settings config sparse-checkout: disallow --no-stdin as an argument to set sparse-checkout: add sanity-checks on initial sparsity state sparse-checkout: break apart functions for sparse_checkout_(set|add) sparse-checkout: pass use_stdin as a parameter instead of as a global
2022-01-03Merge branch 'es/test-chain-lint'Libravatar Junio C Hamano163-847/+740
Broken &&-chains in the test scripts have been corrected. * es/test-chain-lint: t6000-t9999: detect and signal failure within loop t5000-t5999: detect and signal failure within loop t4000-t4999: detect and signal failure within loop t0000-t3999: detect and signal failure within loop tests: simplify by dropping unnecessary `for` loops tests: apply modern idiom for exiting loop upon failure tests: apply modern idiom for signaling test failure tests: fix broken &&-chains in `{...}` groups tests: fix broken &&-chains in `$(...)` command substitutions tests: fix broken &&-chains in compound statements tests: use test_write_lines() to generate line-oriented output tests: simplify construction of large blocks of text t9107: use shell parameter expansion to avoid breaking &&-chain t6300: make `%(raw:size) --shell` test more robust t5516: drop unnecessary subshell and command invocation t4202: clarify intent by creating expected content less cleverly t1020: avoid aborting entire test script when one test fails t1010: fix unnoticed failure on Windows t/lib-pager: use sane_unset() to avoid breaking &&-chain
2022-01-03Merge branch 'ns/tmp-objdir'Libravatar Junio C Hamano11-15/+183
New interface into the tmp-objdir API to help in-core use of the quarantine feature. * ns/tmp-objdir: tmp-objdir: disable ref updates when replacing the primary odb tmp-objdir: new API for creating temporary writable databases
2022-01-03Merge branch 'jc/unleak-log'Libravatar Junio C Hamano1-0/+1
"git format-patch" uses a single rev_info instance and then exits. Mark the structure with UNLEAK() macro to squelch leak sanitizer. * jc/unleak-log: format-patch: mark rev_info with UNLEAK
2021-12-30sparse-checkout: refuse to add to bad patternsLibravatar Derrick Stolee3-3/+9
When in cone mode sparse-checkout, it is unclear how 'git sparse-checkout add <dir1> ...' should behave if the existing sparse-checkout file does not match the cone mode patterns. Change the behavior to fail with an error message about the existing patterns. Also, all cone mode patterns start with a '/' character, so add that restriction. This is necessary for our example test 'cone mode: warn on bad pattern', but also requires modifying the example sparse-checkout file we use to test the warnings related to recognizing cone mode patterns. This error checking would cause a failure further down the test script because of a test that adds non-cone mode patterns without cleaning them up. Perform that cleanup as part of the test now. Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-30sparse-checkout: fix OOM error with mixed patternsLibravatar Derrick Stolee2-1/+12
Add a test to t1091-sparse-checkout-builtin.sh that would result in an infinite loop and out-of-memory error before this change. The issue relies on having non-cone-mode patterns while trying to modify the patterns in cone-mode. The fix is simple, allowing us to break from the loop when the input path does not contain a slash, as the "dir" pattern we added does not. This is only a fix to the critical out-of-memory error. A better response to such a strange state will follow in a later change. Reported-by: Calbabreaker <calbabreaker@gmail.com> Helped-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-30sparse-checkout: fix segfault on malformed patternsLibravatar Derrick Stolee2-3/+22
Then core.sparseCheckoutCone is enabled, the sparse-checkout patterns are used to populate two hashsets that accelerate pattern matching. If the user modifies the sparse-checkout file outside of the 'sparse-checkout' builtin, then strange patterns can happen, triggering some error checks. One of these error checks is possible to hit when some special characters exist in a line. A warning message is correctly written to stderr, but then there is additional logic that attempts to remove the line from the hashset and free the data. This leads to a segfault in the 'git sparse-checkout list' command because it iterates over the contents of the hashset, which is now invalid. The fix here is to stop trying to remove from the hashset. In addition, we disable cone mode sparse-checkout because of the malformed data. This results in the pattern-matching working with a possibly-slower algorithm, but using the patterns as they are in the sparse-checkout file. This also changes the behavior of commands such as 'git sparse-checkout list' because the output patterns will be the contents of the sparse-checkout file instead of the list of directories. This is an existing behavior for other types of bad patterns. Add a test that triggers the segfault without the code change. Reported-by: John Burnett <johnburnett@johnburnett.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-23sparse-checkout: remove stray trailing spaceLibravatar Elijah Newren1-1/+1
Reported-by: Jiang Xin <worldhello.net@gmail.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-22The fifth batchLibravatar Junio C Hamano1-0/+13
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-22Merge branch 'es/chainlint'Libravatar Junio C Hamano71-293/+339
The chainlint test script linter in the test suite has been updated. * es/chainlint: chainlint.sed: stop splitting "(..." into separate lines "(" and "..." chainlint.sed: swallow comments consistently chainlint.sed: stop throwing away here-doc tags chainlint.sed: don't mistake `<< word` in string as here-doc operator chainlint.sed: make here-doc "<<-" operator recognition more POSIX-like chainlint.sed: drop subshell-closing ">" annotation chainlint.sed: drop unnecessary distinction between ?!AMP?! and ?!SEMI?! chainlint.sed: tolerate harmless ";" at end of last line in block chainlint.sed: improve ?!SEMI?! placement accuracy chainlint.sed: improve ?!AMP?! placement accuracy t/Makefile: optimize chainlint self-test t/chainlint/one-liner: avoid overly intimate chainlint.sed knowledge t/chainlint/*.test: generalize self-test commentary t/chainlint/*.test: fix invalid test cases due to mixing quote types t/chainlint/*.test: don't use invalid shell syntax
2021-12-22Merge branch 'jz/apply-quiet-and-allow-empty'Libravatar Junio C Hamano4-8/+36
"git apply" has been taught to ignore a message without a patch with the "--allow-empty" option. It also learned to honor the "--quiet" option given from the command line. * jz/apply-quiet-and-allow-empty: git-apply: add --allow-empty flag git-apply: add --quiet flag
2021-12-22Merge branch 'jk/limit-developers-to-gnu99'Libravatar Junio C Hamano1-0/+5
Enable -std=gnu99 option in DEVELOPER builds. * jk/limit-developers-to-gnu99: config.mak.dev: specify -std=gnu99 for gcc/clang
2021-12-22Merge branch 'ab/common-main-cleanup'Libravatar Junio C Hamano2-5/+9
Code clean-up. * ab/common-main-cleanup: common-main.c: call exit(), don't return
2021-12-22Merge branch 'ab/fetch-set-upstream-while-detached'Libravatar Junio C Hamano2-0/+32
"git fetch --set-upstream" did not check if there is a current branch, leading to a segfault when it is run on a detached HEAD, which has been corrected. * ab/fetch-set-upstream-while-detached: pull, fetch: fix segfault in --set-upstream option
2021-12-21The fourth batchLibravatar Junio C Hamano1-1/+33
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-21Merge branch 'js/scalar'Libravatar Junio C Hamano8-0/+1275
Add pieces from "scalar" to contrib/. * js/scalar: scalar: implement the `version` command scalar: implement the `delete` command scalar: teach 'reconfigure' to optionally handle all registered enlistments scalar: allow reconfiguring an existing enlistment scalar: implement the `run` command scalar: teach 'clone' to support the --single-branch option scalar: implement the `clone` subcommand scalar: implement 'scalar list' scalar: let 'unregister' handle a deleted enlistment directory gracefully scalar: 'unregister' stops background maintenance scalar: 'register' sets recommended config and starts maintenance scalar: create test infrastructure scalar: start documenting the command scalar: create a rudimentary executable scalar: add a README with a roadmap
2021-12-21Merge branch 'ld/sparse-diff-blame'Libravatar Junio C Hamano7-37/+131
Teach diff and blame to work well with sparse index. * ld/sparse-diff-blame: blame: enable and test the sparse index diff: enable and test the sparse index diff: replace --staged with --cached in t1092 tests repo-settings: prepare_repo_settings only in git repos test-read-cache: set up repo after git directory commit-graph: return if there is no git directory git: ensure correct git directory setup with -h
2021-12-21Merge branch 'en/name-rev-shorter-output'Libravatar Junio C Hamano1-4/+13
"git name-rev" has been tweaked to give output that is shorter and easier to understand. * en/name-rev-shorter-output: name-rev: prefer shorter names over following merges
2021-12-21Merge branch 'ak/protect-any-current-branch'Libravatar Junio C Hamano11-131/+198
"git fetch" without the "--update-head-ok" option ought to protect a checked out branch from getting updated, to prevent the working tree that checks it out to go out of sync. The code was written before the use of "git worktree" got widespread, and only checked the branch that was checked out in the current worktree, which has been updated. (originally called ak/fetch-not-overwrite-any-current-branch) * ak/protect-any-current-branch: branch: protect branches checked out in all worktrees receive-pack: protect current branch for bare repository worktree receive-pack: clean dead code from update_worktree() fetch: protect branches checked out in all worktrees worktree: simplify find_shared_symref() memory ownership model branch: lowercase error messages receive-pack: lowercase error messages fetch: lowercase error messages
2021-12-21Merge branch 'fs/ssh-signing-other-keytypes'Libravatar Junio C Hamano5-17/+67
The cryptographic signing using ssh keys can specify literal keys for keytypes whose name do not begin with the "ssh-" prefix by using the "key::" prefix mechanism (e.g. "key::ecdsa-sha2-nistp256"). * fs/ssh-signing-other-keytypes: ssh signing: make sign/amend test more resilient ssh signing: support non ssh-* keytypes
2021-12-21Merge branch 'fs/ssh-signing-key-lifetime'Libravatar Junio C Hamano13-48/+351
Extend the signing of objects with SSH keys and learn to pay attention to the key validity time range when verifying. * fs/ssh-signing-key-lifetime: ssh signing: verify ssh-keygen in test prereq ssh signing: make fmt-merge-msg consider key lifetime ssh signing: make verify-tag consider key lifetime ssh signing: make git log verify key lifetime ssh signing: make verify-commit consider key lifetime ssh signing: add key lifetime test prereqs ssh signing: use sigc struct to pass payload t/fmt-merge-msg: make gpgssh tests more specific t/fmt-merge-msg: do not redirect stderr
2021-12-21Merge branch 'jc/grep-patterntype-default-doc'Libravatar Junio C Hamano1-1/+2
Doc update. * jc/grep-patterntype-default-doc: grep: clarify what `grep.patternType=default` means
2021-12-21Merge branch 'jk/log-decorate-opts-with-implicit-decorate'Libravatar Junio C Hamano2-4/+56
When "git log" implicitly enabled the "decoration" processing without being explicitly asked with "--decorate" option, it failed to read and honor the settings given by the "--decorate-refs" option. * jk/log-decorate-opts-with-implicit-decorate: log: load decorations with --simplify-by-decoration log: handle --decorate-refs with userformat "%d"
2021-12-21Merge branch 'en/rebase-x-wo-git-dir-env'Libravatar Junio C Hamano2-8/+24
"git rebase -x" by mistake started exporting the GIT_DIR and GIT_WORK_TREE environment variables when the command was rewritten in C, which has been corrected. * en/rebase-x-wo-git-dir-env: sequencer: do not export GIT_DIR and GIT_WORK_TREE for 'exec'
2021-12-21Merge branch 'jc/c99-var-decl-in-for-loop'Libravatar Junio C Hamano2-3/+9
Weather balloon to find compilers that do not grok variable declaration in the for() loop. * jc/c99-var-decl-in-for-loop: revision: use C99 declaration of variable in for() loop
2021-12-21Merge branch 'pw/xdiff-classify-record-in-histogram'Libravatar Junio C Hamano3-42/+29
"diff --histogram" optimization. * pw/xdiff-classify-record-in-histogram: xdiff: drop unused flags parameter from recs_match xdiff: drop xpparam_t parameter from histogram cmp_recs() xdiff: drop CMP_ENV macro from xhistogram xdiff: simplify comparison xdiff: avoid unnecessary memory allocations diff histogram: intern strings
2021-12-20merge: allow to pretend a merge is made into a different branchLibravatar Junio C Hamano7-5/+67
When a series of patches for a topic-B depends on having topic-A, the workflow to prepare the topic-B branch would look like this: $ git checkout -b topic-B main $ git merge --no-ff --no-edit topic-A $ git am <mbox-for-topic-B When topic-A gets updated, recreating the first merge and rebasing the rest of the topic-B, all on detached HEAD, is a useful technique. After updating topic-A with its new round of patches: $ git checkout topic-B $ prev=$(git rev-parse 'HEAD^{/^Merge branch .topic-A. into}') $ git checkout --detach $prev^1 $ git merge --no-ff --no-edit topic-A $ git rebase --onto HEAD $prev @{-1}^0 $ git checkout -B @{-1} This will (0) check out the current topic-B. (1) find the previous merge of topic-A into topic-B. (2) detach the HEAD to the parent of the previous merge. (3) merge the updated topic-A to it. (4) reapply the patches to rebuild the rest of topic-B. (5) update topic-B with the result. without contaminating the reflog of topic-B too much. topic-B@{1} is the "logically previous" state before topic-A got updated, for example. At (4), comparison (e.g. range-diff) between HEAD and @{-1} is a meaningful way to sanity check the result, and the same can be done at (5) by comparing topic-B and topic-B@{1}. But there is one glitch. The merge into the detached HEAD done in the step (3) above gives us "Merge branch 'topic-A' into HEAD", and does not say "into topic-B". Teach the "--into-name=<branch>" option to "git merge" and its underlying "git fmt-merge-message", to pretend as if we were merging into <branch>, no matter what branch we are actually merging into, when they prepare the merge message. The pretend name honors the usual "into <target>" suppression mechanism, which can be seen in the tests added here. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-20grep/pcre2: factor out literal variableLibravatar René Scharfe1-2/+2
Patterns that contain no wildcards and don't have to be case-folded are literal. Give this condition a name to increase the readability of the boolean expression for enabling the option PCRE2_UTF. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-20grep/pcre2: use PCRE2_UTF even with ASCII patternsLibravatar René Scharfe2-1/+7
compile_pcre2_pattern() currently uses the option PCRE2_UTF only for patterns with non-ASCII characters. Patterns with ASCII wildcards can match non-ASCII strings, though. Without that option PCRE2 mishandles UTF-8 input, though -- it matches parts of multi-byte characters. Fix that by using PCRE2_UTF even for ASCII-only patterns. This is a remake of the reverted ae39ba431a (grep/pcre2: fix an edge case concerning ascii patterns and UTF-8 data, 2021-10-15). The change to the condition and the test are simplified and more targeted. Original-patch-by: Hamza Mahfooz <someguy@effective-light.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-20daemon: plug memory leak on overlong pathLibravatar René Scharfe1-1/+1
Release the strbuf containing the interpolated path after copying it to a stack buffer and before erroring out if it's too long. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-20repack: make '--quiet' disable progressLibravatar Derrick Stolee3-4/+14
While testing some ideas in 'git repack', I ran it with '--quiet' and discovered that some progress output was still shown. Specifically, the output for writing the multi-pack-index showed the progress. The 'show_progress' variable in cmd_repack() is initialized with isatty(2) and is not modified at all by the '--quiet' flag. The '--quiet' flag modifies the po_args.quiet option which is translated into a '--quiet' flag for the 'git pack-objects' child process. However, 'show_progress' is used to directly send progress information to the multi-pack-index writing logic which does not use a child process. The fix here is to modify 'show_progress' to be false if po_opts.quiet is true, and isatty(2) otherwise. This new expectation simplifies a later condition that checks both. Update the documentation to make it clear that '-q' will disable all progress in addition to ensuring the 'git pack-objects' child process will receive the flag. Use 'test_terminal' to check that this works to get around the isatty(2) check. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>