aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format40
-rw-r--r--.github/workflows/check-style.yml34
-rw-r--r--.gitlab-ci.yml25
-rw-r--r--Documentation/CodingGuidelines79
-rw-r--r--Documentation/Makefile6
-rw-r--r--Documentation/RelNotes/2.46.0.txt119
-rw-r--r--Documentation/RelNotes/2.47.0.txt133
-rw-r--r--Documentation/ReviewingGuidelines.txt25
-rw-r--r--Documentation/config/advice.txt4
-rw-r--r--Documentation/config/commitgraph.txt29
-rw-r--r--Documentation/config/core.txt3
-rw-r--r--Documentation/config/http.txt35
-rw-r--r--Documentation/docinfo-html.in5
-rw-r--r--Documentation/git-archive.txt10
-rw-r--r--Documentation/git-clone.txt6
-rw-r--r--Documentation/git-commit.txt2
-rw-r--r--Documentation/git-ls-files.txt6
-rw-r--r--Documentation/git-rebase.txt2
-rw-r--r--Documentation/git-show-branch.txt2
-rw-r--r--Documentation/gitattributes.txt2
-rw-r--r--Documentation/gitfaq.txt109
-rw-r--r--Documentation/gitformat-commit-graph.txt9
-rw-r--r--Documentation/githooks.txt15
-rw-r--r--Documentation/gitpacking.txt14
-rw-r--r--Documentation/glossary-content.txt2
-rw-r--r--Documentation/howto/maintain-git.txt158
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--Makefile12
l---------RelNotes2
-rw-r--r--add-patch.c41
-rw-r--r--advice.c1
-rw-r--r--advice.h1
-rw-r--r--apply.c89
-rw-r--r--apply.h2
-rw-r--r--blame.c4
-rw-r--r--bloom.c208
-rw-r--r--bloom.h38
-rw-r--r--builtin/am.c9
-rw-r--r--builtin/archive.c7
-rw-r--r--builtin/blame.c8
-rw-r--r--builtin/cat-file.c17
-rw-r--r--builtin/checkout.c23
-rw-r--r--builtin/clone.c3
-rw-r--r--builtin/commit-tree.c11
-rw-r--r--builtin/commit.c12
-rw-r--r--builtin/credential-cache.c9
-rw-r--r--builtin/credential-store.c1
-rw-r--r--builtin/describe.c37
-rw-r--r--builtin/difftool.c3
-rw-r--r--builtin/fmt-merge-msg.c4
-rw-r--r--builtin/get-tar-commit-id.c1
-rw-r--r--builtin/grep.c4
-rw-r--r--builtin/log.c20
-rw-r--r--builtin/ls-remote.c39
-rw-r--r--builtin/ls-tree.c3
-rw-r--r--builtin/merge-recursive.c8
-rw-r--r--builtin/merge-tree.c3
-rw-r--r--builtin/merge.c20
-rw-r--r--builtin/multi-pack-index.c13
-rw-r--r--builtin/name-rev.c6
-rw-r--r--builtin/notes.c22
-rw-r--r--builtin/patch-id.c93
-rw-r--r--builtin/push.c21
-rw-r--r--builtin/remote.c44
-rw-r--r--builtin/replay.c36
-rw-r--r--builtin/rerere.c8
-rw-r--r--builtin/rev-list.c2
-rw-r--r--builtin/rev-parse.c58
-rw-r--r--builtin/shortlog.c6
-rw-r--r--builtin/show-branch.c52
-rw-r--r--builtin/show-ref.c4
-rw-r--r--builtin/sparse-checkout.c1
-rw-r--r--builtin/stash.c43
-rw-r--r--builtin/submodule--helper.c37
-rw-r--r--builtin/var.c3
-rw-r--r--builtin/worktree.c7
-rw-r--r--bundle-uri.c6
-rw-r--r--bundle.c32
-rw-r--r--bundle.h1
-rwxr-xr-xci/check-directional-formatting.bash2
-rwxr-xr-xci/check-whitespace.sh10
-rwxr-xr-xci/install-dependencies.sh6
-rwxr-xr-xci/lib.sh1
-rwxr-xr-xci/run-style-check.sh25
-rw-r--r--commit-graph.c64
-rw-r--r--commit-reach.c1
-rw-r--r--commit.c28
-rw-r--r--commit.h12
-rw-r--r--compat/mingw.c2
-rw-r--r--compat/win32/path-utils.c37
-rw-r--r--compat/win32/path-utils.h4
-rw-r--r--config.c3
-rw-r--r--config.mak.dev2
-rw-r--r--config.mak.uname1
-rw-r--r--contrib/buildsystems/CMakeLists.txt3
-rw-r--r--contrib/credential/osxkeychain/git-credential-osxkeychain.c2
-rw-r--r--convert.c17
-rw-r--r--csum-file.c9
-rw-r--r--csum-file.h1
-rw-r--r--date.c12
-rw-r--r--diff-lib.c2
-rw-r--r--diff.c8
-rw-r--r--dir.c4
-rw-r--r--dir.h4
-rw-r--r--entry.c4
-rw-r--r--fetch-pack.c17
-rw-r--r--fetch-pack.h5
-rw-r--r--git-compat-util.h8
-rwxr-xr-xgit-send-email.perl4
-rwxr-xr-xgitweb/gitweb.perl4
-rw-r--r--grep.c3
-rw-r--r--help.c12
-rw-r--r--help.h2
-rw-r--r--http.c95
-rw-r--r--line-range.c2
-rw-r--r--list-objects-filter.c2
-rw-r--r--log-tree.c16
-rw-r--r--mailmap.c4
-rw-r--r--merge-ort-wrappers.c2
-rw-r--r--merge-ort-wrappers.h2
-rw-r--r--merge-ort.c181
-rw-r--r--merge-ort.h2
-rw-r--r--merge-recursive.c97
-rw-r--r--merge-recursive.h9
-rw-r--r--midx-write.c18
-rw-r--r--notes-merge.c1
-rw-r--r--notes-utils.c9
-rw-r--r--notes-utils.h2
-rw-r--r--notes.c21
-rw-r--r--notes.h5
-rw-r--r--object-name.c66
-rw-r--r--object-name.h2
-rw-r--r--object.h3
-rw-r--r--oss-fuzz/fuzz-commit-graph.c2
-rw-r--r--pager.c50
-rw-r--r--pager.h1
-rw-r--r--pathspec.h2
-rw-r--r--po/bg.po810
-rw-r--r--po/de.po743
-rw-r--r--po/fr.po801
-rw-r--r--po/id.po899
-rw-r--r--po/sv.po734
-rw-r--r--po/tr.po750
-rw-r--r--po/uk.po749
-rw-r--r--po/vi.po1028
-rw-r--r--po/zh_CN.po866
-rw-r--r--po/zh_TW.po1730
-rw-r--r--read-cache.c99
-rw-r--r--ref-filter.c1
-rw-r--r--reflog.c3
-rw-r--r--refs.c38
-rw-r--r--refs.h207
-rw-r--r--refs/files-backend.c30
-rw-r--r--refs/packed-backend.c14
-rw-r--r--refs/refs-internal.h3
-rw-r--r--refs/reftable-backend.c51
-rw-r--r--reftable/pq.c29
-rw-r--r--reftable/pq.h1
-rw-r--r--reftable/pq_test.c74
-rw-r--r--reftable/record_test.c382
-rw-r--r--reftable/reftable-tests.h3
-rw-r--r--reftable/tree.c15
-rw-r--r--reftable/tree_test.c60
-rw-r--r--repo-settings.c6
-rw-r--r--repository.h2
-rw-r--r--rerere.c12
-rw-r--r--revision.c85
-rw-r--r--run-command.c17
-rw-r--r--run-command.h5
-rw-r--r--send-pack.c13
-rw-r--r--sequencer.c120
-rw-r--r--setup.c58
-rw-r--r--sparse-index.c244
-rw-r--r--strvec.c2
-rw-r--r--strvec.h3
-rw-r--r--t/.gitattributes2
-rw-r--r--t/Makefile16
-rw-r--r--t/README34
-rw-r--r--t/chainlint-cat.pl29
-rwxr-xr-xt/chainlint.pl33
-rw-r--r--t/chainlint/arithmetic-expansion.expect18
-rw-r--r--t/chainlint/arithmetic-expansion.test2
-rw-r--r--t/chainlint/bash-array.expect20
-rw-r--r--t/chainlint/bash-array.test2
-rw-r--r--t/chainlint/blank-line-before-esac.expect36
-rw-r--r--t/chainlint/blank-line-before-esac.test2
-rw-r--r--t/chainlint/blank-line.expect16
-rw-r--r--t/chainlint/blank-line.test2
-rw-r--r--t/chainlint/block-comment.expect16
-rw-r--r--t/chainlint/block-comment.test2
-rw-r--r--t/chainlint/block.expect46
-rw-r--r--t/chainlint/block.test2
-rw-r--r--t/chainlint/broken-chain.expect12
-rw-r--r--t/chainlint/broken-chain.test2
-rw-r--r--t/chainlint/case-comment.expect22
-rw-r--r--t/chainlint/case-comment.test2
-rw-r--r--t/chainlint/case.expect38
-rw-r--r--t/chainlint/case.test2
-rw-r--r--t/chainlint/chain-break-background.expect18
-rw-r--r--t/chainlint/chain-break-background.test2
-rw-r--r--t/chainlint/chain-break-continue.expect24
-rw-r--r--t/chainlint/chain-break-continue.test2
-rw-r--r--t/chainlint/chain-break-false.expect18
-rw-r--r--t/chainlint/chain-break-false.test2
-rw-r--r--t/chainlint/chain-break-return-exit.expect38
-rw-r--r--t/chainlint/chain-break-return-exit.test2
-rw-r--r--t/chainlint/chain-break-status.expect18
-rw-r--r--t/chainlint/chain-break-status.test2
-rw-r--r--t/chainlint/chained-block.expect18
-rw-r--r--t/chainlint/chained-block.test2
-rw-r--r--t/chainlint/chained-subshell.expect20
-rw-r--r--t/chainlint/chained-subshell.test2
-rw-r--r--t/chainlint/close-nested-and-parent-together.expect6
-rw-r--r--t/chainlint/close-nested-and-parent-together.test2
-rw-r--r--t/chainlint/close-subshell.expect52
-rw-r--r--t/chainlint/close-subshell.test2
-rw-r--r--t/chainlint/command-substitution-subsubshell.expect4
-rw-r--r--t/chainlint/command-substitution-subsubshell.test2
-rw-r--r--t/chainlint/command-substitution.expect18
-rw-r--r--t/chainlint/command-substitution.test2
-rw-r--r--t/chainlint/comment.expect16
-rw-r--r--t/chainlint/comment.test2
-rw-r--r--t/chainlint/complex-if-in-cuddled-loop.expect18
-rw-r--r--t/chainlint/complex-if-in-cuddled-loop.test2
-rw-r--r--t/chainlint/cuddled-if-then-else.expect12
-rw-r--r--t/chainlint/cuddled-if-then-else.test2
-rw-r--r--t/chainlint/cuddled-loop.expect8
-rw-r--r--t/chainlint/cuddled-loop.test2
-rw-r--r--t/chainlint/cuddled.expect34
-rw-r--r--t/chainlint/cuddled.test2
-rw-r--r--t/chainlint/double-here-doc.expect24
-rw-r--r--t/chainlint/double-here-doc.test2
-rw-r--r--t/chainlint/dqstring-line-splice.expect10
-rw-r--r--t/chainlint/dqstring-line-splice.test2
-rw-r--r--t/chainlint/dqstring-no-interpolate.expect24
-rw-r--r--t/chainlint/dqstring-no-interpolate.test2
-rw-r--r--t/chainlint/empty-here-doc.expect8
-rw-r--r--t/chainlint/empty-here-doc.test2
-rw-r--r--t/chainlint/exclamation.expect8
-rw-r--r--t/chainlint/exclamation.test2
-rw-r--r--t/chainlint/exit-loop.expect48
-rw-r--r--t/chainlint/exit-loop.test2
-rw-r--r--t/chainlint/exit-subshell.expect10
-rw-r--r--t/chainlint/exit-subshell.test2
-rw-r--r--t/chainlint/for-loop-abbreviated.expect10
-rw-r--r--t/chainlint/for-loop-abbreviated.test2
-rw-r--r--t/chainlint/for-loop.expect28
-rw-r--r--t/chainlint/for-loop.test2
-rw-r--r--t/chainlint/function.expect22
-rw-r--r--t/chainlint/function.test2
-rw-r--r--t/chainlint/here-doc-body-indent.expect2
-rw-r--r--t/chainlint/here-doc-body-indent.test4
-rw-r--r--t/chainlint/here-doc-body-pathological.expect7
-rw-r--r--t/chainlint/here-doc-body-pathological.test9
-rw-r--r--t/chainlint/here-doc-body.expect7
-rw-r--r--t/chainlint/here-doc-body.test9
-rw-r--r--t/chainlint/here-doc-close-subshell.expect8
-rw-r--r--t/chainlint/here-doc-close-subshell.test2
-rw-r--r--t/chainlint/here-doc-double.expect2
-rw-r--r--t/chainlint/here-doc-double.test10
-rw-r--r--t/chainlint/here-doc-indent-operator.expect22
-rw-r--r--t/chainlint/here-doc-indent-operator.test2
-rw-r--r--t/chainlint/here-doc-multi-line-command-subst.expect16
-rw-r--r--t/chainlint/here-doc-multi-line-command-subst.test2
-rw-r--r--t/chainlint/here-doc-multi-line-string.expect14
-rw-r--r--t/chainlint/here-doc-multi-line-string.test2
-rw-r--r--t/chainlint/here-doc.expect50
-rw-r--r--t/chainlint/here-doc.test2
-rw-r--r--t/chainlint/if-condition-split.expect14
-rw-r--r--t/chainlint/if-condition-split.test2
-rw-r--r--t/chainlint/if-in-loop.expect24
-rw-r--r--t/chainlint/if-in-loop.test2
-rw-r--r--t/chainlint/if-then-else.expect44
-rw-r--r--t/chainlint/if-then-else.test2
-rw-r--r--t/chainlint/incomplete-line.expect20
-rw-r--r--t/chainlint/incomplete-line.test2
-rw-r--r--t/chainlint/inline-comment.expect16
-rw-r--r--t/chainlint/inline-comment.test2
-rw-r--r--t/chainlint/loop-detect-failure.expect30
-rw-r--r--t/chainlint/loop-detect-failure.test2
-rw-r--r--t/chainlint/loop-detect-status.expect36
-rw-r--r--t/chainlint/loop-detect-status.test2
-rw-r--r--t/chainlint/loop-in-if.expect24
-rw-r--r--t/chainlint/loop-in-if.test2
-rw-r--r--t/chainlint/loop-upstream-pipe.expect20
-rw-r--r--t/chainlint/loop-upstream-pipe.test2
-rw-r--r--t/chainlint/multi-line-nested-command-substitution.expect36
-rw-r--r--t/chainlint/multi-line-nested-command-substitution.test2
-rw-r--r--t/chainlint/multi-line-string.expect28
-rw-r--r--t/chainlint/multi-line-string.test2
-rw-r--r--t/chainlint/negated-one-liner.expect10
-rw-r--r--t/chainlint/negated-one-liner.test2
-rw-r--r--t/chainlint/nested-cuddled-subshell.expect50
-rw-r--r--t/chainlint/nested-cuddled-subshell.test2
-rw-r--r--t/chainlint/nested-here-doc.expect60
-rw-r--r--t/chainlint/nested-here-doc.test2
-rw-r--r--t/chainlint/nested-loop-detect-failure.expect62
-rw-r--r--t/chainlint/nested-loop-detect-failure.test2
-rw-r--r--t/chainlint/nested-subshell-comment.expect22
-rw-r--r--t/chainlint/nested-subshell-comment.test2
-rw-r--r--t/chainlint/nested-subshell.expect26
-rw-r--r--t/chainlint/nested-subshell.test2
-rw-r--r--t/chainlint/not-heredoc.expect28
-rw-r--r--t/chainlint/not-heredoc.test2
-rw-r--r--t/chainlint/one-liner-for-loop.expect18
-rw-r--r--t/chainlint/one-liner-for-loop.test2
-rw-r--r--t/chainlint/one-liner.expect18
-rw-r--r--t/chainlint/one-liner.test2
-rw-r--r--t/chainlint/p4-filespec.expect8
-rw-r--r--t/chainlint/p4-filespec.test2
-rw-r--r--t/chainlint/pipe.expect20
-rw-r--r--t/chainlint/pipe.test2
-rw-r--r--t/chainlint/return-loop.expect10
-rw-r--r--t/chainlint/return-loop.test2
-rw-r--r--t/chainlint/semicolon.expect38
-rw-r--r--t/chainlint/semicolon.test2
-rw-r--r--t/chainlint/sqstring-in-sqstring.expect8
-rw-r--r--t/chainlint/sqstring-in-sqstring.test2
-rw-r--r--t/chainlint/subshell-here-doc.expect60
-rw-r--r--t/chainlint/subshell-here-doc.test2
-rw-r--r--t/chainlint/subshell-one-liner.expect38
-rw-r--r--t/chainlint/subshell-one-liner.test2
-rw-r--r--t/chainlint/t7900-subtree.expect44
-rw-r--r--t/chainlint/t7900-subtree.test2
-rw-r--r--t/chainlint/token-pasting.expect54
-rw-r--r--t/chainlint/token-pasting.test2
-rw-r--r--t/chainlint/unclosed-here-doc-indent.expect8
-rw-r--r--t/chainlint/unclosed-here-doc-indent.test2
-rw-r--r--t/chainlint/unclosed-here-doc.expect14
-rw-r--r--t/chainlint/unclosed-here-doc.test2
-rw-r--r--t/chainlint/while-loop.expect28
-rw-r--r--t/chainlint/while-loop.test2
-rwxr-xr-xt/check-non-portable-shell.pl4
-rw-r--r--t/helper/test-bloom.c9
-rw-r--r--t/helper/test-json-writer.c2
-rw-r--r--t/helper/test-oidmap.c125
-rw-r--r--t/helper/test-parse-options.c1
-rw-r--r--t/helper/test-read-graph.c65
-rw-r--r--t/helper/test-reftable.c4
-rw-r--r--t/helper/test-repository.c4
-rw-r--r--t/helper/test-tool.c1
-rw-r--r--t/helper/test-tool.h1
-rw-r--r--t/helper/test-trace2.c1
-rw-r--r--t/lib-bundle-uri-protocol.sh4
-rw-r--r--t/socks4-proxy.pl48
-rwxr-xr-xt/t0006-date.sh51
-rwxr-xr-xt/t0007-git-var.sh2
-rwxr-xr-xt/t0016-oidmap.sh112
-rwxr-xr-xt/t0018-advice.sh1
-rwxr-xr-xt/t0021-conversion.sh1
-rwxr-xr-xt/t0033-safe-directory.sh178
-rwxr-xr-xt/t0095-bloom.sh8
-rwxr-xr-xt/t0301-credential-cache.sh2
-rwxr-xr-xt/t0302-credential-store.sh2
-rwxr-xr-xt/t0303-credential-external.sh1
-rwxr-xr-xt/t0600-reffiles-backend.sh38
-rwxr-xr-xt/t0612-reftable-jgit-compatibility.sh1
-rwxr-xr-xt/t0613-reftable-write-options.sh1
-rwxr-xr-xt/t1004-read-tree-m-u-wf.sh1
-rwxr-xr-xt/t1015-read-index-unmerged.sh2
-rwxr-xr-xt/t1021-rerere-in-workdir.sh1
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh16
-rwxr-xr-xt/t1300-config.sh9
-rwxr-xr-xt/t1404-update-ref-errors.sh196
-rwxr-xr-xt/t1410-reflog.sh8
-rwxr-xr-xt/t1502-rev-parse-parseopt.sh2
-rwxr-xr-xt/t1511-rev-parse-caret.sh1
-rwxr-xr-xt/t1512-rev-parse-disambiguation.sh1
-rwxr-xr-xt/t2030-unresolve-info.sh1
-rwxr-xr-xt/t2080-parallel-checkout-basics.sh1
-rwxr-xr-xt/t2082-parallel-checkout-attributes.sh1
-rwxr-xr-xt/t2107-update-index-basic.sh1
-rwxr-xr-xt/t2400-worktree-add.sh1
-rwxr-xr-xt/t2500-untracked-overwriting.sh1
-rwxr-xr-xt/t2501-cwd-empty.sh1
-rwxr-xr-xt/t3201-branch-contains.sh1
-rwxr-xr-xt/t3202-show-branch.sh1
-rwxr-xr-xt/t3206-range-diff.sh53
-rwxr-xr-xt/t3301-notes.sh11
-rwxr-xr-xt/t3306-notes-prune.sh1
-rwxr-xr-xt/t3308-notes-merge.sh1
-rwxr-xr-xt/t3309-notes-merge-auto-resolve.sh1
-rwxr-xr-xt/t3400-rebase.sh1
-rwxr-xr-xt/t3401-rebase-and-am-rename.sh1
-rwxr-xr-xt/t3403-rebase-skip.sh1
-rwxr-xr-xt/t3406-rebase-message.sh1
-rwxr-xr-xt/t3407-rebase-abort.sh1
-rwxr-xr-xt/t3417-rebase-whitespace-fix.sh1
-rwxr-xr-xt/t3418-rebase-continue.sh1
-rwxr-xr-xt/t3420-rebase-autostash.sh1
-rwxr-xr-xt/t3421-rebase-topology-linear.sh2
-rwxr-xr-xt/t3424-rebase-empty.sh1
-rwxr-xr-xt/t3428-rebase-signoff.sh1
-rwxr-xr-xt/t3430-rebase-merges.sh4
-rwxr-xr-xt/t3434-rebase-i18n.sh1
-rwxr-xr-xt/t3500-cherry.sh1
-rwxr-xr-xt/t3504-cherry-pick-rerere.sh1
-rwxr-xr-xt/t3505-cherry-pick-empty.sh1
-rwxr-xr-xt/t3508-cherry-pick-many-commits.sh1
-rwxr-xr-xt/t3509-cherry-pick-merge-df.sh1
-rwxr-xr-xt/t3650-replay-basics.sh1
-rwxr-xr-xt/t3701-add-interactive.sh67
-rwxr-xr-xt/t3903-stash.sh1
-rwxr-xr-xt/t3904-stash-patch.sh2
-rwxr-xr-xt/t3905-stash-include-untracked.sh1
-rwxr-xr-xt/t3907-stash-show-config.sh1
-rwxr-xr-xt/t4034-diff-words.sh2
-rwxr-xr-xt/t4061-diff-indent.sh1
-rwxr-xr-xt/t4129-apply-samemode.sh62
-rwxr-xr-xt/t4131-apply-fake-ancestor.sh1
-rwxr-xr-xt/t4151-am-abort.sh1
-rwxr-xr-xt/t4153-am-resume-override-opts.sh3
-rwxr-xr-xt/t4200-rerere.sh1
-rwxr-xr-xt/t4201-shortlog.sh1
-rwxr-xr-xt/t4203-mailmap.sh1
-rwxr-xr-xt/t4204-patch-id.sh40
-rwxr-xr-xt/t4208-log-magic-pathspec.sh1
-rwxr-xr-xt/t4216-log-bloom.sh325
-rwxr-xr-xt/t4253-am-keep-cr-dos.sh1
-rwxr-xr-xt/t4255-am-submodule.sh1
-rwxr-xr-xt/t5150-request-pull.sh1
-rwxr-xr-xt/t5300-pack-object.sh4
-rwxr-xr-xt/t5305-include-tag.sh1
-rwxr-xr-xt/t5318-commit-graph.sh2
-rwxr-xr-xt/t5319-multi-pack-index.sh55
-rwxr-xr-xt/t5407-post-rewrite-hook.sh1
-rwxr-xr-xt/t5512-ls-remote.sh14
-rwxr-xr-xt/t5514-fetch-multiple.sh1
-rwxr-xr-xt/t5516-fetch-push.sh10
-rwxr-xr-xt/t5520-pull.sh1
-rwxr-xr-xt/t5528-push-default.sh1
-rwxr-xr-xt/t5529-push-errors.sh17
-rwxr-xr-xt/t5535-fetch-push-symref.sh1
-rwxr-xr-xt/t5543-atomic-push.sh1
-rwxr-xr-xt/t5551-http-fetch-smart.sh1
-rwxr-xr-xt/t5553-set-upstream.sh8
-rwxr-xr-xt/t5558-clone-bundle-uri.sh187
-rwxr-xr-xt/t5563-simple-http-auth.sh116
-rwxr-xr-xt/t5564-http-proxy.sh55
-rwxr-xr-xt/t5570-git-daemon.sh1
-rwxr-xr-xt/t5605-clone-local.sh1
-rwxr-xr-xt/t5607-clone-bundle.sh36
-rwxr-xr-xt/t5612-clone-refspec.sh1
-rwxr-xr-xt/t6000-rev-list-misc.sh1
-rwxr-xr-xt/t6001-rev-list-graft.sh1
-rwxr-xr-xt/t6007-rev-list-cherry-pick-file.sh1
-rwxr-xr-xt/t6010-merge-base.sh1
-rwxr-xr-xt/t6013-rev-list-reverse-parents.sh1
-rwxr-xr-xt/t6017-rev-list-stdin.sh1
-rwxr-xr-xt/t6020-bundle-misc.sh1
-rwxr-xr-xt/t6115-rev-list-du.sh2
-rwxr-xr-xt/t6120-describe.sh37
-rwxr-xr-xt/t6130-pathspec-noglob.sh2
-rwxr-xr-xt/t6133-pathspec-rev-dwim.sh2
-rwxr-xr-xt/t6402-merge-rename.sh1
-rwxr-xr-xt/t6406-merge-attr.sh42
-rwxr-xr-xt/t6421-merge-partial-clone.sh15
-rwxr-xr-xt/t6427-diff3-conflict-markers.sh1
-rwxr-xr-xt/t6430-merge-recursive.sh1
-rwxr-xr-xt/t6432-merge-recursive-space-options.sh1
-rwxr-xr-xt/t6434-merge-recursive-rename-options.sh1
-rwxr-xr-xt/t6436-merge-overwrite.sh1
-rwxr-xr-xt/t7006-pager.sh18
-rwxr-xr-xt/t7010-setup.sh1
-rwxr-xr-xt/t7012-skip-worktree-writing.sh1
-rwxr-xr-xt/t7064-wtstatus-pv2.sh1
-rwxr-xr-xt/t7201-co.sh14
-rwxr-xr-xt/t7400-submodule-basic.sh1
-rwxr-xr-xt/t7501-commit-basic-functionality.sh1
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh1
-rwxr-xr-xt/t7512-status-help.sh1
-rwxr-xr-xt/t7600-merge.sh1
-rwxr-xr-xt/t7606-merge-custom.sh1
-rwxr-xr-xt/t7611-merge-abort.sh1
-rwxr-xr-xt/t7615-diff-algo-with-mergy-operations.sh60
-rw-r--r--t/t7615/base.c17
-rw-r--r--t/t7615/ours.c17
-rw-r--r--t/t7615/theirs.c17
-rwxr-xr-xt/t7704-repack-cruft.sh2
-rwxr-xr-xt/t7810-grep.sh1
-rwxr-xr-xt/t8002-blame.sh1
-rwxr-xr-xt/t8003-blame-corner-cases.sh1
-rwxr-xr-xt/t8004-blame-with-conflicts.sh1
-rwxr-xr-xt/t8006-blame-textconv.sh2
-rwxr-xr-xt/t8008-blame-formats.sh2
-rwxr-xr-xt/t8009-blame-vs-topicbranches.sh2
-rwxr-xr-xt/t8011-blame-split-file.sh2
-rwxr-xr-xt/t8012-blame-colors.sh1
-rwxr-xr-xt/t8013-blame-ignore-revs.sh2
-rwxr-xr-xt/t8014-blame-ignore-fuzzy.sh2
-rwxr-xr-xt/t9001-send-email.sh43
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh1
-rwxr-xr-xt/t9502-gitweb-standalone-parse-output.sh1
-rwxr-xr-xt/t9800-git-p4-basic.sh17
-rwxr-xr-xt/t9801-git-p4-branch.sh1
-rwxr-xr-xt/t9802-git-p4-filetype.sh19
-rwxr-xr-xt/t9803-git-p4-shell-metachars.sh1
-rwxr-xr-xt/t9804-git-p4-label.sh1
-rwxr-xr-xt/t9805-git-p4-skip-submit-edit.sh1
-rwxr-xr-xt/t9806-git-p4-options.sh1
-rwxr-xr-xt/t9808-git-p4-chdir.sh1
-rwxr-xr-xt/t9809-git-p4-client-view.sh1
-rwxr-xr-xt/t9810-git-p4-rcs.sh1
-rwxr-xr-xt/t9811-git-p4-label-import.sh1
-rwxr-xr-xt/t9812-git-p4-wildcards.sh1
-rwxr-xr-xt/t9813-git-p4-preserve-users.sh1
-rwxr-xr-xt/t9814-git-p4-rename.sh1
-rwxr-xr-xt/t9815-git-p4-submit-fail.sh1
-rwxr-xr-xt/t9816-git-p4-locked.sh1
-rwxr-xr-xt/t9817-git-p4-exclude.sh1
-rwxr-xr-xt/t9818-git-p4-block.sh1
-rwxr-xr-xt/t9819-git-p4-case-folding.sh1
-rwxr-xr-xt/t9820-git-p4-editor-handling.sh1
-rwxr-xr-xt/t9821-git-p4-path-variations.sh1
-rwxr-xr-xt/t9822-git-p4-path-encoding.sh1
-rwxr-xr-xt/t9823-git-p4-mock-lfs.sh1
-rwxr-xr-xt/t9825-git-p4-handle-utf16-without-bom.sh23
-rwxr-xr-xt/t9826-git-p4-keep-empty-commits.sh1
-rwxr-xr-xt/t9827-git-p4-change-filetype.sh1
-rwxr-xr-xt/t9828-git-p4-map-user.sh1
-rwxr-xr-xt/t9829-git-p4-jobs.sh1
-rwxr-xr-xt/t9830-git-p4-symlink-dir.sh1
-rwxr-xr-xt/t9831-git-p4-triggers.sh1
-rwxr-xr-xt/t9832-unshelve.sh1
-rwxr-xr-xt/t9833-errors.sh1
-rwxr-xr-xt/t9834-git-p4-file-dir-bug.sh1
-rwxr-xr-xt/t9835-git-p4-metadata-encoding-python2.sh1
-rwxr-xr-xt/t9836-git-p4-metadata-encoding-python3.sh1
-rwxr-xr-xt/t9902-completion.sh1
-rwxr-xr-xt/t9903-bash-prompt.sh1
-rw-r--r--t/test-lib-functions.sh32
-rw-r--r--t/test-lib.sh40
-rw-r--r--t/unit-tests/t-example-decorate.c24
-rw-r--r--t/unit-tests/t-oidmap.c181
-rw-r--r--t/unit-tests/t-reftable-merged.c (renamed from reftable/merged_test.c)208
-rw-r--r--t/unit-tests/t-reftable-pq.c152
-rw-r--r--t/unit-tests/t-reftable-record.c551
-rw-r--r--t/unit-tests/t-reftable-tree.c84
-rw-r--r--t/unit-tests/t-strvec.c47
-rw-r--r--t/unit-tests/test-lib.h5
-rw-r--r--transport.c7
541 files changed, 13635 insertions, 5834 deletions
diff --git a/.clang-format b/.clang-format
index 3ed4fac753..0b82f3c776 100644
--- a/.clang-format
+++ b/.clang-format
@@ -72,6 +72,10 @@ AlwaysBreakAfterReturnType: None
BinPackArguments: true
BinPackParameters: true
+# Add no space around the bit field
+# unsigned bf:2;
+BitFieldColonSpacing: None
+
# Attach braces to surrounding context except break before braces on function
# definitions.
# void foo()
@@ -96,6 +100,14 @@ BreakStringLiterals: false
# Switch statement body is always indented one level more than case labels.
IndentCaseLabels: false
+# Indents directives before the hash. Each level uses a single space for
+# indentation.
+# #if FOO
+# # include <foo>
+# #endif
+IndentPPDirectives: AfterHash
+PPIndentWidth: 1
+
# Don't indent a function definition or declaration if it is wrapped after the
# type
IndentWrappedFunctionNames: false
@@ -108,11 +120,18 @@ PointerAlignment: Right
# x = (int32)y; not x = (int32) y;
SpaceAfterCStyleCast: false
+# No space is inserted after the logical not operator
+SpaceAfterLogicalNot: false
+
# Insert spaces before and after assignment operators
# int a = 5; not int a=5;
# a += 42; a+=42;
SpaceBeforeAssignmentOperators: true
+# Spaces will be removed before case colon.
+# case 1: break; not case 1 : break;
+SpaceBeforeCaseColon: false
+
# Put a space before opening parentheses only after control statement keywords.
# void f() {
# if (true) {
@@ -124,6 +143,14 @@ SpaceBeforeParens: ControlStatements
# Don't insert spaces inside empty '()'
SpaceInEmptyParentheses: false
+# No space before first '[' in arrays
+# int a[5][5]; not int a [5][5];
+SpaceBeforeSquareBrackets: false
+
+# No space will be inserted into {}
+# while (true) {} not while (true) { }
+SpaceInEmptyBlock: false
+
# The number of spaces before trailing line comments (// - comments).
# This does not affect trailing block comments (/* - comments).
SpacesBeforeTrailingComments: 1
@@ -149,20 +176,25 @@ Cpp11BracedListStyle: false
# A list of macros that should be interpreted as foreach loops instead of as
# function calls. Taken from:
-# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' \
-# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
-# | sort | uniq
+# git grep -h '^#define [^[:space:]]*for_\?each[^[:space:]]*(' |
+# sed "s/^#define / - '/; s/(.*$/'/" | sort | uniq
ForEachMacros:
- - 'for_each_abbrev'
- 'for_each_builtin'
- 'for_each_string_list_item'
- 'for_each_ut'
- 'for_each_wanted_builtin'
+ - 'hashmap_for_each_entry'
+ - 'hashmap_for_each_entry_from'
+ - 'kh_foreach'
+ - 'kh_foreach_value'
- 'list_for_each'
- 'list_for_each_dir'
- 'list_for_each_prev'
- 'list_for_each_prev_safe'
- 'list_for_each_safe'
+ - 'strintmap_for_each_entry'
+ - 'strmap_for_each_entry'
+ - 'strset_for_each_entry'
# The maximum number of consecutive empty lines to keep.
MaxEmptyLinesToKeep: 1
diff --git a/.github/workflows/check-style.yml b/.github/workflows/check-style.yml
new file mode 100644
index 0000000000..c052a5df23
--- /dev/null
+++ b/.github/workflows/check-style.yml
@@ -0,0 +1,34 @@
+name: check-style
+
+# Get the repository with all commits to ensure that we can analyze
+# all of the commits contributed via the Pull Request.
+
+on:
+ pull_request:
+ types: [opened, synchronize]
+
+# Avoid unnecessary builds. Unlike the main CI jobs, these are not
+# ci-configurable (but could be).
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ check-style:
+ env:
+ CC: clang
+ jobname: ClangFormat
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - run: ci/install-dependencies.sh
+
+ - name: git clang-format
+ continue-on-error: true
+ id: check_out
+ run: |
+ ./ci/run-style-check.sh \
+ "${{github.event.pull_request.base.sha}}"
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 37b991e080..2589098eff 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -118,8 +118,31 @@ check-whitespace:
image: ubuntu:latest
before_script:
- ./ci/install-dependencies.sh
+ # Since $CI_MERGE_REQUEST_TARGET_BRANCH_SHA is only defined for merged
+ # pipelines, we fallback to $CI_MERGE_REQUEST_DIFF_BASE_SHA, which should
+ # be defined in all pipelines.
script:
- - ./ci/check-whitespace.sh "$CI_MERGE_REQUEST_TARGET_BRANCH_SHA"
+ - |
+ R=${CI_MERGE_REQUEST_TARGET_BRANCH_SHA-${CI_MERGE_REQUEST_DIFF_BASE_SHA:?}} || exit
+ ./ci/check-whitespace.sh "$R"
+ rules:
+ - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+
+check-style:
+ image: ubuntu:latest
+ allow_failure: true
+ variables:
+ CC: clang
+ jobname: ClangFormat
+ before_script:
+ - ./ci/install-dependencies.sh
+ # Since $CI_MERGE_REQUEST_TARGET_BRANCH_SHA is only defined for merged
+ # pipelines, we fallback to $CI_MERGE_REQUEST_DIFF_BASE_SHA, which should
+ # be defined in all pipelines.
+ script:
+ - |
+ R=${CI_MERGE_REQUEST_TARGET_BRANCH_SHA-${CI_MERGE_REQUEST_DIFF_BASE_SHA:?}} || exit
+ ./ci/run-style-check.sh "$R"
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines
index 1d92b2da03..e4bd0abdcd 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -185,8 +185,8 @@ For shell scripts specifically (not exhaustive):
- Even though "local" is not part of POSIX, we make heavy use of it
in our test suite. We do not use it in scripted Porcelains, and
- hopefully nobody starts using "local" before they are reimplemented
- in C ;-)
+ hopefully nobody starts using "local" before all shells that matter
+ support it (notably, ksh from AT&T Research does not support it yet).
- Some versions of shell do not understand "export variable=value",
so we write "variable=value" and then "export variable" on two
@@ -204,6 +204,33 @@ For shell scripts specifically (not exhaustive):
local variable="$value"
local variable="$(command args)"
+ - The common construct
+
+ VAR=VAL command args
+
+ to temporarily set and export environment variable VAR only while
+ "command args" is running is handy, but this triggers an
+ unspecified behaviour according to POSIX when used for a command
+ that is not an external command (like shell functions). Indeed,
+ dash 0.5.10.2-6 on Ubuntu 20.04, /bin/sh on FreeBSD 13, and AT&T
+ ksh all make a temporary assignment without exporting the variable,
+ in such a case. As it does not work portably across shells, do not
+ use this syntax for shell functions. A common workaround is to do
+ an explicit export in a subshell, like so:
+
+ (incorrect)
+ VAR=VAL func args
+
+ (correct)
+ (
+ VAR=VAL &&
+ export VAR &&
+ func args
+ )
+
+ but be careful that the effect "func" makes to the variables in the
+ current shell will be lost across the subshell boundary.
+
- Use octal escape sequences (e.g. "\302\242"), not hexadecimal (e.g.
"\xc2\xa2") in printf format strings, since hexadecimal escape
sequences are not portable.
@@ -214,6 +241,16 @@ For C programs:
- We use tabs to indent, and interpret tabs as taking up to
8 spaces.
+ - Nested C preprocessor directives are indented after the hash by one
+ space per nesting level.
+
+ #if FOO
+ # include <foo.h>
+ # if BAR
+ # include <bar.h>
+ # endif
+ #endif
+
- We try to keep to at most 80 characters per line.
- As a Git developer we assume you have a reasonably modern compiler
@@ -234,7 +271,7 @@ For C programs:
. since around 2007 with 2b6854c863a, we have been using
initializer elements which are not computable at load time. E.g.:
- const char *args[] = {"constant", variable, NULL};
+ const char *args[] = { "constant", variable, NULL };
. since early 2012 with e1327023ea, we have been using an enum
definition whose last element is followed by a comma. This, like
@@ -531,6 +568,42 @@ For C programs:
use your own debugger and arguments. Example: `GIT_DEBUGGER="ddd --gdb"
./bin-wrappers/git log` (See `wrap-for-bin.sh`.)
+ - The primary data structure that a subsystem 'S' deals with is called
+ `struct S`. Functions that operate on `struct S` are named
+ `S_<verb>()` and should generally receive a pointer to `struct S` as
+ first parameter. E.g.
+
+ struct strbuf;
+
+ void strbuf_add(struct strbuf *buf, ...);
+
+ void strbuf_reset(struct strbuf *buf);
+
+ is preferred over:
+
+ struct strbuf;
+
+ void add_string(struct strbuf *buf, ...);
+
+ void reset_strbuf(struct strbuf *buf);
+
+ - There are several common idiomatic names for functions performing
+ specific tasks on a structure `S`:
+
+ - `S_init()` initializes a structure without allocating the
+ structure itself.
+
+ - `S_release()` releases a structure's contents without freeing the
+ structure.
+
+ - `S_clear()` is equivalent to `S_release()` followed by `S_init()`
+ such that the structure is directly usable after clearing it. When
+ `S_clear()` is provided, `S_init()` shall not allocate resources
+ that need to be released again.
+
+ - `S_free()` releases a structure's contents and frees the
+ structure.
+
For Perl programs:
- Most of the C guidelines above apply.
diff --git a/Documentation/Makefile b/Documentation/Makefile
index dc65759cb1..1bd23fbeef 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -204,12 +204,15 @@ ASCIIDOC_DOCBOOK = docbook5
ASCIIDOC_EXTRA += -acompat-mode -atabsize=8
ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions
ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;'
+ASCIIDOC_EXTRA += -adocinfo=shared
ASCIIDOC_DEPS = asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS
DBLATEX_COMMON =
XMLTO_EXTRA += --skip-validation
XMLTO_EXTRA += -x manpage.xsl
endif
+ASCIIDOC_DEPS += docinfo.html
+
SHELL_PATH ?= $(SHELL)
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
@@ -338,6 +341,9 @@ clean:
$(RM) $(cmds_txt) $(mergetools_txt) *.made
$(RM) GIT-ASCIIDOCFLAGS
+docinfo.html: docinfo-html.in
+ $(QUIET_GEN)$(RM) $@ && cat $< >$@
+
$(MAN_HTML): %.html : %.txt $(ASCIIDOC_DEPS)
$(QUIET_ASCIIDOC)$(TXT_TO_HTML) -d manpage -o $@ $<
diff --git a/Documentation/RelNotes/2.46.0.txt b/Documentation/RelNotes/2.46.0.txt
index 67bae07a40..b25475918a 100644
--- a/Documentation/RelNotes/2.46.0.txt
+++ b/Documentation/RelNotes/2.46.0.txt
@@ -1,10 +1,6 @@
Git v2.46 Release Notes
=======================
-Backward Compatibility Notes
-
- (None at this moment)
-
UI, Workflows & Features
* The "--rfc" option of "git format-patch" learned to take an
@@ -89,6 +85,15 @@ UI, Workflows & Features
variable did nothing but giving a "this does not do anything"
warning. The warning has been removed.
+ * The http transport can now be told to send request with
+ authentication material without first getting a 401 response.
+
+ * A handful of entries are added to the GitFAQ document.
+
+ * "git var GIT_SHELL_PATH" should report the path to the shell used
+ to spawn external commands, but it didn't do so on Windows, which
+ has been corrected.
+
Performance, Internal Implementation, Development Support etc.
@@ -150,7 +155,7 @@ Performance, Internal Implementation, Development Support etc.
* A new test was added to ensure git commands that are designed to
run outside repositories do work.
- * Basic unit tests for reftable have been reimplemented under the
+ * A few tests in reftable library have been rewritten using the
unit test framework.
* A pair of test helpers that essentially are unit tests on hash
@@ -201,6 +206,32 @@ Performance, Internal Implementation, Development Support etc.
remote.*.url configuration values have been straightened out, which
resulted in a few leak fixes and code clarification.
+ * When bundleURI interface fetches multiple bundles, Git failed to
+ take full advantage of all bundles and ended up slurping duplicated
+ objects, which has been corrected.
+
+ * The code to deal with modified paths that are out-of-cone in a
+ sparsely checked out working tree has been optimized.
+
+ * An existing test of oidmap API has been rewritten with the
+ unit-test framework.
+
+ * The "ort" merge backend saw one bugfix for a crash that happens
+ when inner merge gets killed, and assorted code clean-ups.
+
+ * A new warning message is issued when a command has to expand a
+ sparse index to handle working tree cruft that are outside of the
+ sparse checkout.
+
+ * The test framework learned to take the test body not as a single
+ string but as a here-document.
+
+ * "git push '' HEAD:there" used to hit a BUG(); it has been corrected
+ to die with "fatal: bad repository ''".
+
+ * What happens when http.cookieFile gets the special value "" has
+ been clarified in the documentation.
+
Fixes since v2.45
-----------------
@@ -348,5 +379,83 @@ Fixes since v2.45
the "--color-moved" option.
(merge 0f4b0d4cf0 rs/diff-color-moved-w-no-ext-diff-fix later to maint).
+ * "git archive --add-virtual-file=<path>:<contents>" never paid
+ attention to the --prefix=<prefix> option but the documentation
+ said it would. The documentation has been corrected.
+ (merge 72c282098d jc/archive-prefix-with-add-virtual-file later to maint).
+
+ * When GIT_PAGER failed to spawn, depending on the code path taken,
+ we failed immediately (correct) or just spew the payload to the
+ standard output (incorrect). The code now always fail immediately
+ when GIT_PAGER fails.
+ (merge 78f0a5d187 rj/pager-die-upon-exec-failure later to maint).
+
+ * date parser updates to be more careful about underflowing epoch
+ based timestamp.
+ (merge 9d69789770 db/date-underflow-fix later to maint).
+
+ * The Bloom filter used for path limited history traversal was broken
+ on systems whose "char" is unsigned; update the implementation and
+ bump the format version to 2.
+ (merge 9c8a9ec787 tb/path-filter-fix later to maint).
+
+ * Typofix.
+ (merge 231cf7370e as/pathspec-h-typofix later to maint).
+
+ * Code clean-up.
+ (merge 4b837f821e rs/simplify-submodule-helper-super-prefix-invocation later to maint).
+
+ * "git describe --dirty --broken" forgot to refresh the index before
+ seeing if there is any chang, ("git describe --dirty" correctly did
+ so), which has been corrected.
+ (merge b8ae42e292 as/describe-broken-refresh-index-fix later to maint).
+
+ * Test suite has been taught not to unnecessarily rely on DNS failing
+ a bogus external name.
+ (merge 407cdbd271 jk/tests-without-dns later to maint).
+
+ * GitWeb update to use committer date consistently in rss/atom feeds.
+ (merge cf6ead095b am/gitweb-feed-use-committer-date later to maint).
+
+ * Custom control structures we invented more recently have been
+ taught to the clang-format file.
+ (merge 1457dff9be rs/clang-format-updates later to maint).
+
+ * Developer build procedure fix.
+ (merge df32729866 tb/dev-build-pedantic-fix later to maint).
+
+ * "git push" that pushes only deletion gave an unnecessary and
+ harmless error message when push negotiation is configured, which
+ has been corrected.
+ (merge 4d8ee0317f jc/disable-push-nego-for-deletion later to maint).
+
+ * Address-looking strings found on the trailer are now placed on the
+ Cc: list after running through sanitize_address by "git send-email".
+ (merge c852531f45 cb/send-email-sanitize-trailer-addresses later to maint).
+
+ * Tests that use GIT_TEST_SANITIZE_LEAK_LOG feature got their exit
+ status inverted, which has been corrected.
+ (merge 8c1d6691bc rj/test-sanitize-leak-log-fix later to maint).
+
+ * The http.cookieFile and http.saveCookies configuration variables
+ have a few values that need to be avoided, which are now ignored
+ with warning messages.
+ (merge 4f5822076f jc/http-cookiefile later to maint).
+
+ * Repacking a repository with multi-pack index started making stupid
+ pack selections in Git 2.45, which has been corrected.
+ (merge 8fb6d11fad ds/midx-write-repack-fix later to maint).
+
+ * Fix documentation mark-up regression in 2.45.
+ (merge 6474da0aa4 ja/doc-markup-updates-fix later to maint).
+
+ * Work around asciidoctor's css that renders `monospace` material
+ in the SYNOPSIS section of manual pages as block elements.
+ (merge d44ce6ddd5 js/doc-markup-updates-fix later to maint).
+
* Other code cleanup, docfix, build fix, etc.
(merge 493fdae046 ew/object-convert-leakfix later to maint).
+ (merge 00f3661a0a ss/doc-eol-attr-fix later to maint).
+ (merge 428c40da61 ri/doc-show-branch-fix later to maint).
+ (merge 58696bfcaa jc/where-is-bash-for-ci later to maint).
+ (merge 616e94ca24 tb/doc-max-tree-depth-fix later to maint).
diff --git a/Documentation/RelNotes/2.47.0.txt b/Documentation/RelNotes/2.47.0.txt
new file mode 100644
index 0000000000..b948fa4db4
--- /dev/null
+++ b/Documentation/RelNotes/2.47.0.txt
@@ -0,0 +1,133 @@
+Git v2.47 Release Notes
+=======================
+
+UI, Workflows & Features
+------------------------
+
+ * Many Porcelain commands that internally use the merge machinery
+ were taught to consistently honor the diff.algorithm configuration.
+
+ * A few descriptions in "git show-ref -h" have been clarified.
+
+ * A 'P' command to "git add -p" that passes the patch hunk to the
+ pager has been added.
+
+ * "git grep -W" omits blank lines that follow the found function at
+ the end of the file, just like it omits blank lines before the next
+ function.
+
+ * The value of http.proxy can have "path" at the end for a socks
+ proxy that listens to a unix-domain socket, but we started to
+ discard it when we taught proxy auth code path to use the
+ credential helpers, which has been corrected.
+
+
+Performance, Internal Implementation, Development Support etc.
+--------------------------------------------------------------
+
+ * A build tweak knob has been simplified by not setting the value
+ that is already the default; another unused one has been removed.
+
+ * A CI job that use clang-format to check coding style issues in new
+ code has been added.
+
+ * The reviewing guidelines document now explicitly encourages people
+ to give positive reviews and how.
+
+ * Test script linter has been updated to catch an attempt to use
+ one-shot export construct "VAR=VAL func" for shell functions (which
+ does not work for some shells) better.
+
+ * Some project conventions have been added to CodingGuidelines.
+
+ * In the refs subsystem, implicit reliance of the_repository has been
+ eliminated; the repository associated with the ref store object is
+ used instead.
+
+ * Various tests in reftable library have been rewritten using the unit test
+ framework.
+
+ * A test that fails on an unusually slow machine was found, and made
+ less likely to cause trouble by lengthening the expiry value it
+ uses.
+
+
+Fixes since v2.46
+-----------------
+
+ * "git add -p" by users with diff.suppressBlankEmpty set to true
+ failed to parse the patch that represents an unmodified empty line
+ with an empty line (not a line with a single space on it), which
+ has been corrected.
+ (merge 60cf761ed1 pw/add-patch-with-suppress-blank-empty later to maint).
+
+ * "git checkout --ours" (no other arguments) complained that the
+ option is incompatible with branch switching, which is technically
+ correct, but found confusing by some users. It now says that the
+ user needs to give pathspec to specify what paths to checkout.
+ (merge d1e6c61272 jc/checkout-no-op-switch-errors later to maint).
+
+ * It has been documented that we avoid "VAR=VAL shell_func" and why.
+ (merge 728a1962cd jc/doc-one-shot-export-with-shell-func later to maint).
+
+ * "git rebase --help" referred to "offset" (the difference between
+ the location a change was taken from and the change gets replaced)
+ incorrectly and called it "fuzz", which has been corrected.
+ (merge 70058db385 jc/doc-rebase-fuzz-vs-offset-fix later to maint).
+
+ * "git notes add -m '' --allow-empty" and friends that take prepared
+ data to create notes should not invoke an editor, but it started
+ doing so since Git 2.42, which has been corrected.
+ (merge 8b426c84f3 dd/notes-empty-no-edit-by-default later to maint).
+
+ * An expensive operation to prepare tracing was done in re-encoding
+ code path even when the tracing was not requested, which has been
+ corrected.
+ (merge 63ad8dbf16 dh/encoding-trace-optim later to maint).
+
+ * More leakfixes.
+ (merge f30bfafcd4 ps/leakfixes-part-3 later to maint).
+
+ * The credential helper to talk to OSX keychain sometimes sent
+ garbage bytes after the username, which has been corrected.
+ (merge b201316835 jk/osxkeychain-username-is-nul-terminated later to maint).
+
+ * A recent update broke "git ls-remote" used outside a repository,
+ which has been corrected.
+ (merge 9e89dcb66a ps/ls-remote-out-of-repo-fix later to maint).
+
+ * The patch parser in 'git apply' has been a bit more lenient against
+ unexpected mode bits, like 100664, recorded on extended header lines.
+ (merge e95d515141 jk/apply-patch-mode-check-fix later to maint).
+
+ * "git config --value=foo --fixed-value section.key newvalue" barfed
+ when the existing value in the configuration file used the
+ valueless true syntax, which has been corrected.
+ (merge 615d2de3b4 tb/config-fixed-value-with-valueless-true later to maint).
+
+ * The patch parser in "git patch-id" has been tightened to avoid
+ getting confused by lines that look like a patch header in the log
+ message.
+ (merge a6e9429f72 jc/patch-id later to maint).
+
+ * "git reflog expire" failed to honor annotated tags when computing
+ reachable commits.
+ (merge 5133ead528 jc/reflog-expire-lookup-commit-fix later to maint).
+
+ * A flakey test and incorrect calls to strtoX() functions have been
+ fixed.
+ (merge ec60bb9fc4 kl/test-fixes later to maint).
+
+ * Other code cleanup, docfix, build fix, etc.
+ (merge 8db8786fc2 jt/doc-post-receive-hook-update later to maint).
+ (merge 1c473dd6af tn/doc-commit-fix later to maint).
+ (merge bb0498b1bb jc/how-to-maintain-updates later to maint).
+ (merge 6e71d6ac7c ks/unit-test-comment-typofix later to maint).
+ (merge 63ee933383 ps/p4-tests-updates later to maint).
+ (merge 7c7516b8db jc/jl-git-no-advice-fix later to maint).
+ (merge c3d034df16 jc/leakfix-hashfile later to maint).
+ (merge d98d9c77e5 jc/leakfix-mailmap later to maint).
+ (merge c199707496 jr/ls-files-expand-literal-doc later to maint).
+ (merge e2e373ba82 ss/packed-ref-store-leakfix later to maint).
+ (merge 0c4d5aa22d rs/use-decimal-width later to maint).
+ (merge 67be8c4de5 jc/document-use-of-local later to maint).
diff --git a/Documentation/ReviewingGuidelines.txt b/Documentation/ReviewingGuidelines.txt
index 515d470d23..6534643cff 100644
--- a/Documentation/ReviewingGuidelines.txt
+++ b/Documentation/ReviewingGuidelines.txt
@@ -72,12 +72,29 @@ guidance, and concrete tips for interacting with patches on the mailing list.
could fix it. This not only helps the author to understand and fix the issue,
it also deepens and improves your understanding of the topic.
-- Reviews do not need to exclusively point out problems. Feel free to "think out
+- Reviews do not need to exclusively point out problems. Positive
+ reviews indicate that it is not only the original author of the
+ patches who care about the issue the patches address, and are
+ highly encouraged.
+
+- Do not hesitate to give positive reviews on a series from your
+ work colleague. If your positive review is written well, it will
+ not make you look as if you two are representing corporate
+ interest on a series that is otherwise uninteresting to other
+ community members and shoving it down their throat.
+
+- Write a positive review in such a way that others can understand
+ why you support the goal, the approach, and the implementation the
+ patches took. Make sure to demonstrate that you did thoroughly read
+ the series and understood problem area well enough to be able to
+ say that the patches are written well. Feel free to "think out
loud" in your review: describe how you read & understood a complex section of
a patch, ask a question about something that confused you, point out something
- you found exceptionally well-written, etc. In particular, uplifting feedback
- goes a long way towards encouraging contributors to participate more actively
- in the Git community.
+ you found exceptionally well-written, etc.
+
+- In particular, uplifting feedback goes a long way towards
+ encouraging contributors to participate more actively in the Git
+ community.
==== Performing your review
- Provide your review comments per-patch in a plaintext "Reply-All" email to the
diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt
index fa61241756..0ba8989820 100644
--- a/Documentation/config/advice.txt
+++ b/Documentation/config/advice.txt
@@ -116,6 +116,10 @@ advice.*::
skippedCherryPicks::
Shown when linkgit:git-rebase[1] skips a commit that has already
been cherry-picked onto the upstream branch.
+ sparseIndexExpanded::
+ Shown when a sparse index is expanded to a full index, which is likely
+ due to an unexpected set of files existing outside of the
+ sparse-checkout.
statusAheadBehind::
Shown when linkgit:git-status[1] computes the ahead/behind
counts for a local ref compared to its remote tracking ref,
diff --git a/Documentation/config/commitgraph.txt b/Documentation/config/commitgraph.txt
index 30604e4a4c..7f8c9d6638 100644
--- a/Documentation/config/commitgraph.txt
+++ b/Documentation/config/commitgraph.txt
@@ -9,6 +9,29 @@ commitGraph.maxNewFilters::
commit-graph write` (c.f., linkgit:git-commit-graph[1]).
commitGraph.readChangedPaths::
- If true, then git will use the changed-path Bloom filters in the
- commit-graph file (if it exists, and they are present). Defaults to
- true. See linkgit:git-commit-graph[1] for more information.
+ Deprecated. Equivalent to commitGraph.changedPathsVersion=-1 if true, and
+ commitGraph.changedPathsVersion=0 if false. (If commitGraph.changedPathVersion
+ is also set, commitGraph.changedPathsVersion takes precedence.)
+
+commitGraph.changedPathsVersion::
+ Specifies the version of the changed-path Bloom filters that Git will read and
+ write. May be -1, 0, 1, or 2. Note that values greater than 1 may be
+ incompatible with older versions of Git which do not yet understand
+ those versions. Use caution when operating in a mixed-version
+ environment.
++
+Defaults to -1.
++
+If -1, Git will use the version of the changed-path Bloom filters in the
+repository, defaulting to 1 if there are none.
++
+If 0, Git will not read any Bloom filters, and will write version 1 Bloom
+filters when instructed to write.
++
+If 1, Git will only read version 1 Bloom filters, and will write version 1
+Bloom filters.
++
+If 2, Git will only read version 2 Bloom filters, and will write version 2
+Bloom filters.
++
+See linkgit:git-commit-graph[1] for more information.
diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
index 93d65e1dfd..60ca9f2b68 100644
--- a/Documentation/config/core.txt
+++ b/Documentation/config/core.txt
@@ -756,4 +756,5 @@ core.maxTreeDepth::
The maximum depth Git is willing to recurse while traversing a
tree (e.g., "a/b/cde/f" has a depth of 4). This is a fail-safe
to allow Git to abort cleanly, and should not generally need to
- be adjusted. The default is 4096.
+ be adjusted. When Git is compiled with MSVC, the default is 512.
+ Otherwise, the default is 2048.
diff --git a/Documentation/config/http.txt b/Documentation/config/http.txt
index 2d4e0c9b86..a14371b5c9 100644
--- a/Documentation/config/http.txt
+++ b/Documentation/config/http.txt
@@ -5,8 +5,13 @@ http.proxy::
proxy string with a user name but no password, in which case git will
attempt to acquire one in the same way it does for other credentials. See
linkgit:gitcredentials[7] for more information. The syntax thus is
- '[protocol://][user[:password]@]proxyhost[:port]'. This can be overridden
- on a per-remote basis; see remote.<name>.proxy
+ '[protocol://][user[:password]@]proxyhost[:port][/path]'. This can be
+ overridden on a per-remote basis; see remote.<name>.proxy
++
+Any proxy, however configured, must be completely transparent and must not
+modify, transform, or buffer the request or response in any way. Proxies which
+are not completely transparent are known to cause various forms of breakage
+with Git.
http.proxyAuthMethod::
Set the method with which to authenticate against the HTTP proxy. This
@@ -56,6 +61,26 @@ http.emptyAuth::
a username in the URL, as libcurl normally requires a username for
authentication.
+http.proactiveAuth::
+ Attempt authentication without first making an unauthenticated attempt and
+ receiving a 401 response. This can be used to ensure that all requests are
+ authenticated. If `http.emptyAuth` is set to true, this value has no effect.
++
+If the credential helper used specifies an authentication scheme (i.e., via the
+`authtype` field), that value will be used; if a username and password is
+provided without a scheme, then Basic authentication is used. The value of the
+option determines the scheme requested from the helper. Possible values are:
++
+--
+* `basic` - Request Basic authentication from the helper.
+* `auto` - Allow the helper to pick an appropriate scheme.
+* `none` - Disable proactive authentication.
+--
++
+Note that TLS should always be used with this configuration, since otherwise it
+is easy to accidentally expose plaintext credentials if Basic authentication
+is selected.
+
http.delegation::
Control GSSAPI credential delegation. The delegation is disabled
by default in libcurl since version 7.21.7. Set parameter to tell
@@ -82,12 +107,16 @@ http.cookieFile::
in the Git http session, if they match the server. The file format
of the file to read cookies from should be plain HTTP headers or
the Netscape/Mozilla cookie file format (see `curl(1)`).
+ Set it to an empty string, to accept only new cookies from
+ the server and send them back in successive requests within same
+ connection.
NOTE that the file specified with http.cookieFile is used only as
input unless http.saveCookies is set.
http.saveCookies::
If set, store cookies received during requests to the file specified by
- http.cookieFile. Has no effect if http.cookieFile is unset.
+ http.cookieFile. Has no effect if http.cookieFile is unset, or set to
+ an empty string.
http.version::
Use the specified HTTP protocol version when communicating with a server.
diff --git a/Documentation/docinfo-html.in b/Documentation/docinfo-html.in
new file mode 100644
index 0000000000..fb3560eb92
--- /dev/null
+++ b/Documentation/docinfo-html.in
@@ -0,0 +1,5 @@
+<style>
+pre>code {
+ display: inline;
+}
+</style>
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 98526f2beb..a0e3fe7996 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -53,7 +53,7 @@ OPTIONS
--prefix=<prefix>/::
Prepend <prefix>/ to paths in the archive. Can be repeated; its
rightmost value is used for all tracked files. See below which
- value gets used by `--add-file` and `--add-virtual-file`.
+ value gets used by `--add-file`.
-o <file>::
--output=<file>::
@@ -67,9 +67,7 @@ OPTIONS
--add-virtual-file=<path>:<content>::
Add the specified contents to the archive. Can be repeated to add
- multiple files. The path of the file in the archive is built
- by concatenating the value of the last `--prefix` option (if any)
- before this `--add-virtual-file` and `<path>`.
+ multiple files.
+
The `<path>` argument can start and end with a literal double-quote
character; the contained file name is interpreted as a C-style string,
@@ -81,6 +79,10 @@ if the path begins or ends with a double-quote character.
The file mode is limited to a regular file, and the option may be
subject to platform-dependent command-line limits. For non-trivial
cases, write an untracked file and use `--add-file` instead.
++
+Note that unlike `--add-file` the path created in the archive is not
+affected by the `--prefix` option, as a full `<path>` can be given as
+the value of the option.
--worktree-attributes::
Look for attributes in .gitattributes files in the working tree
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 5de18de2ab..8e925db7e9 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -13,9 +13,9 @@ SYNOPSIS
[`-l`] [`-s`] [`--no-hardlinks`] [`-q`] [`-n`] [`--bare`] [`--mirror`]
[`-o` _<name>_] [`-b` _<name>_] [`-u` _<upload-pack>_] [`--reference` _<repository>_]
[`--dissociate`] [`--separate-git-dir` _<git-dir>_]
- [`--depth` _<depth>_] [`--`[`no-`]`single-branch`] [`--no-tags`]
- [++--recurse-submodules++[++=++__<pathspec>__]] [`--`[`no-`]`shallow-submodules`]
- [`--`[`no-`]`remote-submodules`] [`--jobs` _<n>_] [`--sparse`] [`--`[`no-`]`reject-shallow`]
+ [`--depth` _<depth>_] [`--`[`no-`]{empty}`single-branch`] [`--no-tags`]
+ [++--recurse-submodules++[++=++__<pathspec>__]] [++--++[++no-++]{empty}++shallow-submodules++]
+ [`--`[`no-`]{empty}`remote-submodules`] [`--jobs` _<n>_] [`--sparse`] [`--`[`no-`]{empty}`reject-shallow`]
[++--filter=++__<filter-spec>__] [`--also-filter-submodules`]] [`--`] _<repository>_
[_<directory>_]
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 89ecfc63a8..c822113c11 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git commit' [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
- [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)]
+ [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>]
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index d08c7da8f4..58c529afbe 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -219,9 +219,9 @@ followed by the ("attr/<eolattr>").
--format=<format>::
A string that interpolates `%(fieldname)` from the result being shown.
- It also interpolates `%%` to `%`, and `%xx` where `xx` are hex digits
- interpolates to character with hex code `xx`; for example `%00`
- interpolates to `\0` (NUL), `%09` to `\t` (TAB) and %0a to `\n` (LF).
+ It also interpolates `%%` to `%`, and `%xXX` where `XX` are hex digits
+ interpolates to character with hex code `XX`; for example `%x00`
+ interpolates to `\0` (NUL), `%x09` to `\t` (TAB) and %x0a to `\n` (LF).
--format cannot be combined with `-s`, `-o`, `-k`, `-t`, `--resolve-undo`
and `--eol`.
\--::
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 74df345f9e..b18cdbc023 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -737,7 +737,7 @@ The 'apply' backend works by creating a sequence of patches (by calling
`format-patch` internally), and then applying the patches in sequence
(calling `am` internally). Patches are composed of multiple hunks,
each with line numbers, a context region, and the actual changes. The
-line numbers have to be taken with some fuzz, since the other side
+line numbers have to be taken with some offset, since the other side
will likely have inserted or deleted lines earlier in the file. The
context region is meant to help find how to adjust the line numbers in
order to apply the changes to the right lines. However, if multiple
diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt
index c771c89770..bc31d8b6d3 100644
--- a/Documentation/git-show-branch.txt
+++ b/Documentation/git-show-branch.txt
@@ -22,7 +22,7 @@ Shows the commit ancestry graph starting from the commits named
with <rev>s or <glob>s (or all refs under refs/heads
and/or refs/tags) semi-visually.
-It cannot show more than 29 branches and commits at a time.
+It cannot show more than 26 branches and commits at a time.
It uses `showbranch.default` multi-valued configuration items if
no <rev> or <glob> is given on the command line.
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 80cae17f37..e6150595af 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -374,7 +374,7 @@ explicitly define the line endings with `eol` if the `working-tree-encoding`
attribute is used to avoid ambiguity.
------------------------
-*.ps1 text working-tree-encoding=UTF-16LE eol=CRLF
+*.ps1 text working-tree-encoding=UTF-16LE eol=crlf
------------------------
You can get a list of all available encodings on your platform with the
diff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt
index 8c1f2d5675..f2917d142c 100644
--- a/Documentation/gitfaq.txt
+++ b/Documentation/gitfaq.txt
@@ -185,6 +185,58 @@ Then, you can adjust your push URL to use `git@example_author` or
`git@example_committer` instead of `git@example.org` (e.g., `git remote set-url
git@example_author:org1/project1.git`).
+Transfers
+---------
+
+[[sync-working-tree]]
+How do I sync a working tree across systems?::
+ First, decide whether you want to do this at all. Git works best when you
+ push or pull your work using the typical `git push` and `git fetch` commands
+ and isn't designed to share a working tree across systems. This is
+ potentially risky and in some cases can cause repository corruption or data
+ loss.
++
+Usually, doing so will cause `git status` to need to re-read every file in the
+working tree. Additionally, Git's security model does not permit sharing a
+working tree across untrusted users, so it is only safe to sync a working tree
+if it will only be used by a single user across all machines.
++
+It is important not to use a cloud syncing service to sync any portion of a Git
+repository, since this can cause corruption, such as missing objects, changed
+or added files, broken refs, and a wide variety of other problems. These
+services tend to sync file by file on a continuous basis and don't understand
+the structure of a Git repository. This is especially bad if they sync the
+repository in the middle of it being updated, since that is very likely to
+cause incomplete or partial updates and therefore data loss.
++
+An example of the kind of corruption that can occur is conflicts over the state
+of refs, such that both sides end up with different commits on a branch that
+the other doesn't have. This can result in important objects becoming
+unreferenced and possibly pruned by `git gc`, causing data loss.
++
+Therefore, it's better to push your work to either the other system or a central
+server using the normal push and pull mechanism. However, this doesn't always
+preserve important data, like stashes, so some people prefer to share a working
+tree across systems.
++
+If you do this, the recommended approach is to use `rsync -a --delete-after`
+(ideally with an encrypted connection such as with `ssh`) on the root of
+repository. You should ensure several things when you do this:
++
+* If you have additional worktrees or a separate Git directory, they must be
+ synced at the same time as the main working tree and repository.
+* You are comfortable with the destination directory being an exact copy of the
+ source directory, _deleting any data that is already there_.
+* The repository (including all worktrees and the Git directory) is in a
+ quiescent state for the duration of the transfer (that is, no operations of
+ any sort are taking place on it, including background operations like `git
+ gc` and operations invoked by your editor).
++
+Be aware that even with these recommendations, syncing in this way has some risk
+since it bypasses Git's normal integrity checking for repositories, so having
+backups is advised. You may also wish to do a `git fsck` to verify the
+integrity of your data on the destination system after syncing.
+
Common Issues
-------------
@@ -241,6 +293,42 @@ How do I know if I want to do a fetch or a pull?::
ignore the upstream changes. A pull consists of a fetch followed
immediately by either a merge or rebase. See linkgit:git-pull[1].
+[[proxy]]
+Can I use a proxy with Git?::
+ Yes, Git supports the use of proxies. Git honors the standard `http_proxy`,
+ `https_proxy`, and `no_proxy` environment variables commonly used on Unix, and
+ it also can be configured with `http.proxy` and similar options for HTTPS (see
+ linkgit:git-config[1]). The `http.proxy` and related options can be
+ customized on a per-URL pattern basis. In addition, Git can in theory
+ function normally with transparent proxies that exist on the network.
++
+For SSH, Git can support a proxy using OpenSSH's `ProxyCommand`. Commonly used
+tools include `netcat` and `socat`. However, they must be configured not to
+exit when seeing EOF on standard input, which usually means that `netcat` will
+require `-q` and `socat` will require a timeout with something like `-t 10`.
+This is required because the way the Git SSH server knows that no more requests
+will be made is an EOF on standard input, but when that happens, the server may
+not have yet processed the final request, so dropping the connection at that
+point would interrupt that request.
++
+An example configuration entry in `~/.ssh/config` with an HTTP proxy might look
+like this:
++
+----
+Host git.example.org
+ User git
+ ProxyCommand socat -t 10 - PROXY:proxy.example.org:%h:%p,proxyport=8080
+----
++
+Note that in all cases, for Git to work properly, the proxy must be completely
+transparent. The proxy cannot modify, tamper with, or buffer the connection in
+any way, or Git will almost certainly fail to work. Note that many proxies,
+including many TLS middleboxes, Windows antivirus and firewall programs other
+than Windows Defender and Windows Firewall, and filtering proxies fail to meet
+this standard, and as a result end up breaking Git. Because of the many
+reports of problems and their poor security history, we recommend against the
+use of these classes of software and devices.
+
Merging and Rebasing
--------------------
@@ -357,8 +445,9 @@ I'm on Windows and git diff shows my files as having a `^M` at the end.::
+
You can store the files in the repository with Unix line endings and convert
them automatically to your platform's line endings. To do that, set the
-configuration option `core.eol` to `native` and see the following entry for
-information about how to configure files as text or binary.
+configuration option `core.eol` to `native` and see
+<<recommended-storage-settings,the question on recommended storage settings>>
+for information about how to configure files as text or binary.
+
You can also control this behavior with the `core.whitespace` setting if you
don't wish to remove the carriage returns from your line endings.
@@ -420,14 +509,26 @@ references, URLs, and hashes stored in the repository.
+
We also recommend setting a linkgit:gitattributes[5] file to explicitly mark
which files are text and which are binary. If you want Git to guess, you can
-set the attribute `text=auto`. For example, the following might be appropriate
-in some projects:
+set the attribute `text=auto`.
++
+With text files, Git will generally ensure that LF endings are used in the
+repository. The `core.autocrlf` and `core.eol` configuration variables specify
+what line-ending convention is followed when any text file is checked out. You
+can also use the `eol` attribute (e.g., `eol=crlf`) to override which files get
+what line-ending treatment.
++
+For example, generally shell files must have LF endings and batch files must
+have CRLF endings, so the following might be appropriate in some projects:
+
----
# By default, guess.
* text=auto
# Mark all C files as text.
*.c text
+# Ensure all shell files have LF endings and all batch files have CRLF
+# endings in the working tree and both have LF in the repo.
+*.sh text eol=lf
+*.bat text eol=crlf
# Mark all JPEG files as binary.
*.jpg binary
----
diff --git a/Documentation/gitformat-commit-graph.txt b/Documentation/gitformat-commit-graph.txt
index 31cad585e2..3e906e8030 100644
--- a/Documentation/gitformat-commit-graph.txt
+++ b/Documentation/gitformat-commit-graph.txt
@@ -142,13 +142,16 @@ All multi-byte numbers are in network byte order.
==== Bloom Filter Data (ID: {'B', 'D', 'A', 'T'}) [Optional]
* It starts with header consisting of three unsigned 32-bit integers:
- - Version of the hash algorithm being used. We currently only support
- value 1 which corresponds to the 32-bit version of the murmur3 hash
+ - Version of the hash algorithm being used. We currently support
+ value 2 which corresponds to the 32-bit version of the murmur3 hash
implemented exactly as described in
https://en.wikipedia.org/wiki/MurmurHash#Algorithm and the double
hashing technique using seed values 0x293ae76f and 0x7e646e2 as
described in https://doi.org/10.1007/978-3-540-30494-4_26 "Bloom Filters
- in Probabilistic Verification"
+ in Probabilistic Verification". Version 1 Bloom filters have a bug that appears
+ when char is signed and the repository has path names that have characters >=
+ 0x80; Git supports reading and writing them, but this ability will be removed
+ in a future version of Git.
- The number of times a path is hashed and hence the number of bit positions
that cumulatively determine whether a file is present in the commit.
- The minimum number of bits 'b' per entry in the Bloom filter. If the filter
diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index 06e997131b..0397dec64d 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -415,13 +415,13 @@ post-receive
This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
`git push` and updates reference(s) in its repository.
-It executes on the remote repository once after all the refs have
-been updated.
+The hook executes on the remote repository once after all the proposed
+ref updates are processed and if at least one ref is updated as the
+result.
-This hook executes once for the receive operation. It takes no
-arguments, but gets the same information as the
-<<pre-receive,'pre-receive'>>
-hook does on its standard input.
+The hook takes no arguments. It receives one line on standard input for
+each ref that is successfully updated following the same format as the
+<<pre-receive,'pre-receive'>> hook.
This hook does not affect the outcome of `git receive-pack`, as it
is called after the real work is done.
@@ -448,6 +448,9 @@ environment variables will not be set. If the client selects
to use push options, but doesn't transmit any, the count variable
will be set to zero, `GIT_PUSH_OPTION_COUNT=0`.
+See the "post-receive" section in linkgit:git-receive-pack[1] for
+additional details.
+
[[post-update]]
post-update
~~~~~~~~~~~
diff --git a/Documentation/gitpacking.txt b/Documentation/gitpacking.txt
index 4a6fcba6f7..321154d4e6 100644
--- a/Documentation/gitpacking.txt
+++ b/Documentation/gitpacking.txt
@@ -143,14 +143,16 @@ include::config/bitmap-pseudo-merge.txt[]
Suppose that you have a repository with a large number of references,
and you want a bare-bones configuration of pseudo-merge bitmaps that
will enhance bitmap coverage of the `refs/` namespace. You may start
-wiht a configuration like so:
+with a configuration like so:
- [bitmapPseudoMerge "all"]
+----
+[bitmapPseudoMerge "all"]
pattern = "refs/"
threshold = now
stableThreshold = never
sampleRate = 100
maxMerges = 64
+----
This will create pseudo-merge bitmaps for all references, regardless of
their age, and group them into 64 pseudo-merge commits.
@@ -159,8 +161,10 @@ If you wanted to separate tags from branches when generating
pseudo-merge commits, you would instead define the pattern with a
capture group, like so:
- [bitmapPseudoMerge "all"]
+----
+[bitmapPseudoMerge "all"]
pattern = "refs/(heads/tags)/"
+----
Suppose instead that you are working in a fork-network repository, with
each fork specified by some numeric ID, and whose refs reside in
@@ -168,12 +172,14 @@ each fork specified by some numeric ID, and whose refs reside in
fork) in the network. In this instance, you may instead write something
like:
- [bitmapPseudoMerge "all"]
+----
+[bitmapPseudoMerge "all"]
pattern = "refs/virtual/([0-9]+)/(heads|tags)/"
threshold = now
stableThreshold = never
sampleRate = 100
maxMerges = 64
+----
Which would generate pseudo-merge group identifiers like "1234-heads",
and "5678-tags" (for branches in fork "1234", and tags in remote "5678",
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 30b394ab47..42afe04869 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -550,7 +550,7 @@ The following pseudorefs are known to Git:
to the result.
[[def_ref]]ref::
- A name that that points to an <<def_object_name,object name>> or
+ A name that points to an <<def_object_name,object name>> or
another ref (the latter is called a <<def_symref,symbolic ref>>).
For convenience, a ref can sometimes be abbreviated when used
as an argument to a Git command; see linkgit:gitrevisions[7]
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
index 013014bbef..41f54050f8 100644
--- a/Documentation/howto/maintain-git.txt
+++ b/Documentation/howto/maintain-git.txt
@@ -37,22 +37,20 @@ The Policy
The policy on Integration is informally mentioned in "A Note
from the maintainer" message, which is periodically posted to
-this mailing list after each feature release is made.
+the mailing list after each feature release is made:
- Feature releases are numbered as vX.Y.0 and are meant to
contain bugfixes and enhancements in any area, including
functionality, performance and usability, without regression.
- - One release cycle for a feature release is expected to last for
- eight to ten weeks.
-
- - Maintenance releases are numbered as vX.Y.Z and are meant
+ - Maintenance releases are numbered as vX.Y.Z (0 < Z) and are meant
to contain only bugfixes for the corresponding vX.Y.0 feature
release and earlier maintenance releases vX.Y.W (W < Z).
- - 'master' branch is used to prepare for the next feature
+ - The 'master' branch is used to prepare for the next feature
release. In other words, at some point, the tip of 'master'
- branch is tagged with vX.Y.0.
+ branch is tagged as vX.(Y+1).0, when vX.Y.0 is the latest
+ feature release.
- 'maint' branch is used to prepare for the next maintenance
release. After the feature release vX.Y.0 is made, the tip
@@ -63,11 +61,13 @@ this mailing list after each feature release is made.
- 'next' branch is used to publish changes (both enhancements
and fixes) that (1) have worthwhile goal, (2) are in a fairly
good shape suitable for everyday use, (3) but have not yet
- demonstrated to be regression free. New changes are tested
- in 'next' before merged to 'master'.
+ demonstrated to be regression free. Reviews from contributors on
+ the mailing list help to make the determination. After a topic
+ is merged to 'next', it is tested for at least 7 calendar days
+ before getting merged to 'master'.
- 'seen' branch is used to publish other proposed changes that do
- not yet pass the criteria set for 'next'.
+ not yet pass the criteria set for 'next' (see above).
- The tips of 'master' and 'maint' branches will not be rewound to
allow people to build their own customization on top of them.
@@ -86,6 +86,38 @@ this mailing list after each feature release is made.
users are encouraged to test it so that regressions and bugs
are found before new topics are merged to 'master'.
+ - When a problem is found in a topic in 'next', the topic is marked
+ not to be merged to 'master'. Follow-up patches are discussed on
+ the mailing list and applied to the topic after being reviewed and
+ then the topic is merged (again) to 'next'. After going through
+ the usual testing in 'next', the entire (fixed) topic is merged
+ to 'master'.
+
+ - One release cycle for a feature release is expected to last for
+ eight to ten weeks. A few "release candidate" releases are
+ expected to be tagged about a week apart before the final
+ release, and a "preview" release is tagged about a week before
+ the first release candidate gets tagged.
+
+ - After the preview release is tagged, topics that were well
+ reviewed may be merged to 'master' before spending the usual 7
+ calendar days in 'next', with the expectation that any bugs in
+ them can be caught and fixed in the release candidates before
+ the final release.
+
+ - After the first release candidate is tagged, the contributors are
+ strongly encouraged to focus on finding and fixing new regressions
+ introduced during the cycle, over addressing old bugs and any new
+ features. Topics stop getting merged down from 'next' to 'master',
+ and new topics stop getting merged to 'next'. Unless they are fixes
+ to new regressions in the cycle, that is.
+
+ - Soon after a feature release is made, the tip of 'maint' gets
+ fast-forwarded to point at the release. Topics that have been
+ kept in 'next' are merged down to 'master' and a new development
+ cycle starts.
+
+
Note that before v1.9.0 release, the version numbers used to be
structured slightly differently. vX.Y.Z were feature releases while
vX.Y.Z.W were maintenance releases for vX.Y.Z.
@@ -179,12 +211,12 @@ by doing the following:
The initial round is done with:
$ git checkout ai/topic ;# or "git checkout -b ai/topic master"
- $ git am -sc3 mailbox
+ $ git am -sc3 --whitespace=warn mailbox
and replacing an existing topic with subsequent round is done with:
$ git checkout master...ai/topic ;# try to reapply to the same base
- $ git am -sc3 mailbox
+ $ git am -sc3 --whitespace=warn mailbox
to prepare the new round on a detached HEAD, and then
@@ -209,39 +241,59 @@ by doing the following:
(trivial typofixes etc. are often squashed directly into the
patches that need fixing, without being applied as a separate
"SQUASH???" commit), so that they can be removed easily as needed.
+ The expectation is that the original author will make corrections
+ in a reroll.
+ - By now, new topic branches are created and existing topic
+ branches are updated. The integration branches 'next', 'jch',
+ and 'seen' need to be updated to contain them.
- - Merge maint to master as needed:
+ - If there are topics that have been merged to 'master' and should
+ be merged to 'maint', merge them to 'maint', and update the
+ release notes to the next maintenance release.
- $ git checkout master
- $ git merge maint
- $ make test
+ - Review the latest issue of "What's cooking" again. Are topics
+ that have been sufficiently long in 'next' ready to be merged to
+ 'master'? Are topics we saw earlier and are in 'seen' now got
+ positive reviews and are ready to be merged to 'next'?
- - Merge master to next as needed:
+ - If there are topics that have been cooking in 'next' long enough
+ and should be merged to 'master', merge them to 'master', and
+ update the release notes to the next feature release.
- $ git checkout next
- $ git merge master
- $ make test
+ - If there were patches directly made on 'maint', merge 'maint' to
+ 'master'; make sure that the result is what you want.
- - Review the last issue of "What's cooking" again and see if topics
- that are ready to be merged to 'next' are still in good shape
- (e.g. has there any new issue identified on the list with the
- series?)
+ $ git checkout master
+ $ git merge -m "Sync with 'maint'" --no-log maint
+ $ git log -p --first-parent ORIG_HEAD..
+ $ make test
- - Prepare 'jch' branch, which is used to represent somewhere
- between 'master' and 'seen' and often is slightly ahead of 'next'.
+ - Prepare to update the 'jch' branch, which is used to represent
+ somewhere between 'master' and 'seen' and often is slightly ahead
+ of 'next', and the 'seen' branch, which is used to hold the rest.
$ Meta/Reintegrate master..jch >Meta/redo-jch.sh
The result is a script that lists topics to be merged in order to
- rebuild 'seen' as the input to Meta/Reintegrate script. Remove
- later topics that should not be in 'jch' yet. Add a line that
- consists of '### match next' before the name of the first topic
- in the output that should be in 'jch' but not in 'next' yet.
+ rebuild the current 'jch'. Do the same for 'seen'.
+
+ - Review the Meta/redo-jch.sh and Meta/redo-seen.sh scripts. The
+ former should have a line '### match next'---the idea is that
+ merging the topics listed before the line on top of 'master'
+ should result in a tree identical to that of 'next'.
- - Now we are ready to start merging topics to 'next'. For each
- branch whose tip is not merged to 'next', one of three things can
- happen:
+ - As newly created topics are usually merged near the tip of
+ 'seen', add them to the end of the Meta/redo-seen.sh script.
+ Among the topics that were in 'seen', there may be ones that
+ are not quite ready for 'next' but are getting there. Move
+ them from Meta/redo-seen.sh to the end of Meta/redo-jch.sh.
+ The expectation is that you'd use 'jch' as your daily driver
+ as the first guinea pig, so you should choose carefully.
+
+ - Now we are ready to start rebuilding 'jch' and merging topics to
+ 'next'. For each branch whose tip is not merged to 'next', one
+ of three things can happen:
- The commits are all next-worthy; merge the topic to next;
- The new parts are of mixed quality, but earlier ones are
@@ -252,10 +304,12 @@ by doing the following:
If a topic that was already in 'next' gained a patch, the script
would list it as "ai/topic~1". To include the new patch to the
updated 'next', drop the "~1" part; to keep it excluded, do not
- touch the line. If a topic that was not in 'next' should be
- merged to 'next', add it at the end of the list. Then:
+ touch the line.
+
+ If a topic that was not in 'next' should be merged to 'next', add
+ it before the '### match next' line. Then:
- $ git checkout -B jch master
+ $ git checkout --detach master
$ sh Meta/redo-jch.sh -c1
to rebuild the 'jch' branch from scratch. "-c1" tells the script
@@ -267,26 +321,29 @@ by doing the following:
reference to the variable under its old name), in which case
prepare an appropriate merge-fix first (see appendix), and
rebuild the 'jch' branch from scratch, starting at the tip of
- 'master'.
+ 'master', this time without using "-c1" to merge all topics.
- Then do the same to 'next'
+ Then do the same to 'next'.
$ git checkout next
$ sh Meta/redo-jch.sh -c1 -e
The "-e" option allows the merge message that comes from the
history of the topic and the comments in the "What's cooking" to
- be edited. The resulting tree should match 'jch' as the same set
- of topics are merged on 'master'; otherwise there is a mismerge.
- Investigate why and do not proceed until the mismerge is found
- and rectified.
+ be edited. The resulting tree should match 'jch^{/^### match next'}'
+ as the same set of topics are merged on 'master'; otherwise there
+ is a mismerge. Investigate why and do not proceed until the mismerge
+ is found and rectified.
+
+ If 'master' was updated before you started redoing 'next', then
- $ git diff jch next
+ $ git diff 'jch^{/^### match next}' next
- Then build the rest of 'jch':
+ would show differences that went into 'master' (which 'jch' has,
+ but 'next' does not yet---often it is updates to the release
+ notes). Merge 'master' back to 'next' if that is the case.
- $ git checkout jch
- $ sh Meta/redo-jch.sh
+ $ git merge -m "Sync with 'master'" --no-log master
When all is well, clean up the redo-jch.sh script with
@@ -296,12 +353,7 @@ by doing the following:
merged to 'master'. This may lose '### match next' marker;
add it again to the appropriate place when it happens.
- - Rebuild 'seen'.
-
- $ Meta/Reintegrate jch..seen >Meta/redo-seen.sh
-
- Edit the result by adding new topics that are not still in 'seen'
- in the script. Then
+ - Rebuild 'seen' on top of 'jch'.
$ git checkout -B seen jch
$ sh Meta/redo-seen.sh
@@ -312,7 +364,7 @@ by doing the following:
Double check by running
- $ git branch --no-merged seen
+ $ git branch --no-merged seen '??/*'
to see there is no unexpected leftover topics.
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 814cdcf95d..ee71e9d8aa 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.45.GIT
+DEF_VER=v2.46.GIT
LF='
'
diff --git a/Makefile b/Makefile
index 74bb026610..a87e18b317 100644
--- a/Makefile
+++ b/Makefile
@@ -809,7 +809,6 @@ TEST_BUILTINS_OBJS += test-match-trees.o
TEST_BUILTINS_OBJS += test-mergesort.o
TEST_BUILTINS_OBJS += test-mktemp.o
TEST_BUILTINS_OBJS += test-oid-array.o
-TEST_BUILTINS_OBJS += test-oidmap.o
TEST_BUILTINS_OBJS += test-online-cpus.o
TEST_BUILTINS_OBJS += test-pack-mtimes.o
TEST_BUILTINS_OBJS += test-parse-options.o
@@ -1338,9 +1337,14 @@ UNIT_TEST_PROGRAMS += t-example-decorate
UNIT_TEST_PROGRAMS += t-hash
UNIT_TEST_PROGRAMS += t-hashmap
UNIT_TEST_PROGRAMS += t-mem-pool
+UNIT_TEST_PROGRAMS += t-oidmap
UNIT_TEST_PROGRAMS += t-oidtree
UNIT_TEST_PROGRAMS += t-prio-queue
UNIT_TEST_PROGRAMS += t-reftable-basics
+UNIT_TEST_PROGRAMS += t-reftable-merged
+UNIT_TEST_PROGRAMS += t-reftable-pq
+UNIT_TEST_PROGRAMS += t-reftable-record
+UNIT_TEST_PROGRAMS += t-reftable-tree
UNIT_TEST_PROGRAMS += t-strbuf
UNIT_TEST_PROGRAMS += t-strcmp-offset
UNIT_TEST_PROGRAMS += t-strvec
@@ -1376,7 +1380,7 @@ PTHREAD_CFLAGS =
# For the 'sparse' target
SPARSE_FLAGS ?= -std=gnu99
-SP_EXTRA_FLAGS = -Wno-universal-initializer
+SP_EXTRA_FLAGS =
# For informing GIT-BUILD-OPTIONS of the SANITIZE=leak,address targets
SANITIZE_LEAK =
@@ -2680,13 +2684,9 @@ REFTABLE_OBJS += reftable/writer.o
REFTABLE_TEST_OBJS += reftable/block_test.o
REFTABLE_TEST_OBJS += reftable/dump.o
-REFTABLE_TEST_OBJS += reftable/merged_test.o
-REFTABLE_TEST_OBJS += reftable/pq_test.o
-REFTABLE_TEST_OBJS += reftable/record_test.o
REFTABLE_TEST_OBJS += reftable/readwrite_test.o
REFTABLE_TEST_OBJS += reftable/stack_test.o
REFTABLE_TEST_OBJS += reftable/test_framework.o
-REFTABLE_TEST_OBJS += reftable/tree_test.o
TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
diff --git a/RelNotes b/RelNotes
index cc696fc869..0104513a31 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.46.0.txt \ No newline at end of file
+Documentation/RelNotes/2.47.0.txt \ No newline at end of file
diff --git a/add-patch.c b/add-patch.c
index 6e176cd21a..1cec4ab67b 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -7,9 +7,11 @@
#include "environment.h"
#include "gettext.h"
#include "object-name.h"
+#include "pager.h"
#include "read-cache-ll.h"
#include "repository.h"
#include "strbuf.h"
+#include "sigchain.h"
#include "run-command.h"
#include "strvec.h"
#include "pathspec.h"
@@ -402,6 +404,12 @@ static void complete_file(char marker, struct hunk *hunk)
hunk->splittable_into++;
}
+/* Empty context lines may omit the leading ' ' */
+static int normalize_marker(const char *p)
+{
+ return p[0] == '\n' || (p[0] == '\r' && p[1] == '\n') ? ' ' : p[0];
+}
+
static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
{
struct strvec args = STRVEC_INIT;
@@ -487,6 +495,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
while (p != pend) {
char *eol = memchr(p, '\n', pend - p);
const char *deleted = NULL, *mode_change = NULL;
+ char ch = normalize_marker(p);
if (!eol)
eol = pend;
@@ -534,7 +543,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
* Start counting into how many hunks this one can be
* split
*/
- marker = *p;
+ marker = ch;
} else if (hunk == &file_diff->head &&
starts_with(p, "new file")) {
file_diff->added = 1;
@@ -588,10 +597,10 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
(int)(eol - (plain->buf + file_diff->head.start)),
plain->buf + file_diff->head.start);
- if ((marker == '-' || marker == '+') && *p == ' ')
+ if ((marker == '-' || marker == '+') && ch == ' ')
hunk->splittable_into++;
- if (marker && *p != '\\')
- marker = *p;
+ if (marker && ch != '\\')
+ marker = ch;
p = eol == pend ? pend : eol + 1;
hunk->end = p - plain->buf;
@@ -815,7 +824,7 @@ static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
(int)(hunk->end - hunk->start),
plain + hunk->start);
- if (plain[overlap_end] != ' ')
+ if (normalize_marker(&plain[overlap_end]) != ' ')
return error(_("expected context line "
"#%d in\n%.*s"),
(int)(j + 1),
@@ -955,7 +964,7 @@ static int split_hunk(struct add_p_state *s, struct file_diff *file_diff,
context_line_count = 0;
while (splittable_into > 1) {
- ch = s->plain.buf[current];
+ ch = normalize_marker(&s->plain.buf[current]);
if (!ch)
BUG("buffer overrun while splitting hunks");
@@ -1173,14 +1182,14 @@ static ssize_t recount_edited_hunk(struct add_p_state *s, struct hunk *hunk,
header->old_count = header->new_count = 0;
for (i = hunk->start; i < hunk->end; ) {
- switch (s->plain.buf[i]) {
+ switch(normalize_marker(&s->plain.buf[i])) {
case '-':
header->old_count++;
break;
case '+':
header->new_count++;
break;
- case ' ': case '\r': case '\n':
+ case ' ':
header->old_count++;
header->new_count++;
break;
@@ -1391,7 +1400,7 @@ N_("j - leave this hunk undecided, see next undecided hunk\n"
"/ - search for a hunk matching the given regex\n"
"s - split the current hunk into smaller hunks\n"
"e - manually edit the current hunk\n"
- "p - print the current hunk\n"
+ "p - print the current hunk, 'P' to use the pager\n"
"? - print help\n");
static int patch_update_file(struct add_p_state *s,
@@ -1402,7 +1411,7 @@ static int patch_update_file(struct add_p_state *s,
struct hunk *hunk;
char ch;
struct child_process cp = CHILD_PROCESS_INIT;
- int colored = !!s->colored.len, quit = 0;
+ int colored = !!s->colored.len, quit = 0, use_pager = 0;
enum prompt_mode_type prompt_mode_type;
enum {
ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,
@@ -1452,9 +1461,18 @@ static int patch_update_file(struct add_p_state *s,
strbuf_reset(&s->buf);
if (file_diff->hunk_nr) {
if (rendered_hunk_index != hunk_index) {
+ if (use_pager) {
+ setup_pager();
+ sigchain_push(SIGPIPE, SIG_IGN);
+ }
render_hunk(s, hunk, 0, colored, &s->buf);
fputs(s->buf.buf, stdout);
rendered_hunk_index = hunk_index;
+ if (use_pager) {
+ sigchain_pop(SIGPIPE);
+ wait_for_pager();
+ use_pager = 0;
+ }
}
strbuf_reset(&s->buf);
@@ -1675,8 +1693,9 @@ soft_increment:
hunk->use = USE_HUNK;
goto soft_increment;
}
- } else if (s->answer.buf[0] == 'p') {
+ } else if (ch == 'p') {
rendered_hunk_index = -1;
+ use_pager = (s->answer.buf[0] == 'P') ? 1 : 0;
} else if (s->answer.buf[0] == '?') {
const char *p = _(help_patch_remainder), *eol = p;
diff --git a/advice.c b/advice.c
index 558a46fc0b..6b879d805c 100644
--- a/advice.c
+++ b/advice.c
@@ -78,6 +78,7 @@ static struct {
[ADVICE_SEQUENCER_IN_USE] = { "sequencerInUse" },
[ADVICE_SET_UPSTREAM_FAILURE] = { "setUpstreamFailure" },
[ADVICE_SKIPPED_CHERRY_PICKS] = { "skippedCherryPicks" },
+ [ADVICE_SPARSE_INDEX_EXPANDED] = { "sparseIndexExpanded" },
[ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning" },
[ADVICE_STATUS_HINTS] = { "statusHints" },
[ADVICE_STATUS_U_OPTION] = { "statusUoption" },
diff --git a/advice.h b/advice.h
index 5105d90129..d7466bc0ef 100644
--- a/advice.h
+++ b/advice.h
@@ -45,6 +45,7 @@ enum advice_type {
ADVICE_SEQUENCER_IN_USE,
ADVICE_SET_UPSTREAM_FAILURE,
ADVICE_SKIPPED_CHERRY_PICKS,
+ ADVICE_SPARSE_INDEX_EXPANDED,
ADVICE_STATUS_AHEAD_BEHIND_WARNING,
ADVICE_STATUS_HINTS,
ADVICE_STATUS_U_OPTION,
diff --git a/apply.c b/apply.c
index ff939f908a..6e1060a952 100644
--- a/apply.c
+++ b/apply.c
@@ -137,6 +137,7 @@ void clear_apply_state(struct apply_state *state)
strset_clear(&state->removed_symlinks);
strset_clear(&state->kept_symlinks);
strbuf_release(&state->root);
+ FREE_AND_NULL(state->fake_ancestor);
/* &state->fn_table is cleared at the end of apply_patch() */
}
@@ -994,6 +995,7 @@ static int parse_mode_line(const char *line, int linenr, unsigned int *mode)
*mode = strtoul(line, &end, 8);
if (end == line || !isspace(*end))
return error(_("invalid mode on line %d: %s"), linenr, line);
+ *mode = canon_mode(*mode);
return 0;
}
@@ -2495,18 +2497,21 @@ static int match_fragment(struct apply_state *state,
int match_beginning, int match_end)
{
int i;
- char *fixed_buf, *buf, *orig, *target;
- struct strbuf fixed;
- size_t fixed_len, postlen;
+ const char *orig, *target;
+ struct strbuf fixed = STRBUF_INIT;
+ size_t postlen;
int preimage_limit;
+ int ret;
if (preimage->nr + current_lno <= img->nr) {
/*
* The hunk falls within the boundaries of img.
*/
preimage_limit = preimage->nr;
- if (match_end && (preimage->nr + current_lno != img->nr))
- return 0;
+ if (match_end && (preimage->nr + current_lno != img->nr)) {
+ ret = 0;
+ goto out;
+ }
} else if (state->ws_error_action == correct_ws_error &&
(ws_rule & WS_BLANK_AT_EOF)) {
/*
@@ -2523,17 +2528,23 @@ static int match_fragment(struct apply_state *state,
* we are not removing blanks at the end, so we
* should reject the hunk at this position.
*/
- return 0;
+ ret = 0;
+ goto out;
}
- if (match_beginning && current_lno)
- return 0;
+ if (match_beginning && current_lno) {
+ ret = 0;
+ goto out;
+ }
/* Quick hash check */
- for (i = 0; i < preimage_limit; i++)
+ for (i = 0; i < preimage_limit; i++) {
if ((img->line[current_lno + i].flag & LINE_PATCHED) ||
- (preimage->line[i].hash != img->line[current_lno + i].hash))
- return 0;
+ (preimage->line[i].hash != img->line[current_lno + i].hash)) {
+ ret = 0;
+ goto out;
+ }
+ }
if (preimage_limit == preimage->nr) {
/*
@@ -2546,8 +2557,10 @@ static int match_fragment(struct apply_state *state,
if ((match_end
? (current + preimage->len == img->len)
: (current + preimage->len <= img->len)) &&
- !memcmp(img->buf + current, preimage->buf, preimage->len))
- return 1;
+ !memcmp(img->buf + current, preimage->buf, preimage->len)) {
+ ret = 1;
+ goto out;
+ }
} else {
/*
* The preimage extends beyond the end of img, so
@@ -2556,7 +2569,7 @@ static int match_fragment(struct apply_state *state,
* There must be one non-blank context line that match
* a line before the end of img.
*/
- char *buf_end;
+ const char *buf, *buf_end;
buf = preimage->buf;
buf_end = buf;
@@ -2566,8 +2579,10 @@ static int match_fragment(struct apply_state *state,
for ( ; buf < buf_end; buf++)
if (!isspace(*buf))
break;
- if (buf == buf_end)
- return 0;
+ if (buf == buf_end) {
+ ret = 0;
+ goto out;
+ }
}
/*
@@ -2575,12 +2590,16 @@ static int match_fragment(struct apply_state *state,
* fuzzy matching. We collect all the line length information because
* we need it to adjust whitespace if we match.
*/
- if (state->ws_ignore_action == ignore_ws_change)
- return line_by_line_fuzzy_match(img, preimage, postimage,
- current, current_lno, preimage_limit);
+ if (state->ws_ignore_action == ignore_ws_change) {
+ ret = line_by_line_fuzzy_match(img, preimage, postimage,
+ current, current_lno, preimage_limit);
+ goto out;
+ }
- if (state->ws_error_action != correct_ws_error)
- return 0;
+ if (state->ws_error_action != correct_ws_error) {
+ ret = 0;
+ goto out;
+ }
/*
* The hunk does not apply byte-by-byte, but the hash says
@@ -2609,7 +2628,7 @@ static int match_fragment(struct apply_state *state,
* but in this loop we will only handle the part of the
* preimage that falls within the file.
*/
- strbuf_init(&fixed, preimage->len + 1);
+ strbuf_grow(&fixed, preimage->len + 1);
orig = preimage->buf;
target = img->buf + current;
for (i = 0; i < preimage_limit; i++) {
@@ -2645,8 +2664,10 @@ static int match_fragment(struct apply_state *state,
postlen += tgtfix.len;
strbuf_release(&tgtfix);
- if (!match)
- goto unmatch_exit;
+ if (!match) {
+ ret = 0;
+ goto out;
+ }
orig += oldlen;
target += tgtlen;
@@ -2667,9 +2688,13 @@ static int match_fragment(struct apply_state *state,
/* Try fixing the line in the preimage */
ws_fix_copy(&fixed, orig, oldlen, ws_rule, NULL);
- for (j = fixstart; j < fixed.len; j++)
- if (!isspace(fixed.buf[j]))
- goto unmatch_exit;
+ for (j = fixstart; j < fixed.len; j++) {
+ if (!isspace(fixed.buf[j])) {
+ ret = 0;
+ goto out;
+ }
+ }
+
orig += oldlen;
}
@@ -2679,16 +2704,16 @@ static int match_fragment(struct apply_state *state,
* has whitespace breakages unfixed, and fixing them makes the
* hunk match. Update the context lines in the postimage.
*/
- fixed_buf = strbuf_detach(&fixed, &fixed_len);
if (postlen < postimage->len)
postlen = 0;
update_pre_post_images(preimage, postimage,
- fixed_buf, fixed_len, postlen);
- return 1;
+ fixed.buf, fixed.len, postlen);
- unmatch_exit:
+ ret = 1;
+
+out:
strbuf_release(&fixed);
- return 0;
+ return ret;
}
static int find_pos(struct apply_state *state,
diff --git a/apply.h b/apply.h
index b9f18ce87d..cd25d24cc4 100644
--- a/apply.h
+++ b/apply.h
@@ -59,7 +59,7 @@ struct apply_state {
struct repository *repo;
const char *index_file;
enum apply_verbosity apply_verbosity;
- const char *fake_ancestor;
+ char *fake_ancestor;
const char *patch_input_file;
int line_termination;
struct strbuf root;
diff --git a/blame.c b/blame.c
index d403c46a35..90633380cd 100644
--- a/blame.c
+++ b/blame.c
@@ -2930,6 +2930,10 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb)
void cleanup_scoreboard(struct blame_scoreboard *sb)
{
+ free(sb->lineno);
+ clear_prio_queue(&sb->commits);
+ oidset_clear(&sb->ignore_list);
+
if (sb->bloom_data) {
int i;
for (i = 0; i < sb->bloom_data->nr; i++) {
diff --git a/bloom.c b/bloom.c
index bbf146fc30..c915f8b1ba 100644
--- a/bloom.c
+++ b/bloom.c
@@ -6,6 +6,9 @@
#include "commit-graph.h"
#include "commit.h"
#include "commit-slab.h"
+#include "tree.h"
+#include "tree-walk.h"
+#include "config.h"
#include "repository.h"
define_commit_slab(bloom_filter_slab, struct bloom_filter);
@@ -49,9 +52,9 @@ static int check_bloom_offset(struct commit_graph *g, uint32_t pos,
return -1;
}
-static int load_bloom_filter_from_graph(struct commit_graph *g,
- struct bloom_filter *filter,
- uint32_t graph_pos)
+int load_bloom_filter_from_graph(struct commit_graph *g,
+ struct bloom_filter *filter,
+ uint32_t graph_pos)
{
uint32_t lex_pos, start_index, end_index;
@@ -89,6 +92,8 @@ static int load_bloom_filter_from_graph(struct commit_graph *g,
filter->data = (unsigned char *)(g->chunk_bloom_data +
sizeof(unsigned char) * start_index +
BLOOMDATA_CHUNK_HEADER_SIZE);
+ filter->version = g->bloom_filter_settings->hash_version;
+ filter->to_free = NULL;
return 1;
}
@@ -100,7 +105,64 @@ static int load_bloom_filter_from_graph(struct commit_graph *g,
* Not considered to be cryptographically secure.
* Implemented as described in https://en.wikipedia.org/wiki/MurmurHash#Algorithm
*/
-uint32_t murmur3_seeded(uint32_t seed, const char *data, size_t len)
+uint32_t murmur3_seeded_v2(uint32_t seed, const char *data, size_t len)
+{
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+ const uint32_t r1 = 15;
+ const uint32_t r2 = 13;
+ const uint32_t m = 5;
+ const uint32_t n = 0xe6546b64;
+ int i;
+ uint32_t k1 = 0;
+ const char *tail;
+
+ int len4 = len / sizeof(uint32_t);
+
+ uint32_t k;
+ for (i = 0; i < len4; i++) {
+ uint32_t byte1 = (uint32_t)(unsigned char)data[4*i];
+ uint32_t byte2 = ((uint32_t)(unsigned char)data[4*i + 1]) << 8;
+ uint32_t byte3 = ((uint32_t)(unsigned char)data[4*i + 2]) << 16;
+ uint32_t byte4 = ((uint32_t)(unsigned char)data[4*i + 3]) << 24;
+ k = byte1 | byte2 | byte3 | byte4;
+ k *= c1;
+ k = rotate_left(k, r1);
+ k *= c2;
+
+ seed ^= k;
+ seed = rotate_left(seed, r2) * m + n;
+ }
+
+ tail = (data + len4 * sizeof(uint32_t));
+
+ switch (len & (sizeof(uint32_t) - 1)) {
+ case 3:
+ k1 ^= ((uint32_t)(unsigned char)tail[2]) << 16;
+ /*-fallthrough*/
+ case 2:
+ k1 ^= ((uint32_t)(unsigned char)tail[1]) << 8;
+ /*-fallthrough*/
+ case 1:
+ k1 ^= ((uint32_t)(unsigned char)tail[0]) << 0;
+ k1 *= c1;
+ k1 = rotate_left(k1, r1);
+ k1 *= c2;
+ seed ^= k1;
+ break;
+ }
+
+ seed ^= (uint32_t)len;
+ seed ^= (seed >> 16);
+ seed *= 0x85ebca6b;
+ seed ^= (seed >> 13);
+ seed *= 0xc2b2ae35;
+ seed ^= (seed >> 16);
+
+ return seed;
+}
+
+static uint32_t murmur3_seeded_v1(uint32_t seed, const char *data, size_t len)
{
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
@@ -165,8 +227,14 @@ void fill_bloom_key(const char *data,
int i;
const uint32_t seed0 = 0x293ae76f;
const uint32_t seed1 = 0x7e646e2c;
- const uint32_t hash0 = murmur3_seeded(seed0, data, len);
- const uint32_t hash1 = murmur3_seeded(seed1, data, len);
+ uint32_t hash0, hash1;
+ if (settings->hash_version == 2) {
+ hash0 = murmur3_seeded_v2(seed0, data, len);
+ hash1 = murmur3_seeded_v2(seed1, data, len);
+ } else {
+ hash0 = murmur3_seeded_v1(seed0, data, len);
+ hash1 = murmur3_seeded_v1(seed1, data, len);
+ }
key->hashes = (uint32_t *)xcalloc(settings->num_hashes, sizeof(uint32_t));
for (i = 0; i < settings->num_hashes; i++)
@@ -198,6 +266,18 @@ void init_bloom_filters(void)
init_bloom_filter_slab(&bloom_filters);
}
+static void free_one_bloom_filter(struct bloom_filter *filter)
+{
+ if (!filter)
+ return;
+ free(filter->to_free);
+}
+
+void deinit_bloom_filters(void)
+{
+ deep_clear_bloom_filter_slab(&bloom_filters, free_one_bloom_filter);
+}
+
static int pathmap_cmp(const void *hashmap_cmp_fn_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
@@ -211,11 +291,97 @@ static int pathmap_cmp(const void *hashmap_cmp_fn_data UNUSED,
return strcmp(e1->path, e2->path);
}
-static void init_truncated_large_filter(struct bloom_filter *filter)
+static void init_truncated_large_filter(struct bloom_filter *filter,
+ int version)
{
- filter->data = xmalloc(1);
+ filter->data = filter->to_free = xmalloc(1);
filter->data[0] = 0xFF;
filter->len = 1;
+ filter->version = version;
+}
+
+#define VISITED (1u<<21)
+#define HIGH_BITS (1u<<22)
+
+static int has_entries_with_high_bit(struct repository *r, struct tree *t)
+{
+ if (parse_tree(t))
+ return 1;
+
+ if (!(t->object.flags & VISITED)) {
+ struct tree_desc desc;
+ struct name_entry entry;
+
+ init_tree_desc(&desc, &t->object.oid, t->buffer, t->size);
+ while (tree_entry(&desc, &entry)) {
+ size_t i;
+ for (i = 0; i < entry.pathlen; i++) {
+ if (entry.path[i] & 0x80) {
+ t->object.flags |= HIGH_BITS;
+ goto done;
+ }
+ }
+
+ if (S_ISDIR(entry.mode)) {
+ struct tree *sub = lookup_tree(r, &entry.oid);
+ if (sub && has_entries_with_high_bit(r, sub)) {
+ t->object.flags |= HIGH_BITS;
+ goto done;
+ }
+ }
+
+ }
+
+done:
+ t->object.flags |= VISITED;
+ }
+
+ return !!(t->object.flags & HIGH_BITS);
+}
+
+static int commit_tree_has_high_bit_paths(struct repository *r,
+ struct commit *c)
+{
+ struct tree *t;
+ if (repo_parse_commit(r, c))
+ return 1;
+ t = repo_get_commit_tree(r, c);
+ if (!t)
+ return 1;
+ return has_entries_with_high_bit(r, t);
+}
+
+static struct bloom_filter *upgrade_filter(struct repository *r, struct commit *c,
+ struct bloom_filter *filter,
+ int hash_version)
+{
+ struct commit_list *p = c->parents;
+ if (commit_tree_has_high_bit_paths(r, c))
+ return NULL;
+
+ if (p && commit_tree_has_high_bit_paths(r, p->item))
+ return NULL;
+
+ filter->version = hash_version;
+
+ return filter;
+}
+
+struct bloom_filter *get_bloom_filter(struct repository *r, struct commit *c)
+{
+ struct bloom_filter *filter;
+ int hash_version;
+
+ filter = get_or_compute_bloom_filter(r, c, 0, NULL, NULL);
+ if (!filter)
+ return NULL;
+
+ prepare_repo_settings(r);
+ hash_version = r->settings.commit_graph_changed_paths_version;
+
+ if (!(hash_version == -1 || hash_version == filter->version))
+ return NULL; /* unusable filter */
+ return filter;
}
struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
@@ -243,8 +409,23 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
filter, graph_pos);
}
- if (filter->data && filter->len)
- return filter;
+ if (filter->data && filter->len) {
+ struct bloom_filter *upgrade;
+ if (!settings || settings->hash_version == filter->version)
+ return filter;
+
+ /* version mismatch, see if we can upgrade */
+ if (compute_if_not_present &&
+ git_env_bool("GIT_TEST_UPGRADE_BLOOM_FILTERS", 1)) {
+ upgrade = upgrade_filter(r, c, filter,
+ settings->hash_version);
+ if (upgrade) {
+ if (computed)
+ *computed |= BLOOM_UPGRADED;
+ return upgrade;
+ }
+ }
+ }
if (!compute_if_not_present)
return NULL;
@@ -300,19 +481,22 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
}
if (hashmap_get_size(&pathmap) > settings->max_changed_paths) {
- init_truncated_large_filter(filter);
+ init_truncated_large_filter(filter,
+ settings->hash_version);
if (computed)
*computed |= BLOOM_TRUNC_LARGE;
goto cleanup;
}
filter->len = (hashmap_get_size(&pathmap) * settings->bits_per_entry + BITS_PER_WORD - 1) / BITS_PER_WORD;
+ filter->version = settings->hash_version;
if (!filter->len) {
if (computed)
*computed |= BLOOM_TRUNC_EMPTY;
filter->len = 1;
}
CALLOC_ARRAY(filter->data, filter->len);
+ filter->to_free = filter->data;
hashmap_for_each_entry(&pathmap, &iter, e, entry) {
struct bloom_key key;
@@ -326,7 +510,7 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
} else {
for (i = 0; i < diff_queued_diff.nr; i++)
diff_free_filepair(diff_queued_diff.queue[i]);
- init_truncated_large_filter(filter);
+ init_truncated_large_filter(filter, settings->hash_version);
if (computed)
*computed |= BLOOM_TRUNC_LARGE;
diff --git a/bloom.h b/bloom.h
index adde6dfe21..d20e64bfbb 100644
--- a/bloom.h
+++ b/bloom.h
@@ -3,13 +3,16 @@
struct commit;
struct repository;
+struct commit_graph;
struct bloom_filter_settings {
/*
* The version of the hashing technique being used.
- * We currently only support version = 1 which is
+ * The newest version is 2, which is
* the seeded murmur3 hashing technique implemented
- * in bloom.c.
+ * in bloom.c. Bloom filters of version 1 were created
+ * with prior versions of Git, which had a bug in the
+ * implementation of the hash function.
*/
uint32_t hash_version;
@@ -52,6 +55,9 @@ struct bloom_filter_settings {
struct bloom_filter {
unsigned char *data;
size_t len;
+ int version;
+
+ void *to_free;
};
/*
@@ -68,6 +74,10 @@ struct bloom_key {
uint32_t *hashes;
};
+int load_bloom_filter_from_graph(struct commit_graph *g,
+ struct bloom_filter *filter,
+ uint32_t graph_pos);
+
/*
* Calculate the murmur3 32-bit hash value for the given data
* using the given seed.
@@ -75,7 +85,7 @@ struct bloom_key {
* Not considered to be cryptographically secure.
* Implemented as described in https://en.wikipedia.org/wiki/MurmurHash#Algorithm
*/
-uint32_t murmur3_seeded(uint32_t seed, const char *data, size_t len);
+uint32_t murmur3_seeded_v2(uint32_t seed, const char *data, size_t len);
void fill_bloom_key(const char *data,
size_t len,
@@ -88,12 +98,14 @@ void add_key_to_filter(const struct bloom_key *key,
const struct bloom_filter_settings *settings);
void init_bloom_filters(void);
+void deinit_bloom_filters(void);
enum bloom_filter_computed {
BLOOM_NOT_COMPUTED = (1 << 0),
BLOOM_COMPUTED = (1 << 1),
BLOOM_TRUNC_LARGE = (1 << 2),
BLOOM_TRUNC_EMPTY = (1 << 3),
+ BLOOM_UPGRADED = (1 << 4),
};
struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
@@ -102,8 +114,24 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
const struct bloom_filter_settings *settings,
enum bloom_filter_computed *computed);
-#define get_bloom_filter(r, c) get_or_compute_bloom_filter( \
- (r), (c), 0, NULL, NULL)
+/*
+ * Find the Bloom filter associated with the given commit "c".
+ *
+ * If any of the following are true
+ *
+ * - the repository does not have a commit-graph, or
+ * - the repository disables reading from the commit-graph, or
+ * - the given commit does not have a Bloom filter computed, or
+ * - there is a Bloom filter for commit "c", but it cannot be read
+ * because the filter uses an incompatible version of murmur3
+ *
+ * , then `get_bloom_filter()` will return NULL. Otherwise, the corresponding
+ * Bloom filter will be returned.
+ *
+ * For callers who wish to inspect Bloom filters with incompatible hash
+ * versions, use get_or_compute_bloom_filter().
+ */
+struct bloom_filter *get_bloom_filter(struct repository *r, struct commit *c);
int bloom_filter_contains(const struct bloom_filter *filter,
const struct bloom_key *key,
diff --git a/builtin/am.c b/builtin/am.c
index 8f9619ea3a..a12be088f7 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1573,8 +1573,8 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
*/
static int fall_back_threeway(const struct am_state *state, const char *index_path)
{
- struct object_id orig_tree, their_tree, our_tree;
- const struct object_id *bases[1] = { &orig_tree };
+ struct object_id their_tree, our_tree;
+ struct object_id bases[1] = { 0 };
struct merge_options o;
struct commit *result;
char *their_tree_name;
@@ -1588,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
discard_index(the_repository->index);
read_index_from(the_repository->index, index_path, get_git_dir());
- if (write_index_as_tree(&orig_tree, the_repository->index, index_path, 0, NULL))
+ if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL))
return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
say(state, stdout, _("Using index info to reconstruct a base tree..."));
@@ -1630,7 +1630,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
* changes.
*/
- init_merge_options(&o, the_repository);
+ init_ui_merge_options(&o, the_repository);
o.branch1 = "HEAD";
their_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
@@ -1718,6 +1718,7 @@ static void do_commit(const struct am_state *state)
run_hooks("post-applypatch");
+ free_commit_list(parents);
strbuf_release(&sb);
}
diff --git a/builtin/archive.c b/builtin/archive.c
index 7234607aaa..b50981504f 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -90,6 +90,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
N_("path to the remote git-upload-archive command")),
OPT_END()
};
+ int ret;
argc = parse_options(argc, argv, prefix, local_opts, NULL,
PARSE_OPT_KEEP_ALL);
@@ -104,6 +105,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
- UNLEAK(output);
- return write_archive(argc, argv, prefix, the_repository, output, 0);
+ ret = write_archive(argc, argv, prefix, the_repository, output, 0);
+
+ free(output);
+ return ret;
}
diff --git a/builtin/blame.c b/builtin/blame.c
index babc147d67..35e975fb13 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -67,7 +67,7 @@ static int no_whole_file_rename;
static int show_progress;
static char repeated_meta_color[COLOR_MAXLEN];
static int coloring_mode;
-static struct string_list ignore_revs_file_list = STRING_LIST_INIT_NODUP;
+static struct string_list ignore_revs_file_list = STRING_LIST_INIT_DUP;
static int mark_unblamable_lines;
static int mark_ignored_lines;
@@ -687,7 +687,7 @@ static unsigned parse_score(const char *arg)
return score;
}
-static const char *add_prefix(const char *prefix, const char *path)
+static char *add_prefix(const char *prefix, const char *path)
{
return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
}
@@ -725,6 +725,7 @@ static int git_blame_config(const char *var, const char *value,
if (ret)
return ret;
string_list_insert(&ignore_revs_file_list, str);
+ free(str);
return 0;
}
if (!strcmp(var, "blame.markunblamablelines")) {
@@ -866,7 +867,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,
int cmd_blame(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
- const char *path;
+ char *path = NULL;
struct blame_scoreboard sb;
struct blame_origin *o;
struct blame_entry *ent = NULL;
@@ -1227,6 +1228,7 @@ parse_done:
}
cleanup:
+ free(path);
cleanup_scoreboard(&sb);
release_revisions(&revs);
return 0;
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 43a1d7ac49..18fe58d6b8 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -102,7 +102,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
enum object_type type;
char *buf;
unsigned long size;
- struct object_context obj_context;
+ struct object_context obj_context = {0};
struct object_info oi = OBJECT_INFO_INIT;
struct strbuf sb = STRBUF_INIT;
unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
@@ -163,7 +163,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
goto cleanup;
case 'e':
- return !repo_has_object_file(the_repository, &oid);
+ ret = !repo_has_object_file(the_repository, &oid);
+ goto cleanup;
case 'w':
@@ -268,7 +269,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
ret = 0;
cleanup:
free(buf);
- free(obj_context.path);
+ object_context_release(&obj_context);
return ret;
}
@@ -520,7 +521,7 @@ static void batch_one_object(const char *obj_name,
struct batch_options *opt,
struct expand_data *data)
{
- struct object_context ctx;
+ struct object_context ctx = {0};
int flags =
GET_OID_HASH_ANY |
(opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0);
@@ -557,7 +558,8 @@ static void batch_one_object(const char *obj_name,
break;
}
fflush(stdout);
- return;
+
+ goto out;
}
if (ctx.mode == 0) {
@@ -565,10 +567,13 @@ static void batch_one_object(const char *obj_name,
(uintmax_t)ctx.symlink_path.len,
opt->output_delim, ctx.symlink_path.buf, opt->output_delim);
fflush(stdout);
- return;
+ goto out;
}
batch_object_write(obj_name, scratch, opt, data, NULL, 0);
+
+out:
+ object_context_release(&ctx);
}
struct object_cb_data {
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 3cf44b4683..0f21ddd2c6 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -884,7 +884,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
add_files_to_cache(the_repository, NULL, NULL, NULL, 0,
0);
- init_merge_options(&o, the_repository);
+ init_ui_merge_options(&o, the_repository);
o.verbosity = 0;
work = write_in_core_index_as_tree(the_repository);
@@ -1572,6 +1572,10 @@ static void die_if_switching_to_a_branch_in_use(struct checkout_opts *opts,
static int checkout_branch(struct checkout_opts *opts,
struct branch_info *new_branch_info)
{
+ int noop_switch = (!new_branch_info->name &&
+ !opts->new_branch &&
+ !opts->force_detach);
+
if (opts->pathspec.nr)
die(_("paths cannot be used with switching branches"));
@@ -1583,9 +1587,14 @@ static int checkout_branch(struct checkout_opts *opts,
die(_("'%s' cannot be used with switching branches"),
"--[no]-overlay");
- if (opts->writeout_stage)
- die(_("'%s' cannot be used with switching branches"),
- "--ours/--theirs");
+ if (opts->writeout_stage) {
+ const char *msg;
+ if (noop_switch)
+ msg = _("'%s' needs the paths to check out");
+ else
+ msg = _("'%s' cannot be used with switching branches");
+ die(msg, "--ours/--theirs");
+ }
if (opts->force && opts->merge)
die(_("'%s' cannot be used with '%s'"), "-f", "-m");
@@ -1612,10 +1621,8 @@ static int checkout_branch(struct checkout_opts *opts,
die(_("Cannot switch branch to a non-commit '%s'"),
new_branch_info->name);
- if (!opts->switch_branch_doing_nothing_is_ok &&
- !new_branch_info->name &&
- !opts->new_branch &&
- !opts->force_detach)
+ if (noop_switch &&
+ !opts->switch_branch_doing_nothing_is_ok)
die(_("missing branch or commit argument"));
if (!opts->implicit_detach &&
diff --git a/builtin/clone.c b/builtin/clone.c
index 80ef2bfca8..af6017d41a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -533,7 +533,8 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
if (!option_branch)
remote_head = guess_remote_head(head, refs, 0);
else {
- local_refs = NULL;
+ free_one_ref(head);
+ local_refs = head = NULL;
tail = &local_refs;
remote_head = copy_ref(find_remote_branch(refs, option_branch));
}
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index 1bb7819839..84bb450222 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -111,6 +111,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
};
+ int ret;
git_config(git_default_config, NULL);
@@ -132,11 +133,15 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid,
NULL, sign_commit)) {
- strbuf_release(&buffer);
- return 1;
+ ret = 1;
+ goto out;
}
printf("%s\n", oid_to_hex(&commit_oid));
+ ret = 0;
+
+out:
+ free_commit_list(parents);
strbuf_release(&buffer);
- return 0;
+ return ret;
}
diff --git a/builtin/commit.c b/builtin/commit.c
index 75c741173e..66427ba82d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -41,7 +41,7 @@
static const char * const builtin_commit_usage[] = {
N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n"
- " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)]\n"
+ " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>]\n"
" [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n"
" [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n"
" [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n"
@@ -106,7 +106,8 @@ static enum {
COMMIT_PARTIAL
} commit_style;
-static const char *logfile, *force_author;
+static const char *force_author;
+static char *logfile;
static char *template_file;
/*
* The _message variables are commit names from which to take
@@ -1309,7 +1310,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
!!use_message, "-C",
!!logfile, "-F");
if (use_message || edit_message || logfile ||fixup_message || have_option_m)
- template_file = NULL;
+ FREE_AND_NULL(template_file);
if (edit_message)
use_message = edit_message;
if (amend && !use_message && !fixup_message)
@@ -1847,7 +1848,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
rollback_index_files();
die(_("failed to write commit object"));
}
- free_commit_extra_headers(extra);
if (update_head_with_reflog(current_head, &oid, reflog_msg, &sb,
&err)) {
@@ -1889,8 +1889,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
apply_autostash_ref(the_repository, "MERGE_AUTOSTASH");
cleanup:
+ free_commit_extra_headers(extra);
+ free_commit_list(parents);
strbuf_release(&author_ident);
strbuf_release(&err);
strbuf_release(&sb);
+ free(logfile);
+ free(template_file);
return ret;
}
diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c
index 3db8df70a9..aaf2f8438b 100644
--- a/builtin/credential-cache.c
+++ b/builtin/credential-cache.c
@@ -88,6 +88,8 @@ static void spawn_daemon(const char *socket)
die_errno("unable to read result code from cache daemon");
if (r != 3 || memcmp(buf, "ok\n", 3))
die("cache daemon did not start: %.*s", r, buf);
+
+ child_process_clear(&daemon);
close(daemon.out);
}
@@ -137,7 +139,8 @@ static void announce_capabilities(void)
int cmd_credential_cache(int argc, const char **argv, const char *prefix)
{
- char *socket_path = NULL;
+ const char *socket_path_arg = NULL;
+ char *socket_path;
int timeout = 900;
const char *op;
const char * const usage[] = {
@@ -147,7 +150,7 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
struct option options[] = {
OPT_INTEGER(0, "timeout", &timeout,
"number of seconds to cache credentials"),
- OPT_STRING(0, "socket", &socket_path, "path",
+ OPT_STRING(0, "socket", &socket_path_arg, "path",
"path of cache-daemon socket"),
OPT_END()
};
@@ -160,6 +163,7 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
if (!have_unix_sockets())
die(_("credential-cache unavailable; no unix socket support"));
+ socket_path = xstrdup_or_null(socket_path_arg);
if (!socket_path)
socket_path = get_socket_path();
if (!socket_path)
@@ -176,6 +180,7 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
else
; /* ignore unknown operation */
+ free(socket_path);
return 0;
}
diff --git a/builtin/credential-store.c b/builtin/credential-store.c
index 494c809332..97968bfa1c 100644
--- a/builtin/credential-store.c
+++ b/builtin/credential-store.c
@@ -218,5 +218,6 @@ int cmd_credential_store(int argc, const char **argv, const char *prefix)
; /* Ignore unknown operation. */
string_list_clear(&fns, 0);
+ credential_clear(&c);
return 0;
}
diff --git a/builtin/describe.c b/builtin/describe.c
index e5287eddf2..954929c514 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -53,6 +53,10 @@ static const char *diff_index_args[] = {
"diff-index", "--quiet", "HEAD", "--", NULL
};
+static const char *update_index_args[] = {
+ "update-index", "--unmerged", "-q", "--refresh", NULL
+};
+
struct commit_name {
struct hashmap_entry entry;
struct object_id peeled;
@@ -525,6 +529,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst)
traverse_commit_list(&revs, process_commit, process_object, &pcd);
reset_revision_walk();
release_revisions(&revs);
+ strvec_clear(&args);
}
static void describe(const char *arg, int last_one)
@@ -615,6 +620,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
if (contains) {
struct string_list_item *item;
struct strvec args;
+ const char **argv_copy;
+ int ret;
strvec_init(&args);
strvec_pushl(&args, "name-rev",
@@ -633,7 +640,21 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
strvec_pushv(&args, argv);
else
strvec_push(&args, "HEAD");
- return cmd_name_rev(args.nr, args.v, prefix);
+
+ /*
+ * `cmd_name_rev()` modifies the array, so we'd leak its
+ * contained strings if we didn't do a copy here.
+ */
+ ALLOC_ARRAY(argv_copy, args.nr + 1);
+ for (size_t i = 0; i < args.nr; i++)
+ argv_copy[i] = args.v[i];
+ argv_copy[args.nr] = NULL;
+
+ ret = cmd_name_rev(args.nr, argv_copy, prefix);
+
+ strvec_clear(&args);
+ free(argv_copy);
+ return ret;
}
hashmap_init(&names, commit_name_neq, NULL, 0);
@@ -645,6 +666,14 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
if (argc == 0) {
if (broken) {
struct child_process cp = CHILD_PROCESS_INIT;
+
+ strvec_pushv(&cp.args, update_index_args);
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.no_stdout = 1;
+ run_command(&cp);
+
+ child_process_init(&cp);
strvec_pushv(&cp.args, diff_index_args);
cp.git_cmd = 1;
cp.no_stdin = 1;
@@ -667,7 +696,6 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
} else if (dirty) {
struct lock_file index_lock = LOCK_INIT;
struct rev_info revs;
- struct strvec args = STRVEC_INIT;
int fd;
setup_work_tree();
@@ -682,8 +710,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
repo_update_index_if_able(the_repository, &index_lock);
repo_init_revisions(the_repository, &revs, prefix);
- strvec_pushv(&args, diff_index_args);
- if (setup_revisions(args.nr, args.v, &revs, NULL) != 1)
+
+ if (setup_revisions(ARRAY_SIZE(diff_index_args) - 1,
+ diff_index_args, &revs, NULL) != 1)
BUG("malformed internal diff-index command line");
run_diff_index(&revs, 0);
diff --git a/builtin/difftool.c b/builtin/difftool.c
index a1794b7eed..dcc68e190c 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -662,6 +662,9 @@ finish:
free(lbase_dir);
free(rbase_dir);
+ strbuf_release(&info);
+ strbuf_release(&lpath);
+ strbuf_release(&rpath);
strbuf_release(&ldir);
strbuf_release(&rdir);
strbuf_release(&wtdir);
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 0f9855b680..957786d1b3 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -11,7 +11,7 @@ static const char * const fmt_merge_msg_usage[] = {
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
{
- const char *inpath = NULL;
+ char *inpath = NULL;
const char *message = NULL;
char *into_name = NULL;
int shortlog_len = -1;
@@ -66,5 +66,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
if (ret)
return ret;
write_in_full(STDOUT_FILENO, output.buf, output.len);
+
+ free(inpath);
return 0;
}
diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c
index 66a7389f9f..7195a072ed 100644
--- a/builtin/get-tar-commit-id.c
+++ b/builtin/get-tar-commit-id.c
@@ -35,6 +35,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv UNUSED, const char *prefix
if (header->typeflag[0] != TYPEFLAG_GLOBAL_HEADER)
return 1;
+ errno = 0;
len = strtol(content, &end, 10);
if (errno == ERANGE || end == content || len < 0)
return 1;
diff --git a/builtin/grep.c b/builtin/grep.c
index 5777ba82a9..dfc3c3e8bd 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -1114,7 +1114,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
struct object_id oid;
- struct object_context oc;
+ struct object_context oc = {0};
struct object *object;
if (!strcmp(arg, "--")) {
@@ -1140,7 +1140,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (!seen_dashdash)
verify_non_filename(prefix, arg);
add_object_array_with_path(object, arg, &list, oc.mode, oc.path);
- free(oc.path);
+ object_context_release(&oc);
}
/*
diff --git a/builtin/log.c b/builtin/log.c
index 1b43b604a2..a73a767606 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -682,7 +682,7 @@ static void show_tagger(const char *buf, struct rev_info *rev)
static int show_blob_object(const struct object_id *oid, struct rev_info *rev, const char *obj_name)
{
struct object_id oidc;
- struct object_context obj_context;
+ struct object_context obj_context = {0};
char *buf;
unsigned long size;
@@ -698,7 +698,7 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
if (!obj_context.path ||
!textconv_object(the_repository, obj_context.path,
obj_context.mode, &oidc, 1, &buf, &size)) {
- free(obj_context.path);
+ object_context_release(&obj_context);
return stream_blob_to_fd(1, oid, NULL, 0);
}
@@ -706,7 +706,7 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
die(_("git show %s: bad file"), obj_name);
write_or_die(1, buf, size);
- free(obj_context.path);
+ object_context_release(&obj_context);
return 0;
}
@@ -1434,6 +1434,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
int need_8bit_cte = 0;
struct pretty_print_context pp = {0};
struct commit *head = list[0];
+ char *to_free = NULL;
if (!cmit_fmt_is_mail(rev->commit_format))
die(_("cover letter needs email format"));
@@ -1455,7 +1456,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
}
if (!branch_name)
- branch_name = find_branch_name(rev);
+ branch_name = to_free = find_branch_name(rev);
pp.fmt = CMIT_FMT_EMAIL;
pp.date_mode.type = DATE_RFC2822;
@@ -1466,6 +1467,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
encoding, need_8bit_cte, cfg);
fprintf(rev->diffopt.file, "%s\n", sb.buf);
+ free(to_free);
free(pp.after_subject);
strbuf_release(&sb);
@@ -2021,7 +2023,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
const char *rfc = NULL;
int creation_factor = -1;
const char *signature = git_version_string;
- const char *signature_file_arg = NULL;
+ char *signature_file_arg = NULL;
struct keep_callback_data keep_callback_data = {
.cfg = &cfg,
.revs = &rev,
@@ -2561,6 +2563,8 @@ done:
strbuf_release(&rdiff1);
strbuf_release(&rdiff2);
strbuf_release(&rdiff_title);
+ free(description_file);
+ free(signature_file_arg);
free(to_free);
free(rev.message_id);
if (rev.ref_message_ids)
@@ -2675,16 +2679,16 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
commit_list_insert(commit, &list);
}
- while (list) {
+ for (struct commit_list *l = list; l; l = l->next) {
char sign = '+';
- commit = list->item;
+ commit = l->item;
if (has_commit_patch_id(commit, &ids))
sign = '-';
print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
- list = list->next;
}
+ free_commit_list(list);
free_patch_ids(&ids);
return 0;
}
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index debf2d4f88..0a491595ca 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -19,17 +19,16 @@ static const char * const ls_remote_usage[] = {
* Is there one among the list of patterns that match the tail part
* of the path?
*/
-static int tail_match(const char **pattern, const char *path)
+static int tail_match(const struct strvec *pattern, const char *path)
{
- const char *p;
char *pathbuf;
- if (!pattern)
+ if (!pattern->nr)
return 1; /* no restriction */
pathbuf = xstrfmt("/%s", path);
- while ((p = *(pattern++)) != NULL) {
- if (!wildmatch(p, pathbuf, 0)) {
+ for (size_t i = 0; i < pattern->nr; i++) {
+ if (!wildmatch(pattern->v[i], pathbuf, 0)) {
free(pathbuf);
return 1;
}
@@ -47,7 +46,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
int status = 0;
int show_symref_target = 0;
const char *uploadpack = NULL;
- const char **pattern = NULL;
+ struct strvec pattern = STRVEC_INIT;
struct transport_ls_refs_options transport_options =
TRANSPORT_LS_REFS_OPTIONS_INIT;
int i;
@@ -91,15 +90,25 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
PARSE_OPT_STOP_AT_NON_OPTION);
dest = argv[0];
+ /*
+ * TODO: This is buggy, but required for transport helpers. When a
+ * transport helper advertises a "refspec", then we'd add that to a
+ * list of refspecs via `refspec_append()`, which transitively depends
+ * on `the_hash_algo`. Thus, when the hash algorithm isn't properly set
+ * up, this would lead to a segfault.
+ *
+ * We really should fix this in the transport helper logic such that we
+ * lazily parse refspec capabilities _after_ we have learned about the
+ * remote's object format. Otherwise, we may end up misparsing refspecs
+ * depending on what object hash the remote uses.
+ */
+ if (!the_repository->hash_algo)
+ repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+
packet_trace_identity("ls-remote");
- if (argc > 1) {
- int i;
- CALLOC_ARRAY(pattern, argc);
- for (i = 1; i < argc; i++) {
- pattern[i - 1] = xstrfmt("*/%s", argv[i]);
- }
- }
+ for (int i = 1; i < argc; i++)
+ strvec_pushf(&pattern, "*/%s", argv[i]);
if (flags & REF_TAGS)
strvec_push(&transport_options.ref_prefixes, "refs/tags/");
@@ -136,7 +145,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
struct ref_array_item *item;
if (!check_ref_type(ref, flags))
continue;
- if (!tail_match(pattern, ref->name))
+ if (!tail_match(&pattern, ref->name))
continue;
item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
item->symref = xstrdup_or_null(ref->symref);
@@ -158,5 +167,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
if (transport_disconnect(transport))
status = 1;
transport_ls_refs_options_release(&transport_options);
+
+ strvec_clear(&pattern);
return status;
}
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 7bf84b235c..bf372c67d7 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -367,7 +367,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
OPT_END()
};
struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
- struct object_context obj_context;
+ struct object_context obj_context = {0};
int ret;
git_config(git_default_config, NULL);
@@ -441,5 +441,6 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
ret = !!read_tree(the_repository, tree, &options.pathspec, fn, &options);
clear_pathspec(&options.pathspec);
+ object_context_release(&obj_context);
return ret;
}
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index c2ce044a20..e951b09805 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -23,7 +23,7 @@ static char *better_branch_name(const char *branch)
int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
{
- const struct object_id *bases[21];
+ struct object_id bases[21];
unsigned bases_count = 0;
int i, failed;
struct object_id h1, h2;
@@ -31,7 +31,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
char *better1, *better2;
struct commit *result;
- init_merge_options(&o, the_repository);
+ init_basic_merge_options(&o, the_repository);
if (argv[0] && ends_with(argv[0], "-subtree"))
o.subtree_shift = "";
@@ -49,10 +49,8 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
continue;
}
if (bases_count < ARRAY_SIZE(bases)-1) {
- struct object_id *oid = xmalloc(sizeof(struct object_id));
- if (repo_get_oid(the_repository, argv[i], oid))
+ if (repo_get_oid(the_repository, argv[i], &bases[bases_count++]))
die(_("could not parse object '%s'"), argv[i]);
- bases[bases_count++] = oid;
}
else
warning(Q_("cannot handle more than %d base. "
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 1082d919fd..9bca9b5f33 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -482,6 +482,7 @@ static int real_merge(struct merge_tree_options *o,
die(_("refusing to merge unrelated histories"));
merge_bases = reverse_commit_list(merge_bases);
merge_incore_recursive(&opt, merge_bases, parent1, parent2, &result);
+ free_commit_list(merge_bases);
}
if (result.clean < 0)
@@ -570,7 +571,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
};
/* Init merge options */
- init_merge_options(&o.merge_options, the_repository);
+ init_ui_merge_options(&o.merge_options, the_repository);
/* Parse arguments */
original_argc = argc - 1; /* ignoring argv[0] */
diff --git a/builtin/merge.c b/builtin/merge.c
index 66a4fa72e1..c896b18d1a 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -164,7 +164,7 @@ static struct strategy *get_strategy(const char *name)
{
int i;
struct strategy *ret;
- static struct cmdnames main_cmds, other_cmds;
+ static struct cmdnames main_cmds = {0}, other_cmds = {0};
static int loaded;
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
@@ -182,10 +182,9 @@ static struct strategy *get_strategy(const char *name)
return &all_strategy[i];
if (!loaded) {
- struct cmdnames not_strategies;
+ struct cmdnames not_strategies = {0};
loaded = 1;
- memset(&not_strategies, 0, sizeof(struct cmdnames));
load_command_list("git-merge-", &main_cmds, &other_cmds);
for (i = 0; i < main_cmds.cnt; i++) {
int j, found = 0;
@@ -197,6 +196,8 @@ static struct strategy *get_strategy(const char *name)
add_cmdname(&not_strategies, ent->name, ent->len);
}
exclude_cmds(&main_cmds, &not_strategies);
+
+ cmdnames_release(&not_strategies);
}
if (!is_in_cmdlist(&main_cmds, name) && !is_in_cmdlist(&other_cmds, name)) {
fprintf(stderr, _("Could not find merge strategy '%s'.\n"), name);
@@ -216,6 +217,9 @@ static struct strategy *get_strategy(const char *name)
CALLOC_ARRAY(ret, 1);
ret->name = xstrdup(name);
ret->attr = NO_TRIVIAL;
+
+ cmdnames_release(&main_cmds);
+ cmdnames_release(&other_cmds);
return ret;
}
@@ -720,7 +724,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
return 2;
}
- init_merge_options(&o, the_repository);
+ init_ui_merge_options(&o, the_repository);
if (!strcmp(strategy, "subtree"))
o.subtree_shift = "";
@@ -745,6 +749,8 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
else
clean = merge_recursive(&o, head, remoteheads->item,
reversed, &result);
+ free_commit_list(reversed);
+
if (clean < 0) {
rollback_lock_file(&lock);
return 2;
@@ -898,7 +904,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
{
struct object_id result_tree, result_commit;
- struct commit_list *parents, **pptr = &parents;
+ struct commit_list *parents = NULL, **pptr = &parents;
if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET,
SKIP_IF_UNCHANGED, 0, NULL, NULL,
@@ -914,7 +920,9 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
&result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
finish(head, remoteheads, &result_commit, "In-index merge");
+
remove_merge_branch_state(the_repository);
+ free_commit_list(parents);
return 0;
}
@@ -940,8 +948,10 @@ static int finish_automerge(struct commit *head,
die(_("failed to write commit object"));
strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy);
finish(head, remoteheads, &result_commit, buf.buf);
+
strbuf_release(&buf);
remove_merge_branch_state(the_repository);
+ free_commit_list(parents);
return 0;
}
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index 8360932d2e..9cf1a32d65 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -50,7 +50,7 @@ static char const * const builtin_multi_pack_index_usage[] = {
static struct opts_multi_pack_index {
char *object_dir;
const char *preferred_pack;
- const char *refs_snapshot;
+ char *refs_snapshot;
unsigned long batch_size;
unsigned flags;
int stdin_packs;
@@ -135,6 +135,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
N_("refs snapshot for selecting bitmap commits")),
OPT_END(),
};
+ int ret;
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
@@ -157,7 +158,6 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
if (opts.stdin_packs) {
struct string_list packs = STRING_LIST_INIT_DUP;
- int ret;
read_packs_from_stdin(&packs);
@@ -166,12 +166,17 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
opts.refs_snapshot, opts.flags);
string_list_clear(&packs, 0);
+ free(opts.refs_snapshot);
return ret;
}
- return write_midx_file(opts.object_dir, opts.preferred_pack,
- opts.refs_snapshot, opts.flags);
+
+ ret = write_midx_file(opts.object_dir, opts.preferred_pack,
+ opts.refs_snapshot, opts.flags);
+
+ free(opts.refs_snapshot);
+ return ret;
}
static int cmd_multi_pack_index_verify(int argc, const char **argv,
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 70e9ec4e47..f62c0a36cb 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -677,7 +677,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
always, allow_undefined, data.name_only);
}
- UNLEAK(string_pool);
- UNLEAK(revs);
+ string_list_clear(&data.ref_filters, 0);
+ string_list_clear(&data.exclude_filters, 0);
+ mem_pool_discard(&string_pool, 0);
+ object_array_clear(&revs);
return 0;
}
diff --git a/builtin/notes.c b/builtin/notes.c
index d9c356e354..4cc5bfedc3 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -114,7 +114,6 @@ struct note_msg {
};
struct note_data {
- int given;
int use_editor;
int stripspace;
char *edit_path;
@@ -193,7 +192,7 @@ static void write_commented_object(int fd, const struct object_id *object)
static void prepare_note_data(const struct object_id *object, struct note_data *d,
const struct object_id *old_note)
{
- if (d->use_editor || !d->given) {
+ if (d->use_editor || !d->msg_nr) {
int fd;
struct strbuf buf = STRBUF_INIT;
@@ -201,7 +200,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
d->edit_path = git_pathdup("NOTES_EDITMSG");
fd = xopen(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- if (d->given)
+ if (d->msg_nr)
write_or_die(fd, d->buf.buf, d->buf.len);
else if (old_note)
copy_obj_to_fd(fd, old_note);
@@ -515,7 +514,6 @@ static int add(int argc, const char **argv, const char *prefix)
if (d.msg_nr)
concat_messages(&d);
- d.given = !!d.buf.len;
object_ref = argc > 1 ? argv[1] : "HEAD";
@@ -528,7 +526,7 @@ static int add(int argc, const char **argv, const char *prefix)
if (note) {
if (!force) {
free_notes(t);
- if (d.given) {
+ if (d.msg_nr) {
free_note_data(&d);
return error(_("Cannot add notes. "
"Found existing notes for object %s. "
@@ -690,14 +688,14 @@ static int append_edit(int argc, const char **argv, const char *prefix)
usage_with_options(usage, options);
}
- if (d.msg_nr)
+ if (d.msg_nr) {
concat_messages(&d);
- d.given = !!d.buf.len;
-
- if (d.given && edit)
- fprintf(stderr, _("The -m/-F/-c/-C options have been deprecated "
- "for the 'edit' subcommand.\n"
- "Please use 'git notes add -f -m/-F/-c/-C' instead.\n"));
+ if (edit)
+ fprintf(stderr, _("The -m/-F/-c/-C options have been "
+ "deprecated for the 'edit' subcommand.\n"
+ "Please use 'git notes add -f -m/-F/-c/-C' "
+ "instead.\n"));
+ }
object_ref = 1 < argc ? argv[1] : "HEAD";
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index d790ae6354..35c1179f7e 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -7,10 +7,9 @@
#include "parse-options.h"
#include "setup.h"
-static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result)
+static void flush_current_id(struct object_id *id, struct object_id *result)
{
- if (patchlen)
- printf("%s %s\n", oid_to_hex(result), oid_to_hex(id));
+ printf("%s %s\n", oid_to_hex(result), oid_to_hex(id));
}
static int remove_space(char *line)
@@ -60,9 +59,27 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after)
return 1;
}
+/*
+ * flag bits to control get_one_patchid()'s behaviour.
+ *
+ * STABLE/VERBATIM are given from the command line option as
+ * --stable/--verbatim. FIND_HEADER conveys the internal state
+ * maintained by the caller to allow the function to avoid mistaking
+ * lines of log message before seeing the "diff" part as the beginning
+ * of the next patch.
+ */
+enum {
+ GOPID_STABLE = (1<<0), /* --stable */
+ GOPID_VERBATIM = (1<<1), /* --verbatim */
+ GOPID_FIND_HEADER = (1<<2), /* stop at the beginning of patch message */
+};
+
static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
- struct strbuf *line_buf, int stable, int verbatim)
+ struct strbuf *line_buf, unsigned flags)
{
+ int stable = flags & GOPID_STABLE;
+ int verbatim = flags & GOPID_VERBATIM;
+ int find_header = flags & GOPID_FIND_HEADER;
int patchlen = 0, found_next = 0;
int before = -1, after = -1;
int diff_is_binary = 0;
@@ -77,24 +94,40 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
const char *p = line;
int len;
- /* Possibly skip over the prefix added by "log" or "format-patch" */
- if (!skip_prefix(line, "commit ", &p) &&
- !skip_prefix(line, "From ", &p) &&
- starts_with(line, "\\ ") && 12 < strlen(line)) {
- if (verbatim)
- the_hash_algo->update_fn(&ctx, line, strlen(line));
- continue;
- }
-
- if (!get_oid_hex(p, next_oid)) {
- found_next = 1;
- break;
+ /*
+ * The caller hasn't seen us find a patch header and
+ * return to it, or we have started processing patch
+ * and may encounter the beginning of the next patch.
+ */
+ if (find_header) {
+ /*
+ * If we see a line that begins with "<object name>",
+ * "commit <object name>" or "From <object name>", it is
+ * the beginning of a patch. Return to the caller, as
+ * we are done with the one we have been processing.
+ */
+ if (skip_prefix(line, "commit ", &p))
+ ;
+ else if (skip_prefix(line, "From ", &p))
+ ;
+ if (!get_oid_hex(p, next_oid)) {
+ if (verbatim)
+ the_hash_algo->update_fn(&ctx, line, strlen(line));
+ found_next = 1;
+ break;
+ }
}
/* Ignore commit comments */
if (!patchlen && !starts_with(line, "diff "))
continue;
+ /*
+ * We are past the commit log message. Prepare to
+ * stop at the beginning of the next patch header.
+ */
+ find_header = 1;
+
/* Parsing diff header? */
if (before == -1) {
if (starts_with(line, "GIT binary patch") ||
@@ -127,6 +160,16 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
break;
}
+ /*
+ * A hunk about an incomplete line may have this
+ * marker at the end, which should just be ignored.
+ */
+ if (starts_with(line, "\\ ") && 12 < strlen(line)) {
+ if (verbatim)
+ the_hash_algo->update_fn(&ctx, line, strlen(line));
+ continue;
+ }
+
if (diff_is_binary) {
if (starts_with(line, "diff ")) {
diff_is_binary = 0;
@@ -173,17 +216,20 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
return patchlen;
}
-static void generate_id_list(int stable, int verbatim)
+static void generate_id_list(unsigned flags)
{
struct object_id oid, n, result;
int patchlen;
struct strbuf line_buf = STRBUF_INIT;
oidclr(&oid, the_repository->hash_algo);
+ flags |= GOPID_FIND_HEADER;
while (!feof(stdin)) {
- patchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim);
- flush_current_id(patchlen, &oid, &result);
+ patchlen = get_one_patchid(&n, &result, &line_buf, flags);
+ if (patchlen)
+ flush_current_id(&oid, &result);
oidcpy(&oid, &n);
+ flags &= ~GOPID_FIND_HEADER;
}
strbuf_release(&line_buf);
}
@@ -219,6 +265,7 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix)
/* if nothing is set, default to unstable */
struct patch_id_opts config = {0, 0};
int opts = 0;
+ unsigned flags = 0;
struct option builtin_patch_id_options[] = {
OPT_CMDMODE(0, "unstable", &opts,
N_("use the unstable patch-id algorithm"), 1),
@@ -250,7 +297,11 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix)
if (!the_hash_algo)
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
- generate_id_list(opts ? opts > 1 : config.stable,
- opts ? opts == 3 : config.verbatim);
+ if (opts ? opts > 1 : config.stable)
+ flags |= GOPID_STABLE;
+ if (opts ? opts == 3 : config.verbatim)
+ flags |= GOPID_VERBATIM;
+ generate_id_list(flags);
+
return 0;
}
diff --git a/builtin/push.c b/builtin/push.c
index 8260c6e46a..7a67398124 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -96,9 +96,8 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref,
refspec_append(refspec, ref);
}
-static void set_refspecs(const char **refs, int nr, const char *repo)
+static void set_refspecs(const char **refs, int nr, struct remote *remote)
{
- struct remote *remote = NULL;
struct ref *local_refs = NULL;
int i;
@@ -124,17 +123,10 @@ static void set_refspecs(const char **refs, int nr, const char *repo)
local_refs = get_local_heads();
/* Does "ref" uniquely name our ref? */
- if (count_refspec_match(ref, local_refs, &matched) != 1) {
+ if (count_refspec_match(ref, local_refs, &matched) != 1)
refspec_append(&rs, ref);
- } else {
- /* lazily grab remote */
- if (!remote)
- remote = remote_get(repo);
- if (!remote)
- BUG("must get a remote for repo '%s'", repo);
-
+ else
refspec_append_mapped(&rs, ref, remote, matched);
- }
} else
refspec_append(&rs, ref);
}
@@ -630,10 +622,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
if (tags)
refspec_append(&rs, "refs/tags/*");
- if (argc > 0) {
+ if (argc > 0)
repo = argv[0];
- set_refspecs(argv + 1, argc - 1, repo);
- }
remote = pushremote_get(repo);
if (!remote) {
@@ -649,6 +639,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
" git push <name>\n"));
}
+ if (argc > 0)
+ set_refspecs(argv + 1, argc - 1, remote);
+
if (remote->mirror)
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
diff --git a/builtin/remote.c b/builtin/remote.c
index 08292498bd..9d54fddf8c 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -258,7 +258,7 @@ struct branch_info {
char *push_remote_name;
};
-static struct string_list branch_list = STRING_LIST_INIT_NODUP;
+static struct string_list branch_list = STRING_LIST_INIT_DUP;
static const char *abbrev_ref(const char *name, const char *prefix)
{
@@ -292,8 +292,8 @@ static int config_read_branches(const char *key, const char *value,
type = PUSH_REMOTE;
else
return 0;
- name = xmemdupz(key, key_len);
+ name = xmemdupz(key, key_len);
item = string_list_insert(&branch_list, name);
if (!item->util)
@@ -337,6 +337,7 @@ static int config_read_branches(const char *key, const char *value,
BUG("unexpected type=%d", type);
}
+ free(name);
return 0;
}
@@ -554,13 +555,16 @@ static int add_branch_for_removal(const char *refname,
refspec.dst = (char *)refname;
if (remote_find_tracking(branches->remote, &refspec))
return 0;
+ free(refspec.src);
/* don't delete a branch if another remote also uses it */
for (kr = branches->keep->list; kr; kr = kr->next) {
memset(&refspec, 0, sizeof(refspec));
refspec.dst = (char *)refname;
- if (!remote_find_tracking(kr->remote, &refspec))
+ if (!remote_find_tracking(kr->remote, &refspec)) {
+ free(refspec.src);
return 0;
+ }
}
/* don't delete non-remote-tracking refs */
@@ -667,7 +671,11 @@ static int config_read_push_default(const char *key, const char *value,
static void handle_push_default(const char* old_name, const char* new_name)
{
struct push_default_info push_default = {
- old_name, CONFIG_SCOPE_UNKNOWN, STRBUF_INIT, -1 };
+ .old_name = old_name,
+ .scope = CONFIG_SCOPE_UNKNOWN,
+ .origin = STRBUF_INIT,
+ .linenr = -1,
+ };
git_config(config_read_push_default, &push_default);
if (push_default.scope >= CONFIG_SCOPE_COMMAND)
; /* pass */
@@ -687,6 +695,8 @@ static void handle_push_default(const char* old_name, const char* new_name)
push_default.origin.buf, push_default.linenr,
old_name);
}
+
+ strbuf_release(&push_default.origin);
}
@@ -784,7 +794,7 @@ static int mv(int argc, const char **argv, const char *prefix)
}
if (!refspec_updated)
- return 0;
+ goto out;
/*
* First remove symrefs, then rename the rest, finally create
@@ -850,10 +860,15 @@ static int mv(int argc, const char **argv, const char *prefix)
display_progress(progress, ++refs_renamed_nr);
}
stop_progress(&progress);
- string_list_clear(&remote_branches, 1);
handle_push_default(rename.old_name, rename.new_name);
+out:
+ string_list_clear(&remote_branches, 1);
+ strbuf_release(&old_remote_context);
+ strbuf_release(&buf);
+ strbuf_release(&buf2);
+ strbuf_release(&buf3);
return 0;
}
@@ -944,12 +959,21 @@ static int rm(int argc, const char **argv, const char *prefix)
if (!result) {
strbuf_addf(&buf, "remote.%s", remote->name);
- if (git_config_rename_section(buf.buf, NULL) < 1)
- return error(_("Could not remove config section '%s'"), buf.buf);
+ if (git_config_rename_section(buf.buf, NULL) < 1) {
+ result = error(_("Could not remove config section '%s'"), buf.buf);
+ goto out;
+ }
handle_push_default(remote->name, NULL);
}
+out:
+ for (struct known_remote *r = known_remotes.list; r;) {
+ struct known_remote *next = r->next;
+ free(r);
+ r = next;
+ }
+ strbuf_release(&buf);
return result;
}
@@ -982,8 +1006,10 @@ static int append_ref_to_tracked_list(const char *refname,
memset(&refspec, 0, sizeof(refspec));
refspec.dst = (char *)refname;
- if (!remote_find_tracking(states->remote, &refspec))
+ if (!remote_find_tracking(states->remote, &refspec)) {
string_list_append(&states->tracked, abbrev_branch(refspec.src));
+ free(refspec.src);
+ }
return 0;
}
diff --git a/builtin/replay.c b/builtin/replay.c
index 6bf0691f15..138198ce9c 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -52,11 +52,11 @@ static struct commit *create_commit(struct tree *tree,
struct commit *parent)
{
struct object_id ret;
- struct object *obj;
+ struct object *obj = NULL;
struct commit_list *parents = NULL;
char *author;
char *sign_commit = NULL; /* FIXME: cli users might want to sign again */
- struct commit_extra_header *extra;
+ struct commit_extra_header *extra = NULL;
struct strbuf msg = STRBUF_INIT;
const char *out_enc = get_commit_output_encoding();
const char *message = repo_logmsg_reencode(the_repository, based_on,
@@ -73,12 +73,16 @@ static struct commit *create_commit(struct tree *tree,
if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents,
&ret, author, NULL, sign_commit, extra)) {
error(_("failed to write commit object"));
- return NULL;
+ goto out;
}
- free(author);
- strbuf_release(&msg);
obj = parse_object(the_repository, &ret);
+
+out:
+ free_commit_extra_headers(extra);
+ free_commit_list(parents);
+ strbuf_release(&msg);
+ free(author);
return (struct commit *)obj;
}
@@ -147,7 +151,7 @@ static void get_ref_information(struct rev_cmdline_info *cmd_info,
static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
const char *onto_name,
- const char **advance_name,
+ char **advance_name,
struct commit **onto,
struct strset **update_refs)
{
@@ -170,6 +174,7 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
*onto = peel_committish(*advance_name);
if (repo_dwim_ref(the_repository, *advance_name, strlen(*advance_name),
&oid, &fullname, 0) == 1) {
+ free(*advance_name);
*advance_name = fullname;
} else {
die(_("argument to --advance must be a reference"));
@@ -193,6 +198,7 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
if (negative_refs_complete) {
struct hashmap_iter iter;
struct strmap_entry *entry;
+ const char *last_key = NULL;
if (rinfo.negative_refexprs == 0)
die(_("all positive revisions given must be references"));
@@ -204,8 +210,11 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
/* Only one entry, but we have to loop to get it */
strset_for_each_entry(&rinfo.negative_refs,
&iter, entry) {
- *advance_name = entry->key;
+ last_key = entry->key;
}
+
+ free(*advance_name);
+ *advance_name = xstrdup_or_null(last_key);
} else { /* positive_refs_complete */
if (rinfo.negative_refexprs > 1)
die(_("cannot implicitly determine correct base for --onto"));
@@ -267,7 +276,8 @@ static struct commit *pick_regular_commit(struct commit *pickme,
int cmd_replay(int argc, const char **argv, const char *prefix)
{
- const char *advance_name = NULL;
+ const char *advance_name_opt = NULL;
+ char *advance_name = NULL;
struct commit *onto = NULL;
const char *onto_name = NULL;
int contained = 0;
@@ -288,7 +298,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
NULL
};
struct option replay_options[] = {
- OPT_STRING(0, "advance", &advance_name,
+ OPT_STRING(0, "advance", &advance_name_opt,
N_("branch"),
N_("make replay advance given branch")),
OPT_STRING(0, "onto", &onto_name,
@@ -302,14 +312,15 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, replay_options, replay_usage,
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
- if (!onto_name && !advance_name) {
+ if (!onto_name && !advance_name_opt) {
error(_("option --onto or --advance is mandatory"));
usage_with_options(replay_usage, replay_options);
}
- if (advance_name && contained)
+ if (advance_name_opt && contained)
die(_("options '%s' and '%s' cannot be used together"),
"--advance", "--contained");
+ advance_name = xstrdup_or_null(advance_name_opt);
repo_init_revisions(the_repository, &revs, prefix);
@@ -373,7 +384,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
goto cleanup;
}
- init_merge_options(&merge_opt, the_repository);
+ init_basic_merge_options(&merge_opt, the_repository);
memset(&result, 0, sizeof(result));
merge_opt.show_rename_progress = 0;
last_commit = onto;
@@ -437,6 +448,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
cleanup:
release_revisions(&revs);
+ free(advance_name);
/* Return */
if (ret < 0)
diff --git a/builtin/rerere.c b/builtin/rerere.c
index b2efc6f640..81b65ffa39 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -73,11 +73,17 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
if (!strcmp(argv[0], "forget")) {
struct pathspec pathspec;
+ int ret;
+
if (argc < 2)
warning(_("'git rerere forget' without paths is deprecated"));
parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD,
prefix, argv + 1);
- return rerere_forget(the_repository, &pathspec);
+
+ ret = rerere_forget(the_repository, &pathspec);
+
+ clear_pathspec(&pathspec);
+ return ret;
}
if (!strcmp(argv[0], "clear")) {
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 77803727e0..97d077a994 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -508,6 +508,8 @@ static int try_bitmap_disk_usage(struct rev_info *revs,
size_from_bitmap = get_disk_usage_from_bitmap(bitmap_git, revs);
print_disk_usage(size_from_bitmap);
+
+ free_bitmap_index(bitmap_git);
return 0;
}
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 1e2919fd81..5845d3f59b 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -423,12 +423,12 @@ static char *findspace(const char *s)
static int cmd_parseopt(int argc, const char **argv, const char *prefix)
{
- static int keep_dashdash = 0, stop_at_non_option = 0;
- static char const * const parseopt_usage[] = {
+ int keep_dashdash = 0, stop_at_non_option = 0;
+ char const * const parseopt_usage[] = {
N_("git rev-parse --parseopt [<options>] -- [<args>...]"),
NULL
};
- static struct option parseopt_opts[] = {
+ struct option parseopt_opts[] = {
OPT_BOOL(0, "keep-dashdash", &keep_dashdash,
N_("keep the `--` passed as an arg")),
OPT_BOOL(0, "stop-at-non-option", &stop_at_non_option,
@@ -438,12 +438,11 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
N_("output in stuck long form")),
OPT_END(),
};
- static const char * const flag_chars = "*=?!";
-
struct strbuf sb = STRBUF_INIT, parsed = STRBUF_INIT;
- const char **usage = NULL;
+ struct strvec longnames = STRVEC_INIT;
+ struct strvec usage = STRVEC_INIT;
struct option *opts = NULL;
- int onb = 0, osz = 0, unb = 0, usz = 0;
+ size_t opts_nr = 0, opts_alloc = 0;
strbuf_addstr(&parsed, "set --");
argc = parse_options(argc, argv, prefix, parseopt_opts, parseopt_usage,
@@ -453,16 +452,16 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
/* get the usage up to the first line with a -- on it */
for (;;) {
+ strbuf_reset(&sb);
if (strbuf_getline(&sb, stdin) == EOF)
die(_("premature end of input"));
- ALLOC_GROW(usage, unb + 1, usz);
if (!strcmp("--", sb.buf)) {
- if (unb < 1)
+ if (!usage.nr)
die(_("no usage string given before the `--' separator"));
- usage[unb] = NULL;
break;
}
- usage[unb++] = strbuf_detach(&sb, NULL);
+
+ strvec_push(&usage, sb.buf);
}
/* parse: (<short>|<short>,<long>|<long>)[*=?!]*<arghint>? SP+ <help> */
@@ -474,10 +473,10 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
if (!sb.len)
continue;
- ALLOC_GROW(opts, onb + 1, osz);
- memset(opts + onb, 0, sizeof(opts[onb]));
+ ALLOC_GROW(opts, opts_nr + 1, opts_alloc);
+ memset(opts + opts_nr, 0, sizeof(*opts));
- o = &opts[onb++];
+ o = &opts[opts_nr++];
help = findspace(sb.buf);
if (!help || sb.buf == help) {
o->type = OPTION_GROUP;
@@ -494,20 +493,22 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
o->callback = &parseopt_dump;
/* name(s) */
- s = strpbrk(sb.buf, flag_chars);
+ s = strpbrk(sb.buf, "*=?!");
if (!s)
s = help;
if (s == sb.buf)
die(_("missing opt-spec before option flags"));
- if (s - sb.buf == 1) /* short option only */
+ if (s - sb.buf == 1) { /* short option only */
o->short_name = *sb.buf;
- else if (sb.buf[1] != ',') /* long option only */
- o->long_name = xmemdupz(sb.buf, s - sb.buf);
- else {
+ } else if (sb.buf[1] != ',') { /* long option only */
+ o->long_name = strvec_pushf(&longnames, "%.*s",
+ (int)(s - sb.buf), sb.buf);
+ } else {
o->short_name = *sb.buf;
- o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2);
+ o->long_name = strvec_pushf(&longnames, "%.*s",
+ (int)(s - sb.buf - 2), sb.buf + 2);
}
/* flags */
@@ -537,9 +538,9 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
strbuf_release(&sb);
/* put an OPT_END() */
- ALLOC_GROW(opts, onb + 1, osz);
- memset(opts + onb, 0, sizeof(opts[onb]));
- argc = parse_options(argc, argv, prefix, opts, usage,
+ ALLOC_GROW(opts, opts_nr + 1, opts_alloc);
+ memset(opts + opts_nr, 0, sizeof(*opts));
+ argc = parse_options(argc, argv, prefix, opts, usage.v,
(keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0) |
(stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0) |
PARSE_OPT_SHELL_EVAL);
@@ -547,7 +548,16 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
strbuf_addstr(&parsed, " --");
sq_quote_argv(&parsed, argv);
puts(parsed.buf);
+
strbuf_release(&parsed);
+ strbuf_release(&sb);
+ strvec_clear(&longnames);
+ strvec_clear(&usage);
+ for (size_t i = 0; i < opts_nr; i++) {
+ free((char *) opts[i].help);
+ free((char *) opts[i].argh);
+ }
+ free(opts);
return 0;
}
@@ -1121,6 +1131,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!get_oid_with_context(the_repository, name,
flags, &oid, &unused)) {
+ object_context_release(&unused);
if (output_algo)
repo_oid_to_algop(the_repository, &oid,
output_algo, &oid);
@@ -1130,6 +1141,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
show_rev(type, &oid, name);
continue;
}
+ object_context_release(&unused);
if (verify)
die_no_single_rev(quiet);
if (has_dashdash)
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index d4daf31e22..b529608c92 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -460,11 +460,8 @@ parse_done:
else
get_from_rev(&rev, &log);
- release_revisions(&rev);
-
shortlog_output(&log);
- if (log.file != stdout)
- fclose(log.file);
+ release_revisions(&rev);
return 0;
}
@@ -517,4 +514,5 @@ void shortlog_output(struct shortlog *log)
string_list_clear(&log->list, 1);
clear_mailmap(&log->mailmap);
string_list_clear(&log->format, 0);
+ string_list_clear(&log->trailers, 0);
}
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index d72f4cb98d..7d797a880c 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -502,14 +502,14 @@ static int rev_is_head(const char *head, const char *name)
return !strcmp(head, name);
}
-static int show_merge_base(struct commit_list *seen, int num_rev)
+static int show_merge_base(const struct commit_list *seen, int num_rev)
{
int all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
int all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
int exit_status = 1;
- while (seen) {
- struct commit *commit = pop_commit(&seen);
+ for (const struct commit_list *s = seen; s; s = s->next) {
+ struct commit *commit = s->item;
int flags = commit->object.flags & all_mask;
if (!(flags & UNINTERESTING) &&
((flags & all_revs) == all_revs)) {
@@ -635,7 +635,7 @@ static int parse_reflog_param(const struct option *opt, const char *arg,
int cmd_show_branch(int ac, const char **av, const char *prefix)
{
struct commit *rev[MAX_REVS], *commit;
- char *reflog_msg[MAX_REVS];
+ char *reflog_msg[MAX_REVS] = {0};
struct commit_list *list = NULL, *seen = NULL;
unsigned int rev_mask[MAX_REVS];
int num_rev, i, extra = 0;
@@ -692,6 +692,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
parse_reflog_param),
OPT_END()
};
+ const char **args_copy = NULL;
+ int ret;
init_commit_name_slab(&name_slab);
@@ -699,8 +701,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
/* If nothing is specified, try the default first */
if (ac == 1 && default_args.nr) {
+ DUP_ARRAY(args_copy, default_args.v, default_args.nr);
ac = default_args.nr;
- av = default_args.v;
+ av = args_copy;
}
ac = parse_options(ac, av, prefix, builtin_show_branch_options,
@@ -780,7 +783,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
}
for (i = 0; i < reflog; i++) {
- char *logmsg;
+ char *logmsg = NULL;
char *nth_desc;
const char *msg;
char *end;
@@ -790,6 +793,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
if (read_ref_at(get_main_ref_store(the_repository),
ref, flags, 0, base + i, &oid, &logmsg,
&timestamp, &tz, NULL)) {
+ free(logmsg);
reflog = i;
break;
}
@@ -842,7 +846,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
if (!ref_name_cnt) {
fprintf(stderr, "No revs to be shown.\n");
- exit(0);
+ ret = 0;
+ goto out;
}
for (num_rev = 0; ref_name[num_rev]; num_rev++) {
@@ -879,11 +884,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
commit_list_sort_by_date(&seen);
- if (merge_base)
- return show_merge_base(seen, num_rev);
+ if (merge_base) {
+ ret = show_merge_base(seen, num_rev);
+ goto out;
+ }
- if (independent)
- return show_independent(rev, num_rev, rev_mask);
+ if (independent) {
+ ret = show_independent(rev, num_rev, rev_mask);
+ goto out;
+ }
/* Show list; --more=-1 means list-only */
if (1 < num_rev || extra < 0) {
@@ -919,8 +928,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
putchar('\n');
}
}
- if (extra < 0)
- exit(0);
+ if (extra < 0) {
+ ret = 0;
+ goto out;
+ }
/* Sort topologically */
sort_in_topological_order(&seen, sort_order);
@@ -932,8 +943,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
- while (seen) {
- struct commit *commit = pop_commit(&seen);
+ for (struct commit_list *l = seen; l; l = l->next) {
+ struct commit *commit = l->item;
int this_flag = commit->object.flags;
int is_merge_point = ((this_flag & all_revs) == all_revs);
@@ -973,6 +984,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
if (shown_merge_point && --extra < 0)
break;
}
+
+ ret = 0;
+
+out:
+ for (size_t i = 0; i < ARRAY_SIZE(reflog_msg); i++)
+ free(reflog_msg[i]);
+ free_commit_list(seen);
+ free_commit_list(list);
+ free(args_copy);
free(head);
- return 0;
+ return ret;
}
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 839a5c29f3..85700caae9 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -293,8 +293,8 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
struct show_one_options show_one_opts = {0};
int verify = 0, exists = 0;
const struct option show_ref_options[] = {
- OPT_BOOL(0, "tags", &patterns_opts.tags_only, N_("only show tags (can be combined with branches)")),
- OPT_BOOL(0, "branches", &patterns_opts.branches_only, N_("only show branches (can be combined with tags)")),
+ OPT_BOOL(0, "tags", &patterns_opts.tags_only, N_("only show tags (can be combined with --branches)")),
+ OPT_BOOL(0, "branches", &patterns_opts.branches_only, N_("only show branches (can be combined with --tags)")),
OPT_HIDDEN_BOOL(0, "heads", &patterns_opts.branches_only,
N_("deprecated synonym for --branches")),
OPT_BOOL(0, "exists", &exists, N_("check for reference existence without resolving")),
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 3f2bfce8fa..2604ab04df 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -1026,6 +1026,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *
ret = check_rules(&pl, check_rules_opts.null_termination);
clear_pattern_list(&pl);
+ free(check_rules_opts.rules_file);
return ret;
}
diff --git a/builtin/stash.c b/builtin/stash.c
index 7859bc0866..d90e072ddc 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -574,7 +574,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
}
}
- init_merge_options(&o, the_repository);
+ init_ui_merge_options(&o, the_repository);
o.branch1 = "Updated upstream";
o.branch2 = "Stashed changes";
@@ -975,7 +975,9 @@ static int show_stash(int argc, const char **argv, const char *prefix)
log_tree_diff_flush(&rev);
ret = diff_result_code(&rev.diffopt);
+
cleanup:
+ strvec_clear(&revision_args);
strvec_clear(&stash_args);
free_stash_info(&info);
release_revisions(&rev);
@@ -1018,13 +1020,14 @@ static int store_stash(int argc, const char **argv, const char *prefix)
int quiet = 0;
const char *stash_msg = NULL;
struct object_id obj;
- struct object_context dummy;
+ struct object_context dummy = {0};
struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet")),
OPT_STRING('m', "message", &stash_msg, "message",
N_("stash message")),
OPT_END()
};
+ int ret;
argc = parse_options(argc, argv, prefix, options,
git_stash_store_usage,
@@ -1043,10 +1046,15 @@ static int store_stash(int argc, const char **argv, const char *prefix)
if (!quiet)
fprintf_ln(stderr, _("Cannot update %s with %s"),
ref_stash, argv[0]);
- return -1;
+ ret = -1;
+ goto out;
}
- return do_store_stash(&obj, stash_msg, quiet);
+ ret = do_store_stash(&obj, stash_msg, quiet);
+
+out:
+ object_context_release(&dummy);
+ return ret;
}
static void add_pathspecs(struct strvec *args,
@@ -1408,6 +1416,9 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
goto done;
}
+ free_commit_list(parents);
+ parents = NULL;
+
if (include_untracked) {
if (save_untracked_files(info, &msg, untracked_files)) {
if (!quiet)
@@ -1453,11 +1464,6 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
else
strbuf_insertf(stash_msg_buf, 0, "On %s: ", branch_name);
- /*
- * `parents` will be empty after calling `commit_tree()`, so there is
- * no need to call `free_commit_list()`
- */
- parents = NULL;
if (untracked_commit_option)
commit_list_insert(lookup_commit(the_repository,
&info->u_commit),
@@ -1479,6 +1485,7 @@ done:
strbuf_release(&commit_tree_label);
strbuf_release(&msg);
strbuf_release(&untracked_files);
+ free_commit_list(parents);
return ret;
}
@@ -1514,6 +1521,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
struct strbuf patch = STRBUF_INIT;
struct strbuf stash_msg_buf = STRBUF_INIT;
struct strbuf untracked_files = STRBUF_INIT;
+ struct strbuf out = STRBUF_INIT;
if (patch_mode && keep_index == -1)
keep_index = 1;
@@ -1619,7 +1627,6 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
struct child_process cp_add = CHILD_PROCESS_INIT;
struct child_process cp_diff = CHILD_PROCESS_INIT;
struct child_process cp_apply = CHILD_PROCESS_INIT;
- struct strbuf out = STRBUF_INIT;
cp_add.git_cmd = 1;
strvec_push(&cp_add.args, "add");
@@ -1711,6 +1718,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
done:
strbuf_release(&patch);
+ strbuf_release(&out);
free_stash_info(&info);
strbuf_release(&stash_msg_buf);
strbuf_release(&untracked_files);
@@ -1862,6 +1870,8 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
OPT_SUBCOMMAND_F("save", &fn, save_stash, PARSE_OPT_NOCOMPLETE),
OPT_END()
};
+ const char **args_copy;
+ int ret;
git_config(git_stash_config, NULL);
@@ -1885,5 +1895,16 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
/* Assume 'stash push' */
strvec_push(&args, "push");
strvec_pushv(&args, argv);
- return !!push_stash(args.nr, args.v, prefix, 1);
+
+ /*
+ * `push_stash()` ends up modifying the array, which causes memory
+ * leaks if we didn't copy the array here.
+ */
+ DUP_ARRAY(args_copy, args.v, args.nr);
+
+ ret = !!push_stash(args.nr, args_copy, prefix, 1);
+
+ strvec_clear(&args);
+ free(args_copy);
+ return ret;
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 880ab4456e..673810d2c0 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -376,8 +376,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
NULL);
- strvec_pushl(&cpr.args, "--super-prefix", NULL);
- strvec_pushf(&cpr.args, "%s/", displaypath);
+ strvec_pushf(&cpr.args, "--super-prefix=%s/", displaypath);
if (info->quiet)
strvec_push(&cpr.args, "--quiet");
@@ -702,8 +701,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
strvec_pushl(&cpr.args, "submodule--helper", "status",
"--recursive", NULL);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
+ strvec_pushf(&cpr.args, "--super-prefix=%s/", displaypath);
if (flags & OPT_CACHED)
strvec_push(&cpr.args, "--cached");
@@ -1304,9 +1302,7 @@ static void sync_submodule(const char *path, const char *prefix,
strvec_pushl(&cpr.args, "submodule--helper", "sync",
"--recursive", NULL);
- strvec_push(&cpr.args, "--super-prefix");
- strvec_pushf(&cpr.args, "%s/", displaypath);
-
+ strvec_pushf(&cpr.args, "--super-prefix=%s/", displaypath);
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
@@ -1534,7 +1530,7 @@ struct module_clone_data {
const char *path;
const char *name;
const char *url;
- const char *depth;
+ int depth;
struct list_objects_filter_options *filter_options;
unsigned int quiet: 1;
unsigned int progress: 1;
@@ -1733,8 +1729,8 @@ static int clone_submodule(const struct module_clone_data *clone_data,
strvec_push(&cp.args, "--quiet");
if (clone_data->progress)
strvec_push(&cp.args, "--progress");
- if (clone_data->depth && *(clone_data->depth))
- strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
+ if (clone_data->depth > 0)
+ strvec_pushf(&cp.args, "--depth=%d", clone_data->depth);
if (reference->nr) {
struct string_list_item *item;
@@ -1855,8 +1851,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
N_("reference repository")),
OPT_BOOL(0, "dissociate", &dissociate,
N_("use --reference only while cloning")),
- OPT_STRING(0, "depth", &clone_data.depth,
- N_("string"),
+ OPT_INTEGER(0, "depth", &clone_data.depth,
N_("depth for shallow clones")),
OPT__QUIET(&quiet, "suppress output for cloning a submodule"),
OPT_BOOL(0, "progress", &progress,
@@ -2273,6 +2268,7 @@ static int is_tip_reachable(const char *path, const struct object_id *oid)
struct child_process cp = CHILD_PROCESS_INIT;
struct strbuf rev = STRBUF_INIT;
char *hex = oid_to_hex(oid);
+ int reachable;
cp.git_cmd = 1;
cp.dir = path;
@@ -2282,9 +2278,12 @@ static int is_tip_reachable(const char *path, const struct object_id *oid)
prepare_submodule_repo_env(&cp.env);
if (capture_command(&cp, &rev, GIT_MAX_HEXSZ + 1) || rev.len)
- return 0;
+ reachable = 0;
+ else
+ reachable = 1;
- return 1;
+ strbuf_release(&rev);
+ return reachable;
}
static int fetch_in_submodule(const char *module_path, int depth, int quiet,
@@ -2534,10 +2533,9 @@ static void update_data_to_args(const struct update_data *update_data,
enum submodule_update_type update_type = update_data->update_default;
strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
- if (update_data->displaypath) {
- strvec_push(args, "--super-prefix");
- strvec_pushf(args, "%s/", update_data->displaypath);
- }
+ if (update_data->displaypath)
+ strvec_pushf(args, "--super-prefix=%s/",
+ update_data->displaypath);
strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
if (update_data->quiet)
strvec_push(args, "--quiet");
@@ -3205,7 +3203,7 @@ static int add_submodule(const struct add_data *add_data)
}
clone_data.dissociate = add_data->dissociate;
if (add_data->depth >= 0)
- clone_data.depth = xstrfmt("%d", add_data->depth);
+ clone_data.depth = add_data->depth;
if (clone_submodule(&clone_data, &reference))
goto cleanup;
@@ -3228,6 +3226,7 @@ static int add_submodule(const struct add_data *add_data)
die(_("unable to checkout submodule '%s'"), add_data->sm_path);
}
ret = 0;
+
cleanup:
string_list_clear(&reference, 1);
return ret;
diff --git a/builtin/var.c b/builtin/var.c
index 5dc384810c..e30ff45be1 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -12,6 +12,7 @@
#include "refs.h"
#include "path.h"
#include "strbuf.h"
+#include "run-command.h"
static const char var_usage[] = "git var (-l | <variable>)";
@@ -51,7 +52,7 @@ static char *default_branch(int ident_flag UNUSED)
static char *shell_path(int ident_flag UNUSED)
{
- return xstrdup(SHELL_PATH);
+ return git_shell_path();
}
static char *git_attr_val_system(int ident_flag UNUSED)
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 1d51e54fcd..cec3ada6b0 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -769,7 +769,7 @@ static int add(int ac, const char **av, const char *prefix)
char *branch_to_free = NULL;
char *new_branch_to_free = NULL;
const char *new_branch = NULL;
- const char *opt_track = NULL;
+ char *opt_track = NULL;
const char *lock_reason = NULL;
int keep_locked = 0;
int used_new_branch_options;
@@ -846,7 +846,7 @@ static int add(int ac, const char **av, const char *prefix)
if (opts.orphan && !new_branch) {
int n;
const char *s = worktree_basename(path, &n);
- new_branch = xstrndup(s, n);
+ new_branch = new_branch_to_free = xstrndup(s, n);
} else if (opts.orphan) {
; /* no-op */
} else if (opts.detach) {
@@ -875,7 +875,7 @@ static int add(int ac, const char **av, const char *prefix)
remote = unique_tracking_name(branch, &oid, NULL);
if (remote) {
new_branch = branch;
- branch = remote;
+ branch = new_branch_to_free = remote;
}
}
@@ -923,6 +923,7 @@ static int add(int ac, const char **av, const char *prefix)
ret = add_worktree(path, branch, &opts);
free(path);
+ free(opt_track);
free(branch_to_free);
free(new_branch_to_free);
return ret;
diff --git a/bundle-uri.c b/bundle-uri.c
index 804fbcfbfa..1e0ee156ba 100644
--- a/bundle-uri.c
+++ b/bundle-uri.c
@@ -11,6 +11,7 @@
#include "hashmap.h"
#include "pkt-line.h"
#include "config.h"
+#include "fetch-pack.h"
#include "remote.h"
static struct {
@@ -375,7 +376,7 @@ static int unbundle_from_file(struct repository *r, const char *file)
* the prerequisite commits.
*/
if ((result = unbundle(r, &header, bundle_fd, NULL,
- VERIFY_BUNDLE_QUIET)))
+ VERIFY_BUNDLE_QUIET | (fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0))))
return 1;
/*
@@ -402,8 +403,7 @@ static int unbundle_from_file(struct repository *r, const char *file)
refs_update_ref(get_main_ref_store(the_repository),
"fetched bundle", bundle_ref.buf, oid,
has_old ? &old_oid : NULL,
- REF_SKIP_OID_VERIFICATION,
- UPDATE_REFS_MSG_ON_ERR);
+ 0, UPDATE_REFS_MSG_ON_ERR);
}
bundle_header_release(&header);
diff --git a/bundle.c b/bundle.c
index 82c285b905..ce164c37bc 100644
--- a/bundle.c
+++ b/bundle.c
@@ -502,6 +502,7 @@ int create_bundle(struct repository *r, const char *path,
struct rev_info revs, revs_copy;
int min_version = 2;
struct bundle_prerequisites_info bpi;
+ int ret;
int i;
/* init revs to list objects for pack-objects later */
@@ -527,8 +528,8 @@ int create_bundle(struct repository *r, const char *path,
min_version = 3;
if (argc > 1) {
- error(_("unrecognized argument: %s"), argv[1]);
- goto err;
+ ret = error(_("unrecognized argument: %s"), argv[1]);
+ goto out;
}
bundle_to_stdout = !strcmp(path, "-");
@@ -593,23 +594,31 @@ int create_bundle(struct repository *r, const char *path,
/* write bundle refs */
ref_count = write_bundle_refs(bundle_fd, &revs_copy);
- if (!ref_count)
+ if (!ref_count) {
die(_("Refusing to create empty bundle."));
- else if (ref_count < 0)
- goto err;
+ } else if (ref_count < 0) {
+ ret = -1;
+ goto out;
+ }
/* write pack */
- if (write_pack_data(bundle_fd, &revs_copy, pack_options))
- goto err;
+ if (write_pack_data(bundle_fd, &revs_copy, pack_options)) {
+ ret = -1;
+ goto out;
+ }
if (!bundle_to_stdout) {
if (commit_lock_file(&lock))
die_errno(_("cannot create '%s'"), path);
}
- return 0;
-err:
+
+ ret = 0;
+
+out:
+ object_array_clear(&revs_copy.pending);
+ release_revisions(&revs);
rollback_lock_file(&lock);
- return -1;
+ return ret;
}
int unbundle(struct repository *r, struct bundle_header *header,
@@ -627,6 +636,9 @@ int unbundle(struct repository *r, struct bundle_header *header,
if (header->filter.choice)
strvec_push(&ip.args, "--promisor=from-bundle");
+ if (flags & VERIFY_BUNDLE_FSCK)
+ strvec_push(&ip.args, "--fsck-objects");
+
if (extra_index_pack_args) {
strvec_pushv(&ip.args, extra_index_pack_args->v);
strvec_clear(extra_index_pack_args);
diff --git a/bundle.h b/bundle.h
index 021adbdcbb..5ccc9a061a 100644
--- a/bundle.h
+++ b/bundle.h
@@ -33,6 +33,7 @@ int create_bundle(struct repository *r, const char *path,
enum verify_bundle_flags {
VERIFY_BUNDLE_VERBOSE = (1 << 0),
VERIFY_BUNDLE_QUIET = (1 << 1),
+ VERIFY_BUNDLE_FSCK = (1 << 2),
};
int verify_bundle(struct repository *r, struct bundle_header *header,
diff --git a/ci/check-directional-formatting.bash b/ci/check-directional-formatting.bash
index e6211b141a..3cbbb7030e 100755
--- a/ci/check-directional-formatting.bash
+++ b/ci/check-directional-formatting.bash
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
# This script verifies that the non-binary files tracked in the Git index do
# not contain any Unicode directional formatting: such formatting could be used
diff --git a/ci/check-whitespace.sh b/ci/check-whitespace.sh
index db399097a5..c40804394c 100755
--- a/ci/check-whitespace.sh
+++ b/ci/check-whitespace.sh
@@ -9,7 +9,7 @@ baseCommit=$1
outputFile=$2
url=$3
-if test "$#" -ne 1 && test "$#" -ne 3
+if test "$#" -ne 1 && test "$#" -ne 3 || test -z "$1"
then
echo "USAGE: $0 <BASE_COMMIT> [<OUTPUT_FILE> <URL>]"
exit 1
@@ -21,6 +21,12 @@ commitText=
commitTextmd=
goodParent=
+if ! git rev-parse --quiet --verify "${baseCommit}"
+then
+ echo "Invalid <BASE_COMMIT> '${baseCommit}'"
+ exit 1
+fi
+
while read dash sha etc
do
case "${dash}" in
@@ -67,7 +73,7 @@ then
goodParent=${baseCommit: 0:7}
fi
- echo "A whitespace issue was found in onen of more of the commits."
+ echo "A whitespace issue was found in one or more of the commits."
echo "Run the following command to resolve whitespace issues:"
echo "git rebase --whitespace=fix ${goodParent}"
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 6ec0f85972..4781cd20bb 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -7,7 +7,7 @@
begin_group "Install dependencies"
-P4WHENCE=https://cdist2.perforce.com/perforce/r21.2
+P4WHENCE=https://cdist2.perforce.com/perforce/r23.2
LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
JGITWHENCE=https://repo.eclipse.org/content/groups/releases//org/eclipse/jgit/org.eclipse.jgit.pgm/6.8.0.202311291450-r/org.eclipse.jgit.pgm-6.8.0.202311291450-r.sh
@@ -87,6 +87,10 @@ macos-*)
esac
case "$jobname" in
+ClangFormat)
+ sudo apt-get -q update
+ sudo apt-get -q -y install clang-format
+ ;;
StaticAnalysis)
sudo apt-get -q update
sudo apt-get -q -y install coccinelle libcurl4-openssl-dev libssl-dev \
diff --git a/ci/lib.sh b/ci/lib.sh
index 814578ffc6..51f8f59a29 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -370,7 +370,6 @@ linux-musl)
linux-leaks|linux-reftable-leaks)
export SANITIZE=leak
export GIT_TEST_PASSING_SANITIZE_LEAK=true
- export GIT_TEST_SANITIZE_LEAK_LOG=true
;;
linux-asan-ubsan)
export SANITIZE=address,undefined
diff --git a/ci/run-style-check.sh b/ci/run-style-check.sh
new file mode 100755
index 0000000000..6cd4b1d934
--- /dev/null
+++ b/ci/run-style-check.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Perform style check
+#
+
+baseCommit=$1
+
+# Remove optional braces of control statements (if, else, for, and while)
+# according to the LLVM coding style. This avoids braces on simple
+# single-statement bodies of statements but keeps braces if one side of
+# if/else if/.../else cascade has multi-statement body.
+#
+# As this rule comes with a warning [1], we want to experiment with it
+# before adding it in-tree. since the CI job for the style check is allowed
+# to fail, appending the rule here allows us to validate its efficacy.
+# While also ensuring that end-users are not affected directly.
+#
+# [1]: https://clang.llvm.org/docs/ClangFormatStyleOptions.html#removebracesllvm
+{
+ cat .clang-format
+ echo "RemoveBracesLLVM: true"
+} >/tmp/clang-format-rules
+
+git clang-format --style=file:/tmp/clang-format-rules \
+ --diff --extensions c,h "$baseCommit"
diff --git a/commit-graph.c b/commit-graph.c
index 93c075552a..79b0e72cc4 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -346,7 +346,6 @@ static int graph_read_bloom_data(const unsigned char *chunk_start,
size_t chunk_size, void *data)
{
struct commit_graph *g = data;
- uint32_t hash_version;
if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE) {
warning(_("ignoring too-small changed-path chunk"
@@ -358,13 +357,9 @@ static int graph_read_bloom_data(const unsigned char *chunk_start,
g->chunk_bloom_data = chunk_start;
g->chunk_bloom_data_size = chunk_size;
- hash_version = get_be32(chunk_start);
-
- if (hash_version != 1)
- return 0;
g->bloom_filter_settings = xmalloc(sizeof(struct bloom_filter_settings));
- g->bloom_filter_settings->hash_version = hash_version;
+ g->bloom_filter_settings->hash_version = get_be32(chunk_start);
g->bloom_filter_settings->num_hashes = get_be32(chunk_start + 4);
g->bloom_filter_settings->bits_per_entry = get_be32(chunk_start + 8);
g->bloom_filter_settings->max_changed_paths = DEFAULT_BLOOM_MAX_CHANGES;
@@ -461,7 +456,7 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
graph->read_generation_data = 1;
}
- if (s->commit_graph_read_changed_paths) {
+ if (s->commit_graph_changed_paths_version) {
read_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
graph_read_bloom_index, graph);
read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
@@ -546,6 +541,31 @@ static int validate_mixed_generation_chain(struct commit_graph *g)
return 0;
}
+static void validate_mixed_bloom_settings(struct commit_graph *g)
+{
+ struct bloom_filter_settings *settings = NULL;
+ for (; g; g = g->base_graph) {
+ if (!g->bloom_filter_settings)
+ continue;
+ if (!settings) {
+ settings = g->bloom_filter_settings;
+ continue;
+ }
+
+ if (g->bloom_filter_settings->bits_per_entry != settings->bits_per_entry ||
+ g->bloom_filter_settings->num_hashes != settings->num_hashes ||
+ g->bloom_filter_settings->hash_version != settings->hash_version) {
+ g->chunk_bloom_indexes = NULL;
+ g->chunk_bloom_data = NULL;
+ FREE_AND_NULL(g->bloom_filter_settings);
+
+ warning(_("disabling Bloom filters for commit-graph "
+ "layer '%s' due to incompatible settings"),
+ oid_to_hex(&g->oid));
+ }
+ }
+}
+
static int add_graph_to_chain(struct commit_graph *g,
struct commit_graph *chain,
struct object_id *oids,
@@ -670,6 +690,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
}
validate_mixed_generation_chain(graph_chain);
+ validate_mixed_bloom_settings(graph_chain);
free(oids);
fclose(fp);
@@ -814,6 +835,7 @@ void close_commit_graph(struct raw_object_store *o)
return;
clear_commit_graph_data_slab(&commit_graph_data_slab);
+ deinit_bloom_filters();
free_commit_graph(o->commit_graph);
o->commit_graph = NULL;
}
@@ -1152,6 +1174,7 @@ struct write_commit_graph_context {
int count_bloom_filter_not_computed;
int count_bloom_filter_trunc_empty;
int count_bloom_filter_trunc_large;
+ int count_bloom_filter_upgraded;
};
static int write_graph_chunk_fanout(struct hashfile *f,
@@ -1759,6 +1782,8 @@ static void trace2_bloom_filter_write_statistics(struct write_commit_graph_conte
ctx->count_bloom_filter_trunc_empty);
trace2_data_intmax("commit-graph", ctx->r, "filter-trunc-large",
ctx->count_bloom_filter_trunc_large);
+ trace2_data_intmax("commit-graph", ctx->r, "filter-upgraded",
+ ctx->count_bloom_filter_upgraded);
}
static void compute_bloom_filters(struct write_commit_graph_context *ctx)
@@ -1800,6 +1825,8 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
ctx->count_bloom_filter_trunc_empty++;
if (computed & BLOOM_TRUNC_LARGE)
ctx->count_bloom_filter_trunc_large++;
+ } else if (computed & BLOOM_UPGRADED) {
+ ctx->count_bloom_filter_upgraded++;
} else if (computed & BLOOM_NOT_COMPUTED)
ctx->count_bloom_filter_not_computed++;
ctx->total_bloom_filter_data_size += filter
@@ -2481,6 +2508,13 @@ int write_commit_graph(struct object_directory *odb,
}
if (!commit_graph_compatible(r))
return 0;
+ if (r->settings.commit_graph_changed_paths_version < -1
+ || r->settings.commit_graph_changed_paths_version > 2) {
+ warning(_("attempting to write a commit-graph, but "
+ "'commitGraph.changedPathsVersion' (%d) is not supported"),
+ r->settings.commit_graph_changed_paths_version);
+ return 0;
+ }
CALLOC_ARRAY(ctx, 1);
ctx->r = r;
@@ -2493,6 +2527,7 @@ int write_commit_graph(struct object_directory *odb,
ctx->write_generation_data = (get_configured_generation_version(r) == 2);
ctx->num_generation_data_overflows = 0;
+ bloom_settings.hash_version = r->settings.commit_graph_changed_paths_version;
bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY",
bloom_settings.bits_per_entry);
bloom_settings.num_hashes = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_NUM_HASHES",
@@ -2522,12 +2557,20 @@ int write_commit_graph(struct object_directory *odb,
g = ctx->r->objects->commit_graph;
/* We have changed-paths already. Keep them in the next graph */
- if (g && g->chunk_bloom_data) {
+ if (g && g->bloom_filter_settings) {
ctx->changed_paths = 1;
- ctx->bloom_settings = g->bloom_filter_settings;
+
+ /* don't propagate the hash_version unless unspecified */
+ if (bloom_settings.hash_version == -1)
+ bloom_settings.hash_version = g->bloom_filter_settings->hash_version;
+ bloom_settings.bits_per_entry = g->bloom_filter_settings->bits_per_entry;
+ bloom_settings.num_hashes = g->bloom_filter_settings->num_hashes;
+ bloom_settings.max_changed_paths = g->bloom_filter_settings->max_changed_paths;
}
}
+ bloom_settings.hash_version = bloom_settings.hash_version == 2 ? 2 : 1;
+
if (ctx->split) {
struct commit_graph *g = ctx->r->objects->commit_graph;
@@ -2611,6 +2654,9 @@ int write_commit_graph(struct object_directory *odb,
res = write_commit_graph_file(ctx);
+ if (ctx->changed_paths)
+ deinit_bloom_filters();
+
if (ctx->split)
mark_commit_graphs(ctx);
diff --git a/commit-reach.c b/commit-reach.c
index dabc2972e4..02f8218b8e 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -1227,4 +1227,5 @@ void tips_reachable_from_bases(struct repository *r,
done:
free(commits);
repo_clear_commit_marks(r, SEEN);
+ free_commit_list(stack);
}
diff --git a/commit.c b/commit.c
index 45ec3f1183..087cb19f4f 100644
--- a/commit.c
+++ b/commit.c
@@ -682,7 +682,7 @@ unsigned commit_list_count(const struct commit_list *l)
return c;
}
-struct commit_list *copy_commit_list(struct commit_list *list)
+struct commit_list *copy_commit_list(const struct commit_list *list)
{
struct commit_list *head = NULL;
struct commit_list **pp = &head;
@@ -1264,7 +1264,7 @@ int remove_signature(struct strbuf *buf)
return sigs[0].start != NULL;
}
-static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
+static void handle_signed_tag(const struct commit *parent, struct commit_extra_header ***tail)
{
struct merge_remote_desc *desc;
struct commit_extra_header *mergetag;
@@ -1361,17 +1361,17 @@ void verify_merge_signature(struct commit *commit, int verbosity,
signature_check_clear(&signature_check);
}
-void append_merge_tag_headers(struct commit_list *parents,
+void append_merge_tag_headers(const struct commit_list *parents,
struct commit_extra_header ***tail)
{
while (parents) {
- struct commit *parent = parents->item;
+ const struct commit *parent = parents->item;
handle_signed_tag(parent, tail);
parents = parents->next;
}
}
-static int convert_commit_extra_headers(struct commit_extra_header *orig,
+static int convert_commit_extra_headers(const struct commit_extra_header *orig,
struct commit_extra_header **result)
{
const struct git_hash_algo *compat = the_repository->compat_hash_algo;
@@ -1405,7 +1405,7 @@ static int convert_commit_extra_headers(struct commit_extra_header *orig,
}
static void add_extra_header(struct strbuf *buffer,
- struct commit_extra_header *extra)
+ const struct commit_extra_header *extra)
{
strbuf_addstr(buffer, extra->key);
if (extra->len)
@@ -1519,7 +1519,7 @@ void free_commit_extra_headers(struct commit_extra_header *extra)
}
int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree,
- struct commit_list *parents, struct object_id *ret,
+ const struct commit_list *parents, struct object_id *ret,
const char *author, const char *sign_commit)
{
struct commit_extra_header *extra = NULL, **tail = &extra;
@@ -1651,7 +1651,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg
const struct object_id *tree,
const struct object_id *parents, size_t parents_len,
const char *author, const char *committer,
- struct commit_extra_header *extra)
+ const struct commit_extra_header *extra)
{
int encoding_is_utf8;
size_t i;
@@ -1692,10 +1692,10 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg
int commit_tree_extended(const char *msg, size_t msg_len,
const struct object_id *tree,
- struct commit_list *parents, struct object_id *ret,
+ const struct commit_list *parents, struct object_id *ret,
const char *author, const char *committer,
const char *sign_commit,
- struct commit_extra_header *extra)
+ const struct commit_extra_header *extra)
{
struct repository *r = the_repository;
int result = 0;
@@ -1717,10 +1717,8 @@ int commit_tree_extended(const char *msg, size_t msg_len,
nparents = commit_list_count(parents);
CALLOC_ARRAY(parent_buf, nparents);
i = 0;
- while (parents) {
- struct commit *parent = pop_commit(&parents);
- oidcpy(&parent_buf[i++], &parent->object.oid);
- }
+ for (const struct commit_list *p = parents; p; p = p->next)
+ oidcpy(&parent_buf[i++], &p->item->object.oid);
write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra);
if (sign_commit && sign_commit_to_strbuf(&sig, &buffer, sign_commit)) {
@@ -1816,7 +1814,7 @@ out:
define_commit_slab(merge_desc_slab, struct merge_remote_desc *);
static struct merge_desc_slab merge_desc_slab = COMMIT_SLAB_INIT(1, merge_desc_slab);
-struct merge_remote_desc *merge_remote_util(struct commit *commit)
+struct merge_remote_desc *merge_remote_util(const struct commit *commit)
{
return *merge_desc_slab_at(&merge_desc_slab, commit);
}
diff --git a/commit.h b/commit.h
index 3084f591fd..d62b1d93f9 100644
--- a/commit.h
+++ b/commit.h
@@ -181,7 +181,7 @@ struct commit_list *commit_list_insert_by_date(struct commit *item,
void commit_list_sort_by_date(struct commit_list **list);
/* Shallow copy of the input list */
-struct commit_list *copy_commit_list(struct commit_list *list);
+struct commit_list *copy_commit_list(const struct commit_list *list);
/* Modify list in-place to reverse it, returning new head; list will be tail */
struct commit_list *reverse_commit_list(struct commit_list *list);
@@ -260,19 +260,19 @@ struct commit_extra_header {
size_t len;
};
-void append_merge_tag_headers(struct commit_list *parents,
+void append_merge_tag_headers(const struct commit_list *parents,
struct commit_extra_header ***tail);
int commit_tree(const char *msg, size_t msg_len,
const struct object_id *tree,
- struct commit_list *parents, struct object_id *ret,
+ const struct commit_list *parents, struct object_id *ret,
const char *author, const char *sign_commit);
int commit_tree_extended(const char *msg, size_t msg_len,
const struct object_id *tree,
- struct commit_list *parents, struct object_id *ret,
+ const struct commit_list *parents, struct object_id *ret,
const char *author, const char *committer,
- const char *sign_commit, struct commit_extra_header *);
+ const char *sign_commit, const struct commit_extra_header *);
struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **);
@@ -301,7 +301,7 @@ struct merge_remote_desc {
struct object *obj; /* the named object, could be a tag */
char name[FLEX_ARRAY];
};
-struct merge_remote_desc *merge_remote_util(struct commit *);
+struct merge_remote_desc *merge_remote_util(const struct commit *);
void set_merge_remote_desc(struct commit *commit,
const char *name, struct object *obj);
diff --git a/compat/mingw.c b/compat/mingw.c
index 6097b8f9e6..29d3f09768 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1546,7 +1546,7 @@ static int is_msys2_sh(const char *cmd)
return ret;
}
- if (ends_with(cmd, "\\sh.exe")) {
+ if (ends_with(cmd, "\\sh.exe") || ends_with(cmd, "/sh.exe")) {
static char *sh;
if (!sh)
diff --git a/compat/win32/path-utils.c b/compat/win32/path-utils.c
index ebf2f12eb6..b658ca3f81 100644
--- a/compat/win32/path-utils.c
+++ b/compat/win32/path-utils.c
@@ -1,4 +1,5 @@
#include "../../git-compat-util.h"
+#include "../../environment.h"
int win32_has_dos_drive_prefix(const char *path)
{
@@ -50,3 +51,39 @@ int win32_offset_1st_component(const char *path)
return pos + is_dir_sep(*pos) - path;
}
+
+int win32_fspathncmp(const char *a, const char *b, size_t count)
+{
+ int diff;
+
+ for (;;) {
+ if (!count--)
+ return 0;
+ if (!*a)
+ return *b ? -1 : 0;
+ if (!*b)
+ return +1;
+
+ if (is_dir_sep(*a)) {
+ if (!is_dir_sep(*b))
+ return -1;
+ a++;
+ b++;
+ continue;
+ } else if (is_dir_sep(*b))
+ return +1;
+
+ diff = ignore_case ?
+ (unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
+ (unsigned char)*a - (int)(unsigned char)*b;
+ if (diff)
+ return diff;
+ a++;
+ b++;
+ }
+}
+
+int win32_fspathcmp(const char *a, const char *b)
+{
+ return win32_fspathncmp(a, b, (size_t)-1);
+}
diff --git a/compat/win32/path-utils.h b/compat/win32/path-utils.h
index 65fa3b9263..a561c700e7 100644
--- a/compat/win32/path-utils.h
+++ b/compat/win32/path-utils.h
@@ -29,5 +29,9 @@ static inline int win32_has_dir_sep(const char *path)
#define has_dir_sep(path) win32_has_dir_sep(path)
int win32_offset_1st_component(const char *path);
#define offset_1st_component win32_offset_1st_component
+int win32_fspathcmp(const char *a, const char *b);
+#define fspathcmp win32_fspathcmp
+int win32_fspathncmp(const char *a, const char *b, size_t count);
+#define fspathncmp win32_fspathncmp
#endif
diff --git a/config.c b/config.c
index 83bef0e5db..05f369ec0d 100644
--- a/config.c
+++ b/config.c
@@ -1577,6 +1577,7 @@ static int git_default_core_config(const char *var, const char *value,
if (!strcmp(var, "core.notesref")) {
if (!value)
return config_error_nonbool(var);
+ free(notes_ref_name);
notes_ref_name = xstrdup(value);
return 0;
}
@@ -2913,7 +2914,7 @@ static int matches(const char *key, const char *value,
{
if (strcmp(key, store->key))
return 0; /* not ours */
- if (store->fixed_value)
+ if (store->fixed_value && value)
return !strcmp(store->fixed_value, value);
if (!store->value_pattern)
return 1; /* always matches */
diff --git a/config.mak.dev b/config.mak.dev
index 1ce4c70613..5229c35484 100644
--- a/config.mak.dev
+++ b/config.mak.dev
@@ -10,7 +10,7 @@ endif
DEVELOPER_CFLAGS += -Wall
ifeq ($(filter no-pedantic,$(DEVOPTS)),)
DEVELOPER_CFLAGS += -pedantic
-ifneq (($or $(filter gcc5,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),)
+ifneq ($(or $(filter gcc5,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),)
DEVELOPER_CFLAGS += -Wpedantic
ifneq ($(filter gcc10,$(COMPILER_FEATURES)),)
ifeq ($(uname_S),MINGW)
diff --git a/config.mak.uname b/config.mak.uname
index 85d63821ec..aa0fd26bd5 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -8,7 +8,6 @@ uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
-uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
ifneq ($(findstring MINGW,$(uname_S)),)
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 2f9c33585c..832f46b316 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -976,11 +976,12 @@ list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
#unit-tests
add_library(unit-test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c)
+add_library(unit-test-lib-oid OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/lib-oid.c)
parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "")
foreach(unit_test ${unit_test_PROGRAMS})
add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c")
- target_link_libraries("${unit_test}" unit-test-lib common-main)
+ target_link_libraries("${unit_test}" unit-test-lib unit-test-lib-oid common-main)
set_target_properties("${unit_test}"
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin)
if(MSVC)
diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
index 6ce22a28ed..1c8310d7fe 100644
--- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c
+++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
@@ -141,7 +141,7 @@ static void find_username_in_item(CFDictionaryRef item)
username_buf,
buffer_len,
ENCODING)) {
- write_item("username", username_buf, buffer_len - 1);
+ write_item("username", username_buf, strlen(username_buf));
}
free(username_buf);
}
diff --git a/convert.c b/convert.c
index d8737fe0f2..e6184d21f2 100644
--- a/convert.c
+++ b/convert.c
@@ -324,6 +324,9 @@ static void trace_encoding(const char *context, const char *path,
struct strbuf trace = STRBUF_INIT;
int i;
+ if (!trace_want(&coe))
+ return;
+
strbuf_addf(&trace, "%s (%s, considered %s):\n", context, path, encoding);
for (i = 0; i < len && buf; ++i) {
strbuf_addf(
@@ -960,7 +963,7 @@ int async_query_available_blobs(const char *cmd, struct string_list *available_p
while ((line = packet_read_line(process->out, NULL))) {
const char *path;
if (skip_prefix(line, "pathname=", &path))
- string_list_insert(available_paths, xstrdup(path));
+ string_list_insert(available_paths, path);
else
; /* ignore unknown keys */
}
@@ -1050,14 +1053,20 @@ static int read_convert_config(const char *var, const char *value,
* The command-line will not be interpolated in any way.
*/
- if (!strcmp("smudge", key))
+ if (!strcmp("smudge", key)) {
+ FREE_AND_NULL(drv->smudge);
return git_config_string(&drv->smudge, var, value);
+ }
- if (!strcmp("clean", key))
+ if (!strcmp("clean", key)) {
+ FREE_AND_NULL(drv->clean);
return git_config_string(&drv->clean, var, value);
+ }
- if (!strcmp("process", key))
+ if (!strcmp("process", key)) {
+ FREE_AND_NULL(drv->process);
return git_config_string(&drv->process, var, value);
+ }
if (!strcmp("required", key)) {
drv->required = git_config_bool(var, value);
diff --git a/csum-file.c b/csum-file.c
index 8abbf01325..2131ee6b12 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -102,6 +102,15 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result,
return fd;
}
+void discard_hashfile(struct hashfile *f)
+{
+ if (0 <= f->check_fd)
+ close(f->check_fd);
+ if (0 <= f->fd)
+ close(f->fd);
+ free_hashfile(f);
+}
+
void hashwrite(struct hashfile *f, const void *buf, unsigned int count)
{
while (count) {
diff --git a/csum-file.h b/csum-file.h
index 566e05cbd2..36c7c5585f 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -47,6 +47,7 @@ struct hashfile *hashfd(int fd, const char *name);
struct hashfile *hashfd_check(const char *name);
struct hashfile *hashfd_throughput(int fd, const char *name, struct progress *tp);
int finalize_hashfile(struct hashfile *, unsigned char *, enum fsync_component, unsigned int);
+void discard_hashfile(struct hashfile *);
void hashwrite(struct hashfile *, const void *, unsigned int);
void hashflush(struct hashfile *f);
void crc32_begin(struct hashfile *);
diff --git a/date.c b/date.c
index 7365a4ad24..bee9fe8f10 100644
--- a/date.c
+++ b/date.c
@@ -868,6 +868,10 @@ static int match_object_header_date(const char *date, timestamp_t *timestamp, in
return 0;
}
+
+/* timestamp of 2099-12-31T23:59:59Z, including 32 leap days */
+static const timestamp_t timestamp_max = (((timestamp_t)2100 - 1970) * 365 + 32) * 24 * 60 * 60 - 1;
+
/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
(i.e. English) day/month names, and it doesn't work correctly with %z. */
int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset)
@@ -937,8 +941,14 @@ int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset)
}
}
- if (!tm_gmt)
+ if (!tm_gmt) {
+ if (*offset > 0 && *offset * 60 > *timestamp)
+ return -1;
+ if (*offset < 0 && -*offset * 60 > timestamp_max - *timestamp)
+ return -1;
*timestamp -= *offset * 60;
+ }
+
return 0; /* success */
}
diff --git a/diff-lib.c b/diff-lib.c
index b0d0f711e8..7a1eb63757 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -665,9 +665,11 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
repo_init_revisions(opt->repo, &revs, NULL);
copy_pathspec(&revs.prune_data, &opt->pathspec);
revs.diffopt = *opt;
+ revs.diffopt.no_free = 1;
if (diff_cache(&revs, tree_oid, NULL, 1))
exit(128);
+
release_revisions(&revs);
return 0;
}
diff --git a/diff.c b/diff.c
index 7e9041a6a9..ebb7538e04 100644
--- a/diff.c
+++ b/diff.c
@@ -6689,8 +6689,10 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
static void diff_free_file(struct diff_options *options)
{
- if (options->close_file)
+ if (options->close_file && options->file) {
fclose(options->file);
+ options->file = NULL;
+ }
}
static void diff_free_ignore_regex(struct diff_options *options)
@@ -6701,7 +6703,9 @@ static void diff_free_ignore_regex(struct diff_options *options)
regfree(options->ignore_regex[i]);
free(options->ignore_regex[i]);
}
- free(options->ignore_regex);
+
+ FREE_AND_NULL(options->ignore_regex);
+ options->ignore_regex_nr = 0;
}
void diff_free(struct diff_options *options)
diff --git a/dir.c b/dir.c
index b7a6625ebd..5a23376bda 100644
--- a/dir.c
+++ b/dir.c
@@ -95,7 +95,7 @@ int count_slashes(const char *s)
return cnt;
}
-int fspathcmp(const char *a, const char *b)
+int git_fspathcmp(const char *a, const char *b)
{
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
}
@@ -105,7 +105,7 @@ int fspatheq(const char *a, const char *b)
return !fspathcmp(a, b);
}
-int fspathncmp(const char *a, const char *b, size_t count)
+int git_fspathncmp(const char *a, const char *b, size_t count)
{
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
}
diff --git a/dir.h b/dir.h
index 69a76d8bdd..a3a2f00f5d 100644
--- a/dir.h
+++ b/dir.h
@@ -541,9 +541,9 @@ int remove_dir_recursively(struct strbuf *path, int flag);
*/
int remove_path(const char *path);
-int fspathcmp(const char *a, const char *b);
+int git_fspathcmp(const char *a, const char *b);
int fspatheq(const char *a, const char *b);
-int fspathncmp(const char *a, const char *b, size_t count);
+int git_fspathncmp(const char *a, const char *b, size_t count);
unsigned int fspathhash(const char *str);
/*
diff --git a/entry.c b/entry.c
index e7ed440ce2..3143b9996b 100644
--- a/entry.c
+++ b/entry.c
@@ -191,7 +191,7 @@ int finish_delayed_checkout(struct checkout *state, int show_progress)
progress = start_delayed_progress(_("Filtering content"), dco->paths.nr);
while (dco->filters.nr > 0) {
for_each_string_list_item(filter, &dco->filters) {
- struct string_list available_paths = STRING_LIST_INIT_NODUP;
+ struct string_list available_paths = STRING_LIST_INIT_DUP;
if (!async_query_available_blobs(filter->string, &available_paths)) {
/* Filter reported an error */
@@ -245,6 +245,8 @@ int finish_delayed_checkout(struct checkout *state, int show_progress)
} else
errs = 1;
}
+
+ string_list_clear(&available_paths, 0);
}
filter_string_list(&dco->filters, 0, string_is_not_null, NULL);
diff --git a/fetch-pack.c b/fetch-pack.c
index ea8655de31..732511604b 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -956,12 +956,7 @@ static int get_pack(struct fetch_pack_args *args,
strvec_push(&cmd.args, alternate_shallow_file);
}
- if (fetch_fsck_objects >= 0
- ? fetch_fsck_objects
- : transfer_fsck_objects >= 0
- ? transfer_fsck_objects
- : 0)
- fsck_objects = 1;
+ fsck_objects = fetch_pack_fsck_objects();
if (do_keep || args->from_promisor || index_pack_args || fsck_objects) {
if (pack_lockfiles || fsck_objects)
@@ -2050,6 +2045,16 @@ static const struct object_id *iterate_ref_map(void *cb_data)
return &ref->old_oid;
}
+int fetch_pack_fsck_objects(void)
+{
+ fetch_pack_setup();
+ if (fetch_fsck_objects >= 0)
+ return fetch_fsck_objects;
+ if (transfer_fsck_objects >= 0)
+ return transfer_fsck_objects;
+ return 0;
+}
+
struct ref *fetch_pack(struct fetch_pack_args *args,
int fd[],
const struct ref *ref,
diff --git a/fetch-pack.h b/fetch-pack.h
index 6775d26517..b5c579cdae 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -101,4 +101,9 @@ void negotiate_using_fetch(const struct oid_array *negotiation_tips,
*/
int report_unmatched_refs(struct ref **sought, int nr_sought);
+/*
+ * Return true if checks for broken objects in received pack are required.
+ */
+int fetch_pack_fsck_objects(void);
+
#endif
diff --git a/git-compat-util.h b/git-compat-util.h
index ca7678a379..71b4d23f03 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -506,6 +506,14 @@ static inline int git_offset_1st_component(const char *path)
#define offset_1st_component git_offset_1st_component
#endif
+#ifndef fspathcmp
+#define fspathcmp git_fspathcmp
+#endif
+
+#ifndef fspathncmp
+#define fspathncmp git_fspathncmp
+#endif
+
#ifndef is_valid_path
#define is_valid_path(path) 1
#endif
diff --git a/git-send-email.perl b/git-send-email.perl
index f0be4b4560..72044e5ef3 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1847,9 +1847,9 @@ sub pre_process_file {
$what, $_) unless $quiet;
next;
}
- push @cc, $c;
+ push @cc, $sc;
printf(__("(body) Adding cc: %s from line '%s'\n"),
- $c, $_) unless $quiet;
+ $sc, $_) unless $quiet;
}
}
close $fh;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ccd14e0e30..b09a8d0523 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -8326,10 +8326,10 @@ XML
my %co = %{$commitlist[$i]};
my $commit = $co{'id'};
# we read 150, we always show 30 and the ones more recent than 48 hours
- if (($i >= 20) && ((time - $co{'author_epoch'}) > 48*60*60)) {
+ if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) {
last;
}
- my %cd = parse_date($co{'author_epoch'}, $co{'author_tz'});
+ my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});
# get list of changed files
open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
diff --git a/grep.c b/grep.c
index ac34bfeafb..2f8b9553df 100644
--- a/grep.c
+++ b/grep.c
@@ -1735,7 +1735,8 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
peek_eol = end_of_line(peek_bol, &peek_left);
}
- if (match_funcname(opt, gs, peek_bol, peek_eol))
+ if (peek_bol >= gs->buf + gs->size ||
+ match_funcname(opt, gs, peek_bol, peek_eol))
show_function = 0;
}
if (show_function ||
diff --git a/help.c b/help.c
index de0bdd3c8e..a6b4d3b1eb 100644
--- a/help.c
+++ b/help.c
@@ -163,7 +163,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len)
cmds->names[cmds->cnt++] = ent;
}
-static void clean_cmdnames(struct cmdnames *cmds)
+void cmdnames_release(struct cmdnames *cmds)
{
int i;
for (i = 0; i < cmds->cnt; ++i)
@@ -365,8 +365,8 @@ void list_all_main_cmds(struct string_list *list)
for (i = 0; i < main_cmds.cnt; i++)
string_list_append(list, main_cmds.names[i]->name);
- clean_cmdnames(&main_cmds);
- clean_cmdnames(&other_cmds);
+ cmdnames_release(&main_cmds);
+ cmdnames_release(&other_cmds);
}
void list_all_other_cmds(struct string_list *list)
@@ -381,8 +381,8 @@ void list_all_other_cmds(struct string_list *list)
for (i = 0; i < other_cmds.cnt; i++)
string_list_append(list, other_cmds.names[i]->name);
- clean_cmdnames(&main_cmds);
- clean_cmdnames(&other_cmds);
+ cmdnames_release(&main_cmds);
+ cmdnames_release(&other_cmds);
}
void list_cmds_by_category(struct string_list *list,
@@ -695,7 +695,7 @@ const char *help_unknown_cmd(const char *cmd)
if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
const char *assumed = main_cmds.names[0]->name;
main_cmds.names[0] = NULL;
- clean_cmdnames(&main_cmds);
+ cmdnames_release(&main_cmds);
fprintf_ln(stderr,
_("WARNING: You called a Git command named '%s', "
"which does not exist."),
diff --git a/help.h b/help.h
index af073a7a02..e716ee27ea 100644
--- a/help.h
+++ b/help.h
@@ -13,6 +13,8 @@ struct cmdnames {
} **names;
};
+void cmdnames_release(struct cmdnames *cmds);
+
static inline void mput_char(char c, unsigned int num)
{
while (num--)
diff --git a/http.c b/http.c
index 13fa94bef3..6c6cc5c822 100644
--- a/http.c
+++ b/http.c
@@ -108,12 +108,19 @@ static struct {
};
#endif
+enum proactive_auth {
+ PROACTIVE_AUTH_NONE = 0,
+ PROACTIVE_AUTH_IF_CREDENTIALS,
+ PROACTIVE_AUTH_AUTO,
+ PROACTIVE_AUTH_BASIC,
+};
+
static struct credential proxy_auth = CREDENTIAL_INIT;
static const char *curl_proxyuserpwd;
static char *curl_cookie_file;
static int curl_save_cookies;
struct credential http_auth = CREDENTIAL_INIT;
-static int http_proactive_auth;
+static enum proactive_auth http_proactive_auth;
static char *user_agent;
static int curl_empty_auth = -1;
@@ -148,6 +155,12 @@ static int http_schannel_check_revoke = 1;
*/
static int http_schannel_use_ssl_cainfo;
+static int always_auth_proactively(void)
+{
+ return http_proactive_auth != PROACTIVE_AUTH_NONE &&
+ http_proactive_auth != PROACTIVE_AUTH_IF_CREDENTIALS;
+}
+
size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
{
size_t size = eltsize * nmemb;
@@ -539,6 +552,20 @@ static int http_options(const char *var, const char *value,
return 0;
}
+ if (!strcmp("http.proactiveauth", var)) {
+ if (!value)
+ return config_error_nonbool(var);
+ if (!strcmp(value, "auto"))
+ http_proactive_auth = PROACTIVE_AUTH_AUTO;
+ else if (!strcmp(value, "basic"))
+ http_proactive_auth = PROACTIVE_AUTH_BASIC;
+ else if (!strcmp(value, "none"))
+ http_proactive_auth = PROACTIVE_AUTH_NONE;
+ else
+ warning(_("Unknown value for http.proactiveauth"));
+ return 0;
+ }
+
/* Fall back on the default ones */
return git_default_config(var, value, ctx, data);
}
@@ -580,14 +607,29 @@ static void init_curl_http_auth(CURL *result)
{
if ((!http_auth.username || !*http_auth.username) &&
(!http_auth.credential || !*http_auth.credential)) {
- if (curl_empty_auth_enabled())
+ int empty_auth = curl_empty_auth_enabled();
+ if ((empty_auth != -1 && !always_auth_proactively()) || empty_auth == 1) {
curl_easy_setopt(result, CURLOPT_USERPWD, ":");
- return;
+ return;
+ } else if (!always_auth_proactively()) {
+ return;
+ } else if (http_proactive_auth == PROACTIVE_AUTH_BASIC) {
+ strvec_push(&http_auth.wwwauth_headers, "Basic");
+ }
}
credential_fill(&http_auth, 1);
if (http_auth.password) {
+ if (always_auth_proactively()) {
+ /*
+ * We got a credential without an authtype and we don't
+ * know what's available. Since our only two options at
+ * the moment are auto (which defaults to basic) and
+ * basic, use basic for now.
+ */
+ curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ }
curl_easy_setopt(result, CURLOPT_USERNAME, http_auth.username);
curl_easy_setopt(result, CURLOPT_PASSWORD, http_auth.password);
}
@@ -1050,7 +1092,7 @@ static CURL *get_curl_handle(void)
#endif
}
- if (http_proactive_auth)
+ if (http_proactive_auth != PROACTIVE_AUTH_NONE)
init_curl_http_auth(result);
if (getenv("GIT_SSL_VERSION"))
@@ -1185,6 +1227,8 @@ static CURL *get_curl_handle(void)
*/
curl_easy_setopt(result, CURLOPT_PROXY, "");
} else if (curl_http_proxy) {
+ struct strbuf proxy = STRBUF_INIT;
+
if (starts_with(curl_http_proxy, "socks5h"))
curl_easy_setopt(result,
CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
@@ -1223,7 +1267,27 @@ static CURL *get_curl_handle(void)
if (!proxy_auth.host)
die("Invalid proxy URL '%s'", curl_http_proxy);
- curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
+ strbuf_addstr(&proxy, proxy_auth.host);
+ if (proxy_auth.path) {
+ curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
+
+ if (ver->version_num < 0x075400)
+ die("libcurl 7.84 or later is required to support paths in proxy URLs");
+
+ if (!starts_with(proxy_auth.protocol, "socks"))
+ die("Invalid proxy URL '%s': only SOCKS proxies support paths",
+ curl_http_proxy);
+
+ if (strcasecmp(proxy_auth.host, "localhost"))
+ die("Invalid proxy URL '%s': host must be localhost if a path is present",
+ curl_http_proxy);
+
+ strbuf_addch(&proxy, '/');
+ strbuf_add_percentencode(&proxy, proxy_auth.path, 0);
+ }
+ curl_easy_setopt(result, CURLOPT_PROXY, proxy.buf);
+ strbuf_release(&proxy);
+
var_override(&curl_no_proxy, getenv("NO_PROXY"));
var_override(&curl_no_proxy, getenv("no_proxy"));
curl_easy_setopt(result, CURLOPT_NOPROXY, curl_no_proxy);
@@ -1294,7 +1358,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
die("curl_global_init failed");
- http_proactive_auth = proactive_auth;
+ if (proactive_auth && http_proactive_auth == PROACTIVE_AUTH_NONE)
+ http_proactive_auth = PROACTIVE_AUTH_IF_CREDENTIALS;
if (remote && remote->http_proxy)
curl_http_proxy = xstrdup(remote->http_proxy);
@@ -1466,7 +1531,16 @@ struct active_request_slot *get_active_slot(void)
slot->finished = NULL;
slot->callback_data = NULL;
slot->callback_func = NULL;
+
+ if (curl_cookie_file && !strcmp(curl_cookie_file, "-")) {
+ warning(_("refusing to read cookies from http.cookiefile '-'"));
+ FREE_AND_NULL(curl_cookie_file);
+ }
curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file);
+ if (curl_save_cookies && (!curl_cookie_file || !curl_cookie_file[0])) {
+ curl_save_cookies = 0;
+ warning(_("ignoring http.savecookies for empty http.cookiefile"));
+ }
if (curl_save_cookies)
curl_easy_setopt(slot->curl, CURLOPT_COOKIEJAR, curl_cookie_file);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);
@@ -1790,6 +1864,8 @@ static int handle_curl_result(struct slot_results *results)
return HTTP_REAUTH;
}
credential_reject(&http_auth);
+ if (always_auth_proactively())
+ http_proactive_auth = PROACTIVE_AUTH_NONE;
return HTTP_NOAUTH;
} else {
http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE;
@@ -2186,7 +2262,12 @@ static int http_request_reauth(const char *url,
struct http_get_options *options)
{
int i = 3;
- int ret = http_request(url, result, target, options);
+ int ret;
+
+ if (always_auth_proactively())
+ credential_fill(&http_auth, 1);
+
+ ret = http_request(url, result, target, options);
if (ret != HTTP_OK && ret != HTTP_REAUTH)
return ret;
diff --git a/line-range.c b/line-range.c
index 60f0e5ada8..b99f0d9895 100644
--- a/line-range.c
+++ b/line-range.c
@@ -234,6 +234,8 @@ static const char *parse_range_funcname(
}
regfree(&regexp);
+ if (xecfg)
+ xdiff_clear_find_func(xecfg);
free(xecfg);
free(pattern);
diff --git a/list-objects-filter.c b/list-objects-filter.c
index 49e2fa6f97..dc598a081b 100644
--- a/list-objects-filter.c
+++ b/list-objects-filter.c
@@ -544,6 +544,8 @@ static void filter_sparse_oid__init(
filter->filter_data = d;
filter->filter_object_fn = filter_sparse;
filter->free_fn = filter_sparse_free;
+
+ object_context_release(&oc);
}
/*
diff --git a/log-tree.c b/log-tree.c
index 101079e820..fdb24cbef2 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -31,6 +31,7 @@
#include "tree.h"
#include "wildmatch.h"
#include "write-or-die.h"
+#include "pager.h"
static struct decoration name_decoration = { "object names" };
static int decoration_loaded;
@@ -411,16 +412,6 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
strbuf_release(&sb);
}
-static unsigned int digits_in_number(unsigned int number)
-{
- unsigned int i = 10, result = 1;
- while (i <= number) {
- i *= 10;
- result++;
- }
- return result;
-}
-
void fmt_output_subject(struct strbuf *filename,
const char *subject,
struct rev_info *info)
@@ -464,7 +455,7 @@ void fmt_output_email_subject(struct strbuf *sb, struct rev_info *opt)
strbuf_addf(sb, "Subject: [%s%s%0*d/%d] ",
opt->subject_prefix,
*opt->subject_prefix ? " " : "",
- digits_in_number(opt->total),
+ decimal_width(opt->total),
opt->nr, opt->total);
} else if (opt->total == 0 && opt->subject_prefix && *opt->subject_prefix) {
strbuf_addf(sb, "Subject: [%s] ",
@@ -1025,7 +1016,7 @@ static int do_remerge_diff(struct rev_info *opt,
struct strbuf parent2_desc = STRBUF_INIT;
/* Setup merge options */
- init_merge_options(&o, the_repository);
+ init_ui_merge_options(&o, the_repository);
o.show_rename_progress = 0;
o.record_conflict_msgs_as_headers = 1;
o.msg_header_prefix = "remerge";
@@ -1053,6 +1044,7 @@ static int do_remerge_diff(struct rev_info *opt,
log_tree_diff_flush(opt);
/* Cleanup */
+ free_commit_list(bases);
cleanup_additional_headers(&opt->diffopt);
strbuf_release(&parent1_desc);
strbuf_release(&parent2_desc);
diff --git a/mailmap.c b/mailmap.c
index 2d0212f444..2acf97f307 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -201,8 +201,10 @@ static int read_mailmap_blob(struct string_list *map, const char *name)
buf = repo_read_object_file(the_repository, &oid, &type, &size);
if (!buf)
return error("unable to read mailmap object at %s", name);
- if (type != OBJ_BLOB)
+ if (type != OBJ_BLOB) {
+ free(buf);
return error("mailmap is not a blob: %s", name);
+ }
read_mailmap_string(map, buf);
diff --git a/merge-ort-wrappers.c b/merge-ort-wrappers.c
index 4acedf3c33..d6f6135996 100644
--- a/merge-ort-wrappers.c
+++ b/merge-ort-wrappers.c
@@ -48,7 +48,7 @@ int merge_ort_nonrecursive(struct merge_options *opt,
int merge_ort_recursive(struct merge_options *opt,
struct commit *side1,
struct commit *side2,
- struct commit_list *merge_bases,
+ const struct commit_list *merge_bases,
struct commit **result)
{
struct tree *head = repo_get_commit_tree(opt->repo, side1);
diff --git a/merge-ort-wrappers.h b/merge-ort-wrappers.h
index 0c4c57adbb..90af1f69c5 100644
--- a/merge-ort-wrappers.h
+++ b/merge-ort-wrappers.h
@@ -19,7 +19,7 @@ int merge_ort_nonrecursive(struct merge_options *opt,
int merge_ort_recursive(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
- struct commit_list *ancestors,
+ const struct commit_list *ancestors,
struct commit **result);
#endif
diff --git a/merge-ort.c b/merge-ort.c
index 691db9050e..e9d01ac7f7 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -545,17 +545,35 @@ enum conflict_and_info_types {
CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE,
CONFLICT_SUBMODULE_MAY_HAVE_REWINDS,
CONFLICT_SUBMODULE_NULL_MERGE_BASE,
- CONFLICT_SUBMODULE_CORRUPT,
+
+ /* INSERT NEW ENTRIES HERE */
+
+ /*
+ * Keep this entry after all regular conflict and info types; only
+ * errors (failures causing immediate abort of the merge) should
+ * come after this.
+ */
+ NB_REGULAR_CONFLICT_TYPES,
+
+ /*
+ * Something is seriously wrong; cannot even perform merge;
+ * Keep this group _last_ other than NB_TOTAL_TYPES
+ */
+ ERROR_SUBMODULE_CORRUPT,
+ ERROR_THREEWAY_CONTENT_MERGE_FAILED,
+ ERROR_OBJECT_WRITE_FAILED,
+ ERROR_OBJECT_READ_FAILED,
+ ERROR_OBJECT_NOT_A_BLOB,
/* Keep this entry _last_ in the list */
- NB_CONFLICT_TYPES,
+ NB_TOTAL_TYPES,
};
/*
* Short description of conflict type, relied upon by external tools.
*
* We can add more entries, but DO NOT change any of these strings. Also,
- * Order MUST match conflict_info_and_types.
+ * please ensure the order matches what is used in conflict_info_and_types.
*/
static const char *type_short_descriptions[] = {
/*** "Simple" conflicts and informational messages ***/
@@ -599,8 +617,18 @@ static const char *type_short_descriptions[] = {
"CONFLICT (submodule may have rewinds)",
[CONFLICT_SUBMODULE_NULL_MERGE_BASE] =
"CONFLICT (submodule lacks merge base)",
- [CONFLICT_SUBMODULE_CORRUPT] =
- "CONFLICT (submodule corrupt)"
+
+ /* Something is seriously wrong; cannot even perform merge */
+ [ERROR_SUBMODULE_CORRUPT] =
+ "ERROR (submodule corrupt)",
+ [ERROR_THREEWAY_CONTENT_MERGE_FAILED] =
+ "ERROR (three-way content merge failed)",
+ [ERROR_OBJECT_WRITE_FAILED] =
+ "ERROR (object write failed)",
+ [ERROR_OBJECT_READ_FAILED] =
+ "ERROR (object read failed)",
+ [ERROR_OBJECT_NOT_A_BLOB] =
+ "ERROR (object is not a blob)",
};
struct logical_conflict_info {
@@ -764,7 +792,8 @@ static void path_msg(struct merge_options *opt,
/* Sanity checks */
assert(omittable_hint ==
- !starts_with(type_short_descriptions[type], "CONFLICT") ||
+ (!starts_with(type_short_descriptions[type], "CONFLICT") &&
+ !starts_with(type_short_descriptions[type], "ERROR")) ||
type == CONFLICT_DIR_RENAME_SUGGESTED);
if (opt->record_conflict_msgs_as_headers && omittable_hint)
return; /* Do not record mere hints in headers */
@@ -1819,9 +1848,9 @@ static int merge_submodule(struct merge_options *opt,
/* check whether both changes are forward */
ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_a);
if (ret2 < 0) {
- path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+ path_msg(opt, ERROR_SUBMODULE_CORRUPT, 0,
path, NULL, NULL, NULL,
- _("Failed to merge submodule %s "
+ _("error: failed to merge submodule %s "
"(repository corrupt)"),
path);
ret = -1;
@@ -1830,9 +1859,9 @@ static int merge_submodule(struct merge_options *opt,
if (ret2 > 0)
ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_b);
if (ret2 < 0) {
- path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+ path_msg(opt, ERROR_SUBMODULE_CORRUPT, 0,
path, NULL, NULL, NULL,
- _("Failed to merge submodule %s "
+ _("error: failed to merge submodule %s "
"(repository corrupt)"),
path);
ret = -1;
@@ -1850,9 +1879,9 @@ static int merge_submodule(struct merge_options *opt,
/* Case #1: a is contained in b or vice versa */
ret2 = repo_in_merge_bases(&subrepo, commit_a, commit_b);
if (ret2 < 0) {
- path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+ path_msg(opt, ERROR_SUBMODULE_CORRUPT, 0,
path, NULL, NULL, NULL,
- _("Failed to merge submodule %s "
+ _("error: failed to merge submodule %s "
"(repository corrupt)"),
path);
ret = -1;
@@ -1869,9 +1898,9 @@ static int merge_submodule(struct merge_options *opt,
}
ret2 = repo_in_merge_bases(&subrepo, commit_b, commit_a);
if (ret2 < 0) {
- path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+ path_msg(opt, ERROR_SUBMODULE_CORRUPT, 0,
path, NULL, NULL, NULL,
- _("Failed to merge submodule %s "
+ _("error: failed to merge submodule %s "
"(repository corrupt)"),
path);
ret = -1;
@@ -1903,9 +1932,9 @@ static int merge_submodule(struct merge_options *opt,
&merges);
switch (parent_count) {
case -1:
- path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+ path_msg(opt, ERROR_SUBMODULE_CORRUPT, 0,
path, NULL, NULL, NULL,
- _("Failed to merge submodule %s "
+ _("error: failed to merge submodule %s "
"(repository corrupt)"),
path);
ret = -1;
@@ -2111,7 +2140,7 @@ static int handle_content_merge(struct merge_options *opt,
* merges, which happens for example with rename/rename(2to1) and
* rename/add conflicts.
*/
- unsigned clean = 1;
+ int clean = 1;
/*
* handle_content_merge() needs both files to be of the same type, i.e.
@@ -2175,18 +2204,28 @@ static int handle_content_merge(struct merge_options *opt,
pathnames, extra_marker_size,
&result_buf);
- if ((merge_status < 0) || !result_buf.ptr)
- ret = error(_("failed to execute internal merge"));
+ if ((merge_status < 0) || !result_buf.ptr) {
+ path_msg(opt, ERROR_THREEWAY_CONTENT_MERGE_FAILED, 0,
+ pathnames[0], pathnames[1], pathnames[2], NULL,
+ _("error: failed to execute internal merge for %s"),
+ path);
+ ret = -1;
+ }
if (!ret &&
write_object_file(result_buf.ptr, result_buf.size,
- OBJ_BLOB, &result->oid))
- ret = error(_("unable to add %s to database"), path);
-
+ OBJ_BLOB, &result->oid)) {
+ path_msg(opt, ERROR_OBJECT_WRITE_FAILED, 0,
+ pathnames[0], pathnames[1], pathnames[2], NULL,
+ _("error: unable to add %s to database"), path);
+ ret = -1;
+ }
free(result_buf.ptr);
+
if (ret)
return -1;
- clean &= (merge_status == 0);
+ if (merge_status > 0)
+ clean = 0;
path_msg(opt, INFO_AUTO_MERGING, 1, path, NULL, NULL, NULL,
_("Auto-merging %s"), path);
} else if (S_ISGITLINK(a->mode)) {
@@ -2194,6 +2233,8 @@ static int handle_content_merge(struct merge_options *opt,
clean = merge_submodule(opt, pathnames[0],
two_way ? null_oid() : &o->oid,
&a->oid, &b->oid, &result->oid);
+ if (clean < 0)
+ return -1;
if (opt->priv->call_depth && two_way && !clean) {
result->mode = o->mode;
oidcpy(&result->oid, &o->oid);
@@ -3559,18 +3600,27 @@ static int sort_dirs_next_to_their_children(const char *one, const char *two)
return c1 - c2;
}
-static int read_oid_strbuf(const struct object_id *oid,
- struct strbuf *dst)
+static int read_oid_strbuf(struct merge_options *opt,
+ const struct object_id *oid,
+ struct strbuf *dst,
+ const char *path)
{
void *buf;
enum object_type type;
unsigned long size;
buf = repo_read_object_file(the_repository, oid, &type, &size);
- if (!buf)
- return error(_("cannot read object %s"), oid_to_hex(oid));
+ if (!buf) {
+ path_msg(opt, ERROR_OBJECT_READ_FAILED, 0,
+ path, NULL, NULL, NULL,
+ _("error: cannot read object %s"), oid_to_hex(oid));
+ return -1;
+ }
if (type != OBJ_BLOB) {
free(buf);
- return error(_("object %s is not a blob"), oid_to_hex(oid));
+ path_msg(opt, ERROR_OBJECT_NOT_A_BLOB, 0,
+ path, NULL, NULL, NULL,
+ _("error: object %s is not a blob"), oid_to_hex(oid));
+ return -1;
}
strbuf_attach(dst, buf, size, size + 1);
return 0;
@@ -3594,8 +3644,8 @@ static int blob_unchanged(struct merge_options *opt,
if (oideq(&base->oid, &side->oid))
return 1;
- if (read_oid_strbuf(&base->oid, &basebuf) ||
- read_oid_strbuf(&side->oid, &sidebuf))
+ if (read_oid_strbuf(opt, &base->oid, &basebuf, path) ||
+ read_oid_strbuf(opt, &side->oid, &sidebuf, path))
goto error_return;
/*
* Note: binary | is used so that both renormalizations are
@@ -4645,6 +4695,7 @@ void merge_display_update_messages(struct merge_options *opt,
struct hashmap_iter iter;
struct strmap_entry *e;
struct string_list olist = STRING_LIST_INIT_NODUP;
+ FILE *o = stdout;
if (opt->record_conflict_msgs_as_headers)
BUG("Either display conflict messages or record them as headers, not both");
@@ -4661,6 +4712,10 @@ void merge_display_update_messages(struct merge_options *opt,
}
string_list_sort(&olist);
+ /* Print to stderr if we hit errors rather than just conflicts */
+ if (result->clean < 0)
+ o = stderr;
+
/* Iterate over the items, printing them */
for (int path_nr = 0; path_nr < olist.nr; ++path_nr) {
struct string_list *conflicts = olist.items[path_nr].util;
@@ -4668,25 +4723,31 @@ void merge_display_update_messages(struct merge_options *opt,
struct logical_conflict_info *info =
conflicts->items[i].util;
+ /* On failure, ignore regular conflict types */
+ if (result->clean < 0 &&
+ info->type < NB_REGULAR_CONFLICT_TYPES)
+ continue;
+
if (detailed) {
- printf("%lu", (unsigned long)info->paths.nr);
- putchar('\0');
+ fprintf(o, "%lu", (unsigned long)info->paths.nr);
+ fputc('\0', o);
for (int n = 0; n < info->paths.nr; n++) {
- fputs(info->paths.v[n], stdout);
- putchar('\0');
+ fputs(info->paths.v[n], o);
+ fputc('\0', o);
}
- fputs(type_short_descriptions[info->type],
- stdout);
- putchar('\0');
+ fputs(type_short_descriptions[info->type], o);
+ fputc('\0', o);
}
- puts(conflicts->items[i].string);
+ fputs(conflicts->items[i].string, o);
+ fputc('\n', o);
if (detailed)
- putchar('\0');
+ fputc('\0', o);
}
}
string_list_clear(&olist, 0);
- print_submodule_conflict_suggestion(&opti->conflicted_submodules);
+ if (result->clean >= 0)
+ print_submodule_conflict_suggestion(&opti->conflicted_submodules);
/* Also include needed rename limit adjustment now */
diff_warn_rename_limit("merge.renamelimit",
@@ -5002,6 +5063,26 @@ static void merge_check_renames_reusable(struct merge_result *result,
/*** Function Grouping: merge_incore_*() and their internal variants ***/
+static void move_opt_priv_to_result_priv(struct merge_options *opt,
+ struct merge_result *result)
+{
+ /*
+ * opt->priv and result->priv are a bit weird. opt->priv contains
+ * information that we can re-use in subsequent merge operations to
+ * enable our cached renames optimization. The best way to provide
+ * that to subsequent merges is putting it in result->priv.
+ * However, putting it directly there would mean retrofitting lots
+ * of functions in this file to also take a merge_result pointer,
+ * which is ugly and annoying. So, we just make sure at the end of
+ * the merge (the outer merge if there are internal recursive ones)
+ * to move it.
+ */
+ assert(opt->priv && !result->priv);
+ result->priv = opt->priv;
+ result->_properly_initialized = RESULT_INITIALIZED;
+ opt->priv = NULL;
+}
+
/*
* Originally from merge_trees_internal(); heavily adapted, though.
*/
@@ -5032,6 +5113,7 @@ redo:
oid_to_hex(&side1->object.oid),
oid_to_hex(&side2->object.oid));
result->clean = -1;
+ move_opt_priv_to_result_priv(opt, result);
return;
}
trace2_region_leave("merge", "collect_merge_info", opt->repo);
@@ -5062,22 +5144,20 @@ redo:
/* existence of conflicted entries implies unclean */
result->clean &= strmap_empty(&opt->priv->conflicted);
}
- if (!opt->priv->call_depth) {
- result->priv = opt->priv;
- result->_properly_initialized = RESULT_INITIALIZED;
- opt->priv = NULL;
- }
+ if (!opt->priv->call_depth || result->clean < 0)
+ move_opt_priv_to_result_priv(opt, result);
}
/*
* Originally from merge_recursive_internal(); somewhat adapted, though.
*/
static void merge_ort_internal(struct merge_options *opt,
- struct commit_list *merge_bases,
+ const struct commit_list *_merge_bases,
struct commit *h1,
struct commit *h2,
struct merge_result *result)
{
+ struct commit_list *merge_bases = copy_commit_list(_merge_bases);
struct commit *next;
struct commit *merged_merge_bases;
const char *ancestor_name;
@@ -5087,7 +5167,7 @@ static void merge_ort_internal(struct merge_options *opt,
if (repo_get_merge_bases(the_repository, h1, h2,
&merge_bases) < 0) {
result->clean = -1;
- return;
+ goto out;
}
/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
merge_bases = reverse_commit_list(merge_bases);
@@ -5131,7 +5211,7 @@ static void merge_ort_internal(struct merge_options *opt,
opt->branch2 = "Temporary merge branch 2";
merge_ort_internal(opt, NULL, prev, next, result);
if (result->clean < 0)
- return;
+ goto out;
opt->branch1 = saved_b1;
opt->branch2 = saved_b2;
opt->priv->call_depth--;
@@ -5154,6 +5234,9 @@ static void merge_ort_internal(struct merge_options *opt,
result);
strbuf_release(&merge_base_abbrev);
opt->ancestor = NULL; /* avoid accidental re-use of opt->ancestor */
+
+out:
+ free_commit_list(merge_bases);
}
void merge_incore_nonrecursive(struct merge_options *opt,
@@ -5183,7 +5266,7 @@ void merge_incore_nonrecursive(struct merge_options *opt,
}
void merge_incore_recursive(struct merge_options *opt,
- struct commit_list *merge_bases,
+ const struct commit_list *merge_bases,
struct commit *side1,
struct commit *side2,
struct merge_result *result)
diff --git a/merge-ort.h b/merge-ort.h
index a994c9a5fc..82f2b3222d 100644
--- a/merge-ort.h
+++ b/merge-ort.h
@@ -59,7 +59,7 @@ struct merge_result {
* first", 2006-08-09)
*/
void merge_incore_recursive(struct merge_options *opt,
- struct commit_list *merge_bases,
+ const struct commit_list *merge_bases,
struct commit *side1,
struct commit *side2,
struct merge_result *result);
diff --git a/merge-recursive.c b/merge-recursive.c
index 46ee364af7..ed64a4c537 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -242,7 +242,8 @@ enum rename_type {
struct stage_data {
struct diff_filespec stages[4]; /* mostly for oid & mode; maybe path */
struct rename_conflict_info *rename_conflict_info;
- unsigned processed:1;
+ unsigned processed:1,
+ rename_conflict_info_owned:1;
};
struct rename {
@@ -311,6 +312,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
ci->ren1->dst_entry->processed = 0;
ci->ren1->dst_entry->rename_conflict_info = ci;
+ ci->ren1->dst_entry->rename_conflict_info_owned = 1;
if (ren2) {
ci->ren2->dst_entry->rename_conflict_info = ci;
}
@@ -3058,6 +3060,10 @@ static void final_cleanup_rename(struct string_list *rename)
for (i = 0; i < rename->nr; i++) {
re = rename->items[i].util;
diff_free_filepair(re->pair);
+ if (re->src_entry->rename_conflict_info_owned)
+ FREE_AND_NULL(re->src_entry->rename_conflict_info);
+ if (re->dst_entry->rename_conflict_info_owned)
+ FREE_AND_NULL(re->dst_entry->rename_conflict_info);
}
string_list_clear(rename, 1);
free(rename);
@@ -3630,15 +3636,16 @@ static int merge_trees_internal(struct merge_options *opt,
static int merge_recursive_internal(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
- struct commit_list *merge_bases,
+ const struct commit_list *_merge_bases,
struct commit **result)
{
+ struct commit_list *merge_bases = copy_commit_list(_merge_bases);
struct commit_list *iter;
struct commit *merged_merge_bases;
struct tree *result_tree;
- int clean;
const char *ancestor_name;
struct strbuf merge_base_abbrev = STRBUF_INIT;
+ int ret;
if (show(opt, 4)) {
output(opt, 4, _("Merging:"));
@@ -3648,8 +3655,10 @@ static int merge_recursive_internal(struct merge_options *opt,
if (!merge_bases) {
if (repo_get_merge_bases(the_repository, h1, h2,
- &merge_bases) < 0)
- return -1;
+ &merge_bases) < 0) {
+ ret = -1;
+ goto out;
+ }
merge_bases = reverse_commit_list(merge_bases);
}
@@ -3699,14 +3708,18 @@ static int merge_recursive_internal(struct merge_options *opt,
opt->branch1 = "Temporary merge branch 1";
opt->branch2 = "Temporary merge branch 2";
if (merge_recursive_internal(opt, merged_merge_bases, iter->item,
- NULL, &merged_merge_bases) < 0)
- return -1;
+ NULL, &merged_merge_bases) < 0) {
+ ret = -1;
+ goto out;
+ }
opt->branch1 = saved_b1;
opt->branch2 = saved_b2;
opt->priv->call_depth--;
- if (!merged_merge_bases)
- return err(opt, _("merge returned no commit"));
+ if (!merged_merge_bases) {
+ ret = err(opt, _("merge returned no commit"));
+ goto out;
+ }
}
/*
@@ -3723,17 +3736,16 @@ static int merge_recursive_internal(struct merge_options *opt,
repo_read_index(opt->repo);
opt->ancestor = ancestor_name;
- clean = merge_trees_internal(opt,
- repo_get_commit_tree(opt->repo, h1),
- repo_get_commit_tree(opt->repo, h2),
- repo_get_commit_tree(opt->repo,
- merged_merge_bases),
- &result_tree);
- strbuf_release(&merge_base_abbrev);
+ ret = merge_trees_internal(opt,
+ repo_get_commit_tree(opt->repo, h1),
+ repo_get_commit_tree(opt->repo, h2),
+ repo_get_commit_tree(opt->repo,
+ merged_merge_bases),
+ &result_tree);
opt->ancestor = NULL; /* avoid accidental re-use of opt->ancestor */
- if (clean < 0) {
+ if (ret < 0) {
flush_output(opt);
- return clean;
+ goto out;
}
if (opt->priv->call_depth) {
@@ -3742,7 +3754,11 @@ static int merge_recursive_internal(struct merge_options *opt,
commit_list_insert(h1, &(*result)->parents);
commit_list_insert(h2, &(*result)->parents->next);
}
- return clean;
+
+out:
+ strbuf_release(&merge_base_abbrev);
+ free_commit_list(merge_bases);
+ return ret;
}
static int merge_start(struct merge_options *opt, struct tree *head)
@@ -3797,6 +3813,9 @@ static void merge_finalize(struct merge_options *opt)
if (show(opt, 2))
diff_warn_rename_limit("merge.renamelimit",
opt->priv->needed_rename_limit, 0);
+ hashmap_clear_and_free(&opt->priv->current_file_dir_set,
+ struct path_hashmap_entry, e);
+ string_list_clear(&opt->priv->df_conflict_file_set, 0);
FREE_AND_NULL(opt->priv);
}
@@ -3821,7 +3840,7 @@ int merge_trees(struct merge_options *opt,
int merge_recursive(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
- struct commit_list *merge_bases,
+ const struct commit_list *merge_bases,
struct commit **result)
{
int clean;
@@ -3863,7 +3882,7 @@ int merge_recursive_generic(struct merge_options *opt,
const struct object_id *head,
const struct object_id *merge,
int num_merge_bases,
- const struct object_id **merge_bases,
+ const struct object_id *merge_bases,
struct commit **result)
{
int clean;
@@ -3876,10 +3895,10 @@ int merge_recursive_generic(struct merge_options *opt,
int i;
for (i = 0; i < num_merge_bases; ++i) {
struct commit *base;
- if (!(base = get_ref(opt->repo, merge_bases[i],
- oid_to_hex(merge_bases[i]))))
+ if (!(base = get_ref(opt->repo, &merge_bases[i],
+ oid_to_hex(&merge_bases[i]))))
return err(opt, _("Could not parse object '%s'"),
- oid_to_hex(merge_bases[i]));
+ oid_to_hex(&merge_bases[i]));
commit_list_insert(base, &ca);
}
if (num_merge_bases == 1)
@@ -3889,6 +3908,7 @@ int merge_recursive_generic(struct merge_options *opt,
repo_hold_locked_index(opt->repo, &lock, LOCK_DIE_ON_ERROR);
clean = merge_recursive(opt, head_commit, next_commit, ca,
result);
+ free_commit_list(ca);
if (clean < 0) {
rollback_lock_file(&lock);
return clean;
@@ -3901,7 +3921,7 @@ int merge_recursive_generic(struct merge_options *opt,
return clean ? 0 : 1;
}
-static void merge_recursive_config(struct merge_options *opt)
+static void merge_recursive_config(struct merge_options *opt, int ui)
{
char *value = NULL;
int renormalize = 0;
@@ -3930,11 +3950,20 @@ static void merge_recursive_config(struct merge_options *opt)
} /* avoid erroring on values from future versions of git */
free(value);
}
+ if (ui) {
+ if (!git_config_get_string("diff.algorithm", &value)) {
+ long diff_algorithm = parse_algorithm_value(value);
+ if (diff_algorithm < 0)
+ die(_("unknown value for config '%s': %s"), "diff.algorithm", value);
+ opt->xdl_opts = (opt->xdl_opts & ~XDF_DIFF_ALGORITHM_MASK) | diff_algorithm;
+ free(value);
+ }
+ }
git_config(git_xmerge_config, NULL);
}
-void init_merge_options(struct merge_options *opt,
- struct repository *repo)
+static void init_merge_options(struct merge_options *opt,
+ struct repository *repo, int ui)
{
const char *merge_verbosity;
memset(opt, 0, sizeof(struct merge_options));
@@ -3953,7 +3982,7 @@ void init_merge_options(struct merge_options *opt,
opt->conflict_style = -1;
- merge_recursive_config(opt);
+ merge_recursive_config(opt, ui);
merge_verbosity = getenv("GIT_MERGE_VERBOSITY");
if (merge_verbosity)
opt->verbosity = strtol(merge_verbosity, NULL, 10);
@@ -3961,6 +3990,18 @@ void init_merge_options(struct merge_options *opt,
opt->buffer_output = 0;
}
+void init_ui_merge_options(struct merge_options *opt,
+ struct repository *repo)
+{
+ init_merge_options(opt, repo, 1);
+}
+
+void init_basic_merge_options(struct merge_options *opt,
+ struct repository *repo)
+{
+ init_merge_options(opt, repo, 0);
+}
+
/*
* For now, members of merge_options do not need deep copying, but
* it may change in the future, in which case we would need to update
diff --git a/merge-recursive.h b/merge-recursive.h
index e67d38c303..0b91f28f90 100644
--- a/merge-recursive.h
+++ b/merge-recursive.h
@@ -54,7 +54,10 @@ struct merge_options {
struct merge_options_internal *priv;
};
-void init_merge_options(struct merge_options *opt, struct repository *repo);
+/* for use by porcelain commands */
+void init_ui_merge_options(struct merge_options *opt, struct repository *repo);
+/* for use by plumbing commands */
+void init_basic_merge_options(struct merge_options *opt, struct repository *repo);
void copy_merge_options(struct merge_options *dst, struct merge_options *src);
void clear_merge_options(struct merge_options *opt);
@@ -104,7 +107,7 @@ int merge_trees(struct merge_options *opt,
int merge_recursive(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
- struct commit_list *merge_bases,
+ const struct commit_list *merge_bases,
struct commit **result);
/*
@@ -123,7 +126,7 @@ int merge_recursive_generic(struct merge_options *opt,
const struct object_id *head,
const struct object_id *merge,
int num_merge_bases,
- const struct object_id **merge_bases,
+ const struct object_id *merge_bases,
struct commit **result);
#endif
diff --git a/midx-write.c b/midx-write.c
index 478b42e720..a77ee73c68 100644
--- a/midx-write.c
+++ b/midx-write.c
@@ -1499,8 +1499,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
repo_config_get_bool(r, "repack.usedeltabaseoffset", &delta_base_offset);
repo_config_get_bool(r, "repack.usedeltaislands", &use_delta_islands);
- strvec_pushl(&cmd.args, "pack-objects", "--stdin-packs", "--non-empty",
- NULL);
+ strvec_push(&cmd.args, "pack-objects");
strvec_pushf(&cmd.args, "%s/pack/pack", object_dir);
@@ -1524,15 +1523,16 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
}
cmd_in = xfdopen(cmd.in, "w");
- for (i = 0; i < m->num_packs; i++) {
- struct packed_git *p = m->packs[i];
- if (!p)
+
+ for (i = 0; i < m->num_objects; i++) {
+ struct object_id oid;
+ uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
+
+ if (!include_pack[pack_int_id])
continue;
- if (include_pack[i])
- fprintf(cmd_in, "%s\n", pack_basename(p));
- else
- fprintf(cmd_in, "^%s\n", pack_basename(p));
+ nth_midxed_object_oid(&oid, m, i);
+ fprintf(cmd_in, "%s\n", oid_to_hex(&oid));
}
fclose(cmd_in);
diff --git a/notes-merge.c b/notes-merge.c
index d95e683414..dadbbabf86 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -663,6 +663,7 @@ int notes_merge(struct notes_merge_options *o,
commit_list_insert(local, &parents);
create_notes_commit(o->repo, local_tree, parents, o->commit_msg.buf,
o->commit_msg.len, result_oid);
+ free_commit_list(parents);
}
found_result:
diff --git a/notes-utils.c b/notes-utils.c
index bca71274be..ac66b82dd3 100644
--- a/notes-utils.c
+++ b/notes-utils.c
@@ -11,10 +11,11 @@
void create_notes_commit(struct repository *r,
struct notes_tree *t,
- struct commit_list *parents,
+ const struct commit_list *parents,
const char *msg, size_t msg_len,
struct object_id *result_oid)
{
+ struct commit_list *parents_to_free = NULL;
struct object_id tree_oid;
assert(t->initialized);
@@ -29,7 +30,8 @@ void create_notes_commit(struct repository *r,
struct commit *parent = lookup_commit(r, &parent_oid);
if (repo_parse_commit(r, parent))
die("Failed to find/parse commit %s", t->ref);
- commit_list_insert(parent, &parents);
+ commit_list_insert(parent, &parents_to_free);
+ parents = parents_to_free;
}
/* else: t->ref points to nothing, assume root/orphan commit */
}
@@ -37,6 +39,8 @@ void create_notes_commit(struct repository *r,
if (commit_tree(msg, msg_len, &tree_oid, parents, result_oid, NULL,
NULL))
die("Failed to commit notes tree to database");
+
+ free_commit_list(parents_to_free);
}
void commit_notes(struct repository *r, struct notes_tree *t, const char *msg)
@@ -189,6 +193,7 @@ void finish_copy_notes_for_rewrite(struct repository *r,
for (i = 0; c->trees[i]; i++) {
commit_notes(r, c->trees[i], msg);
free_notes(c->trees[i]);
+ free(c->trees[i]);
}
free(c->trees);
free(c);
diff --git a/notes-utils.h b/notes-utils.h
index d9b3c09eaf..c54b1fe141 100644
--- a/notes-utils.h
+++ b/notes-utils.h
@@ -20,7 +20,7 @@ struct repository;
*/
void create_notes_commit(struct repository *r,
struct notes_tree *t,
- struct commit_list *parents,
+ const struct commit_list *parents,
const char *msg, size_t msg_len,
struct object_id *result_oid);
diff --git a/notes.c b/notes.c
index b6a13d0980..1ba6412aae 100644
--- a/notes.c
+++ b/notes.c
@@ -1064,6 +1064,12 @@ void init_display_notes(struct display_notes_opt *opt)
{
memset(opt, 0, sizeof(*opt));
opt->use_default_notes = -1;
+ string_list_init_dup(&opt->extra_notes_refs);
+}
+
+void release_display_notes(struct display_notes_opt *opt)
+{
+ string_list_clear(&opt->extra_notes_refs, 0);
}
void enable_default_display_notes(struct display_notes_opt *opt, int *show_notes)
@@ -1077,19 +1083,15 @@ void enable_ref_display_notes(struct display_notes_opt *opt, int *show_notes,
struct strbuf buf = STRBUF_INIT;
strbuf_addstr(&buf, ref);
expand_notes_ref(&buf);
- string_list_append(&opt->extra_notes_refs,
- strbuf_detach(&buf, NULL));
+ string_list_append_nodup(&opt->extra_notes_refs,
+ strbuf_detach(&buf, NULL));
*show_notes = 1;
}
void disable_display_notes(struct display_notes_opt *opt, int *show_notes)
{
opt->use_default_notes = -1;
- /* we have been strdup'ing ourselves, so trick
- * string_list into free()ing strings */
- opt->extra_notes_refs.strdup_strings = 1;
string_list_clear(&opt->extra_notes_refs, 0);
- opt->extra_notes_refs.strdup_strings = 0;
*show_notes = 0;
}
@@ -1221,11 +1223,16 @@ void prune_notes(struct notes_tree *t, int flags)
for_each_note(t, 0, prune_notes_helper, &l);
while (l) {
+ struct note_delete_list *next;
+
if (flags & NOTES_PRUNE_VERBOSE)
printf("%s\n", hash_to_hex(l->sha1));
if (!(flags & NOTES_PRUNE_DRYRUN))
remove_note(t, l->sha1);
- l = l->next;
+
+ next = l->next;
+ free(l);
+ l = next;
}
}
diff --git a/notes.h b/notes.h
index 064fd7143a..235216944b 100644
--- a/notes.h
+++ b/notes.h
@@ -276,6 +276,11 @@ struct display_notes_opt {
void init_display_notes(struct display_notes_opt *opt);
/*
+ * Release resources acquired by the display_notes_opt.
+ */
+void release_display_notes(struct display_notes_opt *opt);
+
+/*
* This family of functions enables or disables the display of notes. In
* particular, 'enable_default_display_notes' will display the default notes,
* 'enable_ref_display_notes' will display the notes ref 'ref' and
diff --git a/object-name.c b/object-name.c
index f362d54598..240a93e7ce 100644
--- a/object-name.c
+++ b/object-name.c
@@ -27,7 +27,8 @@
#include "date.h"
#include "object-file-convert.h"
-static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *);
+static int get_oid_oneline(struct repository *r, const char *, struct object_id *,
+ const struct commit_list *);
typedef int (*disambiguate_hint_fn)(struct repository *, const struct object_id *, void *);
@@ -1254,6 +1255,8 @@ static int peel_onion(struct repository *r, const char *name, int len,
prefix = xstrndup(sp + 1, name + len - 1 - (sp + 1));
commit_list_insert((struct commit *)o, &list);
ret = get_oid_oneline(r, prefix, oid, list);
+
+ free_commit_list(list);
free(prefix);
return ret;
}
@@ -1388,9 +1391,10 @@ static int handle_one_ref(const char *path, const struct object_id *oid,
static int get_oid_oneline(struct repository *r,
const char *prefix, struct object_id *oid,
- struct commit_list *list)
+ const struct commit_list *list)
{
- struct commit_list *backup = NULL, *l;
+ struct commit_list *copy = NULL;
+ const struct commit_list *l;
int found = 0;
int negative = 0;
regex_t regex;
@@ -1411,14 +1415,14 @@ static int get_oid_oneline(struct repository *r,
for (l = list; l; l = l->next) {
l->item->object.flags |= ONELINE_SEEN;
- commit_list_insert(l->item, &backup);
+ commit_list_insert(l->item, &copy);
}
- while (list) {
+ while (copy) {
const char *p, *buf;
struct commit *commit;
int matches;
- commit = pop_most_recent_commit(&list, ONELINE_SEEN);
+ commit = pop_most_recent_commit(&copy, ONELINE_SEEN);
if (!parse_object(r, &commit->object.oid))
continue;
buf = repo_get_commit_buffer(r, commit, NULL);
@@ -1433,10 +1437,9 @@ static int get_oid_oneline(struct repository *r,
}
}
regfree(&regex);
- free_commit_list(list);
- for (l = backup; l; l = l->next)
+ for (l = list; l; l = l->next)
clear_commit_marks(l->item, ONELINE_SEEN);
- free_commit_list(backup);
+ free_commit_list(copy);
return found ? 0 : -1;
}
@@ -1759,6 +1762,11 @@ int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
return check_refname_format(sb->buf, 0);
}
+void object_context_release(struct object_context *ctx)
+{
+ free(ctx->path);
+}
+
/*
* This is like "get_oid_basic()", except it allows "object ID expressions",
* notably "xyz^" for "parent of xyz"
@@ -1766,7 +1774,9 @@ int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
int repo_get_oid(struct repository *r, const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(r, name, 0, oid, &unused);
+ int ret = get_oid_with_context(r, name, 0, oid, &unused);
+ object_context_release(&unused);
+ return ret;
}
/*
@@ -1804,8 +1814,10 @@ int repo_get_oid_committish(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(r, name, GET_OID_COMMITTISH,
- oid, &unused);
+ int ret = get_oid_with_context(r, name, GET_OID_COMMITTISH,
+ oid, &unused);
+ object_context_release(&unused);
+ return ret;
}
int repo_get_oid_treeish(struct repository *r,
@@ -1813,8 +1825,10 @@ int repo_get_oid_treeish(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(r, name, GET_OID_TREEISH,
- oid, &unused);
+ int ret = get_oid_with_context(r, name, GET_OID_TREEISH,
+ oid, &unused);
+ object_context_release(&unused);
+ return ret;
}
int repo_get_oid_commit(struct repository *r,
@@ -1822,8 +1836,10 @@ int repo_get_oid_commit(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(r, name, GET_OID_COMMIT,
- oid, &unused);
+ int ret = get_oid_with_context(r, name, GET_OID_COMMIT,
+ oid, &unused);
+ object_context_release(&unused);
+ return ret;
}
int repo_get_oid_tree(struct repository *r,
@@ -1831,8 +1847,10 @@ int repo_get_oid_tree(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(r, name, GET_OID_TREE,
- oid, &unused);
+ int ret = get_oid_with_context(r, name, GET_OID_TREE,
+ oid, &unused);
+ object_context_release(&unused);
+ return ret;
}
int repo_get_oid_blob(struct repository *r,
@@ -1840,8 +1858,10 @@ int repo_get_oid_blob(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(r, name, GET_OID_BLOB,
- oid, &unused);
+ int ret = get_oid_with_context(r, name, GET_OID_BLOB,
+ oid, &unused);
+ object_context_release(&unused);
+ return ret;
}
/* Must be called only when object_name:filename doesn't exist. */
@@ -2007,7 +2027,10 @@ static enum get_oid_result get_oid_with_context_1(struct repository *repo,
refs_for_each_ref(get_main_ref_store(repo), handle_one_ref, &cb);
refs_head_ref(get_main_ref_store(repo), handle_one_ref, &cb);
commit_list_sort_by_date(&list);
- return get_oid_oneline(repo, name + 2, oid, list);
+ ret = get_oid_oneline(repo, name + 2, oid, list);
+
+ free_commit_list(list);
+ return ret;
}
if (namelen < 3 ||
name[2] != ':' ||
@@ -2119,6 +2142,7 @@ void maybe_die_on_misspelt_object_name(struct repository *r,
struct object_id oid;
get_oid_with_context_1(r, name, GET_OID_ONLY_TO_DIE | GET_OID_QUIETLY,
prefix, &oid, &oc);
+ object_context_release(&oc);
}
enum get_oid_result get_oid_with_context(struct repository *repo,
diff --git a/object-name.h b/object-name.h
index 064ddc97d1..8dba4a47a4 100644
--- a/object-name.h
+++ b/object-name.h
@@ -22,6 +22,8 @@ struct object_context {
char *path;
};
+void object_context_release(struct object_context *ctx);
+
/*
* Return an abbreviated sha1 unique within this repository's object database.
* The result will be at least `len` characters long, and will be NUL
diff --git a/object.h b/object.h
index 3ea7125d56..05691486eb 100644
--- a/object.h
+++ b/object.h
@@ -62,7 +62,7 @@ void object_array_init(struct object_array *array);
/*
* object flag allocation:
- * revision.h: 0---------10 15 23------27
+ * revision.h: 0---------10 15 23------27
* fetch-pack.c: 01 67
* negotiator/default.c: 2--5
* walker.c: 0-2
@@ -75,6 +75,7 @@ void object_array_init(struct object_array *array);
* commit-reach.c: 16-----19
* sha1-name.c: 20
* list-objects-filter.c: 21
+ * bloom.c: 2122
* builtin/fsck.c: 0--3
* builtin/gc.c: 0
* builtin/index-pack.c: 2021
diff --git a/oss-fuzz/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c
index 951c9c082f..fbb77fec19 100644
--- a/oss-fuzz/fuzz-commit-graph.c
+++ b/oss-fuzz/fuzz-commit-graph.c
@@ -23,7 +23,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
*/
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
the_repository->settings.commit_graph_generation_version = 2;
- the_repository->settings.commit_graph_read_changed_paths = 1;
+ the_repository->settings.commit_graph_changed_paths_version = 1;
g = parse_commit_graph(&the_repository->settings, (void *)data, size);
repo_clear(the_repository);
free_commit_graph(g);
diff --git a/pager.c b/pager.c
index e9e121db69..896f40fcd2 100644
--- a/pager.c
+++ b/pager.c
@@ -14,6 +14,7 @@ int pager_use_color = 1;
static struct child_process pager_process;
static char *pager_program;
+static int old_fd1 = -1, old_fd2 = -1;
/* Is the value coming back from term_columns() just a guess? */
static int term_columns_guessed;
@@ -23,10 +24,11 @@ static void close_pager_fds(void)
{
/* signal EOF to pager */
close(1);
- close(2);
+ if (old_fd2 != -1)
+ close(2);
}
-static void wait_for_pager_atexit(void)
+static void finish_pager(void)
{
fflush(stdout);
fflush(stderr);
@@ -34,8 +36,37 @@ static void wait_for_pager_atexit(void)
finish_command(&pager_process);
}
+static void wait_for_pager_atexit(void)
+{
+ if (old_fd1 == -1)
+ return;
+
+ finish_pager();
+}
+
+void wait_for_pager(void)
+{
+ if (old_fd1 == -1)
+ return;
+
+ finish_pager();
+ sigchain_pop_common();
+ unsetenv("GIT_PAGER_IN_USE");
+ dup2(old_fd1, 1);
+ close(old_fd1);
+ old_fd1 = -1;
+ if (old_fd2 != -1) {
+ dup2(old_fd2, 2);
+ close(old_fd2);
+ old_fd2 = -1;
+ }
+}
+
static void wait_for_pager_signal(int signo)
{
+ if (old_fd1 == -1)
+ return;
+
close_pager_fds();
finish_command_in_signal(&pager_process);
sigchain_pop(signo);
@@ -111,6 +142,7 @@ void prepare_pager_args(struct child_process *pager_process, const char *pager)
void setup_pager(void)
{
+ static int once = 0;
const char *pager = git_pager(isatty(1));
if (!pager)
@@ -137,17 +169,23 @@ void setup_pager(void)
pager_process.in = -1;
strvec_push(&pager_process.env, "GIT_PAGER_IN_USE");
if (start_command(&pager_process))
- return;
+ die("unable to execute pager '%s'", pager);
/* original process continues, but writes to the pipe */
+ old_fd1 = dup(1);
dup2(pager_process.in, 1);
- if (isatty(2))
+ if (isatty(2)) {
+ old_fd2 = dup(2);
dup2(pager_process.in, 2);
+ }
close(pager_process.in);
- /* this makes sure that the parent terminates after the pager */
sigchain_push_common(wait_for_pager_signal);
- atexit(wait_for_pager_atexit);
+
+ if (!once) {
+ once++;
+ atexit(wait_for_pager_atexit);
+ }
}
int pager_in_use(void)
diff --git a/pager.h b/pager.h
index b77433026d..103ecac476 100644
--- a/pager.h
+++ b/pager.h
@@ -5,6 +5,7 @@ struct child_process;
const char *git_pager(int stdout_is_tty);
void setup_pager(void);
+void wait_for_pager(void);
int pager_in_use(void);
int term_columns(void);
void term_clear_line(void);
diff --git a/pathspec.h b/pathspec.h
index fec4399bbc..de537cff3c 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -23,7 +23,7 @@ struct index_state;
#define PATHSPEC_ONESTAR 1 /* the pathspec pattern satisfies GFNM_ONESTAR */
/**
- * See glossary-context.txt for the syntax of pathspec.
+ * See glossary-content.txt for the syntax of pathspec.
* In memory, a pathspec set is represented by "struct pathspec" and is
* prepared by parse_pathspec().
*/
diff --git a/po/bg.po b/po/bg.po
index a7cbc617a5..9e1ae613cf 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -218,8 +218,10 @@
# symref файл с указател (regular file that stores a string that begins with ref: refs/)
# human-readable четим от хора
# pseudoref псевдоуказател, напр. MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD или REBASE_HEAD
+# pseudo-merge псевдо сливанe
# reftable таблица с указатели
# its referent '%s' сочещия го „%s“
+# dry run пробно изпълнение
#
#
# ------------------------
@@ -249,8 +251,8 @@ msgid ""
msgstr ""
"Project-Id-Version: git 2.45\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-21 16:59+0200\n"
-"PO-Revision-Date: 2024-04-21 17:00+0200\n"
+"POT-Creation-Date: 2024-07-20 07:37+0200\n"
+"PO-Revision-Date: 2024-07-21 22:27+0300\n"
"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
"Language: bg\n"
@@ -820,6 +822,10 @@ msgstr ""
"p — извеждане на текущото парче\n"
"? — извеждане на помощта\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Очаква се само един знак, а не „%s“"
+
msgid "No previous hunk"
msgstr "Няма друго парче преди това"
@@ -868,9 +874,19 @@ msgstr "Разделяне на %d парчета."
msgid "Sorry, cannot edit this hunk"
msgstr "Това парче не може да се редактира"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "Непозната команда „%s“ (за помощ натиснете „?“)"
+
msgid "'git apply' failed"
msgstr "неуспешно изпълнение на „git apply“"
+msgid "No changes."
+msgstr "Няма промѐни."
+
+msgid "Only binary files changed."
+msgstr "Променени са само двоични файлове."
+
#, c-format
msgid ""
"\n"
@@ -1399,10 +1415,6 @@ msgstr[0] "Прилагане на кръпката „%%s“ с %d отхвър
msgstr[1] "Прилагане на кръпката „%%s“ с %d отхвърлени парчета…"
#, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "съкращаване на името на файла с отхвърлените парчета на „%.*s.rej“"
-
-#, c-format
msgid "cannot open %s"
msgstr "„%s“ не може да се отвори"
@@ -1752,6 +1764,10 @@ msgstr "прескачане на прекалено големия файл з�
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "прескачане на прекалено големия обект-BLOB за атрибути на git: „%s“"
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr ""
+"опцията „--attr-source“ и променливата „GIT_ATTR_SOURCE“ изискват хранилище"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr ""
"неправилна стойност за опцията „--attr-source“ или променливата "
@@ -1834,6 +1850,10 @@ msgid "could not create file '%s'"
msgstr "файлът „%s“ не може да се създаде"
#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "действието „show“ не може да се изпълни за обект „%s“"
+
+#, c-format
msgid "could not read file '%s'"
msgstr "файлът „%s“ не може да се прочете"
@@ -2072,13 +2092,6 @@ msgstr "права̀та на „%2$s“ не може да се зададат
msgid "Unstaged changes after refreshing the index:"
msgstr "Промѐни, които и след обновяването на индекса не са добавени към него:"
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"Настройката „add.interactive.useBuiltin“ е премахната!\n"
-"За подробности я потърсете в изхода от „git help config“."
-
msgid "could not read the index"
msgstr "индексът не може да се прочете"
@@ -2541,6 +2554,9 @@ msgstr ""
msgid "show the patch being applied"
msgstr "показване на прилаганата кръпка"
+msgid "try to apply current patch again"
+msgstr "нов опит за прилагане на текущата кръпка"
+
msgid "record the empty patch as an empty commit"
msgstr "прилагане на празна кръпка като празно подаване"
@@ -2598,9 +2614,6 @@ msgstr "git apply [ОПЦИЯ…] [КРЪПКА…]"
msgid "could not redirect output"
msgstr "изходът не може да се пренасочи"
-msgid "git archive: Remote with no URL"
-msgstr "git archive: Липсва адрес за отдалеченото хранилище"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr ""
"git archive: очакваше се „ACK“/„NAK“, а бе получен изчистващ пакет „flush“"
@@ -3535,6 +3548,9 @@ msgstr "За създаването на пратка е необходимо х
msgid "do not show bundle details"
msgstr "без подробна информация за пратките"
+msgid "need a repository to verify a bundle"
+msgstr "за проверката на пратка е необходимо хранилище"
+
#, c-format
msgid "%s is okay\n"
msgstr "Пратката „%s“ е наред\n"
@@ -4410,9 +4426,7 @@ msgid "remove only ignored files"
msgstr "изтриване само на игнорирани файлове"
msgid "clean.requireForce is true and -f not given: refusing to clean"
-msgstr ""
-"Настройката „clean.requireForce“ е зададена, което изисква опциията „-f“. "
-"Няма да се извърши изчистване"
+msgstr "Настройката „clean.requireForce“ е зададена, което изисква опцията „-f“. Няма да се извърши изчистване"
msgid "git clone [<options>] [--] <repo> [<dir>]"
msgstr "git clone [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]"
@@ -4569,6 +4583,14 @@ msgid "failed to unlink '%s'"
msgstr "неуспешно изтриване на „%s“"
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "твърдата връзка не може да се провери при „%s“"
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "твърдата връзка е различна от източника „%s“"
+
+#, c-format
msgid "failed to create link '%s'"
msgstr "връзката „%s“ не може да бъде създадена"
@@ -5438,15 +5460,49 @@ msgstr ""
"\n"
" git restore --staged :/"
-msgid "git config [<options>]"
-msgstr "git config [ОПЦИЯ…]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [ОПЦИЯ_ЗА_ФАЙЛ] [ОПЦИЯ_ЗА_ИЗВЕЖДАНЕ] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "непознат аргумент към „--type“: %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [ОПЦИЯ_ЗА_ФАЙЛ] [ОПЦИЯ_ЗА_ИЗВЕЖДАНЕ] [--includes] [--all] [--"
+"regexp=РЕГ_ИЗР][--value=СТОЙНОСТ] [--fixed-value] [--default=СТАНДАРТНО] ИМЕ"
-msgid "only one type at a time"
-msgstr "само по един вид"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [ОПЦИЯ_ЗА_ФАЙЛ] [--type=ВИД] [--all] [--value=СТОЙНОСТ] [--"
+"fixed-value] ИМЕ СТОЙНОСТ"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [ОПЦИЯ_ЗА_ФАЙЛ] [--all] [--value=СТОЙНОСТ] [--fixed-value]"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [ОПЦИЯ_ЗА_ФАЙЛ] СТАРО_ИМЕ НОВО_ИМЕ"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [ОПЦИЯ_ЗА_ФАЙЛ] ИМЕ"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [ОПЦИЯ_ЗА_ФАЙЛ]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr ""
+"git config [ОПЦИЯ_ЗА_ФАЙЛ] --get-colorbool ИМЕ [СТАНД_ИЗХОД_НА_ТЕРМИНАЛ]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [ОПЦИЯ_ЗА_ФАЙЛ] [--type=ВИД] [--comment=СЪОБЩЕНИЕ] [--all] [--"
+"value=СТОЙНОСТ] [--fixed-value] ИМЕ СТОЙНОСТ"
msgid "Config file location"
msgstr "Местоположение на конфигурационния файл"
@@ -5473,57 +5529,6 @@ msgid "read config from given blob object"
msgstr ""
"изчитане на конфигурацията от BLOB с този ИДЕНТИФИКАТОР на съдържанието"
-msgid "Action"
-msgstr "Действие"
-
-msgid "get value: name [value-pattern]"
-msgstr "извеждане на стойност: ИМЕ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "извеждане на всички стойности: ключ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr ""
-"извеждане на стойностите за РЕГУЛЯРНия_ИЗРАЗ: РЕГУЛЯРЕН_ИЗРАЗ_ЗА_ИМЕТО "
-"[ШАБЛОН_ЗА_СТОЙНОСТТА]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "извеждане на стойността за указания адрес: РАЗДЕЛ[.ПРОМЕНЛИВА] АДРЕС"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr ""
-"замяна на всички съвпадащи променливи: ИМЕ СТОЙНОСТ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
-
-msgid "add a new variable: name value"
-msgstr "добавяне на нова променлива: ИМЕ СТОЙНОСТ"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "изтриване на променлива: ИМЕ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "изтриване на всички съвпадащи: ИМЕ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
-
-msgid "rename section: old-name new-name"
-msgstr "преименуване на раздел: СТАРО_ИМЕ НОВО_ИМЕ"
-
-msgid "remove a section: name"
-msgstr "изтриване на раздел: ИМЕ"
-
-msgid "list all"
-msgstr "изброяване на всички"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "дословно равенство при сравняване със ШАБЛОН_ЗА_СТОЙНОСТ"
-
-msgid "open an editor"
-msgstr "отваряне на редактор"
-
-msgid "find the color configured: slot [default]"
-msgstr "извеждане на зададения цвят: номер [стандартно]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "извеждане на зададения цвят: номер (стандартният изход е терминал)"
-
msgid "Type"
msgstr "Вид"
@@ -5551,8 +5556,8 @@ msgstr "СТОЙНОСТТА е път (до файл или директори�
msgid "value is an expiry date"
msgstr "стойността е период на валидност/запазване"
-msgid "Other"
-msgstr "Други"
+msgid "Display options"
+msgstr "Опции за извеждането"
msgid "terminate values with NUL byte"
msgstr "разделяне на стойностите с нулевия знак „NUL“"
@@ -5560,9 +5565,6 @@ msgstr "разделяне на стойностите с нулевия зна�
msgid "show variable names only"
msgstr "извеждане на имената на променливите"
-msgid "respect include directives on lookup"
-msgstr "при търсене да се уважат и директивите за включване"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr ""
"извеждане на мястото на задаване на настройката (файл, стандартен вход, "
@@ -5573,14 +5575,15 @@ msgstr ""
"извеждане на обхвата на настройката „worktree“ (работно дърво), „local“ "
"(хранилище), „global“ (потребител), „system“ (система), „command“ (команда)"
-msgid "value"
-msgstr "СТОЙНОСТ"
+msgid "show config keys in addition to their values"
+msgstr "извеждане на ключовете в настройките заедно със стойностите им"
-msgid "with --get, use default value when missing entry"
-msgstr "с „--get“ се използва стандартна СТОЙНОСТ при липсваща"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "непознат аргумент към „--type“: %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr "низ за подаване четим от хора (при нужда отпред се добавя „#“)"
+msgid "only one type at a time"
+msgstr "само по един вид"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5657,50 +5660,73 @@ msgstr ""
"повече информация вижте раздела „CONFIGURATION FILE“ в\n"
"„git help worktree“"
-msgid "--get-color and variable type are incoherent"
-msgstr "опцията „--get-color“ не съответства на вида на променливата"
+msgid "Other"
+msgstr "Други"
-msgid "only one action at a time"
-msgstr "само по едно действие"
+msgid "respect include directives on lookup"
+msgstr "при търсене да се уважат и директивите за включване"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr ""
-"опцията „--name-only“ е приложима само към опциите „--list“ и „--get-regexp“"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "конфигурационният файл „%s“ не може да бъде прочетен"
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-"опцията „--show-origin“ е приложима само към опциите „--get“, „--get-all“, "
-"„--get-regexp“ и „--list“"
+msgid "error processing config file(s)"
+msgstr "грешка при обработката на конфигурационен файл"
-msgid "--default is only applicable to --get"
-msgstr "опцията „--default“ е приложима само към опцията „--get“"
+msgid "Filter options"
+msgstr "Опции за филтриране"
-msgid "--comment is only applicable to add/set/replace operations"
+msgid "return all values for multi-valued config options"
+msgstr "връщане на всички стойности за опциите, поддържащи много стойности"
+
+msgid "interpret the name as a regular expression"
+msgstr "третиране на името като регулярен израз"
+
+msgid "show config with values matching the pattern"
+msgstr "извеждане на настройките със стойности напасващи на ШАБЛОНа"
+
+msgid "use string equality when comparing values to value pattern"
msgstr ""
-"опцията „--comment“ е съвместима само с действията „add“ (добавяне)/„set“ "
-"(задаване)/„replace“ (замяна)"
+"ползване на равенство на низ при сравняване на стойност с ШАБЛОН_ЗА_СТОЙНОСТ"
+
+msgid "URL"
+msgstr "Адрес"
+
+msgid "show config matching the given URL"
+msgstr "извеждане на настройките напасващи на дадения адрес"
+
+msgid "value"
+msgstr "СТОЙНОСТ"
+
+msgid "use default value when missing entry"
+msgstr "ползване на стандартна СТОЙНОСТ при липсваща"
msgid "--fixed-value only applies with 'value-pattern'"
-msgstr "опцията „--fixed-value“ е приложима само със ШАБЛОН_ЗА_СТОЙНОСТ"
+msgstr "опцията „--fixed-value“ изисква ШАБЛОН_ЗА_СТОЙНОСТ"
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "конфигурационният файл „%s“ не може да бъде прочетен"
+msgid "--default= cannot be used with --all or --url="
+msgstr "опцията „--default=“ е несъвместима с „--all“, „--url=“"
-msgid "error processing config file(s)"
-msgstr "грешка при обработката на конфигурационен файл"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "опцията „--url=“ е несъвместима с „--all“, „--regexp“, „--value“"
-msgid "editing stdin is not supported"
-msgstr "не се поддържа редактиране на стандартния вход"
+msgid "Filter"
+msgstr "Филтриране"
-msgid "editing blobs is not supported"
-msgstr "не се поддържа редактиране на обекти-BLOB"
+msgid "replace multi-valued config option with new value"
+msgstr "замяна на настройка, приемаща много стойности, с нова стойност"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "конфигурационният файл „%s“ не може да бъде създаден"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "низ за подаване четим от хора (при нужда отпред се добавя „#“)"
+
+msgid "add a new line without altering any existing values"
+msgstr "добавяне на нов ред без промяна на съществуващи стойности"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "опцията „--fixed-value“ изисква опцията „--value=ШАБЛОН_ЗА_СТОЙНОСТ“"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "опциитe „--append“ и „--value=ШАБЛОН_ЗА_СТОЙНОСТ“ са несъвместими"
#, c-format
msgid ""
@@ -5715,6 +5741,92 @@ msgstr ""
msgid "no such section: %s"
msgstr "такъв раззел няма: %s"
+msgid "editing stdin is not supported"
+msgstr "не се поддържа редактиране на стандартния вход"
+
+msgid "editing blobs is not supported"
+msgstr "не се поддържа редактиране на обекти-BLOB"
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "конфигурационният файл „%s“ не може да бъде създаден"
+
+msgid "Action"
+msgstr "Действие"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "извеждане на стойност: ИМЕ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "извеждане на всички стойности: ключ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr ""
+"извеждане на стойностите за РЕГУЛЯРНия_ИЗРАЗ: name-regex "
+"[ШАБЛОН_ЗА_СТОЙНОСТТА]"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "извеждане на стойността за указания адрес: РАЗДЕЛ[.ПРОМЕНЛИВА] АДРЕС"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr ""
+"замяна на всички съвпадащи променливи: ИМЕ СТОЙНОСТ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
+
+msgid "add a new variable: name value"
+msgstr "добавяне на нова променлива: ИМЕ СТОЙНОСТ"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "изтриване на променлива: ИМЕ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "изтриване на всички съвпадащи: ИМЕ [ШАБЛОН_ЗА_СТОЙНОСТТА]"
+
+msgid "rename section: old-name new-name"
+msgstr "преименуване на раздел: СТАРО_ИМЕ НОВО_ИМЕ"
+
+msgid "remove a section: name"
+msgstr "изтриване на раздел: ИМЕ"
+
+msgid "list all"
+msgstr "изброяване на всички"
+
+msgid "open an editor"
+msgstr "отваряне на редактор"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "намиране на зададения цвят: номер [СТАНДАРТНО]"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "извеждане на зададения цвят: номер (СТАНД_ИЗХОД_НА_ТЕРМИНАЛ)"
+
+msgid "with --get, use default value when missing entry"
+msgstr "с „--get“ се използва стандартна СТОЙНОСТ при липсваща"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "опцията „--get-color“ не съответства на вида на променливата"
+
+msgid "no action specified"
+msgstr "не е зададено действие"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr ""
+"опцията „--name-only“ е приложима само към опциите „--list“ и „--get-regexp“"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"опцията „--show-origin“ е приложима само към опциите „--get“, „--get-all“, "
+"„--get-regexp“ и „--list“"
+
+msgid "--default is only applicable to --get"
+msgstr "опцията „--default“ е приложима само към опцията „--get“"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr ""
+"опцията „--comment“ е съвместима само с действията „add“ (добавяне)/„set“ "
+"(задаване)/„replace“ (замяна)"
+
msgid "print sizes in human readable format"
msgstr "извеждане на размерите на обектите във формат четим от хора"
@@ -6545,7 +6657,7 @@ msgid "read reference patterns from stdin"
msgstr "изчитане на шаблоните за указатели от стандартния вход"
msgid "also include HEAD ref and pseudorefs"
-msgstr "включване и на указателя „HEAD“ както и псевдоуказателите"
+msgstr "включване и на указателя „HEAD“ както и псевдо указателите"
msgid "unknown arguments supplied with --stdin"
msgstr "непознат аргумент към опцията „--stdin“"
@@ -6559,12 +6671,15 @@ msgstr "настройка"
msgid "config key storing a list of repository paths"
msgstr "настройка, която съдържа списък с пътища към хранилища"
+msgid "keep going even if command fails in a repository"
+msgstr "продължаване на действието дори и командата да е неуспешна в някое хранилище"
+
msgid "missing --config=<config>"
msgstr "липсва --config=НАСТРОЙКА"
#, c-format
msgid "got bad config --config=%s"
-msgstr "получена е неправилена настройка „--config=%s“"
+msgstr "получена е неправилна настройка „--config=%s“"
msgid "unknown"
msgstr "непознат"
@@ -8041,8 +8156,11 @@ msgstr "отбелязване, че това е N-тата поредна ре�
msgid "max length of output filename"
msgstr "максимална дължина на име на всеки пакетен файл"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "използване на „[RFC PATCH]“ вместо „[PATCH]“"
+msgid "rfc"
+msgstr "ПРЕФИКС"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "добавяне на този ПРЕФИКС (стандартно е „RFC“) пред „PATCH“"
msgid "cover-from-description-mode"
msgstr "режим-придружаващо-писмо-по-описание"
@@ -8282,7 +8400,7 @@ msgid "show resolve-undo information"
msgstr "извеждане на информацията за отмяна на разрешените подавания"
msgid "skip files matching pattern"
-msgstr "прескачане на файловете напасващи ШАБЛОНа"
+msgstr "прескачане на файловете напасващи на ШАБЛОНа"
msgid "read exclude patterns from <file>"
msgstr "изчитане на шаблоните за игнориране от ФАЙЛ"
@@ -8325,13 +8443,13 @@ msgstr ""
"deduplicate“/„--eol“"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=КОМАНДА]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=КОМАНДА]\n"
" [-q|--quiet] [--exit-code] [--get-url] [--sort=КЛЮЧ]\n"
-" [--symref] [ХРАНИЛИЩЕ [ШАБЛОН]]"
+" [--symref] [ХРАНИЛИЩЕ [ШАБЛОН…]]"
msgid "do not print remote URL"
msgstr "без извеждане на адресите на отдалечените хранилища"
@@ -8345,8 +8463,11 @@ msgstr "път към командата „git-upload-pack“ на отдале
msgid "limit to tags"
msgstr "само етикетите"
-msgid "limit to heads"
-msgstr "само върховете"
+msgid "limit to branches"
+msgstr "само клоните"
+
+msgid "deprecated synonym for --branches"
+msgstr "остарял синоним на „--branches“"
msgid "do not show peeled tags"
msgstr "без проследяване на непреките етикети"
@@ -9206,10 +9327,6 @@ msgstr "git notes prune [ОПЦИЯ…]"
msgid "Write/edit the notes for the following object:"
msgstr "Записване/редактиране на бележките за следния обект:"
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "действието „show“ не може да се изпълни за обект „%s“"
-
msgid "could not read 'show' output"
msgstr "изведената информация от действието „show“ не може да се прочете"
@@ -11076,6 +11193,22 @@ msgstr "не е указан журнал с подавания за изтри�
msgid "invalid ref format: %s"
msgstr "неправилен формат на указател: %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=ФОРМАТ [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "указване на форма̀та за указател, към който да се конвертира"
+
+msgid "perform a non-destructive dry-run"
+msgstr "пробно изпълнение — без промяна на данни"
+
+msgid "missing --ref-format=<format>"
+msgstr "липсва опцията --ref-format=ФОРМАТ"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "хранилището вече ползва форма̀та „%s“"
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -11363,9 +11496,6 @@ msgstr "● отдалечено хранилище „%s“"
msgid " Fetch URL: %s"
msgstr " Адрес за доставяне: %s"
-msgid "(no URL)"
-msgstr "(без адрес)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -11374,6 +11504,9 @@ msgstr "(без адрес)"
msgid " Push URL: %s"
msgstr " Адрес за изтласкване: %s"
+msgid "(no URL)"
+msgstr "(без адрес)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " клон сочен от HEAD: %s"
@@ -11483,10 +11616,6 @@ msgstr "запитване към адресите за изтласкване,
msgid "return all URLs"
msgstr "извеждане на всички адреси"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "не е зададен адрес за отдалеченото хранилище „%s“"
-
msgid "manipulate push URLs"
msgstr "промяна на адресите за изтласкване"
@@ -12511,12 +12640,12 @@ msgstr "Непознат алгоритъм за контролни суми"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d|--dereference]\n"
-" [-s|--hash[=БРОЙ]] [--abbrev[=БРОЙ]] [--tags]\n"
-" [--heads] [--] [ШАБЛОН…]"
+" [-s|--hash[=БРОЙ]] [--abbrev[=БРОЙ]] [--branches] [--tags]\n"
+" [--] [ШАБЛОН…]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -12539,11 +12668,11 @@ msgstr "указателят не съществува"
msgid "failed to look up reference"
msgstr "соченото от указателя липсва"
-msgid "only show tags (can be combined with heads)"
-msgstr "извеждане на етикетите (може да се комбинира с върховете)"
+msgid "only show tags (can be combined with branches)"
+msgstr "извеждане на етикетите (може да се комбинира с „--branches“ за клони)"
-msgid "only show heads (can be combined with tags)"
-msgstr "извеждане на върховете (може да се комбинира с етикетите)"
+msgid "only show branches (can be combined with tags)"
+msgstr "извеждане на клоните (може да се комбинира с „--tags“ за етикети)"
msgid "check for reference existence without resolving"
msgstr "проверка за съществуване на указател без проследяването му"
@@ -13183,14 +13312,14 @@ msgstr ""
"друг подмодул"
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "Неуспешно клониране на адреса „%s“ в пътя „%s“ като подмодул"
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "директорията не е празна: „%s“"
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "Неуспешно клониране на адреса „%s“ в пътя „%s“ като подмодул"
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "директорията на подмодула „%s“ не може да бъде получена"
@@ -13555,9 +13684,11 @@ msgstr "причина за обновяването"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a|-s|-u ИДЕНТИФИКАТОР_НА_КЛЮЧ] [-f] [-m СЪОБЩЕНИЕ|-F ФАЙЛ] [-e]\n"
+" [(--trailer ЛЕКСЕМА[(=|:)СТОЙНОСТ])…]\n"
" ЕТИКЕТ [ПОДАВАНЕ|ОБЕКТ]"
msgid "git tag -d <tagname>..."
@@ -14443,9 +14574,6 @@ msgstr "непозната заглавна част: %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "В хранилището липсват следните необходими подавания:"
-msgid "need a repository to verify a bundle"
-msgstr "за проверката на пратка е необходимо хранилище"
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14856,6 +14984,9 @@ msgstr "Получаване на изтласканото в хранилище
msgid "Manage reflog information"
msgstr "Управление на информацията в журнала на указателите"
+msgid "Low-level access to refs"
+msgstr "Достъп от ниско ниво до указателите"
+
msgid "Manage set of tracked repositories"
msgstr "Управление на набор от следени хранилища"
@@ -15167,6 +15298,14 @@ msgid "commit-graph required commit data chunk missing or corrupted"
msgstr ""
"откъсът за данните необходими на гра̀фа с подаванията липсва или е повреден"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"изключване на филтрите на Блум за слой „%s“ на гра̀фа с подаванията поради "
+"несъвместими настройки"
+
msgid "commit-graph has no base graphs chunk"
msgstr "базовият откъс липсва в гра̀фа с подаванията"
@@ -15298,6 +15437,14 @@ msgstr ""
"опит за запис на гра̀фа с подаванията, но настройката „core.commitGraph“ е "
"изключена"
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"опит за запис на гра̀фа с подаванията, но настройката „commitGraph."
+"changedPathsVersion“ (%d) не се поддържа"
+
msgid "too many commits to write graph"
msgstr "прекалено много подавания за записване на гра̀фа"
@@ -17213,16 +17360,21 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v|--version] [-h|--help] [-C ПЪТ] [-c ИМЕ=СТОЙНОСТ]\n"
" [--exec-path[=ПЪТ]] [--html-path] [--man-path] [--info-path]\n"
-" [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]\n"
-" [--git-dir=ПЪТ] [--work-tree=ПЪТ] [--namespace=ИМЕ]\n"
-" [--config-env=ИМЕ=ПРОМЕНЛИВА_НА_СРЕДАТА] КОМАНДА [АРГ…]"
+" [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--no-lazy-"
+"fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=ПЪТ]\n"
+" [--work-tree=ПЪТ] [--namespace=ИМЕ] [--config-"
+"env=ИМЕ=ПРОМЕНЛИВА_НА_СРЕДАТА]\n"
+" КОМАНДА [АРГ…]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -17576,13 +17728,13 @@ msgstr ""
"За да изключите това предупреждение, изпълнете:\n"
" git config advice.ignoredHook false"
+msgid "not a git repository"
+msgstr "не е хранилище на Git"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "опцията „--packfile“ изисква валидна контролна сума (а не „%s“)"
-msgid "not a git repository"
-msgstr "не е хранилище на Git"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr ""
@@ -17594,6 +17746,9 @@ msgstr "Управлението на делегирането не се под�
msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "Задаването на постоянен публичен ключ не се поддържа от cURL < 7.39.0"
+msgid "Unknown value for http.proactiveauth"
+msgstr "Непозната стойност за „http.proactiveauth“"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "„CURLSSLOPT_NO_REVOKE“ не се поддържа от cURL < 7.44.0"
@@ -17613,6 +17768,12 @@ msgstr ""
"Реализацията на SSL не може да се зададе да е „%s“, защото вече е зададена "
"друга"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "отказ от прочитане на бисквитките от „http.cookiefile“: „-“"
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "прескачане на „http.savecookies“ за празен „http.cookiefile“"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -17776,6 +17937,10 @@ msgid "quoted CRLF detected"
msgstr "цитирани знаци CRLF"
#, c-format
+msgid "unable to format message: %s"
+msgstr "съобщението не може да се форматира: %s"
+
+#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Неуспешно сливане на подмодула „%s“ (не е изтеглен)"
@@ -17788,8 +17953,8 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "Неуспешно сливане на подмодула „%s“ (няма подавания)"
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "Неуспешно сливане на подмодула „%s“ (хранилището е с грешки)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "ГРЕШКА: неуспешно сливане на подмодула „%s“ (хранилището е с грешки)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -17818,12 +17983,13 @@ msgstr ""
"Неуспешно сливане на подмодула „%s“, но са открити множество решения:\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "неуспешно вътрешно сливане"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "ГРЕШКА: неуспешно вътрешно сливане за „%s“"
#, c-format
-msgid "unable to add %s to database"
-msgstr "„%s“ не може да се добави в базата от данни"
+msgid "error: unable to add %s to database"
+msgstr "ГРЕШКА: „%s“ не може да се добави в базата от данни"
#, c-format
msgid "Auto-merging %s"
@@ -17919,12 +18085,12 @@ msgstr ""
"е изтрит в „%s“."
#, c-format
-msgid "cannot read object %s"
-msgstr "обектът „%s“ не може да се прочете"
+msgid "error: cannot read object %s"
+msgstr "ГРЕШКА: обектът „%s“ не може да се прочете"
#, c-format
-msgid "object %s is not a blob"
-msgstr "обектът „%s“ не е BLOB"
+msgid "error: object %s is not a blob"
+msgstr "ГРЕШКА: обектът „%s“ не е BLOB"
#, c-format
msgid ""
@@ -18067,6 +18233,10 @@ msgstr ""
"не е ясно какво да се прави с обекта „%2$s“ (%3$s) с права̀ за достъп „%1$06o“"
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Неуспешно сливане на подмодула „%s“ (хранилището е с грешки)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Превъртане на подмодула „%s“ до следното подаване:"
@@ -18108,6 +18278,13 @@ msgstr ""
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Неуспешно сливане на подмодула „%s“ (открити са множество сливания)"
+msgid "failed to execute internal merge"
+msgstr "неуспешно вътрешно сливане"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "„%s“ не може да се добави в базата от данни"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr "Грешка: за да не се изтрие неследеният файл „%s“, се записва в „%s“."
@@ -18210,6 +18387,14 @@ msgstr ""
"КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
"„%s“, а „%s“ е преименуван на „%s“ в „%s“"
+#, c-format
+msgid "cannot read object %s"
+msgstr "обектът „%s“ не може да се прочете"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "обектът „%s“ не е BLOB"
+
msgid "modify"
msgstr "промяна"
@@ -18294,11 +18479,6 @@ msgstr "редът не може да се анализира: „%s“"
msgid "malformed line: %s"
msgstr "неправилен ред: „%s“."
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr ""
-"индексът за множество пакети се прескача, защото сумата за проверка не "
-"съвпада"
-
msgid "could not load pack"
msgstr "пакетът не може да се зареди"
@@ -18306,6 +18486,11 @@ msgstr "пакетът не може да се зареди"
msgid "could not open index for %s"
msgstr "индексът за „%s“ не може да се отвори"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr ""
+"индексът за множество пакети се прескача, защото сумата за проверка не "
+"съвпада"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Добавяне на пакетни файлове към индекс за множество пакети"
@@ -18946,6 +19131,17 @@ msgstr "обектът „%s“ не може да бъде анализиран
msgid "hash mismatch %s"
msgstr "разлика в контролната сума: „%s“"
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "повтарящ се запис при запазване на индекс на база битови маски: „%s“"
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "опит за съхраняване на подаване, което не е избрано: „%s“"
+
+msgid "too many pseudo-merges"
+msgstr "прекалено много псевдо сливания"
+
msgid "trying to write commit not in index"
msgstr "опит за записване на обект за подаване извън индекса"
@@ -18973,6 +19169,22 @@ msgstr ""
"повреден файл за индекс на база битови маски (прекалено е малък дори и за "
"таблицата със съответствия)"
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"повреден файл за индекс на база битови маски (прекалено е малък дори и за "
+"заглавната част на таблицата за псевдо сливанията)"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr ""
+"повреден файл за индекс на база битови маски (прекалено е малък дори и за "
+"таблицата с псевдо сливания)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr ""
+"повреден индекс на база битови маски, таблицата с псевдо сливания е "
+"прекалено малка"
+
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "повтарящ се запис в индекс на база битови маски: „%s“"
@@ -19045,6 +19257,11 @@ msgid "unable to load pack: '%s', disabling pack-reuse"
msgstr ""
"пакетът не може да се зареди: „%s“, преизползването на пакети се изключва"
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr ""
+"предпочитаният пакет не може да се определи, преизползването на пакети се "
+"изключва"
+
#, c-format
msgid "object '%s' not found in type bitmaps"
msgstr "обектът „%s“ липсва в битовата маска на видовете"
@@ -19075,6 +19292,10 @@ msgid "mismatch in bitmap results"
msgstr "различие в резултатите от битовите маски"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "индексът за псевдо сливане е извън диапазона (%<PRIu32> ≥ %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "„%s“ липсва в пакет „%s“ при отместване %<PRIuMAX>"
@@ -19244,18 +19465,6 @@ msgstr "непознат флаг „%c“"
msgid "unknown non-ascii option in string: `%s'"
msgstr "непозната стойност извън „ascii“ в низа: „%s“"
-#, c-format
-msgid "[=<%s>]"
-msgstr "[=%s]"
-
-#, c-format
-msgid "[<%s>]"
-msgstr "[%s]"
-
-#, c-format
-msgid " <%s>"
-msgstr " %s"
-
msgid "..."
msgstr "…"
@@ -19468,6 +19677,9 @@ msgstr "не може да се създаде нишка за изпълнен�
msgid "unable to parse --pretty format"
msgstr "аргументът към опцията „--pretty“ не може да се анализира"
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "отложеното доставяне е изключено, някои обекти може и да липсват"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "хранилище-гарант: неуспешно създаване на процес за доставяне"
@@ -19494,6 +19706,66 @@ msgstr "object-info: след аргументите се очаква изчи�
msgid "Removing duplicate objects"
msgstr "Изтриване на повтарящите се обекти"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr ""
+"регулярният израз за псевдо сливания за „%s“, не може да бъде зареден: „%s“"
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s трябва да е неотрицателно, ще се ползва стандартната стойност"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s трябва да е между 0 и 1, ще се ползва стандартната стойност"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s трябва да е положително, ще се ползва стандартната стойност"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "в групата за псевдо сливания „%s“ липсва задължителен шаблон"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr "в групата за псевдо сливания „%s“ има нестабилен праг пред стабилния"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"регулярният израз за псевдо сливания в конфигурационния файл съдържа повече "
+"от максимално поддържаните прихващащи групи (max=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"опит за четене на разширено псевдо сливане извън диапазона (%<PRIuMAX> ≥ "
+"%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"прекалено кратък запис за разширено псевдо сливане (%<PRIuMAX> ≥ %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr "липсва псевдо сливане за подаване „%s“ при отместване %<PRIuMAX>"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr ""
+"четене за група за псевдо сливания зад границите (%<PRIu32> ≥ %<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "четене зад границите (%<PRIuMAX> ≥ %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "таблицата с разширените псевдо сливания за „%s“ не може да се прочете"
+
msgid "could not start `log`"
msgstr "командата за журнала с подавания „log“ не може да се стартира"
@@ -20077,14 +20349,13 @@ msgid ""
"\n"
"\tgit branch -m <name>\n"
msgstr ""
-"Първоначалният клон ще се казва „%s“. Това може да се променѝ. Може да "
-"зададете\n"
+"Първоначалният клон ще се казва „%s“. Това може да се променѝ. Може да зададете\n"
"настройката и да спрете това съобщение. За това изпълнете:\n"
"\n"
" git config --global init.defaultBranch ИМЕ\n"
"\n"
"Често ползвани варианти вместо „master“ са „main“, „trunk“ и „development“.\n"
-"За да преименувата току що създаден клон, изпълнете:\n"
+"За да преименувате току що създаден клон, изпълнете:\n"
"\n"
" git branch -m ИМЕ\n"
@@ -20112,11 +20383,20 @@ msgstr "журналът с подаванията за указателя „%s
msgid "log for %s is empty"
msgstr "журналът с подаванията за указателя „%s“ е празен"
+msgid "refusing to force and skip creation of reflog"
+msgstr ""
+"принудителна операция без създаване на журнал на указателите няма да се "
+"приеме"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "указател не може да се обнови с грешно име „%s“"
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "псевдо указателят „%s“ няма да се обнови"
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "неуспешно обновяване на указателя (update_ref) „%s“: %s"
@@ -20147,6 +20427,25 @@ msgid "could not delete references: %s"
msgstr "Указателите не може да бъдат изтрити: %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "Пробната миграция на указатели завърши, резултатите са в „%s“\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "временната директория за миграция „%s“ не може да се изтрие"
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "мигрираните указатели са в „%s“"
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"указателят „%s“ не може да се заключи: очакваше се файл с указател с цел "
+"„%s“, но вместо това е обикновен указател"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "опасно име на указател: %s"
@@ -20694,9 +20993,7 @@ msgstr "„%s“ съществува и не е символна връзка"
msgid ""
"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
"REVERT_HEAD or REBASE_HEAD"
-msgstr ""
-"„--merge“ изисква някой от псевдоуказателите „MERGE_HEAD“, "
-"„CHERRY_PICK_HEAD“, „REVERT_HEAD“ или „REBASE_HEAD“"
+msgstr "„--merge“ изисква някой от псевдо указателите „MERGE_HEAD“, „CHERRY_PICK_HEAD“, „REVERT_HEAD“ или „REBASE_HEAD“"
#, c-format
msgid "could not get commit for --ancestry-path argument %s"
@@ -21357,6 +21654,56 @@ msgstr ""
"командата „update-ref“ изисква пълно име на указател, напр. „refs/heads/%s“"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "„%s“ не приема подавания със сливане"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"„pick“ не приема подаване със сливане. Ако искате да приложите\n"
+"сливането наново изпълнате:\n"
+"\n"
+" git merge -C ПОДАВАНЕ"
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"„reword“ не приема подаване със сливане. Ако искате да приложите\n"
+"сливането наново и да промените съобщението при подаване, изпълнете\n"
+"\n"
+" git merge -C ПОДАВАНЕ"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"„edit“ не приема подаване със сливане. Ако искате да приложите\n"
+"сливането наново, изпълнете\n"
+"\n"
+" git merge -C ПОДАВАНЕ\n"
+"\n"
+"а след него задайте „break“, за да получите контрол и да изпълнете:\n"
+"\n"
+" git commit --amend && git rebase --continue"
+
+msgid "cannot squash merge commit into another commit"
+msgstr "подаване със сливане не може да се вкара в друго"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "неправилна команда „%.*s“"
@@ -21483,9 +21830,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "указателят „HEAD“ не може да бъде прочетен"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "„%s“ не може да се копира като „%s“"
+msgid "could not write commit message file"
+msgstr "файлът със съобщението за подаване не може да бъде записан"
#, c-format
msgid ""
@@ -21894,6 +22240,18 @@ msgstr "процесът не може да се върне към предиш�
msgid "failed to stat '%*s%s%s'"
msgstr "не може да бъде получена информация чрез „stat“ за „%*s%s%s“"
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"засечено е проблемно притежание на хранилището „%s“\n"
+"%sЗа да зададете изключение за тази директория, изпълнете:\n"
+"\n"
+" git config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Текущата работна директория не може да бъде прочетена"
@@ -21918,18 +22276,6 @@ msgstr ""
"„GIT_DISCOVERY_ACROSS_FILESYSTEM“ не е зададена."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"засечено е проблемно притежание на хранилището „%s“\n"
-"%sЗа да зададете изключение за тази директория, изпълнете:\n"
-"\n"
-" git config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr ""
"голото хранилище „%s“ не може да се ползва („safe.bareRepository“ е „%s“)"
@@ -22241,6 +22587,14 @@ msgid "submodule git dir '%s' is inside git dir '%.*s'"
msgstr "„%s“ (директория на подмодул) е в директорията на git: „%.*s“"
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr "„%.*s“ в пътя за подмодул „%s“ не трябва да е символна връзка"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "пътят за подмодул „%s“ не трябва да е символна връзка"
+
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -22279,10 +22633,6 @@ msgstr "не може да бъде получена информация чре
msgid "no remote configured to get bundle URIs from"
msgstr "не е настроено отдалечено хранилище за списъците с адреси на пратки"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "не е зададен никакъв адрес за отдалеченото хранилище„%s“"
-
msgid "could not get the bundle-uri list"
msgstr "списъкът с адреси на пратки не може да се получи"
@@ -22613,9 +22963,7 @@ msgid "bundle-uri operation not supported by protocol"
msgstr "операцията „bundle-uri“ (адреси на пратки) не се поддържа от протокола"
msgid "could not retrieve server-advertised bundle-uri list"
-msgstr ""
-"спъсъкът с адреси на пратки обявени за налични от сървъра не може да се "
-"получи "
+msgstr "списъкът с адреси на пратки обявени за налични от сървъра не може да се получи "
msgid "operation not supported by protocol"
msgstr "опцията не се поддържа от протокола"
@@ -23379,7 +23727,7 @@ msgid ""
"but the results were cached, and subsequent runs may be faster."
msgstr ""
"Изброяването на неследените файлове отне %.2f секунди, но\n"
-"резултатите са запомнени и може да забързат последващиге изброявания."
+"резултатите са запомнени и може да забързат последващите изброявания."
#, c-format
msgid "It took %.2f seconds to enumerate untracked files."
@@ -23785,24 +24133,24 @@ msgid "Failed to send %s\n"
msgstr "„%s“ не може да бъде изпратен\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Проба за изпращане на „%s“\n"
+msgid "Dry-Sent %s"
+msgstr "Проба за изпращане на „%s“"
#, perl-format
-msgid "Sent %s\n"
-msgstr "Изпращане на „%s“\n"
+msgid "Sent %s"
+msgstr "Изпращане на „%s“"
-msgid "Dry-OK. Log says:\n"
-msgstr "Успех при пробата. От журнала:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Успех при пробата. От журнала:"
-msgid "OK. Log says:\n"
-msgstr "Успех. От журнала:\n"
+msgid "OK. Log says:"
+msgstr "Успех. От журнала:"
msgid "Result: "
msgstr "Резултат: "
-msgid "Result: OK\n"
-msgstr "Резултат: успех\n"
+msgid "Result: OK"
+msgstr "Резултат: успех"
#, perl-format
msgid "can't open file %s"
diff --git a/po/de.po b/po/de.po
index 2946566597..e271476cd2 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-26 16:16+0200\n"
-"PO-Revision-Date: 2024-04-26 16:22+0200\n"
+"POT-Creation-Date: 2024-07-19 19:21+0200\n"
+"PO-Revision-Date: 2024-07-19 19:25+0200\n"
"Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n"
"Language-Team: German\n"
"Language: de\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
-"X-Generator: Poedit 3.4.1\n"
+"X-Generator: Poedit 3.4.4\n"
#, c-format
msgid "Huh (%s)?"
@@ -582,6 +582,10 @@ msgstr ""
"p - aktuellen Patch-Block anzeigen\n"
"? - Hilfe anzeigen\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Es wird nur ein Buchstabe erwartet, '%s' erhalten"
+
msgid "No previous hunk"
msgstr "Kein vorheriger Patch-Block"
@@ -630,9 +634,19 @@ msgstr "In %d Patch-Block aufgeteilt."
msgid "Sorry, cannot edit this hunk"
msgstr "Entschuldigung, kann diesen Patch-Block nicht bearbeiten"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "Unbekannter Befehl '%s' (für Hilfe '?' verwenden)"
+
msgid "'git apply' failed"
msgstr "'git apply' schlug fehl"
+msgid "No changes."
+msgstr "Keine Änderungen."
+
+msgid "Only binary files changed."
+msgstr "Nur Binärdateien geändert."
+
#, c-format
msgid ""
"\n"
@@ -1517,6 +1531,10 @@ msgstr "ignoriere übermäßig große gitattributes-Datei '%s'"
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "ignoriere übermäßig großen gitattribute-Blob '%s'"
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr ""
+"kann nicht --attr-source oder GIT_ATTR_SOURCE ohne Repository verwenden"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "ungültiges --attr-source oder GIT_ATTR_SOURCE"
@@ -1838,13 +1856,6 @@ msgid "Unstaged changes after refreshing the index:"
msgstr ""
"Nicht zum Commit vorgemerkte Änderungen nach Aktualisierung der Staging-Area:"
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"Die Einstellung add.interactive.useBuiltin wurde entfernt!\n"
-"Siehe den Eintrag in 'git help config' für Details."
-
msgid "could not read the index"
msgstr "konnte den Index nicht lesen"
@@ -2302,6 +2313,9 @@ msgstr "Patch-Operation abbrechen, aber HEAD an aktueller Stelle belassen"
msgid "show the patch being applied"
msgstr "den Patch, der gerade angewendet wird, anzeigen"
+msgid "try to apply current patch again"
+msgstr "den aktuellen Patch erneut versuchen anzuwenden"
+
msgid "record the empty patch as an empty commit"
msgstr "leerer Patch als leeren Commit gespeichert"
@@ -2357,9 +2371,6 @@ msgstr "git apply [<Optionen>] [<Patch>...]"
msgid "could not redirect output"
msgstr "konnte Ausgabe nicht umleiten"
-msgid "git archive: Remote with no URL"
-msgstr "git archive: Externes Archiv ohne URL"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive: ACK/NAK erwartet, Flush-Paket bekommen"
@@ -3282,6 +3293,9 @@ msgstr "Um ein Paket zu erstellen wird ein Repository benötigt."
msgid "do not show bundle details"
msgstr "Keine Bundle-Details anzeigen"
+msgid "need a repository to verify a bundle"
+msgstr "um ein Paket zu überprüfen wird ein Repository benötigt"
+
#, c-format
msgid "%s is okay\n"
msgstr "%s ist in Ordnung\n"
@@ -4324,6 +4338,14 @@ msgid "failed to unlink '%s'"
msgstr "Konnte '%s' nicht entfernen."
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "Hardlink bei '%s' kann nicht geprüft werden"
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "Hardlink unterscheidet sich von der Quelle bei '%s'"
+
+#, c-format
msgid "failed to create link '%s'"
msgstr "Konnte Verweis '%s' nicht erstellen"
@@ -5180,15 +5202,52 @@ msgstr ""
"voll und Ihr Kontingent nicht aufgebraucht ist und führen Sie\n"
"anschließend \"git restore --staged :/\" zur Wiederherstellung aus."
-msgid "git config [<options>]"
-msgstr "git config [<Optionen>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<Datei-Option>] [<Anzeige-Option>] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "nicht erkanntes --type Argument, %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<Datei-Option>] [<Anzeige-Option>] [--includes] [--all] [--"
+"regexp=<Regex>] [--value=<Wert>] [--fixed-value] [--default=<Standardwert>] "
+"<Name>"
-msgid "only one type at a time"
-msgstr "nur ein Typ erlaubt"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<Datei-Option>] [--type=<Typ>] [--all] [--value=<Wert>] [--"
+"fixed-value] <Name> <Wert>"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<Datei-Option>] [--all] [--value=<Wert>] [--fixed-value] "
+"<Name> <Wert>"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<Datei-Option>] <alter-Name> <neuer-Name>"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<Datei-Option>] <Name>"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<Datei-Option>]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr ""
+"git config [<Datei-Option>] --get-colorbool <Name> [<Standard-Ausgabe-ist-"
+"Terminal>]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<Datei-Option>] [--type=<Typ>] [--comment=<Nachricht>] [--"
+"all] [--value=<Wert>] [--fixed-value] <Name> <Wert>"
msgid "Config file location"
msgstr "Ort der Konfigurationsdatei"
@@ -5214,55 +5273,6 @@ msgstr "Blob-Id"
msgid "read config from given blob object"
msgstr "Konfiguration von angegebenem Blob-Objekt lesen"
-msgid "Action"
-msgstr "Aktion"
-
-msgid "get value: name [value-pattern]"
-msgstr "Wert zurückgeben: Name [Wert-Muster]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "alle Werte zurückgeben: Schlüssel [Wert-Muster]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "Werte für den regulären Ausdruck zurückgeben: Name-Regex [Wert-Muster]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "Wert spezifisch für eine URL zurückgeben: section[.var] URL"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "alle passenden Variablen ersetzen: Name Wert [Wert-Muster] "
-
-msgid "add a new variable: name value"
-msgstr "neue Variable hinzufügen: Name Wert"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "eine Variable entfernen: Name [Wert-Muster]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "alle Übereinstimmungen entfernen: Name [Wert-Muster]"
-
-msgid "rename section: old-name new-name"
-msgstr "eine Sektion umbenennen: alter-Name neuer-Name"
-
-msgid "remove a section: name"
-msgstr "eine Sektion entfernen: Name"
-
-msgid "list all"
-msgstr "alles auflisten"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr ""
-"nutze String-Gleichheit beim Vergleich von Werten mit dem 'Wert-Muster'"
-
-msgid "open an editor"
-msgstr "einen Editor öffnen"
-
-msgid "find the color configured: slot [default]"
-msgstr "die konfigurierte Farbe finden: Slot [Standard]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "die Farbeinstellung finden: Slot [Standard-Ausgabe-ist-Terminal]"
-
msgid "Type"
msgstr "Typ"
@@ -5290,8 +5300,8 @@ msgstr "Wert ist ein Pfad (Datei oder Verzeichnisname)"
msgid "value is an expiry date"
msgstr "Wert ist ein Verfallsdatum"
-msgid "Other"
-msgstr "Sonstiges"
+msgid "Display options"
+msgstr "Anzeigeoptionen"
msgid "terminate values with NUL byte"
msgstr "schließt Werte mit NUL-Byte ab"
@@ -5299,9 +5309,6 @@ msgstr "schließt Werte mit NUL-Byte ab"
msgid "show variable names only"
msgstr "nur Variablennamen anzeigen"
-msgid "respect include directives on lookup"
-msgstr "beachtet \"include\"-Direktiven beim Nachschlagen"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr ""
"Ursprung der Konfiguration anzeigen (Datei, Standard-Eingabe, Blob, "
@@ -5312,15 +5319,15 @@ msgstr ""
"Zeige Geltungsbereich der Konfiguration (Arbeitsverzeichnis, lokal, global, "
"systemweit, Befehl)"
-msgid "value"
-msgstr "Wert"
+msgid "show config keys in addition to their values"
+msgstr "Konfigurationsschlüssel zusätzlich zu dessen Werten anzeigen"
-msgid "with --get, use default value when missing entry"
-msgstr "mit --get, benutze den Standardwert, wenn der Eintrag fehlt"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "nicht erkanntes --type Argument, %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr ""
-"menschenlesbare Kommentarzeichenfolge (# wird bei Bedarf vorangestellt)"
+msgid "only one type at a time"
+msgstr "nur ein Typ erlaubt"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5398,47 +5405,73 @@ msgstr ""
"lesen Sie die Sektion \"CONFIGURATION FILE\" in \"git help worktree\" für "
"Details"
-msgid "--get-color and variable type are incoherent"
-msgstr "Angabe von --get-color und Variablentyp sind ungültig."
+msgid "Other"
+msgstr "Sonstiges"
-msgid "only one action at a time"
-msgstr "Nur eine Aktion erlaubt."
+msgid "respect include directives on lookup"
+msgstr "beachtet \"include\"-Direktiven beim Nachschlagen"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only ist nur anwendbar auf --list oder --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "Konnte Konfigurationsdatei '%s' nicht lesen."
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-"--show-origin ist nur anwendbar auf --get, --get-all, --get-regexp und --list"
+msgid "error processing config file(s)"
+msgstr "Fehler beim Verarbeiten der Konfigurationsdatei(en)."
-msgid "--default is only applicable to --get"
-msgstr "--default ist nur anwendbar auf --get"
+msgid "Filter options"
+msgstr "Filter-Optionen"
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr ""
-"--comment darf nur für die Operationen add/set/replace verwendet werden"
+msgid "return all values for multi-valued config options"
+msgstr "alle Werte für mehrwertige Konfigurationsoptionen zurückgeben"
+
+msgid "interpret the name as a regular expression"
+msgstr "den Namen als regulären Ausdruck interpretieren"
+
+msgid "show config with values matching the pattern"
+msgstr "Anzeige von Konfiguration mit Werten, die dem Muster entsprechen"
+
+msgid "use string equality when comparing values to value pattern"
+msgstr "String-Gleichheit beim Vergleich von Werten mit Wertmustern verwenden"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "show config matching the given URL"
+msgstr "Konfiguration für die angegebene URL anzeigen"
+
+msgid "value"
+msgstr "Wert"
+
+msgid "use default value when missing entry"
+msgstr "Standardwert verwenden, wenn Eintrag fehlt"
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value wird nur zusammen mit 'Wert-Muster' angewendet"
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "Konnte Konfigurationsdatei '%s' nicht lesen."
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= kann nicht mit --all oder --url= verwendet werden"
-msgid "error processing config file(s)"
-msgstr "Fehler beim Verarbeiten der Konfigurationsdatei(en)."
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= kann nicht mit --all, --regexp oder --value verwendet werden"
-msgid "editing stdin is not supported"
-msgstr "Das Bearbeiten der Standard-Eingabe wird nicht unterstützt."
+msgid "Filter"
+msgstr "Filter"
-msgid "editing blobs is not supported"
-msgstr "Das Bearbeiten von Blobs wird nicht unterstützt."
+msgid "replace multi-valued config option with new value"
+msgstr "mehrwertige Konfigurationsoption durch einen neuen Wert ersetzen"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "Konnte Konfigurationsdatei '%s' nicht erstellen."
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"menschenlesbare Kommentarzeichenfolge (# wird bei Bedarf vorangestellt)"
+
+msgid "add a new line without altering any existing values"
+msgstr "eine neue Zeile hinzufügen, ohne bestehende Werte zu ändern"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value gilt nur mit --value=<pattern>"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append kann nicht mit --value=<pattern> verwendet werden"
#, c-format
msgid ""
@@ -5453,6 +5486,86 @@ msgstr ""
msgid "no such section: %s"
msgstr "Sektion nicht gefunden: %s"
+msgid "editing stdin is not supported"
+msgstr "Das Bearbeiten der Standard-Eingabe wird nicht unterstützt."
+
+msgid "editing blobs is not supported"
+msgstr "Das Bearbeiten von Blobs wird nicht unterstützt."
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "Konnte Konfigurationsdatei '%s' nicht erstellen."
+
+msgid "Action"
+msgstr "Aktion"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "Wert zurückgeben: Name [<Wert-Muster>]"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "alle Werte zurückgeben: Schlüssel [<Wert-Muster>]"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "Werte für den regulären Ausdruck zurückgeben: Name-Regex <Wert-Muster>"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "Wert spezifisch für eine URL zurückgeben: section[.var] URL"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "alle passenden Variablen ersetzen: Name Wert [<Wert-Muster>]"
+
+msgid "add a new variable: name value"
+msgstr "neue Variable hinzufügen: Name Wert"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "eine Variable entfernen: Name [<Wert-Muster>]"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "alle Treffer entfernen: Name [<Wert-Muster>]"
+
+msgid "rename section: old-name new-name"
+msgstr "eine Sektion umbenennen: alter-Name neuer-Name"
+
+msgid "remove a section: name"
+msgstr "eine Sektion entfernen: Name"
+
+msgid "list all"
+msgstr "alles auflisten"
+
+msgid "open an editor"
+msgstr "einen Editor öffnen"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "die konfigurierte Farbe finden: Slot [<Standard>]"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "die Farbeinstellung finden: Slot [Standard-Ausgabe-ist-Terminal]"
+
+msgid "with --get, use default value when missing entry"
+msgstr "mit --get, benutze den Standardwert, wenn der Eintrag fehlt"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "Angabe von --get-color und Variablentyp sind ungültig."
+
+msgid "no action specified"
+msgstr "keine Aktion angegeben"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only ist nur anwendbar auf --list oder --get-regexp"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin ist nur anwendbar auf --get, --get-all, --get-regexp und --list"
+
+msgid "--default is only applicable to --get"
+msgstr "--default ist nur anwendbar auf --get"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr ""
+"--comment darf nur für die Operationen add/set/replace verwendet werden"
+
msgid "print sizes in human readable format"
msgstr "gibt Größenangaben in menschenlesbaren Format aus"
@@ -6306,6 +6419,9 @@ msgstr "Konfiguration"
msgid "config key storing a list of repository paths"
msgstr "Konfigurationsschlüssel für eine Liste von Repository-Pfaden"
+msgid "keep going even if command fails in a repository"
+msgstr "weiterarbeiten, auch wenn der Befehl in einem Repository fehlschlägt"
+
msgid "missing --config=<config>"
msgstr "Option --config=<Konfiguration> fehlt"
@@ -7781,8 +7897,11 @@ msgstr "die Serie als n-te Fassung kennzeichnen"
msgid "max length of output filename"
msgstr "maximale Länge des Dateinamens für die Ausgabe"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "[RFC PATCH] statt [PATCH] verwenden"
+msgid "rfc"
+msgstr "rfc"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "<rfc> (standardmäßig 'RFC') vor 'PATCH' hinzufügen"
msgid "cover-from-description-mode"
msgstr "Modus für Erstellung des Deckblattes aus der Beschreibung"
@@ -8058,11 +8177,11 @@ msgstr ""
"verwendet werden"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<Programm>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<Programm>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<Schlüssel>]\n"
" [--symref] [<Repository> [<Muster>...]]"
@@ -8078,8 +8197,11 @@ msgstr "Pfad zu \"git-upload-pack\" auf der Gegenseite"
msgid "limit to tags"
msgstr "auf Tags einschränken"
-msgid "limit to heads"
-msgstr "auf Branches einschränken"
+msgid "limit to branches"
+msgstr "Beschränkung auf Branches"
+
+msgid "deprecated synonym for --branches"
+msgstr "veraltetes Synonym für --branches"
msgid "do not show peeled tags"
msgstr "keine Tags anzeigen, die andere Tags enthalten"
@@ -10805,6 +10927,22 @@ msgstr "Kein Reflog zum Löschen angegeben."
msgid "invalid ref format: %s"
msgstr "Ungültiges Format für Referenzen: %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<Format> [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "das Referenzformat angeben, in das konvertiert werden soll"
+
+msgid "perform a non-destructive dry-run"
+msgstr "einen zerstörungsfreien Trockenlauf durchführen"
+
+msgid "missing --ref-format=<format>"
+msgstr "fehlendes --ref-format=<Format>"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "das Repository verwendet bereits das Format '%s'"
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -11092,9 +11230,6 @@ msgstr "* Remote-Repository %s"
msgid " Fetch URL: %s"
msgstr " URL zum Abholen: %s"
-msgid "(no URL)"
-msgstr "(keine URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -11103,6 +11238,9 @@ msgstr "(keine URL)"
msgid " Push URL: %s"
msgstr " URL zum Versenden: %s"
+msgid "(no URL)"
+msgstr "(keine URL)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " Hauptbranch: %s"
@@ -11212,10 +11350,6 @@ msgstr "nur URLs für Push ausgeben"
msgid "return all URLs"
msgstr "alle URLs ausgeben"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "Keine URLs für Remote-Repository '%s' konfiguriert."
-
msgid "manipulate push URLs"
msgstr "URLs für \"push\" manipulieren"
@@ -12235,12 +12369,12 @@ msgstr "Unbekannter Hash-Algorithmus"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<Muster>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<Muster>...]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -12263,11 +12397,11 @@ msgstr "Referenz nicht vorhanden"
msgid "failed to look up reference"
msgstr "Fehler beim Nachschlagen der Referenz"
-msgid "only show tags (can be combined with heads)"
-msgstr "nur Tags anzeigen (kann mit \"heads\" kombiniert werden)"
+msgid "only show tags (can be combined with branches)"
+msgstr "nur Tags anzeigen (kann mit Branches kombiniert werden)"
-msgid "only show heads (can be combined with tags)"
-msgstr "nur Branches anzeigen (kann mit \"tags\" kombiniert werden)"
+msgid "only show branches (can be combined with tags)"
+msgstr "nur Branches anzeigen (kann mit Tags kombiniert werden)"
msgid "check for reference existence without resolving"
msgstr "Prüfung auf Vorhandensein einer Referenz, ohne diese aufzulösen"
@@ -12919,14 +13053,14 @@ msgstr ""
"verweigert."
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "Klonen von '%s' in Submodul-Pfad '%s' fehlgeschlagen."
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "Verzeichnis ist nicht leer: '%s'"
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "Klonen von '%s' in Submodul-Pfad '%s' fehlgeschlagen."
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "Konnte Submodul-Verzeichnis '%s' nicht finden."
@@ -13297,9 +13431,11 @@ msgstr "Grund für die Aktualisierung"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <Key-ID>] [-f] [-m <Beschreibung> | -F <Datei>] [-e]\n"
+" [(--trailer <Token>[(=|:)<Wert>])...]\n"
" <Tagname> [<Commit> | <Objekt>]"
msgid "git tag -d <tagname>..."
@@ -14189,9 +14325,6 @@ msgstr "nicht erkannter Kopfbereich: %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "Dem Repository fehlen folgende vorausgesetzte Commits:"
-msgid "need a repository to verify a bundle"
-msgstr "um ein Paket zu überprüfen wird ein Repository benötigt"
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14615,6 +14748,9 @@ msgstr "Empfangen was in das Repository übertragen wurde"
msgid "Manage reflog information"
msgstr "Reflog Informationen verwalten"
+msgid "Low-level access to refs"
+msgstr "Low-Level Zugang zu Referenzen"
+
msgid "Manage set of tracked repositories"
msgstr "Menge von hinterlegten Repositories verwalten"
@@ -14925,6 +15061,14 @@ msgid "commit-graph required commit data chunk missing or corrupted"
msgstr ""
"Commit-Graph erforderlicher Commit-Daten Chunk fehlt oder ist beschädigt"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"deaktiviere Bloom-Filter für die Commit-Graph-Ebene '%s' aufgrund "
+"inkompatibler Einstellungen"
+
msgid "commit-graph has no base graphs chunk"
msgstr "Commit-Graph hat keinen Basis-Graph-Chunk"
@@ -15052,6 +15196,14 @@ msgstr ""
"versuche einen Commit-Graph zu schreiben, aber 'core.commitGraph' ist "
"deaktiviert"
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"versuche, einen Commit-Graphen zu schreiben, aber 'commitGraph."
+"changedPathsVersion' (%d) wird nicht unterstützt"
+
msgid "too many commits to write graph"
msgstr "zu viele Commits zum Schreiben des Graphen"
@@ -16941,17 +17093,21 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C <Pfad>] [-c <Name>=<Wert>]\n"
" [--exec-path[=<Pfad>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<Pfad>] [--work-tree=<Pfad>] [--namespace=<Name>]\n"
-" [--config-env=<Name>=<Umgebungsvariable>] <Befehl> [<Argumente>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<Pfad>]\n"
+" [--work-tree=<Pfad>] [--namespace=<Name>] [--config-"
+"env=<Name>=<Umgebungsvariable>]\n"
+" <Befehl> [<Argumente>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -17293,13 +17449,13 @@ msgstr ""
"Sie können diese Warnung mit `git config advice.ignoredHook false` "
"deaktivieren."
+msgid "not a git repository"
+msgstr "kein Git-Repository"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "Argument für --packfile muss ein gültiger Hash sein ('%s' erhalten)"
-msgid "not a git repository"
-msgstr "kein Git-Repository"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr "negativer Wert für http.postBuffer; benutze Standardwert %d"
@@ -17312,6 +17468,9 @@ msgstr ""
"Das Anheften des öffentlichen Schlüssels wird mit cURL < 7.39.0 nicht "
"unterstützt"
+msgid "Unknown value for http.proactiveauth"
+msgstr "Unbekannter Wert für http.proactiveauth"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE wird mit cURL < 7.44.0 nicht unterstützt."
@@ -17328,6 +17487,12 @@ msgstr ""
msgid "Could not set SSL backend to '%s': already set"
msgstr "Konnte SSL-Backend nicht zu '%s' setzen: bereits gesetzt"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "Lesen von Cookies von http.cookiefile '-' verweigert"
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "http.savecookies wird bei leerem http.cookiefile ignoriert"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -17505,9 +17670,10 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "Fehler beim Merge von Submodul %s (Commits nicht vorhanden)."
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
msgstr ""
-"Submodul %s konnte nicht zusammengeführt werden (Repository beschädigt)"
+"Fehler: Submodul %s konnte nicht zusammengeführt werden (Repository "
+"beschädigt)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -17537,12 +17703,13 @@ msgstr ""
"sind vorhanden:\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "Fehler bei Ausführung des internen Merges"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "Fehler: Der interne Merge für %s konnte nicht ausgeführt werden"
#, c-format
-msgid "unable to add %s to database"
-msgstr "konnte %s nicht zur Datenbank hinzufügen"
+msgid "error: unable to add %s to database"
+msgstr "Fehler: kann %s nicht zur Datenbank hinzufügen"
#, c-format
msgid "Auto-merging %s"
@@ -17640,12 +17807,12 @@ msgstr ""
"KONFLIKT (umbenennen/löschen): %s zu %s in %s umbenannt, aber in %s gelöscht."
#, c-format
-msgid "cannot read object %s"
-msgstr "kann Objekt %s nicht lesen"
+msgid "error: cannot read object %s"
+msgstr "Fehler: kann Objekt %s nicht lesen"
#, c-format
-msgid "object %s is not a blob"
-msgstr "Objekt %s ist kein Blob"
+msgid "error: object %s is not a blob"
+msgstr "Fehler: Objekt %s ist kein Blob"
#, c-format
msgid ""
@@ -17698,7 +17865,7 @@ msgstr ""
#. conflict in a submodule. The first argument is the submodule
#. name, and the second argument is the abbreviated id of the
#. commit that needs to be merged. For example:
-#. - go to submodule (mysubmodule), and either merge commit abc1234"
+#. - go to submodule (mysubmodule), and either merge commit abc1234"
#.
#, c-format
msgid ""
@@ -17788,6 +17955,11 @@ msgid "do not know what to do with %06o %s '%s'"
msgstr "weiß nicht was mit %06o %s '%s' zu machen ist"
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr ""
+"Submodul %s konnte nicht zusammengeführt werden (Repository beschädigt)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Spule Submodul %s zu dem folgenden Commit vor:"
@@ -17828,6 +18000,13 @@ msgstr ""
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Fehler beim Merge von Submodul %s (mehrere Merges gefunden)"
+msgid "failed to execute internal merge"
+msgstr "Fehler bei Ausführung des internen Merges"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "konnte %s nicht zur Datenbank hinzufügen"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr ""
@@ -17935,6 +18114,14 @@ msgstr ""
"KONFLIKT (umbenennen/umbenennen): Benenne Verzeichnis um %s->%s in %s.\n"
"Benenne Verzeichnis um %s->%s in %s"
+#, c-format
+msgid "cannot read object %s"
+msgstr "kann Objekt %s nicht lesen"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "Objekt %s ist kein Blob"
+
msgid "modify"
msgstr "ändern"
@@ -18019,10 +18206,6 @@ msgstr "Zeile konnte nicht geparst werden: %s"
msgid "malformed line: %s"
msgstr "fehlerhafte Zeile: %s"
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr ""
-"ignoriere existierenden Multi-Pack-Index; Prüfsumme stimmt nicht überein"
-
msgid "could not load pack"
msgstr "Paket konnte nicht geladen werden"
@@ -18030,6 +18213,10 @@ msgstr "Paket konnte nicht geladen werden"
msgid "could not open index for %s"
msgstr "konnte Index für %s nicht öffnen"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr ""
+"ignoriere existierenden Multi-Pack-Index; Prüfsumme stimmt nicht überein"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Packdateien zum Multi-Pack-Index hinzufügen"
@@ -18489,7 +18676,7 @@ msgstr "%s [ungültiges Objekt]"
#. TRANSLATORS: This is a line of ambiguous commit
#. object output. E.g.:
#. *
-#. "deadbeef commit 2021-01-01 - Some Commit Message"
+#. "deadbeef commit 2021-01-01 - Some Commit Message"
#.
#, c-format
msgid "%s commit %s - %s"
@@ -18498,7 +18685,7 @@ msgstr "%s Commit %s - %s"
#. TRANSLATORS: This is a line of ambiguous
#. tag object output. E.g.:
#. *
-#. "deadbeef tag 2022-01-01 - Some Tag Message"
+#. "deadbeef tag 2022-01-01 - Some Tag Message"
#. *
#. The second argument is the YYYY-MM-DD found
#. in the tag.
@@ -18514,7 +18701,7 @@ msgstr "%s Tag %s - %s"
#. tag object output where we couldn't parse
#. the tag itself. E.g.:
#. *
-#. "deadbeef [bad tag, could not parse it]"
+#. "deadbeef [bad tag, could not parse it]"
#.
#, c-format
msgid "%s [bad tag, could not parse it]"
@@ -18655,6 +18842,17 @@ msgstr "Konnte Objekt '%s' nicht parsen."
msgid "hash mismatch %s"
msgstr "Hash stimmt nicht mit %s überein."
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "doppelter Eintrag beim Schreiben des Bitmap-Index: %s"
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "versuchte, nicht gewählten Commit '%s' zu speichern"
+
+msgid "too many pseudo-merges"
+msgstr "zu viele Pseudo-Merges"
+
msgid "trying to write commit not in index"
msgstr "Versuch, einen Commit zu schreiben, der nicht im Index steht"
@@ -18679,6 +18877,17 @@ msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr ""
"beschädigte Bitmap-Indexdatei (zu kurz, um in die Lookup-Tabelle zu passen)"
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"beschädigte Bitmap-Indexdatei (zu kurz für den Pseudo-Merge-Tabellenkopf)"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr "beschädigte Bitmap-Indexdatei (zu kurz für die Pseudo-Merge-Tabelle)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "beschädigte Bitmap-Indexdatei, Pseudo-Merge-Tabelle zu kurz"
+
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "duplizierter Eintrag im Bitmap-Index: '%s'"
@@ -18776,6 +18985,10 @@ msgid "mismatch in bitmap results"
msgstr "Unstimmigkeiten bei Bitmap-Ergebnissen"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "Pseudo-Merge-Index außerhalb des Bereichs (%<PRIu32> >= %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "konnte '%s' in Paket '%s' bei Offset %<PRIuMAX> nicht finden"
@@ -19145,6 +19358,10 @@ msgstr "Kann Thread für lstat nicht erzeugen: %s"
msgid "unable to parse --pretty format"
msgstr "Konnte --pretty Format nicht parsen."
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr ""
+"lazy fetching deaktiviert; einige Objekte sind möglicherweise nicht verfügbar"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "Promisor-Remote: konnte Fetch-Subprozess nicht abspalten"
@@ -19170,6 +19387,67 @@ msgstr "object-info: erwartete Flush nach Argumenten"
msgid "Removing duplicate objects"
msgstr "Lösche doppelte Objekte"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "Pseudo-Merge-Regex konnte nicht geladen werden für %s: '%s'"
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s muss nicht-negativ sein, Standardwert wird verwendet"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s muss zwischen 0 und 1 liegen, Standardwert wird verwendet"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s muss positiv sein, verwende Standardwert"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "Pseudo-Merge-Gruppe '%s' fehlt erforderliches Muster"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr ""
+"Pseudo-Merge-Gruppe '%s' hat einen instabilen vor einem stabilen "
+"Schwellenwert"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"Pseudo-Merge-Regex aus der Konfiguration hat zu viele Capture-Gruppen "
+"(maximum=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"erweiterter Pseudo-Merge liest außerhalb des Bereichs (%<PRIuMAX> >= "
+"%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"erweiterter Pseudo-Merge-Eintrag ist zu kurz (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr "konnte keinen Pseudo-Merge für Commit %s bei Offset %<PRIuMAX> finden"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr ""
+"erweiterte Pseudo-Merge-Suche außerhalb des Bereichs (%<PRIu32> >= %<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "Lesen außerhalb des zulässigen Bereichs: (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "konnte erweiterte Pseudo-Merge-Tabelle für Commit %s nicht lesen"
+
msgid "could not start `log`"
msgstr "Konnte `log` nicht starten."
@@ -19778,11 +20056,18 @@ msgstr "Log für Referenz %s unerwartet bei %s beendet."
msgid "log for %s is empty"
msgstr "Log für %s ist leer."
+msgid "refusing to force and skip creation of reflog"
+msgstr "Erzwingen der Aktion verweigert; überspringe Erstellung des Reflogs"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "verweigere Aktualisierung einer Referenz mit fehlerhaftem Namen '%s'"
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "Aktualisierung von Pseudoreferenz '%s' verweigert"
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "update_ref für Referenz '%s' fehlgeschlagen: %s"
@@ -19815,6 +20100,27 @@ msgid "could not delete references: %s"
msgstr "konnte Referenzen nicht entfernen: %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr ""
+"Trockenlauf der Migration von Referenzen abgeschlossen. Das Ergebnis kann "
+"unter '%s' gefunden werden.\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "konnte das temporäre Migrationsverzeichnis '%s' nicht entfernen"
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "migrierte Referenzen befinden sich unter '%s'"
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"kann Referenz '%s' nicht sperren: erwartete symbolische Referenz mit Ziel "
+"'%s': ist aber eine reguläre Referenz"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "Referenzname ist gefährlich: %s"
@@ -20993,6 +21299,50 @@ msgstr ""
"refs/heads/%s"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "'%s' akzeptiert keine Merge-Commits"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"'pick' nimmt keinen Merge-Commit an. Wenn Sie den Merge wiederholen\n"
+"wollen, verwenden Sie 'merge -C' auf den Commit."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"'reword' erfordert keinen Merge-Commit. Wenn Sie\n"
+"den Merge wiederholen und die Commit-Nachricht\n"
+"neu formulieren wollen, verwenden Sie\n"
+"'merge -c' auf den Commit"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"'edit' nimmt keinen Merge-Commit an. Wenn Sie den Merge wiederholen\n"
+"wollen, verwenden Sie 'merge -C' auf den Commit und dann\n"
+"break', um die Kontrolle zurückzugewinnen, sodass Sie\n"
+"'git commit --amend && git rebase --continue' ausführen können."
+
+msgid "cannot squash merge commit into another commit"
+msgstr "kann einen Merge-Commit nicht mit einem anderen Commit zusammenfassen"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "ungültiger Befehl '%.*s'"
@@ -21110,9 +21460,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "kann HEAD nicht lesen"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "konnte '%s' nicht nach '%s' kopieren"
+msgid "could not write commit message file"
+msgstr "konnte keine Commit-Beschreibungsdatei schreiben"
#, c-format
msgid ""
@@ -21522,6 +21871,18 @@ msgstr "Kann nicht zum aktuellen Arbeitsverzeichnis zurückwechseln."
msgid "failed to stat '%*s%s%s'"
msgstr "Konnte '%*s%s%s' nicht lesen."
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"dubiose Besitzverhältnisse im Repository bei '%s' entdeckt\n"
+"%sUm eine Ausnahme für dieses Verzeichnis hinzuzufügen, rufen Sie auf:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Konnte aktuelles Arbeitsverzeichnis nicht lesen."
@@ -21543,18 +21904,6 @@ msgstr ""
"Stoppe bei Dateisystemgrenze (GIT_DISCOVERY_ACROSS_FILESYSTEM nicht gesetzt)."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"dubiose Besitzverhältnisse im Repository bei '%s' entdeckt\n"
-"%sUm eine Ausnahme für dieses Verzeichnis hinzuzufügen, rufen Sie auf:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr ""
"kann Bare-Repository '%s' nicht verwenden (safe.bareRepository ist '%s')"
@@ -21862,6 +22211,14 @@ msgstr ""
"Git-Verzeichnis des Submoduls '%s' ist im Git-Verzeichnis '%.*s' enthalten."
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr "erwartete, dass '%.*s' im Submodulpfad '%s' kein symbolischer Link ist"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "erwartete, dass der Submodulpfad '%s' kein symbolischer Link ist"
+
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -21900,10 +22257,6 @@ msgstr "'lstat' für '%s' fehlgeschlagen"
msgid "no remote configured to get bundle URIs from"
msgstr "kein Remote-Repository zum Erhalten von Bundle-URIs konfiguriert"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "Remote-Repository '%s' hat keine konfigurierte URL"
-
msgid "could not get the bundle-uri list"
msgstr "konnte die Bundle-uri-Liste nicht erhalten"
@@ -23459,24 +23812,24 @@ msgid "Failed to send %s\n"
msgstr "Fehler beim Senden %s\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Probeversand %s\n"
+msgid "Dry-Sent %s"
+msgstr "Probeversand %s"
#, perl-format
-msgid "Sent %s\n"
-msgstr "%s gesendet\n"
+msgid "Sent %s"
+msgstr "%s gesendet"
-msgid "Dry-OK. Log says:\n"
-msgstr "Probeversand OK. Log enthält:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Probelauf OK. Das Protokoll enthält:"
-msgid "OK. Log says:\n"
-msgstr "OK. Log enthält:\n"
+msgid "OK. Log says:"
+msgstr "OK. Das Protokoll enthält:"
msgid "Result: "
msgstr "Ergebnis: "
-msgid "Result: OK\n"
-msgstr "Ergebnis: OK\n"
+msgid "Result: OK"
+msgstr "Ergebnis: OK"
#, perl-format
msgid "can't open file %s"
diff --git a/po/fr.po b/po/fr.po
index 837a695485..7b03f2c25b 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -80,8 +80,8 @@ msgid ""
msgstr ""
"Project-Id-Version: git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-16 22:57+0000\n"
-"PO-Revision-Date: 2024-04-20 17:11+0800\n"
+"POT-Creation-Date: 2024-07-17 21:57+0000\n"
+"PO-Revision-Date: 2024-07-19 20:25+0200\n"
"Last-Translator: Cédric Malard <c.malard-git@valdun.net>\n"
"Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n"
"Language: fr\n"
@@ -642,6 +642,10 @@ msgstr ""
"p - afficher la section actuelle\n"
"? - afficher l'aide\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "une seule lettre est attendue, mais '%s' a été reçu"
+
msgid "No previous hunk"
msgstr "Pas de section précédente"
@@ -690,9 +694,19 @@ msgstr "Découpée en %d sections."
msgid "Sorry, cannot edit this hunk"
msgstr "Désolé, impossible d'éditer cette section"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "commande inconnue : '%s' (utilisez '?' pour de l'aide)"
+
msgid "'git apply' failed"
msgstr "'git apply' a échoué"
+msgid "No changes."
+msgstr "Aucune modification."
+
+msgid "Only binary files changed."
+msgstr "Seuls des fichiers binaires ont changé."
+
#, c-format
msgid ""
"\n"
@@ -1219,10 +1233,6 @@ msgstr[0] "Application du patch %%s avec %d rejet..."
msgstr[1] "Application du patch %%s avec %d rejets..."
#, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "troncature du nom de fichier .rej en %.*s.rej"
-
-#, c-format
msgid "cannot open %s"
msgstr "impossible d'ouvrir %s"
@@ -1573,6 +1583,9 @@ msgstr "fichier gitattributes trop gros ignoré '%s'"
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "blob gitattributes trop gros ignoré '%s'"
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "impossible d'utiliser --attr-source ou GIT_ATTR_SOURCE sans dépôt"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "mauvais --attr-source ou GIT_ATTR_SOURCE"
@@ -1654,6 +1667,10 @@ msgid "could not create file '%s'"
msgstr "impossible de créer le fichier '%s'"
#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "impossible de démarrer 'show' pour l'objet '%s'"
+
+#, c-format
msgid "could not read file '%s'"
msgstr "impossible de lire le fichier '%s'"
@@ -1887,13 +1904,6 @@ msgstr "impossible de chmod %cx '%s'"
msgid "Unstaged changes after refreshing the index:"
msgstr "Modifications non indexées après rafraîchissement de l'index :"
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"le réglage add.interactive.useBuiltin a été supprimé !\n"
-"Référez-vous à cette entrée dans 'git help config' pour plus de détails."
-
msgid "could not read the index"
msgstr "impossible de lire l'index"
@@ -2006,7 +2016,7 @@ msgid "adding embedded git repository: %s"
msgstr "dépôt git embarqué ajouté : %s"
msgid "Use -f if you really want to add them."
-msgstr "Utilisez -f si vous voulez vraiment les ajouter"
+msgstr "Utilisez -f si vous voulez vraiment les ajouter<."
msgid "adding files failed"
msgstr "échec de l'ajout de fichiers"
@@ -2340,6 +2350,9 @@ msgstr "abandonne l'opération de patch mais garde HEAD où il est"
msgid "show the patch being applied"
msgstr "afficher le patch en cours d'application"
+msgid "try to apply current patch again"
+msgstr "essayer d'appliquer de nouveau la rustine"
+
msgid "record the empty patch as an empty commit"
msgstr "enregistrer la rustine vide comme un commit vide"
@@ -2398,9 +2411,6 @@ msgstr "git apply [<options>] [<patch>...]"
msgid "could not redirect output"
msgstr "impossible de rediriger la sortie"
-msgid "git archive: Remote with no URL"
-msgstr "git archive : Dépôt distant sans URL"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive : ACK/NACK attendu, paquet de nettoyage reçu"
@@ -3321,6 +3331,9 @@ msgstr "La création d'un colis requiert un dépôt."
msgid "do not show bundle details"
msgstr "ne pas afficher les détails du colis"
+msgid "need a repository to verify a bundle"
+msgstr "la vérification d'un colis requiert un dépôt"
+
#, c-format
msgid "%s is okay\n"
msgstr "%s est correct\n"
@@ -4351,6 +4364,14 @@ msgid "failed to unlink '%s'"
msgstr "échec pour délier '%s'"
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "le lien dur ne peut pas être vérifier à '%s'"
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "le lien dur est différent de la source à '%s'"
+
+#, c-format
msgid "failed to create link '%s'"
msgstr "échec de la création du lien '%s'"
@@ -5195,15 +5216,53 @@ msgstr ""
"d'index. Vérifiez que le disque n'est pas plein ou que le quota\n"
"n'a pas été dépassé, puis lancez \"git restore --staged :/\" pour réparer."
-msgid "git config [<options>]"
-msgstr "git config [<options>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr ""
+"git config list [<option-de-fichier>] [<option-d-affichage>] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "argument --type non reconnu, %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<option-de-fichier>] [<option-d-affichage>] [--includes] [--"
+"all] [--regexp=<regexp>] [--value=<valeur>] [--fixed-value] [--"
+"default=<défaut>] <name>"
-msgid "only one type at a time"
-msgstr "qu'un seul type à la fois"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<option-de-fichier>] [--type=<type>] [--all] [--"
+"value=<valeur>] [--fixed-value] <nom> <valeur>"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<option-de-fichier>] [--all] [--value=<valeur>] [--fixed-"
+"value] <nom> <valeur>"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr ""
+"git config rename-section [<option-de-fichier>] <ancien-nom> <nouveau-nom>"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<option-de-fichier>] <nom>"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<option-de-fichier>]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr ""
+"git config [<option-de-fichier>] --get-colorbool <nom> [<stdout-est-tty>]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<option-de-fichier>] [--type=<type>] [--comment=<message>] "
+"[--all] [--value=<valeur>] [--fixed-value] <nom> <valeur>"
msgid "Config file location"
msgstr "Emplacement du fichier de configuration"
@@ -5229,56 +5288,6 @@ msgstr "blob-id"
msgid "read config from given blob object"
msgstr "lire la configuration depuis l'objet blob fourni"
-msgid "Action"
-msgstr "Action"
-
-msgid "get value: name [value-pattern]"
-msgstr "obtenir la valeur : nom [motif-de-valeur]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "obtenir toutes les valeurs : clé [motif-de-valeur]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "obtenir les valeur pour la regexp : regex-de-nom [motif-de-valeur]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "obtenir la valeur spécifique pour l'URL : section[.var] URL"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr ""
-"remplacer toutes les variables correspondant : nom valeur [motif-de-valeur]"
-
-msgid "add a new variable: name value"
-msgstr "ajouter une nouvelle variable : nom valeur"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "supprimer une variable : nom [motif-de-valeur]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "supprimer toutes les correspondances nom [motif-de-valeur]"
-
-msgid "rename section: old-name new-name"
-msgstr "renommer une section : ancien-nom nouveau-nom"
-
-msgid "remove a section: name"
-msgstr "supprimer une section : nom"
-
-msgid "list all"
-msgstr "afficher tout"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr ""
-"utiliser l'égalité de chaînes lors de la comparaison de 'motif-de-valeur'"
-
-msgid "open an editor"
-msgstr "ouvrir un éditeur"
-
-msgid "find the color configured: slot [default]"
-msgstr "trouver la couleur configurée : slot [par défaut]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "trouver le réglage de la couleur : slot [stdout-est-tty]"
-
msgid "Type"
msgstr "Type"
@@ -5306,8 +5315,8 @@ msgstr "la valeur est un chemin (vers un fichier ou un répertoire)"
msgid "value is an expiry date"
msgstr "la valeur est une date d'expiration"
-msgid "Other"
-msgstr "Autre"
+msgid "Display options"
+msgstr "Options d'affichage"
msgid "terminate values with NUL byte"
msgstr "terminer les valeurs avec un caractère NUL"
@@ -5315,9 +5324,6 @@ msgstr "terminer les valeurs avec un caractère NUL"
msgid "show variable names only"
msgstr "n'afficher que les noms de variable"
-msgid "respect include directives on lookup"
-msgstr "respecter les directives d'inclusion lors de la recherche"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr ""
"afficher l'origine de la configuration (fichier, entrée standard, blob, "
@@ -5328,16 +5334,15 @@ msgstr ""
"afficher la portée de configuration (arbre de travail, local, global, "
"système, commande)"
-msgid "value"
-msgstr "valeur"
+msgid "show config keys in addition to their values"
+msgstr "afficher les clés de configuration en plus des valeurs"
-msgid "with --get, use default value when missing entry"
-msgstr "avec --get, utiliser le valeur par défaut quand l'entrée n'existe pas"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "argument --type non reconnu, %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr ""
-"chaîne des commentaires lisibles par l'utilisateur (# sera ajouté en préfixe "
-"selon les besoins)"
+msgid "only one type at a time"
+msgstr "qu'un seul type à la fois"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5414,47 +5419,77 @@ msgstr ""
"la section \"CONFIGURATION FILE\" de \"git help worktree\" pour plus de "
"détails"
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color et le type de la variable sont incohérents"
+msgid "Other"
+msgstr "Autre"
-msgid "only one action at a time"
-msgstr "une seule action à la fois"
+msgid "respect include directives on lookup"
+msgstr "respecter les directives d'inclusion lors de la recherche"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only n'est applicable qu'avec --list ou --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "lecture du fichier de configuration '%s' impossible"
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
+msgid "error processing config file(s)"
+msgstr "erreur lors du traitement de fichier(s) de configuration"
+
+msgid "Filter options"
+msgstr "Options de filtre"
+
+msgid "return all values for multi-valued config options"
msgstr ""
-"--show-origin n'est applicable qu'avec --get, --get-all, --get-regexp ou --"
-"list"
+"renvoyer toutes les valeurs pour les options de configuration multi-valeurs"
-msgid "--default is only applicable to --get"
-msgstr "--default n'est applicable qu'avec --get"
+msgid "interpret the name as a regular expression"
+msgstr "interpréter le nom comme une expression régulière"
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment n'est applicable qu'avec les opérations add/set/replace"
+msgid "show config with values matching the pattern"
+msgstr "afficher les configurations dont le nom correspond au motif"
+
+msgid "use string equality when comparing values to value pattern"
+msgstr ""
+"utiliser l'égalité de chaînes lors de la comparaison des valeurs au motif de "
+"valeur"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "show config matching the given URL"
+msgstr "afficher les configs qui correspondent à l'URL donné"
+
+msgid "value"
+msgstr "valeur"
+
+msgid "use default value when missing entry"
+msgstr "utiliser le valeur par défaut quand l'entrée n'existe pas"
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value ne s'applique qu'à 'motif-de-valeur'"
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "lecture du fichier de configuration '%s' impossible"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= ne peut pas être utilisé avec --all ou --url="
-msgid "error processing config file(s)"
-msgstr "erreur lors du traitement de fichier(s) de configuration"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= ne peut pas être utilisé avec --all, --regexp ou --value"
-msgid "editing stdin is not supported"
-msgstr "l'édition de stdin n'est pas supportée"
+msgid "Filter"
+msgstr "Filtre"
-msgid "editing blobs is not supported"
-msgstr "l'édition de blobs n'est pas supportée"
+msgid "replace multi-valued config option with new value"
+msgstr "remplacer l'option de config multi-valeur par la nouvelle valeur"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "création impossible du fichier de configuration '%s'"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"chaîne des commentaires lisibles par l'utilisateur (# sera ajouté en préfixe "
+"selon les besoins)"
+
+msgid "add a new line without altering any existing values"
+msgstr "ajouter une nouvelle ligne sans modifier les valeurs existantes"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value ne s'applique qu'avec --value=<motif>"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append ne s'applique pas avec --value=<motif>"
#, c-format
msgid ""
@@ -5468,6 +5503,87 @@ msgstr ""
msgid "no such section: %s"
msgstr "section inexistante : %s"
+msgid "editing stdin is not supported"
+msgstr "l'édition de stdin n'est pas supportée"
+
+msgid "editing blobs is not supported"
+msgstr "l'édition de blobs n'est pas supportée"
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "création impossible du fichier de configuration '%s'"
+
+msgid "Action"
+msgstr "Action"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "obtenir la valeur : nom [<motif-de-valeur>]"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "obtenir toutes les valeurs : clé [<motif-de-valeur>]"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "obtenir les valeur pour la regexp : name-regex [<motif-de-valeur>]"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "obtenir la valeur spécifique pour l'URL : section[.var] URL"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr ""
+"remplacer toutes les variables correspondant : nom valeur [<motif-de-valeur>]"
+
+msgid "add a new variable: name value"
+msgstr "ajouter une nouvelle variable : nom valeur"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "supprimer une variable : nom [<motif-de-valeur>]"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "supprimer toutes les correspondances nom [<motif-de-valeur>]"
+
+msgid "rename section: old-name new-name"
+msgstr "renommer une section : ancien-nom nouveau-nom"
+
+msgid "remove a section: name"
+msgstr "supprimer une section : nom"
+
+msgid "list all"
+msgstr "afficher tout"
+
+msgid "open an editor"
+msgstr "ouvrir un éditeur"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "trouver la couleur configurée : slot [<valeur-par-défaut>]"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "trouver le réglage de la couleur : slot [<stdout-est-tty>]"
+
+msgid "with --get, use default value when missing entry"
+msgstr "avec --get, utiliser le valeur par défaut quand l'entrée n'existe pas"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color et le type de la variable sont incohérents"
+
+msgid "no action specified"
+msgstr "aucune action spécifiée"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only n'est applicable qu'avec --list ou --get-regexp"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin n'est applicable qu'avec --get, --get-all, --get-regexp ou --"
+"list"
+
+msgid "--default is only applicable to --get"
+msgstr "--default n'est applicable qu'avec --get"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment n'est applicable qu'avec les opérations add/set/replace"
+
msgid "print sizes in human readable format"
msgstr "affiche les tailles dans un format humainement lisible"
@@ -6307,6 +6423,9 @@ msgstr "config"
msgid "config key storing a list of repository paths"
msgstr "clé de config qui stocke la liste des chemins de dépôts"
+msgid "keep going even if command fails in a repository"
+msgstr "continuer mêm si la commande échoue dans un dépôt"
+
msgid "missing --config=<config>"
msgstr "--config=<config> manquant"
@@ -7788,8 +7907,11 @@ msgstr "marquer la série comme une Nième réédition"
msgid "max length of output filename"
msgstr "taille maximum du nom du fichier de sortie"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "utiliser [RFC PATCH] au lieu de [PATCH]"
+msgid "rfc"
+msgstr "rfc"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "ajouter <rfc> (par défaut 'RFC') avant 'PATCH'"
msgid "cover-from-description-mode"
msgstr "cover-from-description-mode"
@@ -8066,11 +8188,11 @@ msgstr ""
"deduplicate, --eol"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--brances] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<clé>]\n"
" [--symref] [<dépôt> [<motif>...]]"
@@ -8086,8 +8208,11 @@ msgstr "chemin vers git-upload-pack sur le serveur distant"
msgid "limit to tags"
msgstr "limiter aux étiquettes"
-msgid "limit to heads"
-msgstr "limiter aux heads"
+msgid "limit to branches"
+msgstr "limiter aux branches"
+
+msgid "deprecated synonym for --branches"
+msgstr "synonyme obsolète de --branches"
msgid "do not show peeled tags"
msgstr "ne pas afficher les étiquettes pelées"
@@ -8938,10 +9063,6 @@ msgstr "git notes prune [<options>]"
msgid "Write/edit the notes for the following object:"
msgstr "Écrire/éditer les notes pour l'objet suivant :"
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "impossible de démarrer 'show' pour l'objet '%s'"
-
msgid "could not read 'show' output"
msgstr "impossible de lire la sortie de 'show'"
@@ -10779,6 +10900,22 @@ msgstr "pas de journal de références à supprimer spécifié"
msgid "invalid ref format: %s"
msgstr "format de référence invalide : %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<format> [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "spécifier le format de réference vers lequel convertir"
+
+msgid "perform a non-destructive dry-run"
+msgstr "faire l'action en mode simulé non destructif"
+
+msgid "missing --ref-format=<format>"
+msgstr "--ref-format=<format> manquant"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "le dépôt utilise déjà le format '%s'"
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -11067,9 +11204,6 @@ msgstr "* distant %s"
msgid " Fetch URL: %s"
msgstr " URL de rapatriement : %s"
-msgid "(no URL)"
-msgstr "(pas d'URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -11078,6 +11212,9 @@ msgstr "(pas d'URL)"
msgid " Push URL: %s"
msgstr " URL push : %s"
+msgid "(no URL)"
+msgstr "(pas d'URL)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " Branche HEAD : %s"
@@ -11187,10 +11324,6 @@ msgstr "interroger les URLs de poussée plutôt que les URLs de récupération"
msgid "return all URLs"
msgstr "retourner toutes les URLs"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "aucune URL configurée pour le dépôt distant '%s'"
-
msgid "manipulate push URLs"
msgstr "manipuler les URLs push"
@@ -12209,12 +12342,12 @@ msgstr "Algorithme d'empreinte inconnu"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<motif>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<motif>...]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -12237,11 +12370,13 @@ msgstr "la référence n'existe pas"
msgid "failed to look up reference"
msgstr "échec de la recherche de la référence"
-msgid "only show tags (can be combined with heads)"
-msgstr "afficher seulement les étiquettes (peut être combiné avec heads)"
+msgid "only show tags (can be combined with branches)"
+msgstr ""
+"afficher seulement les étiquettes (peut être combiné avec les branches)"
-msgid "only show heads (can be combined with tags)"
-msgstr "afficher seulement les têtes (peut être combiné avec tags)"
+msgid "only show branches (can be combined with tags)"
+msgstr ""
+"afficher seulement les branches (peut être combiné avec les étiquettes)"
msgid "check for reference existence without resolving"
msgstr "vérifier l'existence de la référence sans la résoudre"
@@ -12893,14 +13028,14 @@ msgstr ""
"refus de créer/utiliser '%s' dans un répertoire git d'un autre sous-module"
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "le clonage de '%s' dans le chemin de sous-module '%s' a échoué"
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "le répertoire n'est pas vide : '%s'"
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "le clonage de '%s' dans le chemin de sous-module '%s' a échoué"
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "impossible de créer le répertoire de sous-module pour '%s'"
@@ -13266,9 +13401,11 @@ msgstr "raison de la mise à jour"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <id-clé>] [-f] [-m <msg> | -F <fichier>] [-e]\n"
+" [(--trailer <jeton>[(=|:)<valeur>)...]\n"
" <nom-d-étiquette> [<commit> | <objet>]"
msgid "git tag -d <tagname>..."
@@ -14147,9 +14284,6 @@ msgstr "en-tête non reconnu : %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "Le dépôt ne dispose pas des commits prérequis suivants :"
-msgid "need a repository to verify a bundle"
-msgstr "la vérification d'un colis requiert un dépôt"
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14565,6 +14699,9 @@ msgstr "Recevoir ce qui est poussé dans le dépôt"
msgid "Manage reflog information"
msgstr "Gérer l'information de reflog"
+msgid "Low-level access to refs"
+msgstr "accès de bas-niveau aux réfs"
+
msgid "Manage set of tracked repositories"
msgstr "Gérer un ensemble de dépôts suivis"
@@ -14884,6 +15021,14 @@ msgstr ""
"le tronçon d'étalement OID requis par le graphe de commits est manquant ou "
"corrompu"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"désactivation des filtres de Bloom opur la couche de graphe de commits '%s' "
+"à cause de réglages incompatibles"
+
msgid "commit-graph has no base graphs chunk"
msgstr "le graphe de commit n'a pas de tronçon de graphes de base"
@@ -15018,6 +15163,14 @@ msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr ""
"essai d'écriture de graphe de commits, mais 'core.commitGraph' est désactivé"
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"essai d'écriture de graphe de commits, mais 'commitGraph."
+"changedPathsVersion' (%d) n'est pas pris en charge"
+
msgid "too many commits to write graph"
msgstr "trop de commits pour écrire un graphe"
@@ -16931,19 +17084,23 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C <chemin>] [-c <nom>=<valeur>]\n"
" [--exec-path[=<chemin>]] [--html-path] [--man-path] [--info-"
"path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<chemin>] [--work-tree=<chemin>] [--namespace=<nom>]\n"
-" [--config-env=<nom>=<variable-d-environnement>] <commande> "
-"[<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-"
+"dir=<chemin>]\n"
+" [--work-tree=<chemin>] [--namespace=<nom>] [--config-"
+"env=<nom>=<var-d-env>] \n"
+" <commande> [<args>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -17284,13 +17441,13 @@ msgstr ""
"Vous pouvez désactiver cet avertissement avec `git config advice.ignoredHook "
"false`."
+msgid "not a git repository"
+msgstr "pas un dépôt git"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "l'argument de --packfile doit être une empreinte valide ('%s' reçu)"
-msgid "not a git repository"
-msgstr "pas un dépôt git"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr ""
@@ -17302,6 +17459,9 @@ msgstr "La délégation de commande n'est pas supporté avec cuRL < 7.22.0"
msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "L'épinglage de clé publique n'est pas supporté avec cuRL < 7.39.0"
+msgid "Unknown value for http.proactiveauth"
+msgstr "valeur inconnue pour http.proactiveauth"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE n'est pas supporté avec cuRL < 7.44.0"
@@ -17319,6 +17479,12 @@ msgstr ""
msgid "Could not set SSL backend to '%s': already set"
msgstr "Impossible de spécifier le dorsal SSL à '%s' : déjà spécifié"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "refus de lire des cookies depuis http.cookiefile '-'"
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "http.savecookies ignoré pour http.cookiefile vide"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -17481,6 +17647,10 @@ msgid "quoted CRLF detected"
msgstr "CRLF citées détectées"
#, c-format
+msgid "unable to format message: %s"
+msgstr "impossible de formater le message : %s"
+
+#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Échec de la fusion du sous-module %s (non extrait)"
@@ -17493,8 +17663,8 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "Échec de fusion du sous-module %s (commits non présents)"
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "Échec de la fusion du sous-module %s (dépôt corrompu)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "erreur : échec de la fusion du sous-module %s (dépôt corrompu)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -17526,12 +17696,13 @@ msgstr ""
"existent :\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "échec à l'exécution de la fusion interne"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "erreur : échec à l'exécution de la fusion interne pour %s"
#, c-format
-msgid "unable to add %s to database"
-msgstr "impossible d'ajouter %s à la base de données"
+msgid "error: unable to add %s to database"
+msgstr "erreur : impossible d'ajouter %s à la base de données"
#, c-format
msgid "Auto-merging %s"
@@ -17627,12 +17798,12 @@ msgstr ""
"supprimé dans %s."
#, c-format
-msgid "cannot read object %s"
-msgstr "impossible de lire l'objet %s"
+msgid "error: cannot read object %s"
+msgstr "erreur : impossible de lire l'objet %s"
#, c-format
-msgid "object %s is not a blob"
-msgstr "l'objet %s n'est pas un blob"
+msgid "error: object %s is not a blob"
+msgstr "erreur : l'objet %s n'est pas un blob"
#, c-format
msgid ""
@@ -17771,6 +17942,10 @@ msgid "do not know what to do with %06o %s '%s'"
msgstr "ne sait pas traiter %06o %s '%s'"
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Échec de la fusion du sous-module %s (dépôt corrompu)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Avance rapide du sous-module %s au commit suivant :"
@@ -17810,6 +17985,13 @@ msgstr ""
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Échec de fusion du sous-module %s (plusieurs fusions trouvées)"
+msgid "failed to execute internal merge"
+msgstr "échec à l'exécution de la fusion interne"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "impossible d'ajouter %s à la base de données"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr ""
@@ -17910,6 +18092,14 @@ msgstr ""
"CONFLIT (renommage/renommage) : renommage du répertoire %s->%s dans %s. "
"Renommage de répertoire %s->%s dans %s"
+#, c-format
+msgid "cannot read object %s"
+msgstr "impossible de lire l'objet %s"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "l'objet %s n'est pas un blob"
+
msgid "modify"
msgstr "modification"
@@ -17993,10 +18183,6 @@ msgstr "impossible d'analyser la ligne : %s"
msgid "malformed line: %s"
msgstr "ligne malformée : %s"
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr ""
-"index multi-paquet existant ignoré ; non-concordance de la somme de contrôle"
-
msgid "could not load pack"
msgstr "impossible de charger le paquet"
@@ -18004,6 +18190,10 @@ msgstr "impossible de charger le paquet"
msgid "could not open index for %s"
msgstr "impossible d'ouvrir l'index pour %s"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr ""
+"index multi-paquet existant ignoré ; non-concordance de la somme de contrôle"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Ajout de fichiers paquet à un index multi-paquet"
@@ -18628,6 +18818,17 @@ msgstr "impossible d'analyser l'objet : %s"
msgid "hash mismatch %s"
msgstr "incohérence de hachage %s"
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "entrée dupliquée dans l'index en bitmap : '%s'"
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "essai de stockage d'un commit non-sélectionné : '%s'"
+
+msgid "too many pseudo-merges"
+msgstr "trop de pseudo-fusions"
+
msgid "trying to write commit not in index"
msgstr "échec de l'écriture de l'objet commit absent de l'index"
@@ -18654,6 +18855,20 @@ msgstr ""
"fichier d'index en bitmap corrompu (trop court pour correspondre à une table "
"de recherche)"
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"fichier d'index en bitmap corrompu (trop court pour correspondre à un entête "
+"de table de pseudo-fusion)"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr ""
+"fichier d'index en bitmap corrompu (trop court pour correspondre à une table "
+"de pseudo-fusion)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "fichier d'index en bitmap corrompu, table de pseudo-fusion trop courte"
+
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "entrée dupliquée dans l'index en bitmap : '%s'"
@@ -18713,6 +18928,9 @@ msgstr "bitmap ewah corrompue : entête tronqué pour la bitmap du commit '%s'"
msgid "unable to load pack: '%s', disabling pack-reuse"
msgstr "impossible de charger le paquet : '%s', pack-reuse désactivé"
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr "impossible de calculer le paquet préféré, pack-reuse désactivé"
+
#, c-format
msgid "object '%s' not found in type bitmaps"
msgstr "objet '%s' non trouvé dans les bitmaps de type"
@@ -18743,6 +18961,10 @@ msgid "mismatch in bitmap results"
msgstr "décalage dans le résultats de bitmap"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "l'index de pseudo-fusion est hors-limite (%<PRIu32> ≥ %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "impossible de trouver '%s' dans le paquet '%s' à l'offset %<PRIuMAX>"
@@ -19115,6 +19337,11 @@ msgstr "impossible de créer le lstat en fil : %s"
msgid "unable to parse --pretty format"
msgstr "impossible d'analyser le format --pretty"
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr ""
+"récupération paresseuse désactivée ; certains objets pourraient ne pas être "
+"disponibles"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr ""
"promisor-remote : impossible de créer un sous-processus de récupération"
@@ -19142,6 +19369,68 @@ msgstr "object-info : vidage attendu après les arguments"
msgid "Removing duplicate objects"
msgstr "Suppression des objets dupliqués"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "impossible de charger la regex de pseudo-fusion pour %s : '%s'"
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s doit être non négatif, utilisation de la valeur par défaut"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s doit valoir entre 0 et 1, utilisation de la valeur par défaut"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s doit être positif, utilisation de la valeur par défaut"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "le groupe de pseudo-fusion '%s' n'a pas de motif requis"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr ""
+"le group de pseudo-fusion '%s' a un seuil instable avec un seuil stable"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"l'expression rationnelle de pseudo-fusion a trop de groupes de capture "
+"(max=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"la lecture de la pseudo-fusion étendue est hors-limite "
+"(%<PRIuMAX>=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"l'entrée de pseudo-fusion étendue est trop courte (%<PRIuMAX> ≥ %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr ""
+"impossible de trouver la pseudo-fusion pour le commit '%s' à l'offset "
+"%<PRIuMAX>"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr "recherche de pseudo-fusion étendue hors-limite (%<PRIu32> ≥ %<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "lecture hors-limite : (%<PRIuMAX> ≥ %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr ""
+"impossible de lire la table de pseudo-fusions étendues pour le commit %s"
+
msgid "could not start `log`"
msgstr "impossible de démarrer `log`"
@@ -19749,11 +20038,18 @@ msgstr "le journal pour la réf %s s'arrête de manière inattendue sur %s"
msgid "log for %s is empty"
msgstr "le journal pour la réf %s est vide"
+msgid "refusing to force and skip creation of reflog"
+msgstr "refus de forcer et sauter la création du reflog"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "refus de mettre à jour une réf avec un nom cassé '%s'"
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "refus de mettre à jour la pseudo-réf '%s'"
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "échec de update_ref pour la réf '%s' : %s"
@@ -19784,6 +20080,26 @@ msgid "could not delete references: %s"
msgstr "impossible de supprimer les références : %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr ""
+"Migration simulée des réfs terminée, le résultat peut être trouvé à '%s'\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "impossible de supprimer le répetoire de migration temporaire '%s'"
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "les références migrées peuvent être trouvées dans '%s'"
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"impossible de vérrouiller '%s' : symref attendu avec la cible '%s', mais réf "
+"normale trouvée"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "le nom de réference est dangereux : %s"
@@ -20963,6 +21279,49 @@ msgstr ""
"heads/%s"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "'%s' n'accepte pas de commit de fusion"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"'pick' n'accepte pas de commit de fusion. Si vous voulez\n"
+"rejouer la fusion, utilisez 'merge -C' sur le commit."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"'reword' n'accepte pas de commit de fusion.\n"
+"Si vous vouliez rejouer la fusion et la reformuler,\n"
+"utilisez 'merge -c' sur le commit"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"'edit' n'accepte pas de commit de fusion. Si vous vouliez\n"
+"rejouer la fusion, utilisez 'merge -C' sur le commit, puis\n"
+"'break' pour vous redonner le contrôle pour pouvoir faire\n"
+"'git commit --amend && git rebase --continue'."
+
+msgid "cannot squash merge commit into another commit"
+msgstr "impossible d'écraser un commit de fusion avec un autre commit"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "commande '%.*s' invalide"
@@ -21079,9 +21438,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "impossible de lire HEAD"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "impossible de copier '%s' vers '%s'"
+msgid "could not write commit message file"
+msgstr "impossible d'écrire le fichier de message de validation"
#, c-format
msgid ""
@@ -21487,6 +21845,18 @@ msgstr "impossible de revenir au répertoire de travail courant"
msgid "failed to stat '%*s%s%s'"
msgstr "échec du stat de '%*s%s%s'"
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"propriétaire douteux détecté dans le dépôt à '%s'\n"
+"%sPour ajouter une exception pour ce dépôt, lancez :\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Impossible d'accéder au répertoire de travail courant"
@@ -21509,18 +21879,6 @@ msgstr ""
"n'est pas défini)."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"propriétaire douteux détecté dans le dépôt à '%s'\n"
-"%sPour ajouter une exception pour ce dépôt, lancez :\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr "impossible d'utiliser le dépôt nu '%s' (safe.bareRepository vaut '%s')"
@@ -21830,6 +22188,16 @@ msgstr ""
"'%.*s'"
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr ""
+"'%.*s' dans le chemin du sous-module '%s' ne devait pas être un lien "
+"symbolique"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "le chemin du sous-module '%s' ne devait pas être un lien symbolique"
+
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -21868,10 +22236,6 @@ msgstr "échec du lstat de '%s'"
msgid "no remote configured to get bundle URIs from"
msgstr "aucun distant configuré depuis lequel récupérer des URIs de colis"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "le distant '%s' n'a pas d'URL configuré"
-
msgid "could not get the bundle-uri list"
msgstr "impossible d'avoir la liste de bundle-uris"
@@ -23374,24 +23738,24 @@ msgid "Failed to send %s\n"
msgstr "Échec de l'envoi de %s\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Envoi simulé de %s\n"
+msgid "Dry-Sent %s"
+msgstr "Envoi simulé de %s"
#, perl-format
-msgid "Sent %s\n"
-msgstr "%s envoyé\n"
+msgid "Sent %s"
+msgstr "%s envoyé"
-msgid "Dry-OK. Log says:\n"
-msgstr "Simulation OK. Le journal indique :\n"
+msgid "Dry-OK. Log says:"
+msgstr "Simulation OK. Le journal indique :"
-msgid "OK. Log says:\n"
-msgstr "OK. Le journal indique :\n"
+msgid "OK. Log says:"
+msgstr "OK. Le journal indique :"
msgid "Result: "
msgstr "Résultat : "
-msgid "Result: OK\n"
-msgstr "Résultat : OK\n"
+msgid "Result: OK"
+msgstr "Résultat : OK"
#, perl-format
msgid "can't open file %s"
@@ -23466,6 +23830,38 @@ msgstr "%s sauté avec un suffix de sauvegarde '%s'.\n"
msgid "Do you really want to send %s? [y|N]: "
msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
+#, c-format
+#~ msgid "truncating .rej filename to %.*s.rej"
+#~ msgstr "troncature du nom de fichier .rej en %.*s.rej"
+
+#~ msgid ""
+#~ "the add.interactive.useBuiltin setting has been removed!\n"
+#~ "See its entry in 'git help config' for details."
+#~ msgstr ""
+#~ "le réglage add.interactive.useBuiltin a été supprimé !\n"
+#~ "Référez-vous à cette entrée dans 'git help config' pour plus de détails."
+
+#~ msgid "git archive: Remote with no URL"
+#~ msgstr "git archive : Dépôt distant sans URL"
+
+#~ msgid "only one action at a time"
+#~ msgstr "une seule action à la fois"
+
+#~ msgid "use [RFC PATCH] instead of [PATCH]"
+#~ msgstr "utiliser [RFC PATCH] au lieu de [PATCH]"
+
+#, c-format
+#~ msgid "no URLs configured for remote '%s'"
+#~ msgstr "aucune URL configurée pour le dépôt distant '%s'"
+
+#, c-format
+#~ msgid "unable to copy '%s' to '%s'"
+#~ msgstr "impossible de copier '%s' vers '%s'"
+
+#, c-format
+#~ msgid "remote '%s' has no configured URL"
+#~ msgstr "le distant '%s' n'a pas d'URL configuré"
+
#~ msgid ""
#~ "Use -f if you really want to add them.\n"
#~ "Turn this message off by running\n"
@@ -23509,9 +23905,6 @@ msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
#~ msgid "core.commentChar should only be one ASCII character"
#~ msgstr "core.commentChar ne devrait être qu'un unique caractère ASCII"
-#~ msgid "-x and -X cannot be used together"
-#~ msgstr "-x et -X ne peuvent pas être utilisés ensemble"
-
#~ msgid ""
#~ "--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
#~ "exclude"
diff --git a/po/id.po b/po/id.po
index 2dc4b79e8a..7131a49e85 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-25 18:57+0000\n"
-"PO-Revision-Date: 2024-04-26 15:33+0700\n"
+"POT-Creation-Date: 2024-07-19 14:03+0700\n"
+"PO-Revision-Date: 2024-07-19 14:25+0700\n"
"Last-Translator: Bagas Sanjaya <bagasdotme@gmail.com>\n"
"Language-Team: Indonesian\n"
"Language: id\n"
@@ -104,12 +104,12 @@ msgstr[1] "%d jalur ditambahkan\n"
msgid "ignoring unmerged: %s"
msgstr "mengabaikan tak tergabung: %s"
-#: add-interactive.c add-patch.c
+#: add-interactive.c
#, c-format
msgid "Only binary files changed.\n"
msgstr "Hanya berkas biner yang berubah.\n"
-#: add-interactive.c add-patch.c
+#: add-interactive.c
#, c-format
msgid "No changes.\n"
msgstr "Tidak ada perubahan.\n"
@@ -666,6 +666,11 @@ msgstr ""
"? - lihat bantuan\n"
#: add-patch.c
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Hanya satu huruf yang diharapkan, dapat '%s'"
+
+#: add-patch.c
msgid "No previous hunk"
msgstr "Tidak ada bingkah sebelumnya"
@@ -728,9 +733,22 @@ msgid "Sorry, cannot edit this hunk"
msgstr "Maaf, tidak dapat menyunting bingkah ini"
#: add-patch.c
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "Perintah tidak dikenal '%s' (gunakan '?' untuk bantuan)"
+
+#: add-patch.c
msgid "'git apply' failed"
msgstr "'git apply' gagal"
+#: add-patch.c
+msgid "No changes."
+msgstr "Tidak ada perubahan."
+
+#: add-patch.c
+msgid "Only binary files changed."
+msgstr "Hanya berkas biner yang berubah."
+
#: advice.c
#, c-format
msgid ""
@@ -911,7 +929,7 @@ msgid "unclosed quote"
msgstr "tanda kutip tak ditutup"
#: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c
-#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c
+#: builtin/receive-pack.c builtin/refs.c builtin/tag.c t/helper/test-pkt-line.c
msgid "too many arguments"
msgstr "terlalu banyak argumen"
@@ -1808,6 +1826,11 @@ msgid "ignoring overly large gitattributes blob '%s'"
msgstr "mengabaikan blob gitattributes '%s' yang terlalu besar"
#: attr.c
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr ""
+"tidak dapat menggunakan --attr-source atau GIT_ATTR_SOURCE tanpa repositori"
+
+#: attr.c
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "--attr-source atau GIT_ATTR_SOURCE jelek"
@@ -2183,14 +2206,6 @@ msgid "Unstaged changes after refreshing the index:"
msgstr "Perubahan tak tergelar setelah menyegarkan indeks:"
#: builtin/add.c
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"setelan add.interactive.useBuiltin sudah dihapus!\n"
-"Selengkapnya lihat entrinya di 'git help config'."
-
-#: builtin/add.c
msgid "could not read the index"
msgstr "tidak dapat membaca indeks"
@@ -2644,7 +2659,7 @@ msgstr ""
"Sepertinya Anda telah memindahkan HEAD sejak kegagalan 'am' terakhir.\n"
"Tidak memutar ulang ke ORIG_HEAD"
-#: builtin/am.c builtin/bisect.c worktree.c
+#: builtin/am.c builtin/bisect.c builtin/tag.c worktree.c
#, c-format
msgid "failed to read '%s'"
msgstr "gagal membaca '%s'"
@@ -2722,8 +2737,8 @@ msgstr "n"
#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c
-#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c
+#: builtin/tag.c builtin/verify-tag.c
msgid "format"
msgstr "format"
@@ -2760,6 +2775,10 @@ msgid "show the patch being applied"
msgstr "perlihatkan tambalan yang diterapkan"
#: builtin/am.c
+msgid "try to apply current patch again"
+msgstr "coba terapkan lagi tambalan saat ini"
+
+#: builtin/am.c
msgid "record the empty patch as an empty commit"
msgstr "rekam tambalan kosong sebagai komit kosong"
@@ -2832,10 +2851,6 @@ msgid "could not redirect output"
msgstr "tidak dapat mengalihkan keluaran"
#: builtin/archive.c
-msgid "git archive: Remote with no URL"
-msgstr "git archive: Remote tanpa URL"
-
-#: builtin/archive.c
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive: ACK/NAK diharapkan, dapat paket bilasan"
@@ -3960,6 +3975,10 @@ msgstr "Perlu sebuah repositori untuk membuat bundel."
msgid "do not show bundle details"
msgstr "jangan perlihatkan detail bundel"
+#: builtin/bundle.c bundle.c
+msgid "need a repository to verify a bundle"
+msgstr "perlu sebuah repositori untuk verifikasi bundel"
+
#: builtin/bundle.c
#, c-format
msgid "%s is okay\n"
@@ -5018,9 +5037,9 @@ msgstr "pembersihan interaktif"
msgid "remove whole directories"
msgstr "hapus keseluruhan direktori"
-#: builtin/clean.c builtin/describe.c builtin/grep.c builtin/log.c
-#: builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c builtin/show-ref.c
-#: ref-filter.h
+#: builtin/clean.c builtin/config.c builtin/describe.c builtin/grep.c
+#: builtin/log.c builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c
+#: builtin/show-ref.c ref-filter.h
msgid "pattern"
msgstr "pola"
@@ -5239,6 +5258,16 @@ msgstr "gagal menghapus tautan '%s'"
#: builtin/clone.c
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "tautan keras tidak dapat diperiksa pada '%s'"
+
+#: builtin/clone.c
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "tautan keras berbeda dari sumber pada '%s'"
+
+#: builtin/clone.c
+#, c-format
msgid "failed to create link '%s'"
msgstr "gagal membuat tautan '%s'"
@@ -5313,7 +5342,7 @@ msgstr "Terlalu banyak argumen."
msgid "You must specify a repository to clone."
msgstr "Anda harus sebutkan repositori untuk diklon."
-#: builtin/clone.c builtin/init-db.c setup.c
+#: builtin/clone.c builtin/init-db.c builtin/refs.c setup.c
#, c-format
msgid "unknown ref storage format '%s'"
msgstr "format penyimpanan referensi tidak dikenal '%s'"
@@ -5936,7 +5965,7 @@ msgstr "%sPengkomit: %.*s <%.*s>"
msgid "Cannot read index"
msgstr "Tidak dapat membaca indeks"
-#: builtin/commit.c
+#: builtin/commit.c builtin/tag.c
msgid "unable to pass trailers to --trailers"
msgstr "tidak dapat melewatkan trailer ke --trailers"
@@ -6152,11 +6181,11 @@ msgstr "gunakan pesan terformat autosquash untuk lumat komit tersebut"
msgid "the commit is authored by me now (used with -C/-c/--amend)"
msgstr "komit sekarang dikarang olehku (gunakan dengan -C/-c/--amend)"
-#: builtin/commit.c builtin/interpret-trailers.c
+#: builtin/commit.c builtin/interpret-trailers.c builtin/tag.c
msgid "trailer"
msgstr "trailer"
-#: builtin/commit.c
+#: builtin/commit.c builtin/tag.c
msgid "add custom trailer(s)"
msgstr "tambahkan trailer kustom"
@@ -6269,17 +6298,58 @@ msgstr ""
"tidak terlampaui, lalu \"git restore --staged :/\" untuk pulihkan."
#: builtin/config.c
-msgid "git config [<options>]"
-msgstr "git config [<opsi>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<opsi berkas>] [<opsi tampilan>] [--includes]"
#: builtin/config.c
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "argumen --type tidak dikenal %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<opsi berkas>] [<opsi tampilan] [--includes] [--all] [--"
+"regexp=<regexp> [--value=<nilai>] [--fixed-value] [--default=<default>] "
+"<nama>"
#: builtin/config.c
-msgid "only one type at a time"
-msgstr "hanya satu tipe pada suatu saat"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<opsi berkas>] [--type=<tipe>] [--all] [--value=<nilai>] [--"
+"fixed-value] <nama> <nilai>"
+
+#: builtin/config.c
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<opsi berkas] [--all] [--value=<nilai>] [--fixed-value] "
+"<nama> <nilai>"
+
+#: builtin/config.c
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<opsi berkas>] <nama lama> <nama baru>"
+
+#: builtin/config.c
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<opsi berkas>] <nama>"
+
+#: builtin/config.c
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<opsi berkas>]"
+
+#: builtin/config.c
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr "git config [<opsi berkas>] --get-colorbool <nama> [<stdout-is-tty>]"
+
+#: builtin/config.c
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<opsi berkas>] [--type=<tipe>] [--comment=<pesan>] [--all] "
+"[--value=<nilai>] [--fixed-value] <nama> <nilai>"
#: builtin/config.c
msgid "Config file location"
@@ -6314,70 +6384,6 @@ msgid "read config from given blob object"
msgstr "baca konfigurasi dari objek blob yang diberikan"
#: builtin/config.c
-msgid "Action"
-msgstr "Tindakan"
-
-#: builtin/config.c
-msgid "get value: name [value-pattern]"
-msgstr "dapatkan nilai: name [pola nilai]"
-
-#: builtin/config.c
-msgid "get all values: key [value-pattern]"
-msgstr "dapatkan semua nilai: key [pola nilai]"
-
-#: builtin/config.c
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "dapatkan nilai dari regexp: name-regex [pola nilai]"
-
-#: builtin/config.c
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "dapatkan nilai spesifik untuk URL: section[.var] URL"
-
-#: builtin/config.c
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "ganti semua variabel yang cocok: name value [pola nilai]"
-
-#: builtin/config.c
-msgid "add a new variable: name value"
-msgstr "tambahkan variabel baru: name value"
-
-#: builtin/config.c
-msgid "remove a variable: name [value-pattern]"
-msgstr "hapus variabel: name [pola nilai]"
-
-#: builtin/config.c
-msgid "remove all matches: name [value-pattern]"
-msgstr "hapus semua cocokan: name [pola nilai]"
-
-#: builtin/config.c
-msgid "rename section: old-name new-name"
-msgstr "ganti nama bagian: old-name new-name"
-
-#: builtin/config.c
-msgid "remove a section: name"
-msgstr "hapus bagian: name"
-
-#: builtin/config.c
-msgid "list all"
-msgstr "daftar semua"
-
-#: builtin/config.c
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "gunakan kesamaan untai ketika membandingkan nilai ke 'pola nilai'"
-
-#: builtin/config.c
-msgid "open an editor"
-msgstr "buka penyunting"
-
-#: builtin/config.c
-msgid "find the color configured: slot [default]"
-msgstr "temukan warna terkonfigurasi: slot [asali]"
-
-#: builtin/config.c
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "temukan setelan warna: slot [stdout-is-tty]"
-
-#: builtin/config.c
msgid "Type"
msgstr "Tipe"
@@ -6414,8 +6420,8 @@ msgid "value is an expiry date"
msgstr "nilai adalah tanggal kadaluarsa"
#: builtin/config.c
-msgid "Other"
-msgstr "Lainnya"
+msgid "Display options"
+msgstr "Tampilkan opsi"
#: builtin/config.c
msgid "terminate values with NUL byte"
@@ -6426,10 +6432,6 @@ msgid "show variable names only"
msgstr "perlihatkan hanya nama variabel"
#: builtin/config.c
-msgid "respect include directives on lookup"
-msgstr "segani arahan masukkan pada pencarian"
-
-#: builtin/config.c
msgid "show origin of config (file, standard input, blob, command line)"
msgstr ""
"perlihatkan asal konfigurasi (berkas, masukan standar, blob, baris perintah)"
@@ -6441,17 +6443,17 @@ msgstr ""
"perintah)"
#: builtin/config.c
-msgid "value"
-msgstr "nilai"
+msgid "show config keys in addition to their values"
+msgstr "perlihatkan kunci opsi beserta nilainya"
#: builtin/config.c
-msgid "with --get, use default value when missing entry"
-msgstr "dengan --get, gunakan nilai asali ketika kehilangan entri"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "argumen --type tidak dikenal %s"
#: builtin/config.c
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr ""
-"untai komentar yang dapat dibaca manusia (# akan ditambahkan bila diperlukan"
+msgid "only one type at a time"
+msgstr "hanya satu tipe pada suatu saat"
#: builtin/config.c
#, c-format
@@ -6545,60 +6547,94 @@ msgstr ""
"\"CONFIGURATION FILE\" di \"git help worktree\" untuk selengkapnya"
#: builtin/config.c
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color dan tipe variabel raban"
+msgid "Other"
+msgstr "Lainnya"
#: builtin/config.c
-msgid "only one action at a time"
-msgstr "hanya satu tindakan pada suatu saat"
+msgid "respect include directives on lookup"
+msgstr "segani arahan masukkan pada pencarian"
#: builtin/config.c
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only hanya dapat diterapkan pada --list atau --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "tidak dapat membaca berkas konfigurasi '%s'"
#: builtin/config.c
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-"--show-origin hanya dapat diterapkan pada --get, --get-all, --get-regexp, "
-"dan --list"
+msgid "error processing config file(s)"
+msgstr "kesalahan memproses berkas konfigurasi"
#: builtin/config.c
-msgid "--default is only applicable to --get"
-msgstr "--default hanya dapat diterapkan pada --get"
+msgid "Filter options"
+msgstr "Opsi penyaringan"
#: builtin/config.c
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr ""
-"--comment hanya dapat diterapkan pada operasi penambahan/penyetelan/"
-"penggantian"
+msgid "return all values for multi-valued config options"
+msgstr "dapatkan semua nilai untuk opsi konfigurasi multi-nilai"
+
+#: builtin/config.c
+msgid "interpret the name as a regular expression"
+msgstr "tafsirkan nama sebagai ekspresi reguler"
+
+#: builtin/config.c
+msgid "show config with values matching the pattern"
+msgstr "perlihatkan konfigurasi dengan nilai yang cocok dengan pola"
+
+#: builtin/config.c
+msgid "use string equality when comparing values to value pattern"
+msgstr "gunakan kesamaan untai ketika membandingkan nilai dan pola nilai"
+
+#: builtin/config.c
+msgid "URL"
+msgstr "URL"
+
+#: builtin/config.c
+msgid "show config matching the given URL"
+msgstr "perlihatkan konfigurasi yang cocok dengan URL yang diberikan"
+
+#: builtin/config.c
+msgid "value"
+msgstr "nilai"
+
+#: builtin/config.c
+msgid "use default value when missing entry"
+msgstr "gunakan nilai asali ketika entri hilang"
#: builtin/config.c
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value hanya diterapkan dengan 'pola nilai'"
#: builtin/config.c
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "tidak dapat membaca berkas konfigurasi '%s'"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= tidak dapat digunakan dengan --all atau --url="
#: builtin/config.c
-msgid "error processing config file(s)"
-msgstr "kesalahan memproses berkas konfigurasi"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= tidak dapat digunakan dengan --all, --regexp atau --value"
#: builtin/config.c
-msgid "editing stdin is not supported"
-msgstr "menyunting stdin tidak didukung"
+msgid "Filter"
+msgstr "Penyaring"
#: builtin/config.c
-msgid "editing blobs is not supported"
-msgstr "menyunting blob tidak didukung"
+msgid "replace multi-valued config option with new value"
+msgstr "ganti opsi konfigurasi multi-nilai dengan nilai baru"
#: builtin/config.c
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "tidak dapat membuat berkas konfigurasi %s"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"untai komentar yang dapat dibaca manusia (# akan ditambahkan bila diperlukan"
+
+#: builtin/config.c
+msgid "add a new line without altering any existing values"
+msgstr "tambahkan baris baru tanpa mengubah nilai yang ada"
+
+#: builtin/config.c
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value hanya diterapkan dengan --value=<pola>"
+
+#: builtin/config.c
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append tidak dapat digunakan dengan --value=<pola>"
#: builtin/config.c
#, c-format
@@ -6614,6 +6650,113 @@ msgstr ""
msgid "no such section: %s"
msgstr "tidak ada bagian seperti: %s"
+#: builtin/config.c
+msgid "editing stdin is not supported"
+msgstr "menyunting stdin tidak didukung"
+
+#: builtin/config.c
+msgid "editing blobs is not supported"
+msgstr "menyunting blob tidak didukung"
+
+#: builtin/config.c
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "tidak dapat membuat berkas konfigurasi %s"
+
+#: builtin/config.c
+msgid "Action"
+msgstr "Tindakan"
+
+#: builtin/config.c
+msgid "get value: name [<value-pattern>]"
+msgstr "dapatkan nilai: name [<pola nilai>]"
+
+#: builtin/config.c
+msgid "get all values: key [<value-pattern>]"
+msgstr "dapatkan semua nilai: key [<pola nilai>]"
+
+#: builtin/config.c
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "dapatkan nilai dari ekspresi reguler: name-regex [<pola nilai>]"
+
+#: builtin/config.c
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "dapatkan nilai spesifik untuk URL: section[.var] URL"
+
+#: builtin/config.c
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "ganti semua variabel yang cocok: name value [<pola nilai>]"
+
+#: builtin/config.c
+msgid "add a new variable: name value"
+msgstr "tambahkan variabel baru: name value"
+
+#: builtin/config.c
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "hapus variabel: name [<pola nilai>]"
+
+#: builtin/config.c
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "hapus semua cocokan: name [<pola nilai>]"
+
+#: builtin/config.c
+msgid "rename section: old-name new-name"
+msgstr "ganti nama bagian: old-name new-name"
+
+#: builtin/config.c
+msgid "remove a section: name"
+msgstr "hapus bagian: name"
+
+#: builtin/config.c
+msgid "list all"
+msgstr "daftar semua"
+
+#: builtin/config.c
+msgid "open an editor"
+msgstr "buka penyunting"
+
+#: builtin/config.c
+msgid "find the color configured: slot [<default>]"
+msgstr "temukan warna terkonfigurasi: slot [<asali>]"
+
+#: builtin/config.c
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "temukan setelan warna: slot [<stdout-is-tty>]"
+
+#: builtin/config.c
+msgid "with --get, use default value when missing entry"
+msgstr "dengan --get, gunakan nilai asali ketika kehilangan entri"
+
+#: builtin/config.c
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color dan tipe variabel raban"
+
+#: builtin/config.c
+msgid "no action specified"
+msgstr "tidak ada tindakan yang dipilih"
+
+#: builtin/config.c
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only hanya dapat diterapkan pada --list atau --get-regexp"
+
+#: builtin/config.c
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin hanya dapat diterapkan pada --get, --get-all, --get-regexp, "
+"dan --list"
+
+#: builtin/config.c
+msgid "--default is only applicable to --get"
+msgstr "--default hanya dapat diterapkan pada --get"
+
+#: builtin/config.c
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr ""
+"--comment hanya dapat diterapkan pada operasi penambahan/penyetelan/"
+"penggantian"
+
#: builtin/count-objects.c
msgid "print sizes in human readable format"
msgstr "cetak ukuran dalam format yang bisa dibaca manusia"
@@ -7662,6 +7805,10 @@ msgid "config key storing a list of repository paths"
msgstr "kunci konfigurasi yang menampung daftar jalur repositori"
#: builtin/for-each-repo.c
+msgid "keep going even if command fails in a repository"
+msgstr "tetap lanjut meski perintah gagal pada repositori"
+
+#: builtin/for-each-repo.c
msgid "missing --config=<config>"
msgstr "kehilangan --config=<config>"
@@ -9518,8 +9665,12 @@ msgid "max length of output filename"
msgstr "panjang nama berkas keluaran maksimum"
#: builtin/log.c
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "gunakan [RFC PATCH] daripada [PATCH]"
+msgid "rfc"
+msgstr "rfc"
+
+#: builtin/log.c
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "tambahkan <rfc> (asali 'RFC') sebelum 'PATCH'"
#: builtin/log.c
msgid "cover-from-description-mode"
@@ -9870,11 +10021,11 @@ msgstr ""
#: builtin/ls-remote.c
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<kunci>]\n"
" [--symref] [<repositori> [<pola>...]]"
@@ -9895,8 +10046,12 @@ msgid "limit to tags"
msgstr "batasi ke tag"
#: builtin/ls-remote.c
-msgid "limit to heads"
-msgstr "batasi ke kepala"
+msgid "limit to branches"
+msgstr "batasi ke cabang"
+
+#: builtin/ls-remote.c builtin/show-ref.c
+msgid "deprecated synonym for --branches"
+msgstr "sinonim usang untuk --branches"
#: builtin/ls-remote.c
msgid "do not show peeled tags"
@@ -13177,6 +13332,27 @@ msgstr "tidak ada log referensi yang disebutkan untuk dihapus"
msgid "invalid ref format: %s"
msgstr "format referensi tidak valid: %s"
+#: builtin/refs.c
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<format> [--dry-run]"
+
+#: builtin/refs.c
+msgid "specify the reference format to convert to"
+msgstr "sebutkan format referensi untuk dikonversi"
+
+#: builtin/refs.c
+msgid "perform a non-destructive dry-run"
+msgstr "lakukan uji coba non desktruktif"
+
+#: builtin/refs.c
+msgid "missing --ref-format=<format>"
+msgstr "--ref-format=<format> hilang"
+
+#: builtin/refs.c
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "repositori telah menggunakan format '%s'"
+
#: builtin/remote.c
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
@@ -13530,10 +13706,6 @@ msgstr "* remote %s"
msgid " Fetch URL: %s"
msgstr " URL pengambilan: %s"
-#: builtin/remote.c
-msgid "(no URL)"
-msgstr "(tidak ada URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -13544,6 +13716,10 @@ msgid " Push URL: %s"
msgstr " URL pendorongan: %s"
#: builtin/remote.c
+msgid "(no URL)"
+msgstr "(tidak ada URL)"
+
+#: builtin/remote.c
#, c-format
msgid " HEAD branch: %s"
msgstr " Cabang HEAD: %s"
@@ -13678,11 +13854,6 @@ msgid "return all URLs"
msgstr "kembalikan semua URL"
#: builtin/remote.c
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "tidak ada URL yang dikonfigurasi untuk remote '%s'"
-
-#: builtin/remote.c
msgid "manipulate push URLs"
msgstr "manipulasi URL pendorongan"
@@ -14951,12 +15122,12 @@ msgstr "algoritma hash tidak dikenal"
#: builtin/show-ref.c
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pola>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pola>...]"
#: builtin/show-ref.c
msgid ""
@@ -14985,12 +15156,12 @@ msgid "failed to look up reference"
msgstr "gagal mencari referensi"
#: builtin/show-ref.c
-msgid "only show tags (can be combined with heads)"
-msgstr "hanya perlihatkan tag (bisa dikombinasikan dengan kepala)"
+msgid "only show tags (can be combined with branches)"
+msgstr "hanya perlihatkan tag (bisa dikombinasikan dengan cabang)"
#: builtin/show-ref.c
-msgid "only show heads (can be combined with tags)"
-msgstr "hanya perlihatkan kepala (bisa dikombinasikan dengan tag)"
+msgid "only show branches (can be combined with tags)"
+msgstr "hanya perlihatkan cabang (bisa dikombinasikan dengan tag)"
#: builtin/show-ref.c
msgid "check for reference existence without resolving"
@@ -15765,7 +15936,7 @@ msgstr "Nilai '%s' untuk submodule.alternateErrorStrategy tidak dikenal"
msgid "Value '%s' for submodule.alternateLocation is not recognized"
msgstr "Nilai '%s' untuk submodule.alternateLocation tidak dikenal"
-#: builtin/submodule--helper.c
+#: builtin/submodule--helper.c submodule.c
#, c-format
msgid "refusing to create/use '%s' in another submodule's git dir"
msgstr ""
@@ -15773,13 +15944,13 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "gagal mengkloning '%s' ke dalam jalur submodul '%s'"
+msgid "directory not empty: '%s'"
+msgstr "direktori tidak kosong: '%s'"
#: builtin/submodule--helper.c
#, c-format
-msgid "directory not empty: '%s'"
-msgstr "direktori tidak kosong: '%s'"
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "gagal mengkloning '%s' ke dalam jalur submodul '%s'"
#: builtin/submodule--helper.c
#, c-format
@@ -16230,9 +16401,11 @@ msgstr "alasan pembaruan"
#: builtin/tag.c
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <id kunci>] [-f] [-m <pesan> | -F <berkas>] [-e]\n"
+" [(--trailer <token>[(=|:)<nilai>])...]\n"
" <nama tag> [<komit> | <objek>]"
#: builtin/tag.c
@@ -17292,10 +17465,6 @@ msgid "Repository lacks these prerequisite commits:"
msgstr "Repositori kekurangan komit prasyarat berikut:"
#: bundle.c
-msgid "need a repository to verify a bundle"
-msgstr "perlu sebuah repositori untuk verifikasi bundel"
-
-#: bundle.c
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -17825,6 +17994,10 @@ msgid "Manage reflog information"
msgstr "Kelola informasi log referensi"
#: command-list.h
+msgid "Low-level access to refs"
+msgstr "Akses tingat bawah ke referensi"
+
+#: command-list.h
msgid "Manage set of tracked repositories"
msgstr "Kelola set repositori terlacak"
@@ -18226,6 +18399,15 @@ msgid "commit-graph required commit data chunk missing or corrupted"
msgstr "bingkah grafik komit data komit yang diperlukan hilang atau rusak"
#: commit-graph.c
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"menonaktifkan penyaring Bloom untuk lapisan grafik komit '%s' karena setelan "
+"yang tidak cocok"
+
+#: commit-graph.c
msgid "commit-graph has no base graphs chunk"
msgstr "grafik komit tidak punya bingkah grafik dasar"
@@ -18384,6 +18566,15 @@ msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr "mencoba menulis grafik komit, tapi 'core.commitGraph' dimatikan"
#: commit-graph.c
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"mencoba menulis grafik komit, tapi 'commitGraph.changedPathsVersion (%d) "
+"tidak didukung"
+
+#: commit-graph.c
msgid "too many commits to write graph"
msgstr "terlalu banyak komit untuk menulis grafik"
@@ -20693,15 +20884,17 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v| --version] [-h | --help] [-C <jalur>] [-c <nama>=<nilai>]\n"
" [--exec-path[=<jalur>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects]\n"
+" [--no-lazy-fetch] [--no-optional-locks] [--no-advice] [--bare]\n"
" [--git-dir=<jalur>] [--work-tree=<jalur>] [--namespace=<nama>]\n"
" [--config-env=<nama>=<variabel lingkungan>]\n"
" <perintah> [<argumen>]"
@@ -21117,14 +21310,14 @@ msgstr ""
"ignoredHook false`."
#: http-fetch.c
+msgid "not a git repository"
+msgstr "bukan sebuah repositori git"
+
+#: http-fetch.c
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "argumen ke --packfile harus sebuah hash valid (dapat '%s')"
-#: http-fetch.c
-msgid "not a git repository"
-msgstr "bukan sebuah repositori git"
-
#: http.c
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
@@ -21139,6 +21332,10 @@ msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "Penyematan kunci publik tidak didukung oleh cURL < 7.39.0"
#: http.c
+msgid "Unknown value for http.proactiveauth"
+msgstr "nilai tidak dikenal untuk http.proactiveauth"
+
+#: http.c
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE tidak didukung dengan cURL < 7.44.0"
@@ -21160,6 +21357,14 @@ msgid "Could not set SSL backend to '%s': already set"
msgstr "Tidak dapat menyetel tulang punggung SSL ke '%s': sudah disetel"
#: http.c
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "menolak membaca kuki dari http.cookiefile '-'"
+
+#: http.c
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "mengabaikan http.savecookies karena http.cookiefile kosong"
+
+#: http.c
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -21367,10 +21572,10 @@ msgstr "Gagal menggabungkan submodul %s (tidak ada dasar penggabungan)"
msgid "Failed to merge submodule %s (commits not present)"
msgstr "Gagal menggabungkan submodul %s (komit tidak ada)"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "Gagal menggabungkan submodul %s (repositori rusak)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "kesalahan: gagal menggabungkan submodul %s (repositori rusak)"
#: merge-ort.c merge-recursive.c
#, c-format
@@ -21406,14 +21611,15 @@ msgstr ""
"mungkin:\n"
"%s"
-#: merge-ort.c merge-recursive.c
-msgid "failed to execute internal merge"
-msgstr "gagal menjalankan penggabungan internal"
+#: merge-ort.c
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "kesalahan: gagal menjalankan penggabungan internal untuk %s"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "unable to add %s to database"
-msgstr "tidak dapat menambahkan %s ke basis data"
+msgid "error: unable to add %s to database"
+msgstr "kesalahan: tidak dapat menambahkan %s ke basis data"
#: merge-ort.c merge-recursive.c
#, c-format
@@ -21520,15 +21726,15 @@ msgstr ""
"KONFLIK (penamaan ulang/penghapusan): %s dinamai ulang ke %s di %s, tetapi "
"dihapus di %s."
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "cannot read object %s"
-msgstr "tidak dapat membaca objek %s"
+msgid "error: cannot read object %s"
+msgstr "kesalahan: tidak dapat membaca objek %s"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "object %s is not a blob"
-msgstr "objek %s bukanlah sebuah blob"
+msgid "error: object %s is not a blob"
+msgstr "kesalahan: objek %s bukanlah suatu blob"
#: merge-ort.c
#, c-format
@@ -21689,6 +21895,11 @@ msgstr "tidak tahu apa yang dilakukan dengan %06o %s '%s'"
#: merge-recursive.c
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Gagal menggabungkan submodul %s (repositori rusak)"
+
+#: merge-recursive.c
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Memaju-cepat submodul %s ke komit berikut:"
@@ -21735,6 +21946,15 @@ msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Gagal menggabungkan submodul %s (banyak penggabungan ditemukan)"
#: merge-recursive.c
+msgid "failed to execute internal merge"
+msgstr "gagal menjalankan penggabungan internal"
+
+#: merge-recursive.c
+#, c-format
+msgid "unable to add %s to database"
+msgstr "tidak dapat menambahkan %s ke basis data"
+
+#: merge-recursive.c
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr ""
@@ -21857,6 +22077,16 @@ msgstr ""
"%s. Penamaan ulang %s->%s di %s"
#: merge-recursive.c
+#, c-format
+msgid "cannot read object %s"
+msgstr "tidak dapat membaca objek %s"
+
+#: merge-recursive.c
+#, c-format
+msgid "object %s is not a blob"
+msgstr "objek %s bukanlah sebuah blob"
+
+#: merge-recursive.c
msgid "modify"
msgstr "ubah"
@@ -21962,10 +22192,6 @@ msgid "malformed line: %s"
msgstr "baris jelek '%s'."
#: midx-write.c
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "abaikan indeks multipak yang sudah ada; checksum tidak cocok"
-
-#: midx-write.c
msgid "could not load pack"
msgstr "tidak dapat memuat pak"
@@ -21975,6 +22201,10 @@ msgid "could not open index for %s"
msgstr "tidak dapat membuka indeks untuk %s"
#: midx-write.c
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "abaikan indeks multipak yang sudah ada; checksum tidak cocok"
+
+#: midx-write.c
msgid "Adding packfiles to multi-pack-index"
msgstr "Menambahkan berkas pak ke indeks multipak"
@@ -22723,6 +22953,20 @@ msgid "hash mismatch %s"
msgstr "hash tidak cocok %s"
#: pack-bitmap-write.c
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "entri duplikat ketika menulis indeks bitmap: %s"
+
+#: pack-bitmap-write.c
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "mencoba menyimpan komit yang tidak dipilih: '%s'"
+
+#: pack-bitmap-write.c
+msgid "too many pseudo-merges"
+msgstr "terlalu banyak penggabungan semu"
+
+#: pack-bitmap-write.c
msgid "trying to write commit not in index"
msgstr "mencoba menulis komit yang bukan di indeks"
@@ -22753,6 +22997,23 @@ msgstr ""
"berkas indeks bitmap rusak (terlalu pendek untuk masuk tabel pencarian)"
#: pack-bitmap.c
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"berkas indeks bitmap rusak (terlalu pendek untuk masuk kepala tabel "
+"penggabungan semu)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr ""
+"berkas indeks bitmap rusak (terlalu pendek untuk masuk tabel penggabungan "
+"semu)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "berkas indeks bitmap rusak (tabel penggabungan semu terlalu pendek)"
+
+#: pack-bitmap.c
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "entri duplikat di indeks bitmap: '%s'"
@@ -22868,6 +23129,11 @@ msgstr "ketidaksesuaian di dalam hasil bitmap"
#: pack-bitmap.c
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "indeks penggabungan semu di luar jangkauan (%<PRIu32> >= %<PRIuMAX>)"
+
+#: pack-bitmap.c
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "tidak dapat menemukan %s di dalam pak '%s' pada offset %<PRIuMAX>"
@@ -23325,6 +23591,10 @@ msgid "unable to parse --pretty format"
msgstr "tidak dapat menguraikan format --pretty"
#: promisor-remote.c
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "pengambilan malas dimatikan; beberapa objek mungkin tidak tersedia"
+
+#: promisor-remote.c
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote: tidak dapat menggarpu subproses pengambilan"
@@ -23355,6 +23625,83 @@ msgstr "object-info: bilasan diharapkan setelah argumen"
msgid "Removing duplicate objects"
msgstr "Menghapus objek duplikat"
+#: pseudo-merge.c
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "gagal memuat regex penggabungan semu untuk %s: '%s'"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s harus non-negatif, menggunakan yang asali"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s harus di antara 0 atau 1, menggunakan yang asali"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s harus positif, menggunakan yang asali"
+
+#: pseudo-merge.c
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "grup penggabungan semu '%s' kehilangan pola yang diperlukan"
+
+#: pseudo-merge.c
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr ""
+"grup penggabungan semu '%s' punya ambang batas tidak stabil sebelum yang "
+"stabil"
+
+#: pseudo-merge.c
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"regex penggabungan semu dari konfigurasi punya terlalu banyak grup tangkap "
+"(max=%<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"pembacaan penggabungan semu yang diperluas di luar batas (%<PRIuMAX> >= "
+"%<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"entri penggabungan semu yang diperluas terlalu pendek (%<PRIuMAX> >= "
+"%<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr ""
+"tidak dapat menemukan penggabungan semu untuk %s pada offset %<PRIuMAX>"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr ""
+"pencarian penggabungan semu yang diperluas di luar batas (%<PRIu32> >= "
+"%<PRIu32>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "pembacaan di luar batas: (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "tidak dapat membaca tabel penggabungan semu untuk komit %s"
+
#: range-diff.c
msgid "could not start `log`"
msgstr "tidak dapat memulai `log`"
@@ -24081,12 +24428,21 @@ msgid "log for %s is empty"
msgstr "log untuk %s kosong"
#: refs.c
+msgid "refusing to force and skip creation of reflog"
+msgstr "menolak memaksa dan melewatkan pembuatan reflog"
+
+#: refs.c
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "menolak memperbarui referensi dengan nama jelek '%s'"
#: refs.c
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "menolak memperbarui referensi semu '%s'"
+
+#: refs.c
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "update_ref gagal untuk referensi '%s': %s"
@@ -24123,6 +24479,29 @@ msgstr "tidak dapat menghapus referensi %s: %s"
msgid "could not delete references: %s"
msgstr "tidak dapat menghapus referensi: %s"
+#: refs.c
+#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "Selesai uji coba migrasi referensi, hasilnya bisa dilihat di '%s'\n"
+
+#: refs.c
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "tidak dapat menamai ulang direktori migrasi sementara '%s'"
+
+#: refs.c
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "referensi termigrasi dapat ditemukan pada '%s'"
+
+#: refs/files-backend.c refs/reftable-backend.c
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"tidak dapat mengunci referensi '%s': diharapkan referensi simbolik dengan "
+"target '%s': tetapi bukan referensi reguler"
+
#: refs/reftable-backend.c
#, c-format
msgid "refname is dangerous: %s"
@@ -25545,6 +25924,55 @@ msgstr ""
#: sequencer.c
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "'%s' tidak menerima komit penggabungan"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+#: sequencer.c
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"'pick' tidak mengambil komit penggabungan. Apabila Anda\n"
+"ingin memainkan ulang penggabungan, gunakan 'merge -C'\n"
+"pada komit."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+#: sequencer.c
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"'reword' tidak mengambil komit penggabungan. Apabila Anda\n"
+"ingin memainkan ulang penggabungan dan menulis ulang pesan\n"
+"komit, gunakan 'merge -c' pada komit"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+#: sequencer.c
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"'edit' tidak mengambil komit penggabungan. Apabila Anda\n"
+"ingin memainkan ulang komit, gunakan 'merge -C' pada komit,\n"
+"lalu 'break' untuk memberikan Anda kembali kendali agar\n"
+"Anda dapat menjalankan 'git commit --amend && git rebase --continue'."
+
+#: sequencer.c
+msgid "cannot squash merge commit into another commit"
+msgstr "tidak dapat melumatkan komit penggabungan ke dalam komit lainnya"
+
+#: sequencer.c
+#, c-format
msgid "invalid command '%.*s'"
msgstr "perintah tidak valid '%.*s'"
@@ -25695,9 +26123,8 @@ msgid "cannot read HEAD"
msgstr "tidak dapat membaca HEAD"
#: sequencer.c
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "tidak dapat menyalin '%s' ke '%s'"
+msgid "could not write commit message file"
+msgstr "tidak dapat menulis berkas pesan komit"
#: sequencer.c
#, c-format
@@ -26180,6 +26607,19 @@ msgid "failed to stat '%*s%s%s'"
msgstr "gagal men-stat '%*s%s%s'"
#: setup.c
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"perizinan meragukan terdeteksi di dalam repositori pada '%s'\n"
+"%sUntuk menambahkan pengecualian untuk direktori ini, panggil:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
+#: setup.c
msgid "Unable to read current working directory"
msgstr "tidak dapat membaca direktori kerja saat ini"
@@ -26205,19 +26645,6 @@ msgstr ""
#: setup.c
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"perizinan meragukan terdeteksi di dalam repositori pada '%s'\n"
-"%sUntuk menambahkan pengecualian untuk direktori ini, panggil:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#: setup.c
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr ""
"tidak dapat menggunakan repositori bare '%s' (safe.bareRepository yaitu '%s')"
@@ -26591,6 +27018,17 @@ msgstr "direktori submodul git '%s' di dalam direktori git '%.*s'"
#: submodule.c
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr ""
+"'%.*s' diharapkan di jalur submodul '%s' yang tidak menjadi tautan simbolik"
+
+#: submodule.c
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "jalur submodul '%s' diharapkan yang tidak menjadi tautan simbolik"
+
+#: submodule.c
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -26637,11 +27075,6 @@ msgid "no remote configured to get bundle URIs from"
msgstr "tidak ada remote yang dikonfigurasi untuk mendapatkan URI bundel"
#: t/helper/test-bundle-uri.c
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "remote '%s' tidak punya URL terkonfigurasi"
-
-#: t/helper/test-bundle-uri.c
msgid "could not get the bundle-uri list"
msgstr "tidak dapat mendapatkan daftar bundle-uri"
@@ -28440,29 +28873,29 @@ msgstr "Gagal mengirim %s\n"
#: git-send-email.perl
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Terkirim-kering %s\n"
+msgid "Dry-Sent %s"
+msgstr "Uji-coba-Terkirim %s"
#: git-send-email.perl
#, perl-format
-msgid "Sent %s\n"
-msgstr "Terkirim %s\n"
+msgid "Sent %s"
+msgstr "Terkirim %s"
#: git-send-email.perl
-msgid "Dry-OK. Log says:\n"
-msgstr "OK-kering. Log berkata:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Uji-coba-OK. Log berkata:"
#: git-send-email.perl
-msgid "OK. Log says:\n"
-msgstr "OK. Log berkata:\n"
+msgid "OK. Log says:"
+msgstr "OK. Log berkata:"
#: git-send-email.perl
msgid "Result: "
msgstr "Hasil: "
#: git-send-email.perl
-msgid "Result: OK\n"
-msgstr "Hasil: OK\n"
+msgid "Result: OK"
+msgstr "Hasil: OK"
#: git-send-email.perl
#, perl-format
diff --git a/po/sv.po b/po/sv.po
index ad1aad94ff..4e05168183 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,10 +5,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: git 2.45.0\n"
+"Project-Id-Version: git 2.46.0\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-27 15:19+0100\n"
-"PO-Revision-Date: 2024-04-27 15:20+0100\n"
+"POT-Creation-Date: 2024-07-20 21:56+0100\n"
+"PO-Revision-Date: 2024-07-21 14:53+0100\n"
"Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
"Language-Team: Svenska <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@@ -556,6 +556,10 @@ msgstr ""
"p - visa aktuellt stycke\n"
"? - visa hjälp\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Förväntade endast en bokstav, fick ”%s”"
+
msgid "No previous hunk"
msgstr "Inget föregående stycke"
@@ -604,9 +608,19 @@ msgstr "Dela i %d stycken."
msgid "Sorry, cannot edit this hunk"
msgstr "Beklagar, kan inte redigera stycket"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "Okänt kommando ”%s” (använd ”?” för hjälp)"
+
msgid "'git apply' failed"
msgstr "”git apply” misslyckades"
+msgid "No changes."
+msgstr "Inga ändringar."
+
+msgid "Only binary files changed."
+msgstr "Endast binära filer ändrade."
+
#, c-format
msgid ""
"\n"
@@ -1461,6 +1475,9 @@ msgstr "ignorerar allt för stor gitattributes-fil ”%s”"
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "ignorerar allt för stor gitattributes-objekt ”%s”"
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "kan inte använda --attr-source eller GIT_ATTR_SOURCE utan arkiv"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "felaktig --attr-source eller GIT_ATTR_SOURCE"
@@ -1778,13 +1795,6 @@ msgstr "kan inte utföra chmod %cx ”%s”"
msgid "Unstaged changes after refreshing the index:"
msgstr "Oköade ändringar efter att ha uppdaterat indexet:"
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"inställningen add.interactive.useBuiltin har tagits bort!\n"
-"Se dess post i ”git help config” för detaljer."
-
msgid "could not read the index"
msgstr "kunde inte läsa indexet"
@@ -2219,6 +2229,9 @@ msgstr "avbryt patchningen men behåll HEAD där det är"
msgid "show the patch being applied"
msgstr "visa patchen som tillämpas"
+msgid "try to apply current patch again"
+msgstr "försök applicera aktuell patch på nytt"
+
msgid "record the empty patch as an empty commit"
msgstr "lagra den tomma patchen som en tom incheckning"
@@ -2274,9 +2287,6 @@ msgstr "git apply [<flaggor>] [<patch>...]"
msgid "could not redirect output"
msgstr "kunde inte omdirigera utdata"
-msgid "git archive: Remote with no URL"
-msgstr "git archive: Fjärr utan URL"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive: förväntade ACK/NAK, fick flush-paket"
@@ -3169,6 +3179,9 @@ msgstr "Behöver ett arkiv för att skapa en bunt."
msgid "do not show bundle details"
msgstr "visa inte buntdetaljer"
+msgid "need a repository to verify a bundle"
+msgstr "behöver ett arkiv för att bekräfta en bunt."
+
#, c-format
msgid "%s is okay\n"
msgstr "%s är okej\n"
@@ -4174,6 +4187,14 @@ msgid "failed to unlink '%s'"
msgstr "misslyckades ta bort länken ”%s”"
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "hård länk kan inte kontrolleras vid ”%s”"
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "hård länk skiljer sig från källan vid ”%s”"
+
+#, c-format
msgid "failed to create link '%s'"
msgstr "misslyckades skapa länken ”%s”"
@@ -4996,15 +5017,50 @@ msgstr ""
"att kvoten inte har överskridits, och kör sedan\n"
"”git restore --staged :/” för att återställa."
-msgid "git config [<options>]"
-msgstr "git config [<flaggor>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<filflagga>] [<visningsflagga>] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "okänt argument för --type, %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<filflagga>] [<visningsflagga>] [--includes] [--all] [--"
+"regexp=<reguttr>] [--value=<värde>] [--fixed-value] [--default=<förval>] "
+"<namn>"
-msgid "only one type at a time"
-msgstr "endast en typ åt gången"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<filflagga>] [--type=<typ>] [--all] [--value=<värde>] [--"
+"fixed-value] <namn> <värde>"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<filflagga>] [--all] [--value=<värde>] [--fixed-value] "
+"<namn> <värde>"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<filflagga>] <gammalt-namn> <nytt-namn>"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<filflagga>] <namn>"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<filflagga>]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr "git config [<filflagga>] --get-colorbool <namn> [<stdout-är-tty>]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<filflagga>] [--type=<typ>] [--comment=<meddelande>] [--all] "
+"[--value=<värde>] [--fixed-value] <namn> <värde>"
msgid "Config file location"
msgstr "Konfigurationsfilens plats"
@@ -5030,54 +5086,6 @@ msgstr "blob-id"
msgid "read config from given blob object"
msgstr "läs konfiguration från givet blob-objekt"
-msgid "Action"
-msgstr "Åtgärd"
-
-msgid "get value: name [value-pattern]"
-msgstr "hämta värde: namn [värde-mönster]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "hämta alla värden: nyckel [värde-mönster]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "hämta värden för reguttr: namn-reguttr [värde-mönster]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "hämta värde specifikt URL:en: sektion[.var] URL"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "ersätt alla motsvarande variabler: namn värde [värde-mönster]"
-
-msgid "add a new variable: name value"
-msgstr "lägg till en ny variabel: namn värde"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "ta bort en variabel: namn [värde-mönster]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "ta bort alla träffar: namn [värde-mönster]"
-
-msgid "rename section: old-name new-name"
-msgstr "byt namn på sektion: gammalt-namn nytt-namn"
-
-msgid "remove a section: name"
-msgstr "ta bort en sektion: namn"
-
-msgid "list all"
-msgstr "visa alla"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "använd stränglikhet vid när värden jämförs med ”värde-mönster”"
-
-msgid "open an editor"
-msgstr "öppna textredigeringsprogram"
-
-msgid "find the color configured: slot [default]"
-msgstr "hitta den inställda färgen: slot [default]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "hitta färginställningen: slot [stdout-is-tty]"
-
msgid "Type"
msgstr "Typ"
@@ -5105,8 +5113,8 @@ msgstr "värdet är en sökväg (fil- eller katalognamn)"
msgid "value is an expiry date"
msgstr "värdet är ett utgångsdatum"
-msgid "Other"
-msgstr "Andra"
+msgid "Display options"
+msgstr "Visningsflaggor"
msgid "terminate values with NUL byte"
msgstr "terminera värden med NUL-byte"
@@ -5114,9 +5122,6 @@ msgstr "terminera värden med NUL-byte"
msgid "show variable names only"
msgstr "visa endast variabelnamn"
-msgid "respect include directives on lookup"
-msgstr "respektera inkluderingsdirektiv vid uppslag"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr "visa konfigurationskälla (fil, standard in, blob, kommandorad)"
@@ -5125,14 +5130,15 @@ msgstr ""
"visa omfång för konfiguration (arbetskatalog, lokalt, globalt, system, "
"kommando)"
-msgid "value"
-msgstr "värde"
+msgid "show config keys in addition to their values"
+msgstr "visa konfigurationsnycklar tillsammans med deras värden"
-msgid "with --get, use default value when missing entry"
-msgstr "med --get, använd standardvärde vid saknad post"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "okänt argument för --type, %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr "människoläsbar kommentarssträng (# läggs in först efter behov)"
+msgid "only one type at a time"
+msgstr "endast en typ åt gången"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5208,46 +5214,72 @@ msgstr ""
"konfigurationsutöknignen worktreeConfig har aktiverats. Läsa stycket\n"
"”KONFIGURATIONSFIL” i ”git help worktree” för detaljer"
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color och variabeltyp stämmer inte överens"
+msgid "Other"
+msgstr "Andra"
-msgid "only one action at a time"
-msgstr "endast en åtgärd åt gången"
+msgid "respect include directives on lookup"
+msgstr "respektera inkluderingsdirektiv vid uppslag"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only gäller bara för --list eller --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "kan inte läsa konfigurationsfilen ”%s”"
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-"--show-origin gäller bara för --get, --get-all, --get-regexp och --list"
+msgid "error processing config file(s)"
+msgstr "fel vid hantering av konfigurationsfil(er)"
-msgid "--default is only applicable to --get"
-msgstr "--default gäller bara för --get"
+msgid "Filter options"
+msgstr "Filterflaggor"
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment gäller bara för ”get”/”set”/”replace”-operationerna"
+msgid "return all values for multi-valued config options"
+msgstr "returnera alla värden för konfigurationsflaggor med flera värden"
+
+msgid "interpret the name as a regular expression"
+msgstr "tolka namnet som reguljärt uttryck"
+
+msgid "show config with values matching the pattern"
+msgstr "via konfiguration med värden som motsvarar mönster"
+
+msgid "use string equality when comparing values to value pattern"
+msgstr "använd stränglikhet vid när värden jämförs med värde-mönster"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "show config matching the given URL"
+msgstr "visa konfiguration som motsvarar given URL"
+
+msgid "value"
+msgstr "värde"
+
+msgid "use default value when missing entry"
+msgstr "använd standardvärde vid saknad post"
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value gäller endast med ”värde-mönster”"
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "kan inte läsa konfigurationsfilen ”%s”"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= kan inte användas med --all eller --url="
-msgid "error processing config file(s)"
-msgstr "fel vid hantering av konfigurationsfil(er)"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= kan inte användas med --all, --regexp eller --value"
-msgid "editing stdin is not supported"
-msgstr "redigering av standard in stöds ej"
+msgid "Filter"
+msgstr "Filter"
-msgid "editing blobs is not supported"
-msgstr "redigering av blobbar stöds ej"
+msgid "replace multi-valued config option with new value"
+msgstr "ersätt konfigurationsflagga med flera värden med nytt värde"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "kan inte skapa konfigurationsfilen ”%s”"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "människoläsbar kommentarssträng (# läggs in först efter behov)"
+
+msgid "add a new line without altering any existing values"
+msgstr "lägg till ny rad utan att ändra befintliga värden"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value gäller endast med --value=<mönster>"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append kan inte användas med --value=<mönster>"
#, c-format
msgid ""
@@ -5261,6 +5293,85 @@ msgstr ""
msgid "no such section: %s"
msgstr "ingen sådan sektion: %s"
+msgid "editing stdin is not supported"
+msgstr "redigering av standard in stöds ej"
+
+msgid "editing blobs is not supported"
+msgstr "redigering av blobbar stöds ej"
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "kan inte skapa konfigurationsfilen ”%s”"
+
+msgid "Action"
+msgstr "Åtgärd"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "hämta värde: namn <värde-mönster>"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "hämta alla värden: nyckel <värde-mönster>"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "hämta värden för reguttr: namn-reguttr <värde-mönster>"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "hämta värde specifikt URL:en: sektion[.var] URL"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "ersätt alla motsvarande variabler: namn värde <värde-mönster>"
+
+msgid "add a new variable: name value"
+msgstr "lägg till en ny variabel: namn värde"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "ta bort en variabel: namn <värde-mönster>"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "ta bort alla träffar: namn <värde-mönster>"
+
+msgid "rename section: old-name new-name"
+msgstr "byt namn på sektion: gammalt-namn nytt-namn"
+
+msgid "remove a section: name"
+msgstr "ta bort en sektion: namn"
+
+msgid "list all"
+msgstr "visa alla"
+
+msgid "open an editor"
+msgstr "öppna textredigeringsprogram"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "hitta den inställda färgen: lucka <förval>"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "hitta färginställningen: lucka <stdout-är-tty>"
+
+msgid "with --get, use default value when missing entry"
+msgstr "med --get, använd standardvärde vid saknad post"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color och variabeltyp stämmer inte överens"
+
+msgid "no action specified"
+msgstr "ingen handling angavs"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only gäller bara för --list eller --get-regexp"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin gäller bara för --get, --get-all, --get-regexp och --list"
+
+msgid "--default is only applicable to --get"
+msgstr "--default gäller bara för --get"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment gäller bara för ”get”/”set”/”replace”-operationerna"
+
msgid "print sizes in human readable format"
msgstr "skriv storlekar i människoläsbart format"
@@ -6079,6 +6190,9 @@ msgstr "konfig"
msgid "config key storing a list of repository paths"
msgstr "konfigurationsnyckel som innehåller en lista över arkivsökvägar"
+msgid "keep going even if command fails in a repository"
+msgstr "fortsätt även om kommandot misslyckas i ett arkiv"
+
msgid "missing --config=<config>"
msgstr "saknar --config=<konfig>"
@@ -7531,8 +7645,11 @@ msgstr "markera serien som N:te försök"
msgid "max length of output filename"
msgstr "maximal längd för utdatafilnamn"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "använd [RFC PATCH] istället för [PATCH]"
+msgid "rfc"
+msgstr "rfc"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "lägg till <rfc> (förval ”RFC”) före ”PATCH”"
msgid "cover-from-description-mode"
msgstr "cover-from-description-läge"
@@ -7793,11 +7910,11 @@ msgstr ""
"deduplicate, --eol"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<nyckel>]\n"
" [--symref] [<arkiv> [<mönster>...]]"
@@ -7813,8 +7930,11 @@ msgstr "sökväg till git-upload-pack på fjärren"
msgid "limit to tags"
msgstr "begränsa till taggar"
-msgid "limit to heads"
-msgstr "begränsa till huvuden"
+msgid "limit to branches"
+msgstr "begränsa till grenar"
+
+msgid "deprecated synonym for --branches"
+msgstr "föråldrad synonym till --branches"
msgid "do not show peeled tags"
msgstr "visa inte avskalade taggar"
@@ -10423,6 +10543,22 @@ msgstr "ingen referenslogg att ta bort angavs"
msgid "invalid ref format: %s"
msgstr "felaktigt referensformat: %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<format> [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "ange referensformatet att konvertera till"
+
+msgid "perform a non-destructive dry-run"
+msgstr "utför ett icke-destruktiv testkörning"
+
+msgid "missing --ref-format=<format>"
+msgstr "saknad --ref-format=<format>"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "arkivet använder redan ”%s”-format"
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -10703,9 +10839,6 @@ msgstr "* fjärr %s"
msgid " Fetch URL: %s"
msgstr " Hämt-URL: %s"
-msgid "(no URL)"
-msgstr "(ingen URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -10714,6 +10847,9 @@ msgstr "(ingen URL)"
msgid " Push URL: %s"
msgstr " Sänd-URL: %s"
+msgid "(no URL)"
+msgstr "(ingen URL)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " HEAD-gren: %s"
@@ -10819,10 +10955,6 @@ msgstr "fråga sänd-URL:er istället för hämta-URL:er"
msgid "return all URLs"
msgstr "returnera alla URL:er"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "ingen URL:er angivna för fjärren ”%s”"
-
msgid "manipulate push URLs"
msgstr "manipulera URL:ar för sändning"
@@ -11818,12 +11950,12 @@ msgstr "okänd hashningsalgoritm"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<mönster>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<mönster>...]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -11846,11 +11978,11 @@ msgstr "referensen existerar inte"
msgid "failed to look up reference"
msgstr "misslyckades slå upp referensen"
-msgid "only show tags (can be combined with heads)"
-msgstr "visa endast taggar (kan kombineras med huvuden)"
+msgid "only show tags (can be combined with branches)"
+msgstr "visa endast taggar (kan kombineras med grenar)"
-msgid "only show heads (can be combined with tags)"
-msgstr "visa endast huvuden (kan kombineras med taggar)"
+msgid "only show branches (can be combined with tags)"
+msgstr "visa endast grenar (kan kombineras med taggar)"
msgid "check for reference existence without resolving"
msgstr "kontrollerar att referensen existerar utan att slå upp dem"
@@ -12471,14 +12603,14 @@ msgid "refusing to create/use '%s' in another submodule's git dir"
msgstr "vägrar skapa/använda ”%s” i en annan undermoduls gitkatalog"
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "misslyckades klona ”%s” till undermodulsökvägen ”%s”"
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "katalogen inte tom: ”%s”"
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "misslyckades klona ”%s” till undermodulsökvägen ”%s”"
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "kunde inte få tag i undermodulkatalog för ”%s”"
@@ -12835,9 +12967,11 @@ msgstr "skäl till uppdateringen"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <nyckel-id>] [-f] [-m <medd> | -F <fil>] [-e]\n"
+" [(--trailer <symbol>[(=|:)<värde>])...]\n"
" <taggnamn> [<incheckning> | <objekt>]"
msgid "git tag -d <tagname>..."
@@ -13682,9 +13816,6 @@ msgstr "okänt huvud: %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "Arkivet saknar dessa nödvändiga incheckningar:"
-msgid "need a repository to verify a bundle"
-msgstr "behöver ett arkiv för att bekräfta en bunt."
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14082,6 +14213,9 @@ msgstr "Ta emot det som sänds till arkivet"
msgid "Manage reflog information"
msgstr "Hantera referenslogg-information"
+msgid "Low-level access to refs"
+msgstr "Lågnivååtkomst till referenser"
+
msgid "Manage set of tracked repositories"
msgstr "Hantera uppsättningen spårade arkiv"
@@ -14387,6 +14521,14 @@ msgid "commit-graph required commit data chunk missing or corrupted"
msgstr ""
"incheckningsgrafens nödvändiga incheckningsdatastycke saknas eller är trasigt"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"inaktivera Bloom-filter för incheckningsgraflager ”%s” på grund av "
+"inkompatibla inställningar"
+
msgid "commit-graph has no base graphs chunk"
msgstr "incheckningsgrafen har inga bas-graf-stycken"
@@ -14510,6 +14652,14 @@ msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr ""
"försöker skriva en incheckningsgraf, men ”core.commitGraph” är inaktiverad"
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph."
+"changedPathsVersion' (%d) is not supported"
+msgstr ""
+"försöker skriva en incheckningsgraf, men ”commitGraph."
+"changedPathsVersion” (%d) stöds inte"
+
msgid "too many commits to write graph"
msgstr "för många incheckningar för att skriva graf"
@@ -16348,18 +16498,23 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h |--help] [-C <sökväg>] [-c <namn>=<värde>]\n"
" [--exec-path[=<sökväg>]] [--html-path] [--man-path] [--info-"
"path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<sökväg>] [--work-tree=<sökväg>] [--namespace=<namn>]\n"
-" [--config-env=<namn>=<miljövar>] <kommando> [<flaggor>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-"
+"dir=<sökväg>]\n"
+" [--work-tree=<sökväg>] [--namespace=<namn>] [--config-"
+"env=<namn>=<miljövar>]\n"
+" <kommando> [<flaggor>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -16695,14 +16850,14 @@ msgstr ""
"Kroken ”%s” ignorerades eftersom den inte är markerad som körbar.\n"
"Du kan inaktivera varningen med ”git config advice.ignoredHook false”."
+msgid "not a git repository"
+msgstr "inte ett git-arkiv"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr ""
"argumentet till --packfile måste vara ett giltigt hashvärde (fick '%s')"
-msgid "not a git repository"
-msgstr "inte ett git-arkiv"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr "http.postBuffer har negativt värde; använder förvalet %d"
@@ -16713,6 +16868,9 @@ msgstr "Delegerad styrning stöds inte av cURL < 7.22.0"
msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "Fastnålning av öppen nyckel stöds inte av cURL < 7.39.0"
+msgid "Unknown value for http.proactiveauth"
+msgstr "Okänt värde för http.proactiveauth"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE stöds inte av cURL < 7.44.0"
@@ -16728,6 +16886,12 @@ msgstr "Kan inte sätta SSL-bakända till ”%s”: cURL byggdes utan SSL-bakän
msgid "Could not set SSL backend to '%s': already set"
msgstr "Kunde inte sätta SSL-bakända till ”%s”: redan valt"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "vägrar läsa kakor från filen ”-” angiven i http.cookiefile"
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "ignorerar http.savecookies för tom http.cookiefile"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -16902,8 +17066,8 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "Misslyckades slå ihop undermodulen %s (incheckningar saknas)"
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "Misslyckades slå ihop undermodulen %s (arkivet är trasigt)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "fel: misslyckades slå ihop undermodulen %s (arkivet är trasigt)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -16933,12 +17097,13 @@ msgstr ""
"finns:\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "misslyckades exekvera intern sammanslagning"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "fel: misslyckades exekvera intern sammanslagning för %s"
#, c-format
-msgid "unable to add %s to database"
-msgstr "kan inte lägga till %s till databasen"
+msgid "error: unable to add %s to database"
+msgstr "fel: kan inte lägga till %s till databasen"
#, c-format
msgid "Auto-merging %s"
@@ -17031,12 +17196,12 @@ msgstr ""
"KONFLIKT (namnbyte/radera): %s namnbytt till %s i %s, men borttagen i %s."
#, c-format
-msgid "cannot read object %s"
-msgstr "kan inte läsa objektet %s"
+msgid "error: cannot read object %s"
+msgstr "fel: kan inte läsa objektet %s"
#, c-format
-msgid "object %s is not a blob"
-msgstr "objektet %s är inte en blob"
+msgid "error: object %s is not a blob"
+msgstr "fel: objektet %s är inte en blob"
#, c-format
msgid ""
@@ -17176,6 +17341,10 @@ msgid "do not know what to do with %06o %s '%s'"
msgstr "vet inte hur %06o %s ”%s” ska hanteras"
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Misslyckades slå ihop undermodulen %s (arkivet är trasigt)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Snabbspolar undermodulen %s till följande incheckning:"
@@ -17217,6 +17386,13 @@ msgid "Failed to merge submodule %s (multiple merges found)"
msgstr ""
"Misslyckades slå ihop undermodulen %s (flera sammanslagningar hittades)"
+msgid "failed to execute internal merge"
+msgstr "misslyckades exekvera intern sammanslagning"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "kan inte lägga till %s till databasen"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr "Fel: Vägrar förlora ospårad fil vid %s; skriver till %s istället."
@@ -17312,6 +17488,14 @@ msgstr ""
"KONFLIKT (namnbyte/namnbyte): Namnbytt katalog %s→%s i %s. Namnbytt katalog "
"%s→%s i %s"
+#, c-format
+msgid "cannot read object %s"
+msgstr "kan inte läsa objektet %s"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "objektet %s är inte en blob"
+
msgid "modify"
msgstr "ändra"
@@ -17395,9 +17579,6 @@ msgstr "kunde inte tolka rad: %s"
msgid "malformed line: %s"
msgstr "felaktig rad: %s"
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "ignorerar befintlig multi-pack-index; felaktig kontrollsumma"
-
msgid "could not load pack"
msgstr "kunde inte läsa paket{"
@@ -17405,6 +17586,9 @@ msgstr "kunde inte läsa paket{"
msgid "could not open index for %s"
msgstr "kunde inte öppna indexet för %s"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "ignorerar befintlig multi-pack-index; felaktig kontrollsumma"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Lägger till paketfiler till multi-pack-index"
@@ -18011,6 +18195,17 @@ msgstr "kan inte tolka objektet: %s"
msgid "hash mismatch %s"
msgstr "hashvärde stämmer inte överens %s"
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "duplicerad post när bitkarteindex skulle skrivas: %s"
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "försökta lagra icke-vald incheckning: ”%s”"
+
+msgid "too many pseudo-merges"
+msgstr "för många pseudo-sammanslagningar"
+
msgid "trying to write commit not in index"
msgstr "försöker skriva incheckning som inte finns i indexet"
@@ -18033,6 +18228,20 @@ msgstr "trasigt bitkarteindex (för kort för att få plats för hash-cache)"
msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr "trasigt bitkarteindex (för kort för att få plats för uppslagstabell)"
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"trasig bitkarteindexfil (för kort för att få plats för pseudo-"
+"sammanslagningsatbellhuvudet)"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr ""
+"trasig bitkarteindexfil (för kort för att få plats för pseudo-"
+"sammanslagningstabell)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "trasig bitkarteindexfil, pseudosammanslagningstabellen är för kort"
+
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "duplicerad post i bitkarteindex: ”%s”"
@@ -18123,6 +18332,10 @@ msgid "mismatch in bitmap results"
msgstr "bitkarteresultat stämmer inte överens"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "pseudosammanslaningsindex utenför intervallet (%<PRIu32> ≥ %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "kunde inte hitta ”%s” i paketet ”%s” på offset %<PRIuMAX>"
@@ -18483,6 +18696,10 @@ msgstr "kan inte skapa trådad lstat: %s"
msgid "unable to parse --pretty format"
msgstr "kan inte tolka format för --pretty"
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr ""
+"fördröjd hämtning inaktiverad; några objekt kanske inte är tillgängliga"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote: kan inte grena (fork) av underprocessen för fetch"
@@ -18507,6 +18724,71 @@ msgstr "object-info: förväntade ”flush” efter argument"
msgid "Removing duplicate objects"
msgstr "Tar bort duplicerade objekt"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr ""
+"misslyckades läsa reguljärt uttryck för pseudosammanslagning för ”%s”: %s"
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s måste vara icke-negativt, använder förval"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s måste vara mellan 0 och 1, använder förval"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s måste vara positivt, använder förval"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "pseudosammanslagningsgruppen ”%s” saknar nödvändigt mönster"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr ""
+"pseudosammanslagningsgruppen ”%s” har instabila tröskelvärden innan de "
+"stabila"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"reguljärt uttryck för pseudosammanslagning har för många fångstgrupper "
+"(max=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"läsning utanför intervallet för utökad pseudosammanslagning (%<PRIuMAX> ≥ "
+"%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"posten för utökad pseudosammanslagning är för kort (%<PRIuMAX> ≥ %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr ""
+"kunde inte hitta pseudosammanslagning för incheckningen %s på offset "
+"%<PRIuMAX>"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr ""
+"uppslagning utanför intervallet för utökad pseudosammanslagning (%<PRIu32> ≥ "
+"%<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "läsning utanför intervallet: (%<PRIuMAX> ≥ %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "kunde inte läsa utökad pseudosammanslagningstabell för incheckning %s"
+
msgid "could not start `log`"
msgstr "kunde inte starta ”log”"
@@ -19108,11 +19390,18 @@ msgstr "loggen för referensen %s slutade oväntat på %s"
msgid "log for %s is empty"
msgstr "loggen för %s är tom"
+msgid "refusing to force and skip creation of reflog"
+msgstr "vägrar att tvinga och hoppa över skapande av reflogg"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "vägrar uppdatera referens med trasigt namn ”%s”"
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "vägrar uppdatera pseudoreferensen ”%s”"
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "update_ref misslyckades för referensen ”%s”: %s"
@@ -19143,6 +19432,25 @@ msgid "could not delete references: %s"
msgstr "kunde inte ta bort referenser: %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "Avslutade testkörning av referensmigrering, resultatet hittas i ”%s”\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "kunde ta bort temporär migreringskatalog ”%s”"
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "migrerade referenser hittas vid ”%s”"
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"kan inte läsa referensen ”%s”: förväntade symbolisk referens med målet ”%s”: "
+"men är en vanlig referens"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "refnamnet är farligt: %s"
@@ -20289,6 +20597,53 @@ msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s"
msgstr "update-ref kräver ett fullständigt referensnamn, t.ex refs/heads/%s"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "”%s” godtar inte sammanslagningsincheckningar"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"”pick” tar inte en sammanslagningsincheckning. Om du\n"
+"ville spela upp sammanslagningen på nytt använder du\n"
+"”merge -C” på incheckningen."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"”reword” tar inte en sammanslagningsincheckning. Om du\n"
+"ville spela upp sammanslagningen på nytt och ändra texten\n"
+"i incheckningsmeddelandet använder du ”merge -C” på\n"
+"incheckningen"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"”edit” tar inte en sammanslagningsincheckning. Om du\n"
+"ville spela upp sammanslagningen på nytt använder du\n"
+"”merge -C” på incheckningen och sedan ”break” för att\n"
+"lämna kontrollen tillbaka till dig så att du kan\n"
+"använda ”git commit --amend && git rebase --continue”."
+
+msgid "cannot squash merge commit into another commit"
+msgstr ""
+"kan inte slå ihop en sammanslagningsincheckning med en annan incheckning"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "ogiltigt kommando ”%.*s”"
@@ -20406,9 +20761,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "kan inte läsa HEAD"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "kan inte kopiera in ”%s” till ”%s”"
+msgid "could not write commit message file"
+msgstr "kunde inte skriva fil för incheckningsmeddelande"
#, c-format
msgid ""
@@ -20807,6 +21161,18 @@ msgstr "kan inte gå tillbaka till arbetskatalogen (cwd)"
msgid "failed to stat '%*s%s%s'"
msgstr "misslyckades ta status på ”%*ss%s%s”"
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"upptäckte tveksamt ägarskap i arkivet i ”%s”\n"
+"%sFör att lägga till ett undantag för denna katalog, kör:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Kan inte läsa aktuell arbetskatalog"
@@ -20828,18 +21194,6 @@ msgstr ""
"Stoppar vid filsystemsgräns (GIT_DISCOVERY_ACROSS_FILESYSTEM är inte satt)."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"upptäckte tveksamt ägarskap i arkivet i ”%s”\n"
-"%sFör att lägga till ett undantag för denna katalog, kör:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr "kan inte använda naket arkiv ”%s” (safe.bareRepository är ”%s”)"
@@ -21141,6 +21495,16 @@ msgid "submodule git dir '%s' is inside git dir '%.*s'"
msgstr "undermodul-gitkatalogen ”%s” är inuti gitkatalogen ”%.*s”"
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr ""
+"förväntade att ”%.*s” i undermodulsökvägen ”%s” inte ska vara en symbolisk "
+"länk"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "förväntade att undermodulsökvägen ”%s” inte ska vara en symbolisk länk"
+
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -21179,10 +21543,6 @@ msgstr "misslyckades ta status (lstat) på ”%s”"
msgid "no remote configured to get bundle URIs from"
msgstr "ingen fjärr att hämta bunt-URI:er från inställd"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "fjärren ”%s” har ingen URL konfigurerad"
-
msgid "could not get the bundle-uri list"
msgstr "kunde inte hämta bundle-uri-listan"
@@ -22641,24 +23001,24 @@ msgid "Failed to send %s\n"
msgstr "Misslyckades sända %s\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Test-Sände %s\n"
+msgid "Dry-Sent %s"
+msgstr "Test-Sände %s"
#, perl-format
-msgid "Sent %s\n"
-msgstr "Sände %s\n"
+msgid "Sent %s"
+msgstr "Sände %s"
-msgid "Dry-OK. Log says:\n"
-msgstr "Test-OK. Loggen säger:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Test-OK. Loggen säger:"
-msgid "OK. Log says:\n"
-msgstr "OK. Loggen säger:\n"
+msgid "OK. Log says:"
+msgstr "OK. Loggen säger:"
msgid "Result: "
msgstr "Resultat: "
-msgid "Result: OK\n"
-msgstr "Resultat: OK\n"
+msgid "Result: OK"
+msgstr "Resultat: OK"
#, perl-format
msgid "can't open file %s"
diff --git a/po/tr.po b/po/tr.po
index 0e220e1c1c..61692d4b20 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -96,8 +96,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git Turkish Localization Project\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-29 01:09+0300\n"
-"PO-Revision-Date: 2024-04-29 01:10+0300\n"
+"POT-Creation-Date: 2024-07-19 13:59+0300\n"
+"PO-Revision-Date: 2024-07-19 14:00+0300\n"
"Last-Translator: Emir SARI <emir_sari@icloud.com>\n"
"Language-Team: Turkish (https://github.com/bitigchi/git-po/)\n"
"Language: tr\n"
@@ -646,6 +646,10 @@ msgstr ""
"p - geçerli parçalı yazdır\n"
"? - yardımı yazdır\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Yalnızca bir harf bekleniyordu, '%s' alındı"
+
msgid "No previous hunk"
msgstr "Öncesinde parça yok"
@@ -694,9 +698,19 @@ msgstr "%d parçaya bölündü."
msgid "Sorry, cannot edit this hunk"
msgstr "Üzgünüm, bu parça düzenlenemiyor"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "Bilinmeyen komut '%s' (yardım için '?')"
+
msgid "'git apply' failed"
msgstr "'git apply' başarısız oldu"
+msgid "No changes."
+msgstr "Değişiklik yok."
+
+msgid "Only binary files changed."
+msgstr "Yalnızca ikili dosyalar değiştirildi."
+
#, c-format
msgid ""
"\n"
@@ -1545,6 +1559,9 @@ msgstr "pek büyük gitattributes dosyası '%s' dosyası yok sayılıyor"
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "pek büyük gitattributes ikili nesnesi '%s' yok sayılıyor"
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "depo olmadan --attr-source veya GIT_ATTR_SOURCE kullanılamaz"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "hatalı --attr-source veya GIT_ATTR_SOURCE"
@@ -1862,13 +1879,6 @@ msgstr "%cx '%s' chmod yapılamıyor"
msgid "Unstaged changes after refreshing the index:"
msgstr "İndeksi yeniledikten sonra hazırlanmamış değişiklikler:"
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"add.interactive.useBuiltin ayarı kaldırıldı!\n"
-"Ayrıntılar için onun 'git help config' içindeki girdisine bakın."
-
msgid "could not read the index"
msgstr "indeks okunamadı"
@@ -1979,7 +1989,7 @@ msgid "adding embedded git repository: %s"
msgstr "gömülü git deposu ekleniyor: %s"
msgid "Use -f if you really want to add them."
-msgstr "Onları gerçekten eklemek istiyorsanız -f kullanın."
+msgstr "Onları eklemeyi gerçekten istiyorsanız -f kullanın."
msgid "adding files failed"
msgstr "dosya ekleme başarısız"
@@ -2310,6 +2320,9 @@ msgstr "yamalama işlemini iptal et; ancak HEAD'i olduğu yerde bırak"
msgid "show the patch being applied"
msgstr "uygulanmakta olan yamayı göster"
+msgid "try to apply current patch again"
+msgstr "yeniden geçerli yamayı uygulamaya çalış"
+
msgid "record the empty patch as an empty commit"
msgstr "boş yamayı bir boş işleme olarak kayıt yaz"
@@ -2366,9 +2379,6 @@ msgstr "git apply [<seçenekler>] [<yama>...]"
msgid "could not redirect output"
msgstr "çıktı yeniden yönlendirilemedi"
-msgid "git archive: Remote with no URL"
-msgstr "git archive: URL'si olmayan uzak konum"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive: ACK/NAK bekleniyordu, floş paketi alındı"
@@ -3261,6 +3271,9 @@ msgstr "Bir demet oluşturmak için bir depo gerekli."
msgid "do not show bundle details"
msgstr "demet ayrıntılarını gösterme"
+msgid "need a repository to verify a bundle"
+msgstr "bir demeti doğrulamak için bir depo gerekiyor"
+
#, c-format
msgid "%s is okay\n"
msgstr "%s tamam\n"
@@ -4272,6 +4285,14 @@ msgid "failed to unlink '%s'"
msgstr "'%s' bağlantısı kesilemedi"
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "sabit bağlantı, '%s' konumunda denetlenemiyor"
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "sabit bağlantı, '%s' konumundaki kaynaktan farklı"
+
+#, c-format
msgid "failed to create link '%s'"
msgstr "'%s' bağı oluşturulamadı"
@@ -5104,15 +5125,51 @@ msgstr ""
"Diskin dolu olup olmadığını ve kotanızı aşıp aşmadığınızı denetleyin,\n"
"sonra kurtarmak için \"git restore --staged :/\" kullanın."
-msgid "git config [<options>]"
-msgstr "git config [<seçenekler>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr ""
+"git config list [<dosya-seçeneği>] [<görüntüleme-seçeneği>] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "tanımlanamayan --type argümanı, %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<dosya-seçeneği>] [<görüntüleme-seçeneği>] [--includes] [--"
+"all] [--regexp=<düzenli-ifade>] [--value=<değer>] [--fixed-value] [--"
+"default=<öntanımlı>] <ad>"
-msgid "only one type at a time"
-msgstr "bir kerede yalnızca bir tür"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<dosya-seçeneği>] [--type=<tür>] [--all] [--value=<değer>] "
+"[--fixed-value] <ad> <değer>"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<dosya-seçeneği>] [--all] [--value=<değer>] [--fixed-"
+"value] <ad> <değer>"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<dosya-seçeneği>] <eski-ad> <yeni-ad>"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<dosya-seçeneği>] <ad>"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<dosya-seçeneği>]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr "git config [<dosya-seçeneği>] --get-colorbool <ad> [<stdout-tty>]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<dosya-seçeneği>] [--type=<tür>] [--comment=<ileti>] [--all] "
+"[--value=<değer>] [--fixed-value] <ad> <değer>"
msgid "Config file location"
msgstr "Yapılandırma dosyası konumu"
@@ -5138,54 +5195,6 @@ msgstr "ikili nesne numarası"
msgid "read config from given blob object"
msgstr "verilen ikili nesneden yapılandırmayı oku"
-msgid "Action"
-msgstr "Eylem"
-
-msgid "get value: name [value-pattern]"
-msgstr "değer al: ad [değer-dizgisi]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "tüm değerleri al: anahtar [değer-dizgisi]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "düzenli ifade için değerleri al: düzenli ifade adı [değer-dizgisi]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "URL için özel olan değeri al: bölüm[.var] URL"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "tüm eşleşen değişkenleri değiştir: ad değer [değer-dizgisi]"
-
-msgid "add a new variable: name value"
-msgstr "yeni bir değişken ekle: ad değer"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "bir değişken kaldır: ad [değer-dizgisi]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "tüm eşleşmeleri kaldır: ad [değer-dizgisi]"
-
-msgid "rename section: old-name new-name"
-msgstr "bölümü yeniden adlandır: eski-ad yeni-ad"
-
-msgid "remove a section: name"
-msgstr "bir bölümü kaldır: ad"
-
-msgid "list all"
-msgstr "tümünü listele"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "değerleri 'değer-dizgisi' ile karşılaştırırken dizi eşitliği kullan"
-
-msgid "open an editor"
-msgstr "bir düzenleyici aç"
-
-msgid "find the color configured: slot [default]"
-msgstr "yapılandırılan rengi bul: yuva [öntanımlı]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "renk ayarını bul: yuva [stdout tty]"
-
msgid "Type"
msgstr "Tür"
@@ -5213,8 +5222,8 @@ msgstr "değer bir yol (dosya veya dizin adı)"
msgid "value is an expiry date"
msgstr "değer bir son kullanım tarihi"
-msgid "Other"
-msgstr "Diğer"
+msgid "Display options"
+msgstr "Seçenekleri görüntüle"
msgid "terminate values with NUL byte"
msgstr "değerleri NUL baytı ile sonlandır"
@@ -5222,9 +5231,6 @@ msgstr "değerleri NUL baytı ile sonlandır"
msgid "show variable names only"
msgstr "yalnızca değişken adlarını göster"
-msgid "respect include directives on lookup"
-msgstr "arama sırasında içerme yönergelerine uy"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr ""
"yapılandırmanın kökenini göster (dosya, stdin, ikili nesne, komut satırı)"
@@ -5234,14 +5240,15 @@ msgstr ""
"yapılandırmanın kapsamını göster (çalışma ağacı, yerel, global, sistem, "
"komut)"
-msgid "value"
-msgstr "değer"
+msgid "show config keys in addition to their values"
+msgstr "değerlerine ek olarak yapılandırma anahtarlarını da göster"
-msgid "with --get, use default value when missing entry"
-msgstr "--get ile girdi verilmemişse öntanımlı değeri kullan"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "tanımlanamayan --type argümanı, %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr "kişi tarafından okunabilir yorum satırı (gerekirse önüne # koyulur)"
+msgid "only one type at a time"
+msgstr "bir kerede yalnızca bir tür"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5317,47 +5324,72 @@ msgstr ""
"sürece birden çok çalışma ağacı ile birlikte kullanılamaz. Ayrıntılar için\n"
"lütfen \"git help worktree\" içindeki \"CONFIGURATION FILE\" bölümünü okuyun"
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color ve değişken türü tutarsız"
+msgid "Other"
+msgstr "Diğer"
-msgid "only one action at a time"
-msgstr "bir kerede yalnızca bir eylem"
+msgid "respect include directives on lookup"
+msgstr "arama sırasında içerme yönergelerine uy"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only yalnızca şunlara uygulanabilir: --list, --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "'%s' yapılandırma dosyası okunamıyor"
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-"--show-origin yalnızca şunlara uygulanabilir: --get, --get-all, --get-regexp "
-"ve --list"
+msgid "error processing config file(s)"
+msgstr "yapılandırma dosyaları işlenirken hata"
-msgid "--default is only applicable to --get"
-msgstr "--default yalnızca --get için uygulanabilir"
+msgid "Filter options"
+msgstr "Süzme seçenekleri"
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment yalnızca ekle/ayarla/değiştir işlemlerine uygulanabilir"
+msgid "return all values for multi-valued config options"
+msgstr "birden çok değerli yapılandırma seçeneklerinin tüm değerlerini döndür"
+
+msgid "interpret the name as a regular expression"
+msgstr "adı düzenli ifade olarak yorumla"
+
+msgid "show config with values matching the pattern"
+msgstr "dizgiyle eşleşen değerleri olan yapılandırmayı göster"
+
+msgid "use string equality when comparing values to value pattern"
+msgstr "değerleri değer dizgisiyle karşılaştırırken dizi eşitliğini kullan"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "show config matching the given URL"
+msgstr "verilen URL ile eşleşen yapılandırmayı göster"
+
+msgid "value"
+msgstr "değer"
+
+msgid "use default value when missing entry"
+msgstr "girdi eksikse öntanımlı değeri kullan"
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value yalnızca 'değer-dizgisi' ile uygulanır"
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "'%s' yapılandırma dosyası okunamıyor"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default=, --all veya --url= ile kullanılamaz"
-msgid "error processing config file(s)"
-msgstr "yapılandırma dosyaları işlenirken hata"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url=; --all, --regexp veya --value ile kullanılamaz"
-msgid "editing stdin is not supported"
-msgstr "stdin'i düzenleme desteklenmiyor"
+msgid "Filter"
+msgstr "Süzgeç"
-msgid "editing blobs is not supported"
-msgstr "ikili nesneleri düzenleme desteklenmiyor"
+msgid "replace multi-valued config option with new value"
+msgstr "birden çok değerli yapılandırma seçeneğini yeni değerle değiştir"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "%s yapılandırma dosyası oluşturulamıyor"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "kişi tarafından okunabilir yorum satırı (gerekirse önüne # koyulur)"
+
+msgid "add a new line without altering any existing values"
+msgstr "var olan herhangi değeri değiştirmeden yeni satır ekle"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value, yalnızca --value=<dizgi> ile geçerlidir"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append, --value=<dizgi> ile kullanılamaz"
#, c-format
msgid ""
@@ -5372,6 +5404,86 @@ msgstr ""
msgid "no such section: %s"
msgstr "böyle bir bölüm yok: %s"
+msgid "editing stdin is not supported"
+msgstr "stdin'i düzenleme desteklenmiyor"
+
+msgid "editing blobs is not supported"
+msgstr "ikili nesneleri düzenleme desteklenmiyor"
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "%s yapılandırma dosyası oluşturulamıyor"
+
+msgid "Action"
+msgstr "Eylem"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "değer al: ad [<değer-dizgisi>]"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "tüm değerleri al: anahtar [<değer-dizgisi>]"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "düzenli ifade için değerleri al: düzenli ifade adı [<değer-dizgisi>]"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "URL için özel olan değeri al: bölüm[.var] URL"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "tüm eşleşen değişkenleri değiştir: ad değer [<değer-dizgisi>]"
+
+msgid "add a new variable: name value"
+msgstr "yeni bir değişken ekle: ad değer"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "bir değişken kaldır: ad [<değer-dizgisi>]"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "tüm eşleşmeleri kaldır: ad [<değer-dizgisi>]"
+
+msgid "rename section: old-name new-name"
+msgstr "bölümü yeniden adlandır: eski-ad yeni-ad"
+
+msgid "remove a section: name"
+msgstr "bir bölümü kaldır: ad"
+
+msgid "list all"
+msgstr "tümünü listele"
+
+msgid "open an editor"
+msgstr "bir düzenleyici aç"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "yapılandırılan rengi bul: yuva [<öntanımlı>]"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "renk ayarını bul: yuva [<stdout-tty>]"
+
+msgid "with --get, use default value when missing entry"
+msgstr "--get ile girdi verilmemişse öntanımlı değeri kullan"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color ve değişken türü tutarsız"
+
+msgid "no action specified"
+msgstr "belirtilen eylem yok"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only yalnızca şunlara uygulanabilir: --list, --get-regexp"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin yalnızca şunlara uygulanabilir: --get, --get-all, --get-regexp "
+"ve --list"
+
+msgid "--default is only applicable to --get"
+msgstr "--default yalnızca --get için uygulanabilir"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment yalnızca ekle/ayarla/değiştir işlemlerine uygulanabilir"
+
msgid "print sizes in human readable format"
msgstr "yazdırma boyutları kişi tarafından okunabilir biçimde"
@@ -6194,6 +6306,9 @@ msgstr "yapılandırma"
msgid "config key storing a list of repository paths"
msgstr "bir depo yolları listesi tutan yapılandırma anahtarı"
+msgid "keep going even if command fails in a repository"
+msgstr "komut depoda başarısız olsa bile gitmeyi sürdür"
+
msgid "missing --config=<config>"
msgstr "--config=<yapılandırma> eksik"
@@ -7645,8 +7760,11 @@ msgstr "diziyi n. deneme olarak imle"
msgid "max length of output filename"
msgstr "çıktı dosya adının olabilecek en çok uzunluğu"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "[PATCH] yerine [RFC PATCH] kullan"
+msgid "rfc"
+msgstr "rfc"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "'PATCH' öncesi <rfc> ekle (öntanımlı 'RFC')"
msgid "cover-from-description-mode"
msgstr "açıklama kipinden kapak sayfası kipi"
@@ -7909,11 +8027,12 @@ msgstr ""
"kullanılamaz"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<yürütülebilir>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-"
+"pack=<yürütülebilir>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<anahtar>]\n"
" [--symref] [<depo> [<dizgiler>...]]"
@@ -7929,8 +8048,11 @@ msgstr "uzak konum makinesindeki git-upload-pack yolu"
msgid "limit to tags"
msgstr "etiketlere kısıtla"
-msgid "limit to heads"
-msgstr "uç işlemelere kısıtla"
+msgid "limit to branches"
+msgstr "dallara kısıtla"
+
+msgid "deprecated synonym for --branches"
+msgstr "--branches için artık kullanılmayan eşanlamlı"
msgid "do not show peeled tags"
msgstr "soyulmuş etiketleri gösterme"
@@ -10553,6 +10675,22 @@ msgstr "silmek için bir başvuru günlüğü belirtilmedi"
msgid "invalid ref format: %s"
msgstr "geçersiz başvuru biçimi: %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<biçim> [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "dönüştürülecek başvuru biçimini belirt"
+
+msgid "perform a non-destructive dry-run"
+msgstr "yıkıcı olmayan bir deneme gerçekleştir"
+
+msgid "missing --ref-format=<format>"
+msgstr "--ref-format=<biçim> eksik"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "depo halihazırda '%s' biçimini kullanıyor"
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -10838,9 +10976,6 @@ msgstr "* uzak konum %s"
msgid " Fetch URL: %s"
msgstr " URL'yi getir: %s"
-msgid "(no URL)"
-msgstr "(URL yok)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -10849,6 +10984,9 @@ msgstr "(URL yok)"
msgid " Push URL: %s"
msgstr " URL'yi it: %s"
+msgid "(no URL)"
+msgstr "(URL yok)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " HEAD dalı: %s"
@@ -10955,10 +11093,6 @@ msgstr "itme URL'lerinden çok getirme URL'lerini sorgula"
msgid "return all URLs"
msgstr "tüm URL'leri döndür"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "'%s' uzak konumu için URL yapılandırılmamış"
-
msgid "manipulate push URLs"
msgstr "itme URL'lerini değiştir"
@@ -11959,12 +12093,12 @@ msgstr "bilinmeyen sağlama algoritması '%s'"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<dizgi>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<dizgi>...]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -11987,11 +12121,11 @@ msgstr "başvuru yok"
msgid "failed to look up reference"
msgstr "başvuru bakılamadı"
-msgid "only show tags (can be combined with heads)"
-msgstr "yalnızca etiketleri göster (dal uçlarıyla birlikte kullanılabilir)"
+msgid "only show tags (can be combined with branches)"
+msgstr "yalnızca etiketleri göster (dallarla birlikte kullanılabilir)"
-msgid "only show heads (can be combined with tags)"
-msgstr "yalnızca dal uçlarını göster (etiketlerle birlikte kullanılabilir)"
+msgid "only show branches (can be combined with tags)"
+msgstr "yalnızca dalları göster (etiketlerle birlikte kullanılabilir)"
msgid "check for reference existence without resolving"
msgstr "çözmeden başvuru varlığını denetle"
@@ -12611,14 +12745,14 @@ msgstr ""
"başka bir altmodülün git dizininde '%s' oluşturma/kullanma reddediliyor"
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "'%s' ögesinin '%s' altmodül yoluna klonlanması başarısız"
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "dizin boş değil: '%s'"
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "'%s' ögesinin '%s' altmodül yoluna klonlanması başarısız"
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "'%s' için altmodül dizini alınamadı"
@@ -12975,10 +13109,12 @@ msgstr "güncelleme nedeni"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <anahtar-kimliği>] [-f] [-m <ileti> | -F <dosya>] [-"
"e]\n"
+" [(--trailer <jeton>[(=|:)<değer>])...]\n"
" <etiket-adı> [<işleme> | <nesne>]"
msgid "git tag -d <tagname>..."
@@ -13324,8 +13460,8 @@ msgid ""
"core.untrackedCache is set to true; remove or change it, if you really want "
"to disable the untracked cache"
msgstr ""
-"core.untrackedCache 'true' olarak ayarlanmış; izlenmeyen önbelleği gerçekten "
-"devre dışı bırakmayı istiyorsanız bunu kaldırın veya değiştirin"
+"core.untrackedCache 'true' olarak ayarlanmış; izlenmeyen önbelleği devre "
+"dışı bırakmayı gerçekten istiyorsanız bunu kaldırın veya değiştirin"
msgid "Untracked cache disabled"
msgstr "İzlenmeyen önbellek devre dışı bırakıldı"
@@ -13335,7 +13471,7 @@ msgid ""
"to enable the untracked cache"
msgstr ""
"core.untrackedCache 'false' olarak ayarlanmış; izlenmeyen önbelleği "
-"gerçekten etkinleştirmek istiyorsanız bunu kaldırın veya değiştirin"
+"etkinleştirmeyi gerçekten istiyorsanız bunu kaldırın veya değiştirin"
#, c-format
msgid "Untracked cache enabled for '%s'"
@@ -13343,8 +13479,8 @@ msgstr "İzlenmeyen önbellek '%s' için etkinleştirildi"
msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
msgstr ""
-"core.fsmonitor ayarlanmamış; dosya sistemin monitörünü gerçekten "
-"etkinleştirmek istiyorsanız onu ayarlayın"
+"core.fsmonitor ayarlanmamış; dosya sistemin monitörünü etkinleştirmeyi "
+"gerçekten istiyorsanız onu ayarlayın"
msgid "fsmonitor enabled"
msgstr "dosya sistemi monitörü etkin"
@@ -13352,8 +13488,8 @@ msgstr "dosya sistemi monitörü etkin"
msgid ""
"core.fsmonitor is set; remove it if you really want to disable fsmonitor"
msgstr ""
-"core.fsmonitor ayarlanmış; dosya sistemi monitörünü gerçekten devre dışı "
-"bırakmak istiyorsanız onu kaldırın"
+"core.fsmonitor ayarlanmış; dosya sistemi monitörünü devre dışı bırakmayı "
+"gerçekten istiyorsanız onu kaldırın"
msgid "fsmonitor disabled"
msgstr "dosya sistemi monitörü devre dışı"
@@ -13818,9 +13954,6 @@ msgstr "tanımlanamayan üstbilgi: %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "Depo aşağıdaki önkoşul işlemelere iye değil:"
-msgid "need a repository to verify a bundle"
-msgstr "bir demeti doğrulamak için bir depo gerekiyor"
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14217,6 +14350,9 @@ msgstr "Depoya ne itildiyse al"
msgid "Manage reflog information"
msgstr "Başvuru günlüğü bilgisini yönet"
+msgid "Low-level access to refs"
+msgstr "Başvurulara alt düzeyden erişim"
+
msgid "Manage set of tracked repositories"
msgstr "İzlenen depolar setini yönet"
@@ -14521,6 +14657,14 @@ msgid "commit-graph required commit data chunk missing or corrupted"
msgstr ""
"commit-graph'ten gerekli OID çıkış sayısı iri parçası eksik veya hasarlı"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"uyumsuz ayarlardan dolayı '%s' commit-graph katmanı için olan Bloom "
+"süzgeçleri devre dışı bırakılıyor"
+
msgid "commit-graph has no base graphs chunk"
msgstr "commit-graph temel grafiği iri parçasına iye değil"
@@ -14645,6 +14789,14 @@ msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr ""
"bir commit-graph yazılmaya çalışılıyor; ancak 'core.commitGraph' devre dışı"
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"bir commit-graph yazılmaya çalışılıyor; ancak 'commitGraph."
+"changedPathsVersion' (%d) desteklenmiyor"
+
msgid "too many commits to write graph"
msgstr "grafik yazımı için pek fazla işleme"
@@ -16488,17 +16640,21 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C <yol>] [-c <ad>=<değer>]\n"
" [--exec-path[=<yol>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<yol>] [--work-tree=<yol>] [--namespace=<ad>]\n"
-" [--config-env=<ad>=<çevre-değişkeni>] <komut> [<argümanlar>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<ad>] [--config-env=<ad>=<çevre-"
+"değişkeni>]\n"
+" <komut> [<argümanlar>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -16838,13 +16994,13 @@ msgstr ""
"'%s' kancası yok sayıldı; çünkü bir yürütülebilir olarak ayarlanmamış.\n"
"Bu uyarıyı 'git config advice.ignoredHook false' ile kapatabilirsiniz."
+msgid "not a git repository"
+msgstr "bir git deposu değil"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "--packfile için argüman geçerli bir sağlama olmalıdır ('%s' alındı)"
-msgid "not a git repository"
-msgstr "bir git deposu değil"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr "http.postBuffer için negatif değer; %d olarak varsayılıyor"
@@ -16855,6 +17011,9 @@ msgstr "Delegasyon denetimi cURL < 7.22.0 tarafından desteklenmiyor"
msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "Ortak anahtar iğnelemesi cURL < 7.39.0 tarafından desteklenmiyor"
+msgid "Unknown value for http.proactiveauth"
+msgstr "http.proactiveauth için bilinmeyen değer"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE cURL < 7.44.0 tarafından desteklenmiyor"
@@ -16871,6 +17030,12 @@ msgstr ""
msgid "Could not set SSL backend to '%s': already set"
msgstr "SSL arka ucu '%s' olarak ayarlanamadı: Halihazırda ayarlanmış"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "http.cookiefile '-' konumundan çerezleri okuma reddediliyor"
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "boş http.cookiefile için http.savecookies yok sayılıyor"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -17047,8 +17212,8 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "%s altmodülü birleştirilemedi (işlemeler yok)"
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "%s altmodülü birleştirilemedi (depo hasarlı)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "hata: %s altmodülü birleştirilemedi (depo hasarlı)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -17076,12 +17241,13 @@ msgstr ""
"%s altmodülü birleştirilemedi; ancak birden çok olası birleştirmeler var:\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "iç birleştirme yürütülemedi"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "hata: %s için iç birleştirme yürütülemedi"
#, c-format
-msgid "unable to add %s to database"
-msgstr "%s veritabanına eklenemiyor"
+msgid "error: unable to add %s to database"
+msgstr "hata: %s veritabanına eklenemiyor"
#, c-format
msgid "Auto-merging %s"
@@ -17178,12 +17344,12 @@ msgstr ""
"ancak %s içinde silindi."
#, c-format
-msgid "cannot read object %s"
-msgstr "%s nesnesi okunamıyor"
+msgid "error: cannot read object %s"
+msgstr "hata: %s nesnesi okunamıyor"
#, c-format
-msgid "object %s is not a blob"
-msgstr "%s nesnesi ikili bir nesne değil"
+msgid "error: object %s is not a blob"
+msgstr "hata: %s nesnesi ikili bir nesne değil"
#, c-format
msgid ""
@@ -17322,6 +17488,10 @@ msgid "do not know what to do with %06o %s '%s'"
msgstr "şununla ne yapılacağı bilinmiyor: %06o %s '%s'"
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "%s altmodülü birleştirilemedi (depo hasarlı)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "%s altmodülü şu işlemeye ileri sarılıyor:"
@@ -17360,6 +17530,13 @@ msgstr ""
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "%s altmodülü birleştirilemedi (birden çok birleştirme bulundu)"
+msgid "failed to execute internal merge"
+msgstr "iç birleştirme yürütülemedi"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "%s veritabanına eklenemiyor"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr ""
@@ -17464,6 +17641,14 @@ msgstr ""
"ÇAKIŞMA (y. adlandır/y. adlandır): Dizini %s->%s olarak adlandır (%s "
"içinde). Dizini %s->%s olarak adlandır (%s içinde)"
+#, c-format
+msgid "cannot read object %s"
+msgstr "%s nesnesi okunamıyor"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "%s nesnesi ikili bir nesne değil"
+
msgid "modify"
msgstr "değiştir"
@@ -17547,9 +17732,6 @@ msgstr "satır ayrıştırılamadı: %s"
msgid "malformed line: %s"
msgstr "hatalı oluşturulmuş satır: %s"
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "var olan multi-pack-index yok sayılıyor; sağlama toplamı uyumsuzluğu"
-
msgid "could not load pack"
msgstr "paket yüklenemedi"
@@ -17557,6 +17739,9 @@ msgstr "paket yüklenemedi"
msgid "could not open index for %s"
msgstr "%s için indeks açılamadı"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "var olan multi-pack-index yok sayılıyor; sağlama toplamı uyumsuzluğu"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Paket dosyaları multi-pack-index'e ekleniyor"
@@ -18160,6 +18345,17 @@ msgstr "nesne ayrıştırılamıyor: %s"
msgid "hash mismatch %s"
msgstr "sağlama uyuşmazlığı %s"
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "biteşlem indeksi yazılırken yinelenen girdi: %s"
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "seçili olmayan işleme yazılmaya çalışıldı: '%s'"
+
+msgid "too many pseudo-merges"
+msgstr "pek çok yalancı birleştirme"
+
msgid "trying to write commit not in index"
msgstr "indekste olmayan işleme yazılmaya çalışılıyor"
@@ -18184,6 +18380,20 @@ msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr ""
"hasarlı biteşlem indeks dosyası (arama tablosuna sığmak için pek küçük)"
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"hasarlı biteşlem indeks dosyası (yalancı birleştirme tablo üstbilgisine "
+"sığmak için pek kısa)"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr ""
+"hasarlı biteşlem indeks dosyası (yalancı birleştirme tablosuna sığmak için "
+"pek kısa)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "hasarlı biteşlem indeks dosyası, yalancı birleştirme tablosu pek kısa"
+
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "biteşlem indeksinde yinelenen girdi: '%s'"
@@ -18274,6 +18484,10 @@ msgid "mismatch in bitmap results"
msgstr "biteşlem sonuçlarında uyuşmazlık"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "yalancı birleştirme indeksi erim dışında (%<PRIu32> >= %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "öge bulunamadı: '%s'; '%s' paketinde, %<PRIuMAX> ofsetinde"
@@ -18635,6 +18849,9 @@ msgstr "iş parçacıklarına ayrılmış 'lstat' oluşturulamıyor: %s"
msgid "unable to parse --pretty format"
msgstr "--pretty biçimi ayrıştırılamıyor"
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "gerekince getirme devre dışı; bazı nesneler kullanılamayabilir"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote: getirme alt süreci çatallanamıyor"
@@ -18658,6 +18875,67 @@ msgstr "object-info: argümanlardan sonra floş bekleniyordu"
msgid "Removing duplicate objects"
msgstr "Yinelenmiş nesneler kaldırılıyor"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "%s için yalancı birleştirme düzenli ifadesi yüklenemedi: '%s'"
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s negatif dışı bir değer olmalı, öntanımlı değer kullanılıyor"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s, 0 ve 1 arasında olmalıdır, öntanımlı kullanılıyor"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s pozitif olmalıdır, öntanımlı kullanılıyor"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "yalancı birleştirme grubu '%s' içinde gerekli dizgi yok"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr ""
+"yalancı birleştirme gribi '%s' içinde kararlıdan önce kararsız eşik var"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"yapılandırmadaki yalancı birleştirme düzenli ifadesinde pek çok yakalama "
+"grubu var (max=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"genişletilmiş yalancı birleştirme sınırlar dışında okundu (%<PRIuMAX> >= "
+"%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"genişletilmiş yalancı birleştirme girdisi pek kısa (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr "%s işlemesi için yalancı birleştirme bulunamadı, %<PRIuMAX> ofsetinde"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr ""
+"genişletilmiş yalancı birleştirme araması sınırlar dışında (%<PRIu32> >= "
+"%<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "sınırlar dışında okundu: (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "%s işlemesi için genişletilmiş yalancı birleştirme tablosu okunamadı"
+
msgid "could not start `log`"
msgstr "'log' başlatılamadı"
@@ -19258,11 +19536,18 @@ msgstr ""
msgid "log for %s is empty"
msgstr "%s için olan günlük boş"
+msgid "refusing to force and skip creation of reflog"
+msgstr "başvuru günlüğünün oluşturulma/atlanma zorlanması reddediliyor"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "hatalı ada iye '%s' başvurusunu güncelleme reddediliyor"
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "'%s' yalancı başvurusunun güncellenmesi reddediliyor"
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "'%s' başvurusu için update_ref başarısız oldu: %s"
@@ -19293,6 +19578,25 @@ msgid "could not delete references: %s"
msgstr "başvurular silinemedi: %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "Başvuruların göç denemesi bitti, sonuç '%s' konumunda bulunabilir\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "geçici göç dizini '%s' kaldırılamadı"
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "göç ettirilen başvurular '%s' konumunda bulunabilir"
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"'%s' başvurusu kilitlenemiyor: '%s' hedefiyle bir sembolik başvuru "
+"bekleniyordu; ancak bu normal bir başvuru"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "başvuru adı tehlikeli: %s"
@@ -19324,8 +19628,8 @@ msgstr "'%s' başvurusu kilitlenemiyor: Başvuruyu okurken hata"
msgid ""
"multiple updates for '%s' (including one via symref '%s') are not allowed"
msgstr ""
-"'%s' için birden çok güncellemeye ('%s' sembolik bağlantısı ile olan bir "
-"tanesini de içeren) izin verilmiyor"
+"'%s' için birden çok güncellemeye ('%s' sembolik bağı ile olan bir tanesini "
+"de içeren) izin verilmiyor"
#, c-format
msgid "cannot lock ref '%s': reference already exists"
@@ -19357,7 +19661,7 @@ msgstr "başvuru adı %s bulunamadı"
#, c-format
msgid "refname %s is a symbolic ref, copying it is not supported"
-msgstr "başvuru adı %s bir sembolik bağlantı, onu kopyalamak desteklenmiyor"
+msgstr "başvuru adı %s bir sembolik bağ, onu kopyalamak desteklenmiyor"
#, c-format
msgid "invalid refspec '%s'"
@@ -20443,6 +20747,50 @@ msgstr ""
"update-ref, tümüyle kalifiye bir başvuru adı gerektiriyor; örn. refs/heads/%s"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "'%s' birleştirme işlemelerini kabul etmiyor"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"'pick', bir birleştirme işlemesi almaz. Birleştirmeyi\n"
+"yeniden oynatmak istediyseniz işlemede 'merge -C' kullanın."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"'reword', bir birleştirme işlemesi almaz. Birleştirmeyi\n"
+"yeniden oynatmak ve işleme iletisini düzenlemek istediyseniz\n"
+"işlemede 'merge -c' kullanın."
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"'edit', bir birleştirme işlemesi almaz. Birleştirmeyi\n"
+"yeniden oynatmak istediyseniz işlemede 'merge -C' kullanın,sonrasında "
+"denetimin size geri verilmesi için 'break'\n"
+"yapın; böylece 'git commit --amend && git rebase --continue'\n"
+"yapabilirsiniz."
+
+msgid "cannot squash merge commit into another commit"
+msgstr "birleştirme işlemesi başka bir işlemeye tıkıştırılamaz"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "geçersiz komut %.*s"
@@ -20558,9 +20906,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "HEAD okunamıyor"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "'%s', '%s' konumuna kopyalanamıyor"
+msgid "could not write commit message file"
+msgstr "işleme iletisi dosyası yazılamadı"
#, c-format
msgid ""
@@ -20958,6 +21305,18 @@ msgstr "cwd'ye geri dönülemiyor"
msgid "failed to stat '%*s%s%s'"
msgstr "'%*s%s%s' bilgileri alınamadı"
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"'%s' konumundaki depoda belirsiz iyelik algılandı\n"
+"%sBu dizin için istisna eklemek için şunu çağırın:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Şu anki çalışma dizini okunamıyor"
@@ -20979,18 +21338,6 @@ msgstr ""
"ayarlanmamış)."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"'%s' konumundaki depoda belirsiz iyelik algılandı\n"
-"%sBu dizin için istisna eklemek için şunu çağırın:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr "çıplak depo '%s', kullanılamaz (safe.bareRepository '%s')"
@@ -21294,6 +21641,15 @@ msgid "submodule git dir '%s' is inside git dir '%.*s'"
msgstr "altmodül git dizini '%s', '%.*s' git dizini içinde"
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr ""
+"'%.*s' ögesinin bir sembolik bağ olması beklenmiyordu, '%s' altmodül yolunda"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "'%s' altmodül yolunun bir sembolik bağ olması beklenmiyordu"
+
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -21331,10 +21687,6 @@ msgstr "'%s', lstat yapılamadı"
msgid "no remote configured to get bundle URIs from"
msgstr "demet URI'lerini almak için bir uzak konum yapılandırılmamış"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "'%s' uzak konumunun yapılandırılmış bir URL'si yok"
-
msgid "could not get the bundle-uri list"
msgstr "bundle-uri listesi alınamadı"
@@ -22790,24 +23142,24 @@ msgid "Failed to send %s\n"
msgstr "%s gönderilemedi\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "%s gönderilir gibi yapıldı\n"
+msgid "Dry-Sent %s"
+msgstr "%s gönderilir gibi yapıldı"
#, perl-format
-msgid "Sent %s\n"
-msgstr "%s gönderildi\n"
+msgid "Sent %s"
+msgstr "%s gönderildi"
-msgid "Dry-OK. Log says:\n"
-msgstr "Sınama tamam. Günlük çıktısı:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Sınama tamam. Günlük çıktısı:"
-msgid "OK. Log says:\n"
-msgstr "Tamam. Günlük çıktısı:\n"
+msgid "OK. Log says:"
+msgstr "Tamam. Günlük çıktısı:"
msgid "Result: "
msgstr "Sonuç: "
-msgid "Result: OK\n"
-msgstr "Sonuç: Tamam\n"
+msgid "Result: OK"
+msgstr "Sonuç: Tamam"
#, perl-format
msgid "can't open file %s"
@@ -22880,4 +23232,4 @@ msgstr "%s, yedek sonek '%s' ile atlanıyor.\n"
#. TRANSLATORS: please keep "[y|N]" as is.
#, perl-format
msgid "Do you really want to send %s? [y|N]: "
-msgstr "%s ögesini gerçekten göndermek istiyor musunuz? [y|N]: "
+msgstr "%s ögesini göndermeyi gerçekten istiyor musunuz? [y|N]: "
diff --git a/po/uk.po b/po/uk.po
index 528a3dc6f7..297f7b0687 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -6,10 +6,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Git v2.45\n"
+"Project-Id-Version: Git v2.46\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-27 09:55-0700\n"
-"PO-Revision-Date: 2024-04-15 15:55-0700\n"
+"POT-Creation-Date: 2023-04-11 09:55-0700\n"
+"PO-Revision-Date: 2024-07-24 08:45-0700\n"
"Last-Translator: Arkadii Yakovets <ark@cho.red>\n"
"Language-Team: Ukrainian <https://github.com/arkid15r/git-uk-l10n/>\n"
"Language: uk\n"
@@ -565,6 +565,10 @@ msgstr ""
"p - показати поточний шматок\n"
"? - показати довідку\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Очікувався лише один символ, отримано \"%s\""
+
msgid "No previous hunk"
msgstr "Немає попереднього шматка"
@@ -614,9 +618,19 @@ msgstr "Розщепити на %d шматків."
msgid "Sorry, cannot edit this hunk"
msgstr "Вибачайте, не можу редагувати цей шматок"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "Невідома команда: \"%s\" (використовуйте \"?\" для допомоги)"
+
msgid "'git apply' failed"
msgstr "\"git apply\" завершився невдало"
+msgid "No changes."
+msgstr "Нічого не змінено."
+
+msgid "Only binary files changed."
+msgstr "Змінено лише бінарні файли."
+
#, c-format
msgid ""
"\n"
@@ -1487,6 +1501,9 @@ msgstr "ігнорування надто великого файлу gitattribu
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "ігнорування надто великих gitattributes blob \"%s\""
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "неможливо використати --attr-source або GIT_ATTR_SOURCE без сховища"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "невірний --attr-source або GIT_ATTR_SOURCE"
@@ -1809,13 +1826,6 @@ msgstr "неможливо виконати chmod %cx \"%s\""
msgid "Unstaged changes after refreshing the index:"
msgstr "Неіндексовані зміни після оновлення індексу:"
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"параметр add.interactive.useBuiltin було видалено!\n"
-"Дивіться запис у \"git help config\" для більш детальної інформації."
-
msgid "could not read the index"
msgstr "не вдалося прочитати індекс"
@@ -2258,6 +2268,9 @@ msgstr "перервати латання, але залишити HEAD на т�
msgid "show the patch being applied"
msgstr "показати латку, що застосовується"
+msgid "try to apply current patch again"
+msgstr "спробувати застосувати поточну латку ще раз"
+
msgid "record the empty patch as an empty commit"
msgstr "записати порожню латку як порожній коміт"
@@ -2314,9 +2327,6 @@ msgstr "git apply [<опції>] [<латка>...]"
msgid "could not redirect output"
msgstr "неможливо перенаправити вивід"
-msgid "git archive: Remote with no URL"
-msgstr "git archive: віддалене призначення без URL"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive: очікувалось ACK/NAK, отримано flush-пакет"
@@ -3231,6 +3241,9 @@ msgstr "Для створення пакунка потрібне сховище
msgid "do not show bundle details"
msgstr "не показувати деталі пакунка"
+msgid "need a repository to verify a bundle"
+msgstr "потрібне сховище для перевірки пакунка"
+
#, c-format
msgid "%s is okay\n"
msgstr "%s у порядку\n"
@@ -4262,6 +4275,14 @@ msgid "failed to unlink '%s'"
msgstr "не вдалося видалити \"%s\""
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "неможливо перевірити жорстке посилання \"%s\""
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "жорстке посилання відрізняється від джерела в \"%s\""
+
+#, c-format
msgid "failed to create link '%s'"
msgstr "не вдалося створити посилання \"%s\""
@@ -5095,15 +5116,50 @@ msgstr ""
"новий файл індексу. Переконайтеся, що диск не переповнений і квота\n"
"не перевищена, а потім виконайте \"git restore --staged :/\" для відновлення."
-msgid "git config [<options>]"
-msgstr "git config [<опції>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<опція-файлу>] [<опція-відображення>] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "нерозпізнаний аргумент --type, %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<опція-файлу>] [<опція-відображення>] [--includes] [--all] "
+"[--regexp=<регвир>] [--value=<значення>] [--fixed-value] [--"
+"default=<значення -за-умовчанням>] <назва>"
-msgid "only one type at a time"
-msgstr "лише один тип за раз"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<опція-файлу>] [--type=<тип>] [--all] [--value=<значення>] "
+"[--fixed-value] <назва> <значення>"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<опція-файлу>] [--all] [--value=<значення>] [--fixed-"
+"value] <назва> <значення>"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<опція-файлу>] <стара-назва> <нова-назва>"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<опція-файлу>] <назва>"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<опція-файлу>]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr "git config [<опція-файлу>] --get-colorbool <назва> [<stdout-is-tty>]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<опція-файлу>] [--type=<тип>] [--comment=<допис>] [--all][--"
+"value=<значення>] [--fixed-value] <назва> <значення>"
msgid "Config file location"
msgstr "Розташування файлу конфігурації"
@@ -5129,55 +5185,6 @@ msgstr "blob-id"
msgid "read config from given blob object"
msgstr "прочитати конфігурацію з наданого blob-обʼєкту"
-msgid "Action"
-msgstr "Дія"
-
-msgid "get value: name [value-pattern]"
-msgstr "отримати значення: назва [шаблон-значення]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "отримати всі значення: ключ [шаблон-значення]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "отримати значення для регвиру: регвир-назви [шаблон-значення]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "отримати значення для конкретної URL-адреси: розділ[.var] URL-адреса"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "замінити всі відповідні змінні: назва значення [шаблон-значення]"
-
-msgid "add a new variable: name value"
-msgstr "додати нову змінну: назва значення"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "видалити змінну: назва [шаблон-значення]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "видалити всі збіги: назва [шаблон-значення]"
-
-msgid "rename section: old-name new-name"
-msgstr "перейменувати розділ: стара-назва нова-назва"
-
-msgid "remove a section: name"
-msgstr "видалити розділ: назва"
-
-msgid "list all"
-msgstr "показати всі змінні"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr ""
-"використовувати рівність строк при порівнянні значень з \"шаблон-значенням\""
-
-msgid "open an editor"
-msgstr "відкрити редактор"
-
-msgid "find the color configured: slot [default]"
-msgstr "знайти налаштований колір: слот [за замовчуванням]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "знайти налаштування кольору: slot [stdout-is-tty]"
-
msgid "Type"
msgstr "Тип"
@@ -5205,8 +5212,8 @@ msgstr "значення шлях (файл або назва директорі
msgid "value is an expiry date"
msgstr "значення - дата закінчення терміну дії"
-msgid "Other"
-msgstr "Інше"
+msgid "Display options"
+msgstr "Опції відображення"
msgid "terminate values with NUL byte"
msgstr "завершити значення байтом NUL"
@@ -5214,9 +5221,6 @@ msgstr "завершити значення байтом NUL"
msgid "show variable names only"
msgstr "показувати тільки назви змінних"
-msgid "respect include directives on lookup"
-msgstr "дотримуватись директив включення при пошуку"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr ""
"показати походження конфігурації (файл, стандартний ввід, blob, командний "
@@ -5227,16 +5231,15 @@ msgstr ""
"показати межі дії конфігурації (робоче дерево, локально, глобально, система, "
"команда)"
-msgid "value"
-msgstr "значення"
+msgid "show config keys in addition to their values"
+msgstr "показувати ключі конфігурації на додачу до їхніх значень"
-msgid "with --get, use default value when missing entry"
-msgstr ""
-"з --get використовувати значення за замовчуванням, якщо запис відсутній"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "нерозпізнаний аргумент --type, %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr ""
-"зрозумілий для людини рядок коментаря (# буде додано перед за потребою)"
+msgid "only one type at a time"
+msgstr "лише один тип за раз"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5314,46 +5317,75 @@ msgstr ""
"ФАЙЛ\"\n"
"у \"git help worktree\" для більш детальної інформації"
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color і тип змінної не узгоджуються"
+msgid "Other"
+msgstr "Інше"
-msgid "only one action at a time"
-msgstr "лише одна дія за раз"
+msgid "respect include directives on lookup"
+msgstr "дотримуватись директив включення при пошуку"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only застосовується лише до --list або --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "не вдалося прочитати файл конфігурації \"%s\""
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
+msgid "error processing config file(s)"
+msgstr "помилка при обробці файлу(ів) конфігурації"
+
+msgid "Filter options"
+msgstr "Опції фільтрації"
+
+msgid "return all values for multi-valued config options"
+msgstr "повернути всі значення для багатозначних параметрів конфігурації"
+
+msgid "interpret the name as a regular expression"
+msgstr "інтерпретувати назву як регулярний вираз"
+
+msgid "show config with values matching the pattern"
+msgstr "показати конфіг зі значеннями, що відповідають шаблону"
+
+msgid "use string equality when comparing values to value pattern"
msgstr ""
-"--show-origin застосовується лише до --get, --get-all, --get-regexp та --list"
+"використовувати рядкову еквівалентність при порівнянні з шаблоном значень"
-msgid "--default is only applicable to --get"
-msgstr "--default застосовується лише до --get"
+msgid "URL"
+msgstr "URL"
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment застосовується лише до add/set/replace операцій"
+msgid "show config matching the given URL"
+msgstr "показати конфіг, що відповідає вказаній URL-адресі"
+
+msgid "value"
+msgstr "значення"
+
+msgid "use default value when missing entry"
+msgstr "використовувати значення за замовчуванням, якщо запис відсутній"
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value застосовується лише з \"шаблоном-значення\""
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "не вдалося прочитати файл конфігурації \"%s\""
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= не можна використовувати з --all або --url="
-msgid "error processing config file(s)"
-msgstr "помилка при обробці файлу(ів) конфігурації"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= не можна використовувати з --all, --regexp або --value"
-msgid "editing stdin is not supported"
-msgstr "редагування stdin не підтримується"
+msgid "Filter"
+msgstr "Фільтрація"
-msgid "editing blobs is not supported"
-msgstr "редагування blobs не підтримується"
+msgid "replace multi-valued config option with new value"
+msgstr "замінити багатозначний параметр конфігурації новим значенням"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "неможливо створити конфігураційний файл %s"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"зрозумілий для людини рядок коментаря (# буде додано попереду при "
+"необхідності)"
+
+msgid "add a new line without altering any existing values"
+msgstr "додати новий рядок, не змінюючи жодного з існуючих значень"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value застосовується лише з --value=<шаблон>"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append не можна використовувати з --value=<шаблон>"
#, c-format
msgid ""
@@ -5367,6 +5399,87 @@ msgstr ""
msgid "no such section: %s"
msgstr "немає такого розділу: %s"
+msgid "editing stdin is not supported"
+msgstr "редагування stdin не підтримується"
+
+msgid "editing blobs is not supported"
+msgstr "редагування blobs не підтримується"
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "неможливо створити конфігураційний файл %s"
+
+msgid "Action"
+msgstr "Дія"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "отримати значення: назва [шаблон-значення]"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "отримати всі значення: ключ [шаблон-значення]"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "отримати значення для регвиру: регвир-назви [шаблон-значення]"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr ""
+"отримати значення для конкретної URL-адреси: розділ[.змінна] URL-адреса"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "замінити всі відповідні змінні: назва значення [шаблон-значення]"
+
+msgid "add a new variable: name value"
+msgstr "додати нову змінну: назва значення"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "видалити змінну: назва [шаблон-значення]"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "видалити всі збіги: назва [шаблон-значення]"
+
+msgid "rename section: old-name new-name"
+msgstr "перейменувати розділ: стара-назва нова-назва"
+
+msgid "remove a section: name"
+msgstr "видалити розділ: назва"
+
+msgid "list all"
+msgstr "показати всі змінні"
+
+msgid "open an editor"
+msgstr "відкрити редактор"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "знайти налаштований колір: слот [<за замовчуванням>]"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "знайти налаштування кольору: слот [<stdout-is-tty>]"
+
+msgid "with --get, use default value when missing entry"
+msgstr ""
+"з --get використовувати значення за замовчуванням, якщо запис відсутній"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color і тип змінної не узгоджуються"
+
+msgid "no action specified"
+msgstr "дію не зазначено"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only застосовується лише до --list або --get-regexp"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin застосовується лише до --get, --get-all, --get-regexp та --list"
+
+msgid "--default is only applicable to --get"
+msgstr "--default застосовується лише до --get"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment застосовується лише до add/set/replace операцій"
+
msgid "print sizes in human readable format"
msgstr "показувати розмір у зручному для читання форматі"
@@ -6200,6 +6313,10 @@ msgstr "конфіг"
msgid "config key storing a list of repository paths"
msgstr "ключ конфігурації, в якому зберігається список шляхів до сховищ"
+msgid "keep going even if command fails in a repository"
+msgstr ""
+"продовжувати роботу, навіть якщо команда завершилася невдало в репозиторії"
+
msgid "missing --config=<config>"
msgstr "відсутній --config=<конфіг>"
@@ -7666,8 +7783,11 @@ msgstr "позначити ряд як N-не перекидання"
msgid "max length of output filename"
msgstr "максимальна довжина назви вихідного файлу"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "використати [RFC PATCH] замість [PATCH]"
+msgid "rfc"
+msgstr "rfc"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "додати <rfc> (за замовчуванням \"RFC\") перед \"PATCH\""
msgid "cover-from-description-mode"
msgstr "cover-from-description-mode"
@@ -7937,11 +8057,12 @@ msgstr ""
"deduplicate, --eol"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<виконавчий-файл>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<виконавчий-"
+"файл>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<ключ>]\n"
" [--symref] [<сховище> [<шаблони>...]]"
@@ -7957,8 +8078,11 @@ msgstr "шлях до git-upload-pack на віддаленому сервері
msgid "limit to tags"
msgstr "обмежити до тегів"
-msgid "limit to heads"
-msgstr "обмежити до голів"
+msgid "limit to branches"
+msgstr "обмежити до гілок"
+
+msgid "deprecated synonym for --branches"
+msgstr "застарілий синонім до --branches"
msgid "do not show peeled tags"
msgstr "не показувати очищені теги"
@@ -10619,6 +10743,22 @@ msgstr "не вказано журнал посилань для видален�
msgid "invalid ref format: %s"
msgstr "неприпустимий формат посилання: %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<формат> [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "вкажіть формат посилання, в який потрібно конвертувати"
+
+msgid "perform a non-destructive dry-run"
+msgstr "виконати неруйнівний пробний запуск"
+
+msgid "missing --ref-format=<format>"
+msgstr "відсутній --ref-format=<формат>"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "сховище вже використовує формат \"%s\""
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -10907,9 +11047,6 @@ msgstr "* віддалене %s"
msgid " Fetch URL: %s"
msgstr " URL-адреса отримання: %s"
-msgid "(no URL)"
-msgstr "(без URL-адреси)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -10918,6 +11055,9 @@ msgstr "(без URL-адреси)"
msgid " Push URL: %s"
msgstr " URL-адреса надсилання: %s"
+msgid "(no URL)"
+msgstr "(без URL-адреси)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " HEAD гілка: %s"
@@ -11030,10 +11170,6 @@ msgstr "запитувати URL-адреси надсилань замість
msgid "return all URLs"
msgstr "повернути всі URL-адреси"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "не налаштовано URL-адреси для віддаленого \"%s\""
-
msgid "manipulate push URLs"
msgstr "маніпулювати URL-адресами надсилання"
@@ -11402,7 +11538,7 @@ msgid "only one pattern can be given with -l"
msgstr "тільки один шаблон може бути заданий з -l"
msgid "need some commits to replay"
-msgstr "потрібні деякі комміти для відтворення"
+msgstr "потрібні деякі коміти для відтворення"
msgid "--onto and --advance are incompatible"
msgstr "--onto та --advance несумісні"
@@ -11468,7 +11604,7 @@ msgid "replaying down to root commit is not supported yet!"
msgstr "відтворення до кореневого коміту поки що не підтримується!"
msgid "replaying merge commits is not supported yet!"
-msgstr "відтворення коммітів злиття поки що не підтримується!"
+msgstr "відтворення комітів злиття поки що не підтримується!"
msgid ""
"git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
@@ -12047,12 +12183,12 @@ msgstr "Невідомий хеш-алгоритм"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<н>]] [--abbrev[=<н>]] [--tags]\n"
-" [--heads] [--] [<шаблон>...]"
+" [-s | --hash[=<н>]] [--abbrev[=<н>]] [--branches] [--tags]\n"
+" [--] [<шаблон>...]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -12075,11 +12211,11 @@ msgstr "посилання не існує"
msgid "failed to look up reference"
msgstr "не вдалося знайти посилання"
-msgid "only show tags (can be combined with heads)"
-msgstr "показати тільки теги (можна комбінувати з верхівками)"
+msgid "only show tags (can be combined with branches)"
+msgstr "показати тільки теги (можна комбінувати з гілками)"
-msgid "only show heads (can be combined with tags)"
-msgstr "показати тільки верхівки (можна комбінувати з тегами)"
+msgid "only show branches (can be combined with tags)"
+msgstr "показати тільки гілки (можна комбінувати з тегами)"
msgid "check for reference existence without resolving"
msgstr "перевіряти наявність посилання без розвʼязання"
@@ -12714,14 +12850,14 @@ msgstr ""
"відмовлено в створенні/використанні \"%s\" у git директорії іншого підмодуля"
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "не вдалося клонувати \"%s\" у шлях підмодуля \"%s\""
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "директорія не порожня: \"%s\""
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "не вдалося клонувати \"%s\" у шлях підмодуля \"%s\""
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "не вдалося отримати директорію підмодуля для \"%s\""
@@ -13086,14 +13222,16 @@ msgstr "причина оновлення"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <ідентифікатор-ключа>] [-f] [-m <допис> | -F <файл>] [-"
"e]\n"
+" [(--trailer <токен>[(=|:)<значення>])...]\n"
" <назва-тегу> [<коміт> | <об’єкт>]"
msgid "git tag -d <tagname>..."
-msgstr "git tag -d <назва-тега>..."
+msgstr "git tag -d <назва-тегу>..."
msgid ""
"git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n"
@@ -13948,9 +14086,6 @@ msgstr "нерозпізнаний заголовок: %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "У сховищі не вистачає обовʼязкових комітів:"
-msgid "need a repository to verify a bundle"
-msgstr "потрібне сховище для перевірки пакунка"
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14353,6 +14488,9 @@ msgstr "Отримати те, що надсилається до сховища
msgid "Manage reflog information"
msgstr "Керування інформацією журналу посилань"
+msgid "Low-level access to refs"
+msgstr "Низькорівневий доступ до посилань"
+
msgid "Manage set of tracked repositories"
msgstr "Керувати набором відстежуваних сховищ"
@@ -14364,8 +14502,8 @@ msgstr "Створити, показати, видалити посилання
msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
msgstr ""
-"ЕКСПЕРИМЕНТАЛЬНО: Відтворення коммітів на новій базі також працює з "
-"порожніми сховищами"
+"ЕКСПЕРИМЕНТАЛЬНО: Відтворення комітів на новій базі також працює з порожніми "
+"сховищами"
msgid "Generates a summary of pending changes"
msgstr "Створює підсумок змін для розгляду"
@@ -14440,7 +14578,7 @@ msgid "Initialize, update or inspect submodules"
msgstr "Ініціалізувати, оновити або перевірити підмодулі"
msgid "Bidirectional operation between a Subversion repository and Git"
-msgstr "Двонаправлена операція між Subversion сховищем та Git"
+msgstr "Двонапрямлена операція між Subversion сховищем та Git"
msgid "Switch branches"
msgstr "Переключити гілки"
@@ -14656,6 +14794,14 @@ msgstr "необхідний шматок OID lookup коміт-графа ві�
msgid "commit-graph required commit data chunk missing or corrupted"
msgstr "необхідний шматок commit data коміт-графа відсутній або пошкоджений"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"вимкнення фільтрів Блума для шару коміт-графа \"%s\" через несумісність "
+"параметрів"
+
msgid "commit-graph has no base graphs chunk"
msgstr "коміт-граф не має шматка базових графів"
@@ -14780,6 +14926,14 @@ msgstr "Злиття коміт-графа"
msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr "спроба записати коміт-граф, але \"core.commitGraph\" відключено"
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"спроба записати коміт-граф, але \"commitGraph.changedPathsVersion\" (%d) не "
+"підтримується"
+
msgid "too many commits to write graph"
msgstr "занадто багато комітів, щоб записати граф"
@@ -16635,17 +16789,21 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C <шлях>] [-c <назва>=<значення>]\n"
" [--exec-path[=<шлях>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<шлях>] [--work-tree=<шлях>] [--namespace=<назва>]\n"
-"[--config-env=<назва>=<змінна-оточення>] <команда> [<аргументи>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<шлях>]\n"
+" [--work-tree=<шлях>] [--namespace=<назва>] [--config-"
+"env=<шлях>=<змінна-оточення>]\n"
+" <команда> [<аргументи>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -16988,13 +17146,13 @@ msgstr ""
"Ви можете вимкнути це попередження за допомогою \"git config advice."
"ignoredHook false\"."
+msgid "not a git repository"
+msgstr "не є git сховищем"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "аргумент до --packfile має бути коректним хешем (отримано \"%s\")"
-msgid "not a git repository"
-msgstr "не є git сховищем"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr ""
@@ -17006,6 +17164,9 @@ msgstr "Контроль делегування не підтримується
msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "Закріплення відкритих ключів не підтримується з cURL < 7.39.0"
+msgid "Unknown value for http.proactiveauth"
+msgstr "Невідоме значення для http.proactiveauth"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE не підтримується з cURL < 7.44.0"
@@ -17023,6 +17184,12 @@ msgstr ""
msgid "Could not set SSL backend to '%s': already set"
msgstr "Не вдалося встановити SSL обробник в \"%s\": вже встановлено"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "відмова від читання cookies з http.cookiefile \"-\""
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "ігнорування http.savecookies для порожнього http.cookiefile"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -17198,8 +17365,8 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "Не вдалося злити підмодуль %s (відсутні коміти)"
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "Не вдалося обʼєднати підмодуль %s (сховище пошкоджено)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "помилка: не вдалося обʼєднати підмодуль %s (сховище пошкоджено)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -17226,12 +17393,13 @@ msgstr ""
"Не вдалося злити підмодуль %s, але існує кілька можливих варіантів злиття:\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "не вдалося виконати внутрішнє злиття"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "помилка: не вдалося виконати внутрішнє злиття для %s"
#, c-format
-msgid "unable to add %s to database"
-msgstr "не вдалося додати %s до бази даних"
+msgid "error: unable to add %s to database"
+msgstr "помилка: не вдалося додати %s до бази даних"
#, c-format
msgid "Auto-merging %s"
@@ -17328,12 +17496,12 @@ msgstr ""
"в %s."
#, c-format
-msgid "cannot read object %s"
-msgstr "неможливо прочитати обʼєкт %s"
+msgid "error: cannot read object %s"
+msgstr "помилка: неможливо прочитати обʼєкт %s"
#, c-format
-msgid "object %s is not a blob"
-msgstr "обʼєкт %s не є blob"
+msgid "error: object %s is not a blob"
+msgstr "помилка: обʼєкт %s не є blob"
#, c-format
msgid ""
@@ -17470,6 +17638,10 @@ msgid "do not know what to do with %06o %s '%s'"
msgstr "не знаю, що робити з %06o %s \"%s\""
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Не вдалося обʼєднати підмодуль %s (сховище пошкоджено)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Перемотування підмодуля %s вперед до наступного коміту:"
@@ -17508,6 +17680,13 @@ msgstr ""
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Не вдалося злити підмодуль %s (знайдено більше одного злиття)"
+msgid "failed to execute internal merge"
+msgstr "не вдалося виконати внутрішнє злиття"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "не вдалося додати %s до бази даних"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr ""
@@ -17610,6 +17789,14 @@ msgstr ""
"КОНФЛІКТ (перейменовано/перейменовано): перейменовано директорію %s->%s в "
"%s. Перейменовано директорію %s->%s в %s"
+#, c-format
+msgid "cannot read object %s"
+msgstr "неможливо прочитати обʼєкт %s"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "обʼєкт %s не є blob"
+
msgid "modify"
msgstr "змінити"
@@ -17693,10 +17880,6 @@ msgstr "не вдалося розібрати рядок: %s"
msgid "malformed line: %s"
msgstr "невірно сформований рядок: %s"
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr ""
-"ігнорування існуючого multi-pack-index; невідповідність контрольних сум"
-
msgid "could not load pack"
msgstr "не вдалося завантажити пакунок"
@@ -17704,6 +17887,10 @@ msgstr "не вдалося завантажити пакунок"
msgid "could not open index for %s"
msgstr "не вдалося відкрити індекс для %s"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr ""
+"ігнорування існуючого multi-pack-index; невідповідність контрольних сум"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Додавання пакунків до multi-pack-index"
@@ -18317,6 +18504,17 @@ msgstr "не вдалося розібрати обʼєкт: %s"
msgid "hash mismatch %s"
msgstr "невідповідність хешу %s"
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "дубльований елемент під час запису bitmap індексу: \"%s\""
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "спроба зберегти невибраний коміт: \"%s\""
+
+msgid "too many pseudo-merges"
+msgstr "занадто багато псевдозлиття"
+
msgid "trying to write commit not in index"
msgstr "спроба записати коміт, якого немає в індексі"
@@ -18339,8 +18537,21 @@ msgstr ""
msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr ""
+"пошкоджений файл bitmap індексу (занадто малий, щоб вмістити таблицю пошуку)"
+
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"пошкоджений файл bitmap індексу (занадто малий, щоб вмістити заголовок "
+"таблиці псевдозлиття"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr ""
"пошкоджений файл bitmap індексу (занадто короткий, щоб вмістити таблицю "
-"пошуку)"
+"псевдозлиття)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "пошкоджений файл bitmap індексу, таблиця псевдозлиття занадто мала"
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
@@ -18437,6 +18648,10 @@ msgid "mismatch in bitmap results"
msgstr "розбіжність в bitmap результатах"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "індекс псевдозлиття поза діапазоном (%<PRIu32> >= %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "не вдалося знайти \"%s\" у пакунку \"%s\" зі зміщенням %<PRIuMAX>"
@@ -18808,6 +19023,9 @@ msgstr "не вдалося створити потоковий lstat: %s"
msgid "unable to parse --pretty format"
msgstr "не вдалося розібрати --pretty формат"
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "лінива вибірка вимкнена; деякі обʼєкти можуть бути недоступні"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote: не вдалося розгалужити підпроцес отримання"
@@ -18831,6 +19049,65 @@ msgstr "object-info: очікувався flush після аргументів"
msgid "Removing duplicate objects"
msgstr "Видалення дублікатів обʼєктів"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "не вдалося завантажити регвир псевдозлиття для %s: \"%s\""
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr ""
+"%s має бути невідʼємним значенням, використано значення за замовчуванням"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr ""
+"%s має бути в діапазоні від 0 до 1, використано значення за замовчуванням"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s має бути додатнім, використано значення за замовчуванням"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "у групі псевдозлиття \"%s\" відсутній потрібний шаблон"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr "група псевдозлиття \"%s\" має нестабільний поріг перед стабільним"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"регвир псевдозлиття з конфігурації має забагато груп захоплення "
+"(max=%<PRIuMAX>"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"читання за межами (%<PRIuMAX> >= %<PRIuMAX>) при розширеному псевдозлитті"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr ""
+"запис розширенного псевдозлиття занадто малий (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr "не вдалося знайти псеводозлиття для коміта %s зі зміщенням %<PRIuMAX>"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr "розширене псевдозлиття, пошук за межами (%<PRIu32> >= %<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "читання за межами: (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "не вдалося прочитати таблицю розширеного псевдо-злиття для коміту %s"
+
msgid "could not start `log`"
msgstr "не вдалося розпочати \"log\""
@@ -19434,11 +19711,18 @@ msgstr "лог для посилання %s несподівано заверш�
msgid "log for %s is empty"
msgstr "лог для %s порожній"
+msgid "refusing to force and skip creation of reflog"
+msgstr "відмовлено в примусовому пропуску створення рефлогу"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "відмовлено в оновленні посилання з невірною назвою \"%s\""
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "відмовлено в оновленні псевдопосилання \"%s\""
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "update_ref завершився невдало для посилання \"%s\": %s"
@@ -19469,6 +19753,25 @@ msgid "could not delete references: %s"
msgstr "не вдалося видалити посилання: %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "Закінчено пробну міграцію посилань, результат можна знайти в \"%s\"\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "не вдалося видалити тимчасову директорію міграції \"%s\""
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "перенесені посилання можна знайти в \"%s\""
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"неможливо заблокувати посилання \"%s\": очікувалось символьне посилання з "
+"призначенням \"%s\", але це звичайне посилання"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "refname є небезпечним: %s"
@@ -20446,7 +20749,7 @@ msgid ""
" git rebase --continue\n"
msgstr ""
"ви маєте індексовані зміни у вашому робочому дереві\n"
-"Якщо ці зміни мають бути стиснуті у попередній коміт, запустіть:\n"
+"Якщо ці зміни мають бути зчавлені у попередній коміт, запустіть:\n"
"\n"
" git commit --amend %s\n"
"\n"
@@ -20657,6 +20960,49 @@ msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s"
msgstr "update-ref потребує повної назви посилання, наприклад, refs/heads/%s"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "\"%s\" не приймає коміти злиття"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"\"pick\" не приймає коміти злиття. Якщо ви хочете\n"
+"відтворити злиття, використовуйте \"merge -C\" для коміта."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"\"reword\" не приймає коміти злиття. Якщо ви хочете\n"
+"відтворити злиття та змінити текст допису, використовуйте\n"
+"\"merge -c\" для коміта."
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"\"edit\" не приймає коміти злиття. Якщо ви хочете\n"
+"відтворити злиття, використовуйте \"merge -C\" для коміта, а потім\n"
+"\"break\" для повернення керування, щоб ви могли\n"
+"виконати \"git commit --amend && git rebase --continue\"."
+
+msgid "cannot squash merge commit into another commit"
+msgstr "неможливо зчавити коміт злиття в інший коміт"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "неприпустима команда \"%.*s\""
@@ -20774,9 +21120,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "неможливо прочитати HEAD"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "не вдалося скопіювати \"%s\" в \"%s\""
+msgid "could not write commit message file"
+msgstr "не вдалося записати файл допису до коміта"
#, c-format
msgid ""
@@ -21180,6 +21525,18 @@ msgstr "неможливо повернутися до поточної робо
msgid "failed to stat '%*s%s%s'"
msgstr "не вдалося записати \"%*s%s%s\""
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"виявлено сумнівне право власності у сховищі за адресою \"%s\"\n"
+"%sЩоб додати виняток для цієї директорії, виконайте:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Не вдалося прочитати поточну робочу директорію"
@@ -21202,18 +21559,6 @@ msgstr ""
"встановлено)."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"виявлено сумнівне право власності у сховищі за адресою \"%s\"\n"
-"%sЩоб додати виняток для цієї директорії, виконайте:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr ""
"неможливо використати порожнє сховище \"%s\" (safe.bareRepository "
@@ -21518,7 +21863,17 @@ msgstr "Не вдалося оновити підмодуль \"%s\"."
#, c-format
msgid "submodule git dir '%s' is inside git dir '%.*s'"
-msgstr "підмодуль git dir \"%s\" знаходиться всередині git директорії \"%.*s\""
+msgstr "підмодуль git dir \"%s\" знаходиться всередині git директорії \"%*s\""
+
+#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr ""
+"очікувалось, що \"%.*s\" у шляху підмодуля \"%s\" не буде символьним "
+"посиланням"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "очікувалось, що шлях підмодуля \"%s\" не буде символьним посиланням"
#, c-format
msgid ""
@@ -21561,10 +21916,6 @@ msgstr ""
"немає налаштованого віддаленого призначення для отримання URI пакунків з "
"нього"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "віддалений \"%s\" не має налаштованої URL-адреси"
-
msgid "could not get the bundle-uri list"
msgstr "не вдалося отримати список bundle-uri"
@@ -23058,24 +23409,24 @@ msgid "Failed to send %s\n"
msgstr "Не вдалося надіслати %s\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Пробно відправлено %s\n"
+msgid "Dry-Sent %s"
+msgstr "Пробно відправлено %s"
#, perl-format
-msgid "Sent %s\n"
-msgstr "Відправлено %s\n"
+msgid "Sent %s"
+msgstr "Відправлено %s"
-msgid "Dry-OK. Log says:\n"
-msgstr "Пробно OK. Журнал каже:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Пробно OK. Журнал каже:"
-msgid "OK. Log says:\n"
-msgstr "ОК. Журнал каже:\n"
+msgid "OK. Log says:"
+msgstr "ОК. Журнал каже:"
msgid "Result: "
msgstr "Результат: "
-msgid "Result: OK\n"
-msgstr "Результат: OK\n"
+msgid "Result: OK"
+msgstr "Результат: OK"
#, perl-format
msgid "can't open file %s"
diff --git a/po/vi.po b/po/vi.po
index 965e79e965..5f42970d4f 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -2,19 +2,72 @@
# Bản dịch tiếng Việt dành cho GIT-CORE.
# This file is distributed under the same license as the git-core package.
# https://raw.githubusercontent.com/git-l10n/git-po/pot/main/po/git.pot
+# ---
# Copyright (C) 2012-2022, Translation Project, Vietnamese Team <http://translationproject.org/team/vi.html>
# Copyright (C) 2024, Vũ Tiến Hưng <newcomerminecraft@gmail.com>
# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2012.
# Đoàn Trần Công Danh <congdanhqx@gmail.com>, 2020.
# Trần Ngọc Quân <vnwildman@gmail.com>, 2012-2022.
# Vũ Tiến Hưng <newcomerminecraft@gmail.com>, 2024.
+# ---
+# BẢNG THUẬT NGỮ / TERMINOLOGY
+# Updated: 2024-07-26, git 2.46
#
-msgid ""
-msgstr ""
-"Project-Id-Version: git 2.45\n"
+# Ghi chú:
+# - Bảng thuật ngữ này chưa hoàn thiện.
+# - Tuỳ vào ngữ cảnh, bản dịch có thể thay đổi cho phù hợp.
+#
+# CÁCH VIẾT TẮT
+# n. = danh từ
+# v. = động từ
+# a. = tính từ
+#
+# +------------------------------------------------------------------+
+# | Thuật ngữ / Term | Bản dịch / Translation |
+# +------------------------------------------------------------------+
+# | file | tập tin |
+# | folder | thư mục |
+# | path | đường dẫn |
+# | error | lỗi |
+# | fatal / fatal error | lỗi nghiêm trọng |
+# | warning | cảnh báo |
+# | (v.) commit | chuyển giao |
+# | (n.) commit | lần chuyển giao |
+# | (n.) branch | nhánh |
+# | (v.) branch | tạo nhánh |
+# | (n.) log | nhật ký |
+# | (v.) log | ghi lại |
+# | (n.) ref/refs | tham chiếu |
+# | hunk | khúc |
+# | index | chỉ mục |
+# | (n.) stage | vùng chờ |
+# | (v.) stage <...> | đưa <...> vào vùng chờ |
+# | (v.) unstage <...> | bỏ <...> ra khỏi vùng chờ |
+# | revert | hoàn nguyên |
+# | add | thêm |
+# | restore | phục hồi |
+# | (n./v.) change | thay đổi |
+# | (v.) update | cập nhật |
+# | (v.) track | theo dõi |
+# | (v.) untrack | bỏ theo dõi |
+# | (a.) tracked | được theo dõi |
+# | (a.) untracked | không được theo dõi |
+# | (v.) parse | hiểu cú pháp |
+# | (n.) output | đầu ra, kết quả |
+# | (v.) output | in ra, xuất ra |
+# | (v.) merge | hoà trộn |
+# | (v.) rebase | cải tổ |
+# | (v.) squash | squash |
+# | (v.) amend | tu bổ |
+# | | |
+# | ... TODO ... | |
+# +------------------------------------------------------------------+
+msgid ""
+msgstr ""
+"Project-Id-Version: git 2.46\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-25 18:57+0000\n"
-"PO-Revision-Date: 2024-04-28 14:01+0700\n"
+"POT-Creation-Date: 2024-07-21 00:11+0700\n"
+"PO-Revision-Date: 2024-07-26 11:31+0700\n"
"Last-Translator: Vũ Tiến Hưng <newcomerminecraft@gmail.com>\n"
"Language-Team: Vietnamese <https://github.com/Nekosha/git-po>\n"
"Language: vi\n"
@@ -44,7 +97,7 @@ msgstr "Cập nhật"
#, c-format
msgid "could not stage '%s'"
-msgstr "không thể đưa '%s' lên bệ phóng"
+msgstr "không thể đưa '%s' vào vùng chờ"
msgid "could not write index"
msgstr "không thể ghi chỉ mục"
@@ -113,7 +166,7 @@ msgstr ""
msgid "revert staged set of changes back to the HEAD version"
msgstr ""
-"hoàn nguyên lại tập hợp các thay đổi đã được đưa lên bệ phóng trở lại phiên "
+"hoàn nguyên lại tập hợp các thay đổi đã được đưa vào vùng chờ trở lại phiên "
"bản HEAD"
msgid "pick hunks and update selectively"
@@ -125,7 +178,7 @@ msgstr "xem khác biệt giữa HEAD và chỉ mục"
msgid "add contents of untracked files to the staged set of changes"
msgstr ""
"thêm nội dung của các tập tin chưa được theo dõi vào tập hợp các thay đổi đã "
-"được đưa lên bệ phóng"
+"được đưa vào vùng chờ"
msgid "Prompt help:"
msgstr "Trợ giúp về nhắc:"
@@ -164,10 +217,10 @@ msgid "What now"
msgstr "Giờ thì sao"
msgid "staged"
-msgstr "đã đưa lên bệ phóng"
+msgstr "đã đưa vào vùng chờ"
msgid "unstaged"
-msgstr "chưa đưa lên bệ phóng"
+msgstr "chưa đưa vào vùng chờ"
msgid "path"
msgstr "đường-dẫn"
@@ -181,26 +234,26 @@ msgstr "Tạm biệt.\n"
#, c-format
msgid "Stage mode change [y,n,q,a,d%s,?]? "
-msgstr "Đưa lên bệ phóng thay đổi chế độ [y,n,q,a,d%s,?]? "
+msgstr "Đưa vào vùng chờ thay đổi chế độ [y,n,q,a,d%s,?]? "
#, c-format
msgid "Stage deletion [y,n,q,a,d%s,?]? "
-msgstr "Đưa lên bệ phóng thao tác xoá [y,n,q,a,d%s,?]? "
+msgstr "Đưa vào vùng chờ thao tác xoá [y,n,q,a,d%s,?]? "
#, c-format
msgid "Stage addition [y,n,q,a,d%s,?]? "
-msgstr "Đưa lên bệ phóng thao tác thêm [y,n,q,a,d%s,?]? "
+msgstr "Đưa vào vùng chờ thao tác thêm [y,n,q,a,d%s,?]? "
#, c-format
msgid "Stage this hunk [y,n,q,a,d%s,?]? "
-msgstr "Đưa lên bệ phóng khúc này [y,n,q,a,d%s,?]? "
+msgstr "Đưa vào vùng chờ khúc này [y,n,q,a,d%s,?]? "
msgid ""
"If the patch applies cleanly, the edited hunk will immediately be marked for "
"staging."
msgstr ""
"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
-"để chuyển lên bệ phóng."
+"để chuyển vào vùng chờ."
msgid ""
"y - stage this hunk\n"
@@ -209,11 +262,11 @@ msgid ""
"a - stage this hunk and all later hunks in the file\n"
"d - do not stage this hunk or any of the later hunks in the file\n"
msgstr ""
-"y - đưa lên bệ phóng khúc này\n"
-"n - đừng đưa lên bệ phóng khúc này\n"
-"q - thoát; đừng đưa lên bệ phóng khúc này hay bất kỳ cái nào còn lại\n"
-"a - đưa lên bệ phóng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng đưa lên bệ phóng khúc này hay bất kỳ cái nào còn lại trong tập tin\n"
+"y - đưa vào vùng chờ khúc này\n"
+"n - đừng đưa vào vùng chờ khúc này\n"
+"q - thoát; đừng đưa vào vùng chờ khúc này hay bất kỳ cái nào còn lại\n"
+"a - đưa vào vùng chờ khúc này và tất cả các khúc sau này trong tập tin\n"
+"d - đừng đưa vào vùng chờ khúc này hay bất kỳ cái nào còn lại trong tập tin\n"
#, c-format
msgid "Stash mode change [y,n,q,a,d%s,?]? "
@@ -253,26 +306,26 @@ msgstr ""
#, c-format
msgid "Unstage mode change [y,n,q,a,d%s,?]? "
-msgstr "Bỏ ra khỏi bệ phóng thay đổi chế độ [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi vùng chờ thay đổi chế độ [y,n,q,a,d%s,?]? "
#, c-format
msgid "Unstage deletion [y,n,q,a,d%s,?]? "
-msgstr "Bỏ ra khỏi bệ phóng thao tác xoá [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi vùng chờ thao tác xoá [y,n,q,a,d%s,?]? "
#, c-format
msgid "Unstage addition [y,n,q,a,d%s,?]? "
-msgstr "Bỏ ra khỏi bệ phóng thao tác thêm [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi vùng chờ thao tác thêm [y,n,q,a,d%s,?]? "
#, c-format
msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
-msgstr "Bỏ ra khỏi bệ phóng khúc này [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi vùng chờ khúc này [y,n,q,a,d%s,?]? "
msgid ""
"If the patch applies cleanly, the edited hunk will immediately be marked for "
"unstaging."
msgstr ""
"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
-"để bỏ ra khỏi bệ phóng."
+"để bỏ ra khỏi vùng chờ."
msgid ""
"y - unstage this hunk\n"
@@ -281,11 +334,11 @@ msgid ""
"a - unstage this hunk and all later hunks in the file\n"
"d - do not unstage this hunk or any of the later hunks in the file\n"
msgstr ""
-"y - đưa ra khỏi bệ phóng khúc này\n"
-"n - đừng đưa ra khỏi bệ phóng khúc này\n"
-"q - thoát; đừng đưa ra khỏi bệ phóng khúc này hay bất kỳ cái nào còn lại\n"
-"a - đưa ra khỏi bệ phóng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng đưa ra khỏi bệ phóng khúc này hay bất kỳ cái nào còn lại trong tập "
+"y - đưa ra khỏi vùng chờ khúc này\n"
+"n - đừng đưa ra khỏi vùng chờ khúc này\n"
+"q - thoát; đừng đưa ra khỏi vùng chờ khúc này hay bất kỳ cái nào còn lại\n"
+"a - đưa ra khỏi vùng chờ khúc này và tất cả các khúc sau này trong tập tin\n"
+"d - đừng đưa ra khỏi vùng chờ khúc này hay bất kỳ cái nào còn lại trong tập "
"tin\n"
#, c-format
@@ -566,6 +619,10 @@ msgstr ""
"p - in ra khúc hiện hành\n"
"? - hiển thị trợ giúp\n"
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "Cần một ký tự, nhưng lại có '%s'"
+
msgid "No previous hunk"
msgstr "Không có khúc kế trước"
@@ -613,9 +670,19 @@ msgstr "Chia nhỏ thành %d khúc."
msgid "Sorry, cannot edit this hunk"
msgstr "Không thể sửa khúc này"
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "không hiểu câu lệnh: '%s' ('?' để hiển thị trợ giúp)"
+
msgid "'git apply' failed"
msgstr "'git apply' gặp lỗi"
+msgid "No changes."
+msgstr "Không có thay đổi nào."
+
+msgid "Only binary files changed."
+msgstr "Chỉ có các tập tin nhị phân thay đổi."
+
#, c-format
msgid ""
"\n"
@@ -1462,6 +1529,9 @@ msgstr "bỏ qua tập tin gitattributes quá lớn '%s'"
msgid "ignoring overly large gitattributes blob '%s'"
msgstr "bỏ qua blob gitattributes quá lớn '%s'"
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "không thể dùng --attr-source hoặc GIT_ATTR_SOURCE mà không có kho chứa"
+
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "--attr-source hoặc GIT_ATTR_SOURCE sai"
@@ -1772,14 +1842,7 @@ msgid "cannot chmod %cx '%s'"
msgstr "không thể chmod %cx '%s'"
msgid "Unstaged changes after refreshing the index:"
-msgstr "Đưa ra khỏi bệ phóng các thay đổi sau khi làm mới lại chỉ mục:"
-
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"mục cài đặt add.interactive.useBuiltin đã không còn!\n"
-"Xem mục tin của nó trong 'git help config' để biết chi tiết."
+msgstr "Đưa ra khỏi vùng chờ các thay đổi sau khi làm mới lại chỉ mục:"
msgid "could not read the index"
msgstr "Không thể đọc chỉ mục"
@@ -2065,8 +2128,8 @@ msgstr "Thân của lần chuyển giao là:"
#, c-format
msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "
msgstr ""
-"Áp dụng? đồng ý [y]/khô[n]g/chỉnh sửa [e]/hiển thị miếng [v]á/chấp nhận tất "
-"cả [a]: "
+"Áp dụng? đồng ý [y]/không [n]/chỉnh sửa [e]/hiển thị bản vá [v]/chấp nhận "
+"tất cả [a]: "
msgid "unable to write index file"
msgstr "không thể ghi tập tin chỉ mục"
@@ -2110,9 +2173,8 @@ msgid ""
"already introduced the same changes; you might want to skip this patch."
msgstr ""
"Không có thay đổi nào - bạn đã quên sử dụng lệnh 'git add' à?\n"
-"Nếu ở đây không có gì còn lại stage, tình cờ là có một số thứ khác\n"
-"đã sẵn được đưa vào với cùng nội dung thay đổi; bạn có lẽ muốn bỏ qua miếng "
-"vá này."
+"Nếu ở đây không còn gì để đưa vào vùng chờ, có lẽ một số người khác\n"
+"đã thêm các thay đổi trong này rồi; bạn có lẽ muốn bỏ qua bản vá này."
msgid ""
"You still have unmerged paths in your index.\n"
@@ -2121,8 +2183,8 @@ msgid ""
"You might run `git rm` on a file to accept \"deleted by them\" for it."
msgstr ""
"Bạn vẫn có những đường dẫn chưa hòa trộn trong chỉ mục của bạn.\n"
-"Bạn nên 'git add' từng tập tin với các xung đột đã được giải quyết để đánh "
-"dấu chúng là thế.\n"
+"Bạn nên 'git add' những tập tin đã giải quyết xung đột để đánh dấu chúng là "
+"đã xong.\n"
"Bạn có lẽ muốn chạy 'git rm' trên một tập tin để chấp nhận \"được xóa bởi "
"họ\" cho nó."
@@ -2222,11 +2284,14 @@ msgstr "huỷ thao tác vá nhưng vẫn giữ HEAD nơi nó chỉ đến"
msgid "show the patch being applied"
msgstr "hiển thị bản vá đã được áp dụng rồi"
+msgid "try to apply current patch again"
+msgstr "thử áp dụng bản vá hiện hành thêm lần nữa"
+
msgid "record the empty patch as an empty commit"
msgstr "ghi lại bản vá trống rỗng như là một lần chuyển giao trống"
msgid "lie about committer date"
-msgstr "nói dối về ngày chuyển giao"
+msgstr "làm giả ngày chuyển giao"
msgid "use current timestamp for author date"
msgstr "dùng dấu thời gian hiện tại cho ngày tác giả"
@@ -2277,9 +2342,6 @@ msgstr "git apply [<các tùy chọn>] [<miếng-vá>...]"
msgid "could not redirect output"
msgstr "không thể chuyển hướng đầu ra"
-msgid "git archive: Remote with no URL"
-msgstr "git archive: Máy chủ không có địa chỉ URL"
-
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive: cần ACK/NAK, nhưng lại nhận được gói flush"
@@ -2603,7 +2665,7 @@ msgid "force progress reporting"
msgstr "ép buộc báo cáo tiến độ công việc"
msgid "show output score for blame entries"
-msgstr "hiển thị kết xuất điểm số cho các mục tin 'blame'"
+msgstr "hiển thị điểm số đầu ra cho các mục tin 'blame'"
msgid "show original filename (Default: auto)"
msgstr "hiển thị tên tập tin gốc (Mặc định: auto)"
@@ -2881,7 +2943,7 @@ msgid "unset the upstream info"
msgstr "bỏ đặt thông tin thượng nguồn"
msgid "use colored output"
-msgstr "tô màu kết xuất"
+msgstr "tô màu đầu ra"
msgid "act on remote-tracking branches"
msgstr "thao tác trên nhánh 'remote-tracking'"
@@ -3175,6 +3237,9 @@ msgstr "Cần một kho chứa để có thể tạo một bundle."
msgid "do not show bundle details"
msgstr "không hiển thị chi tiết bundle (bó)"
+msgid "need a repository to verify a bundle"
+msgstr "cần một kho chứa để thẩm tra một bundle"
+
#, c-format
msgid "%s is okay\n"
msgstr "%s tốt\n"
@@ -3288,7 +3353,7 @@ msgid "Change or optimize batch output"
msgstr "Thay đổi hay tối ưu hóa đầu ra batch"
msgid "buffer --batch output"
-msgstr "đệm kết xuất --batch"
+msgstr "buffer đầu ra --batch"
msgid "follow in-tree symlinks"
msgstr "theo liên kết mềm trong-cây"
@@ -3456,7 +3521,7 @@ msgid "write the content to temporary files"
msgstr "ghi nội dung vào tập tin tạm"
msgid "copy out the files from named stage"
-msgstr "sao chép ra các tập tin từ bệ phóng có tên"
+msgstr "sao chép ra các tập tin từ vùng chờ có tên"
msgid "git checkout [<options>] <branch>"
msgstr "git checkout [<các tùy chọn>] <nhánh>"
@@ -3550,7 +3615,7 @@ msgid ""
"cannot continue with staged changes in the following files:\n"
"%s"
msgstr ""
-"không thể tiếp tục với các thay đổi đã được đưa lên bệ phóng trong các dòng "
+"không thể tiếp tục với các thay đổi đã được đưa vào vùng chờ trong các dòng "
"sau:\n"
"%s"
@@ -3570,7 +3635,7 @@ msgstr "Đặt lại nhánh '%s'\n"
#, c-format
msgid "Already on '%s'\n"
-msgstr "Đã sẵn sàng trên '%s'\n"
+msgstr "Đã sẵn ở trên '%s'\n"
#, c-format
msgid "Switched to and reset branch '%s'\n"
@@ -4177,12 +4242,20 @@ msgid "failed to unlink '%s'"
msgstr "gặp lỗi khi unlink '%s'"
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "không thể kiểm tra liên kết cứng '%s'"
+
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "liên kết cứng '%s' khác với nguồn"
+
+#, c-format
msgid "failed to create link '%s'"
-msgstr "gặp lỗi khi tạo được liên kết mềm %s"
+msgstr "gặp lỗi khi tạo liên kết mềm %s"
#, c-format
msgid "failed to copy file to '%s'"
-msgstr "gặp lỗi khi sao chép tập tin và '%s'"
+msgstr "gặp lỗi khi sao chép tập tin tới '%s'"
#, c-format
msgid "failed to iterate over '%s'"
@@ -4841,7 +4914,7 @@ msgid "version"
msgstr "phiên bản"
msgid "machine-readable output"
-msgstr "kết xuất dạng máy-có-thể-đọc"
+msgstr "xuất ra dạng máy-có-thể-đọc"
msgid "show status in long format (default)"
msgstr "hiển thị trạng thái ở định dạng dài (mặc định)"
@@ -4930,15 +5003,14 @@ msgstr ""
msgid "use autosquash formatted message to squash specified commit"
msgstr ""
-"dùng lời nhắn có định dạng tự động nén để nén lại các lần chuyển giao đã chỉ "
-"ra"
+"dùng lời nhắn có định dạng autosquash để squash các lần chuyển giao đã chỉ ra"
msgid "the commit is authored by me now (used with -C/-c/--amend)"
msgstr ""
"lần chuyển giao nhận tôi là tác giả (được dùng với tùy chọn -C/-c/--amend)"
msgid "trailer"
-msgstr "bộ dò vết"
+msgstr "trailer"
msgid "add custom trailer(s)"
msgstr "thêm đuôi tự chọn"
@@ -5029,15 +5101,51 @@ msgstr ""
"có bị đầy quá hay hạn nghạch đĩa (quota) bị vượt quá hay không,\n"
"và sau đó \"git restore --staged :/\" để khắc phục."
-msgid "git config [<options>]"
-msgstr "git config [<các tùy chọn>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<tuỳ-chọn>] [<tuỳ-chọn-hiển-thị>] [--includes]"
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "đối số không được thừa nhận --type, %s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<tuỳ-chọn>] [<tuỳ-chọn-hiển-thị>] [--includes] [--all] [--"
+"regexp=<biểu-thức-chính-quy>] [--value=<giá-trị>] [--fixed-value] [--"
+"default=<giá-trị-mặc-định>] <khoá>"
-msgid "only one type at a time"
-msgstr "chỉ một kiểu một lần"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<tuỳ-chọn>] [--type=<kiểu>] [--all] [--value=<giá-trị>] [--"
+"fixed-value] <khoá> <giá-trị>"
+
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<tuỳ-chọn>] [--all] [--value=<giá-trị>] [--fixed-value] "
+"<khoá> <giá-trị>"
+
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<tuỳ-chọn>] <tên-cũ> <tên-mới>"
+
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<tuỳ-chọn>] <tên>"
+
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<tùy-chọn>]"
+
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr ""
+"git config [<tuỳ-chọn>] --get-colorbool <tên> [<stdout-là-tty-hay-không>]"
+
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<tuỳ-chọn>] [--type=<kiểu>] [--comment=<chú-thích>] [--all] "
+"[--value=<giá-trị>] [--fixed-value] <khoá> <giá-trị>"
msgid "Config file location"
msgstr "Vị trí tập tin cấu hình"
@@ -5063,54 +5171,6 @@ msgstr "blob-id"
msgid "read config from given blob object"
msgstr "đọc cấu hình từ đối tượng blob đã cho"
-msgid "Action"
-msgstr "Hành động"
-
-msgid "get value: name [value-pattern]"
-msgstr "lấy giá trị: tên [value-pattern]"
-
-msgid "get all values: key [value-pattern]"
-msgstr "lấy tất cả giá trị: khóa [value-pattern]"
-
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "lấy giá trị cho regexp: name-regex [value-pattern]"
-
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "lấy đặc tả giá trị cho URL: phần[.biến] URL"
-
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "thay thế tất cả các biến khớp mẫu: tên giá-trị [value-pattern]"
-
-msgid "add a new variable: name value"
-msgstr "thêm biến mới: tên giá-trị"
-
-msgid "remove a variable: name [value-pattern]"
-msgstr "gỡ bỏ biến: tên [value-pattern]"
-
-msgid "remove all matches: name [value-pattern]"
-msgstr "gỡ bỏ mọi cái khớp: tên [value-pattern]"
-
-msgid "rename section: old-name new-name"
-msgstr "đổi tên phần: tên-cũ tên-mới"
-
-msgid "remove a section: name"
-msgstr "gỡ bỏ phần: tên"
-
-msgid "list all"
-msgstr "liệt kê tất"
-
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "sử dụng so sánh bằng chuỗi khi so sánh các giá trị với 'value-pattern'"
-
-msgid "open an editor"
-msgstr "mở một trình biên soạn"
-
-msgid "find the color configured: slot [default]"
-msgstr "tìm cấu hình màu sắc: slot [mặc định]"
-
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "tìm các cài đặt về màu sắc: slot [stdout-là-tty]"
-
msgid "Type"
msgstr "Kiểu"
@@ -5138,8 +5198,8 @@ msgstr "giá trị là đường dẫn (tên tập tin hay thư mục)"
msgid "value is an expiry date"
msgstr "giá trị là một ngày hết hạn"
-msgid "Other"
-msgstr "Khác"
+msgid "Display options"
+msgstr "Tuỳ chọn hiển thị"
msgid "terminate values with NUL byte"
msgstr "kết thúc giá trị với byte NUL"
@@ -5147,9 +5207,6 @@ msgstr "kết thúc giá trị với byte NUL"
msgid "show variable names only"
msgstr "chỉ hiển thị các tên biến"
-msgid "respect include directives on lookup"
-msgstr "tôn trọng kể cà các hướng trong tìm kiếm"
-
msgid "show origin of config (file, standard input, blob, command line)"
msgstr "hiển thị nguồn gốc của cấu hình (tập tin, stdin, blob, dòng lệnh)"
@@ -5158,14 +5215,15 @@ msgstr ""
"hiển thị phạm vi của cấu hình (cây làm việc, cục bộ, toàn cầu, hệ thống, "
"lệnh)"
-msgid "value"
-msgstr "giá trị"
+msgid "show config keys in addition to their values"
+msgstr "hiển thị khoá cùng vói giá trị"
-msgid "with --get, use default value when missing entry"
-msgstr "với --get, dùng giá trị mặc định khi thiếu mục tin"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "đối số không được thừa nhận --type, %s"
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr "ghi chú cho người đọc được (tự động thêm # vào trước nếu cần)"
+msgid "only one type at a time"
+msgstr "chỉ một kiểu một lần"
#, c-format
msgid "wrong number of arguments, should be %d"
@@ -5241,47 +5299,72 @@ msgstr ""
"worktreeConfig được bật. Vui lòng đọc phần \"CONFIGURATION FILE\"\n"
"trong \"git help worktree\" để biết thêm chi tiết"
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color và kiểu biến là không mạch lạc"
+msgid "Other"
+msgstr "Khác"
-msgid "only one action at a time"
-msgstr "chỉ một thao tác mỗi lần"
+msgid "respect include directives on lookup"
+msgstr "tôn trọng kể cà các hướng trong tìm kiếm"
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only chỉ được áp dụng cho --list hoặc --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "không thể đọc tập tin cấu hình '%s'"
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-"--show-origin chỉ được áp dụng cho --get, --get-all, --get-regexp, hoặc --"
-"list"
+msgid "error processing config file(s)"
+msgstr "gặp lỗi khi xử lý các tập tin cấu hình"
-msgid "--default is only applicable to --get"
-msgstr "--default chỉ được áp dụng cho --get"
+msgid "Filter options"
+msgstr "Tùy chọn lọc"
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment chỉ được áp dụng cho thao tác add/set/replace"
+msgid "return all values for multi-valued config options"
+msgstr "trả về tất cả giá trị cho tuỳ chọn cấu hình đa trị"
+
+msgid "interpret the name as a regular expression"
+msgstr "coi khoá là biểu thức chính quy"
+
+msgid "show config with values matching the pattern"
+msgstr "hiển thị giá trị cấu hình khớp với mẫu"
+
+msgid "use string equality when comparing values to value pattern"
+msgstr "sử dụng so sánh xâu khi so sánh các giá trị với mẫu"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "show config matching the given URL"
+msgstr "hiển thị giá trị cấu hình khớp với URL"
+
+msgid "value"
+msgstr "giá trị"
+
+msgid "use default value when missing entry"
+msgstr "dùng giá trị mặc định khi không tồn tại"
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value chỉ áp dụng với 'value-pattern'"
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "không thể đọc tập tin cấu hình '%s'"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= không thể được dùng với --all hay --url"
-msgid "error processing config file(s)"
-msgstr "gặp lỗi khi xử lý các tập tin cấu hình"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= không thể được dùng với --all, --regexp hay --value"
-msgid "editing stdin is not supported"
-msgstr "sửa chữa stdin là không được hỗ trợ"
+msgid "Filter"
+msgstr "Bộ lọc"
-msgid "editing blobs is not supported"
-msgstr "việc sửa chữa các blob là không được hỗ trợ"
+msgid "replace multi-valued config option with new value"
+msgstr "thay thế tuỳ chọn cấu hình đa trị thành giá trị"
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "không thể tạo tập tin cấu hình '%s'"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "ghi chú cho người đọc được (tự động thêm # vào trước nếu cần)"
+
+msgid "add a new line without altering any existing values"
+msgstr "thêm dòng mới giữ nguyên các giá trị cũ"
+
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value chỉ áp dụng với --value=<mẫu>"
+
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append không thể được dùng với --value=<mẫu>"
#, c-format
msgid ""
@@ -5295,6 +5378,86 @@ msgstr ""
msgid "no such section: %s"
msgstr "không có đoạn: %s"
+msgid "editing stdin is not supported"
+msgstr "sửa chữa stdin là không được hỗ trợ"
+
+msgid "editing blobs is not supported"
+msgstr "việc sửa chữa các blob là không được hỗ trợ"
+
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "không thể tạo tập tin cấu hình '%s'"
+
+msgid "Action"
+msgstr "Hành động"
+
+msgid "get value: name [<value-pattern>]"
+msgstr "lấy giá trị: khoá [<mẫu-giá-trị>]"
+
+msgid "get all values: key [<value-pattern>]"
+msgstr "lấy tất cả giá trị: khóa [<mẫu-giá-trị>]"
+
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "lấy giá trị cho biểu thức chính quy: regex [<mẫu-giá-trị>]"
+
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "lấy giá trị riêng cho URL: phần[.biến] URL"
+
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "thay thế tất cả các biến khớp mẫu: tên giá-trị [<mẫu-giá-trị>]"
+
+msgid "add a new variable: name value"
+msgstr "thêm biến mới: tên giá-trị"
+
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "gỡ bỏ biến: tên [<mẫu-giá-trị>]"
+
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "gỡ bỏ mọi biến khớp: tên [<mẫu-giá-trị>]"
+
+msgid "rename section: old-name new-name"
+msgstr "đổi tên phần: tên-cũ tên-mới"
+
+msgid "remove a section: name"
+msgstr "gỡ bỏ phần: tên"
+
+msgid "list all"
+msgstr "liệt kê tất"
+
+msgid "open an editor"
+msgstr "mở một trình biên soạn"
+
+msgid "find the color configured: slot [<default>]"
+msgstr "tìm cấu hình màu sắc: slot [<mặc định>]"
+
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "tìm các cài đặt về màu sắc: slot [<stdout-là-tty-hay-không>]"
+
+msgid "with --get, use default value when missing entry"
+msgstr "với --get, dùng giá trị mặc định khi thiếu mục tin"
+
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color và kiểu biến là không mạch lạc"
+
+msgid "no action specified"
+msgstr "chưa chỉ ra hành động"
+
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only chỉ được áp dụng cho --list hoặc --get-regexp"
+
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr ""
+"--show-origin chỉ được áp dụng cho --get, --get-all, --get-regexp, hoặc --"
+"list"
+
+msgid "--default is only applicable to --get"
+msgstr "--default chỉ được áp dụng cho --get"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment chỉ được áp dụng cho thao tác add/set/replace"
+
msgid "print sizes in human readable format"
msgstr "hiển thị kích cỡ theo định dạng dành cho người đọc"
@@ -5637,7 +5800,7 @@ msgid "use the done feature to terminate the stream"
msgstr "sử dụng tính năng done để kết thúc luồng dữ liệu"
msgid "skip output of blob data"
-msgstr "bỏ qua kết xuất của dữ liệu blob"
+msgstr "bỏ qua đầu ra của dữ liệu blob"
msgid "refspec"
msgstr "refspec"
@@ -5646,7 +5809,7 @@ msgid "apply refspec to exported refs"
msgstr "áp dụng refspec cho refs đã xuất"
msgid "anonymize output"
-msgstr "kết xuất anonymize"
+msgstr "ẩn danh đầu ra"
msgid "from:to"
msgstr "từ:đến"
@@ -5946,7 +6109,7 @@ msgid "re-fetch without negotiating common commits"
msgstr "re-fetch mà không dàn xếp các lần chuyển giao chung"
msgid "prepend this to submodule path output"
-msgstr "soạn sẵn cái này cho kết xuất đường dẫn mô-đun-con"
+msgstr "soạn sẵn cái này cho đầu ra đường dẫn mô-đun-con"
msgid ""
"default for recursive fetching of submodules (lower priority than config "
@@ -6038,7 +6201,7 @@ msgid "populate log with at most <n> entries from shortlog"
msgstr "gắn nhật ký với ít nhất <n> mục từ lệnh 'shortlog'"
msgid "alias for --log (deprecated)"
-msgstr "bí danh cho --log (đã lạc hậu)"
+msgstr "đồng nghĩa với --log (đã không còn)"
msgid "text"
msgstr "văn bản"
@@ -6119,6 +6282,9 @@ msgstr "config"
msgid "config key storing a list of repository paths"
msgstr "khóa cấu hình lưu trữ danh sách đường dẫn kho lưu trữ"
+msgid "keep going even if command fails in a repository"
+msgstr "tiếp tục dù có lệnh thất bại trong kho chứa"
+
msgid "missing --config=<config>"
msgstr "thiếu --config=<config>"
@@ -6141,7 +6307,7 @@ msgstr "có cảnh báo trong %s %s: %s"
#, c-format
msgid "broken link from %7s %s"
-msgstr "liên kết gãy từ %7s %s"
+msgstr "liên kết hỏng từ %7s %s"
msgid "wrong object type in link"
msgstr "kiểu đối tượng sai trong liên kết"
@@ -6151,7 +6317,7 @@ msgid ""
"broken link from %7s %s\n"
" to %7s %s"
msgstr ""
-"liên kết gãy từ %7s %s \n"
+"liên kết hỏng từ %7s %s \n"
" tới %7s %s"
msgid "Checking connectivity"
@@ -6858,7 +7024,7 @@ msgid "combine patterns specified with -e"
msgstr "tổ hợp mẫu được chỉ ra với tùy chọn -e"
msgid "indicate hit with exit status without output"
-msgstr "đưa ra gợi ý với trạng thái thoát mà không có kết xuất"
+msgstr "chỉ ra có khớp mẫu hay không với trạng thái thoát thay vì đầu ra"
msgid "show only matches from files that match all patterns"
msgstr "chỉ hiển thị những cái khớp từ tập tin mà nó khớp toàn bộ các mẫu"
@@ -7402,7 +7568,7 @@ msgid "invalid --decorate option: %s"
msgstr "tùy chọn --decorate không hợp lệ: %s"
msgid "suppress diff output"
-msgstr "chặn mọi kết xuất từ diff"
+msgstr "chặn mọi đầu ra từ diff"
msgid "show source"
msgstr "hiển thị mã nguồn"
@@ -7435,7 +7601,7 @@ msgstr "-L<vùng>:<tập tin> không thể được sử dụng với đặc t�
#, c-format
msgid "Final output: %d %s\n"
-msgstr "Kết xuất cuối cùng: %d %s\n"
+msgstr "Đầu ra cuối cùng: %d %s\n"
msgid "unable to create temporary object directory"
msgstr "không thể tạo thư mục đối tượng tạm thời"
@@ -7487,7 +7653,7 @@ msgid "git format-patch [<options>] [<since> | <revision-range>]"
msgstr "git format-patch [<các tùy chọn>] [<kể-từ> | <vùng-xem-xét>]"
msgid "two output directories?"
-msgstr "hai thư mục kết xuất?"
+msgstr "hai thư mục đầu ra?"
#, c-format
msgid "unknown commit %s"
@@ -7563,8 +7729,11 @@ msgstr "đánh dấu chuỗi là lần chạy lại thứ N"
msgid "max length of output filename"
msgstr "chiều dài tên tập tin đầu ra tối đa"
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "dùng [RFC PATCH] thay cho [PATCH]"
+msgid "rfc"
+msgstr "rfc"
+
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "thêm <rfc> (mặc định 'RFC') trước 'PATCH'"
msgid "cover-from-description-mode"
msgstr "cover-from-description-mode"
@@ -7585,7 +7754,7 @@ msgid "don't strip/add [PATCH]"
msgstr "không loại bỏ/thêm [PATCH]"
msgid "don't output binary diffs"
-msgstr "không kết xuất diff nhị phân"
+msgstr "không xuất diff nhị phân"
msgid "output all-zero hash in From header"
msgstr "xuất mọi mã băm all-zero trong phần đầu From"
@@ -7722,7 +7891,7 @@ msgid "Generating patches"
msgstr "Đang tạo các bản vá"
msgid "failed to create output files"
-msgstr "gặp lỗi khi tạo các tập tin kết xuất"
+msgstr "gặp lỗi khi tạo các tập tin đầu ra"
msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
msgstr "git cherry [-v] [<thượng-nguồn> [<đầu> [<giới-hạn>]]]"
@@ -7759,19 +7928,19 @@ msgid "show cached files in the output (default)"
msgstr "hiển thị các tập tin được nhớ tạm vào đầu ra (mặc định)"
msgid "show deleted files in the output"
-msgstr "hiển thị các tập tin đã xóa trong kết xuất"
+msgstr "hiển thị các tập tin đã xóa trong đầu ra"
msgid "show modified files in the output"
-msgstr "hiển thị các tập tin đã bị sửa đổi ra kết xuất"
+msgstr "hiển thị các tập tin đã bị sửa đổi ra đầu ra"
msgid "show other files in the output"
-msgstr "hiển thị các tập tin khác trong kết xuất"
+msgstr "hiển thị các tập tin khác trong đầu ra"
msgid "show ignored files in the output"
-msgstr "hiển thị các tập tin bị bỏ qua trong kết xuất"
+msgstr "hiển thị các tập tin bị bỏ qua trong đầu ra"
msgid "show staged contents' object name in the output"
-msgstr "hiển thị tên đối tượng của nội dung được đặt lên bệ phóng ra kết xuất"
+msgstr "hiển thị tên đối tượng của nội dung được đặt vào vùng chờ ra đầu ra"
msgid "show files on the filesystem that need to be removed"
msgstr "hiển thị các tập tin trên hệ thống tập tin mà nó cần được gỡ bỏ"
@@ -7786,13 +7955,13 @@ msgid "don't show empty directories"
msgstr "không hiển thị thư mục rỗng"
msgid "show unmerged files in the output"
-msgstr "hiển thị các tập tin chưa hòa trộn trong kết xuất"
+msgstr "hiển thị các tập tin chưa hòa trộn trong đầu ra"
msgid "show resolve-undo information"
msgstr "hiển thị thông tin resolve-undo"
msgid "skip files matching pattern"
-msgstr "bỏ qua những tập tin khớp với một mẫu"
+msgstr "bỏ qua những tập tin khớp với mẫu"
msgid "read exclude patterns from <file>"
msgstr "đọc mẫu cần loại trừ từ <tập-tin>"
@@ -7804,10 +7973,10 @@ msgid "add the standard git exclusions"
msgstr "thêm loại trừ tiêu chuẩn kiểu git"
msgid "make the output relative to the project top directory"
-msgstr "làm cho kết xuất liên quan đến thư mục ở mức cao nhất (gốc) của dự án"
+msgstr "cho kết quả là đường dẫn tương đối từ thư mục gốc của dự án"
msgid "if any <file> is not in the index, treat this as an error"
-msgstr "nếu <tập tin> bất kỳ không ở trong chỉ mục, xử lý nó như một lỗi"
+msgstr "nếu có bất kỳ <tập tin> không ở trong chỉ mục, coi nó như một lỗi"
msgid "tree-ish"
msgstr "tree-ish"
@@ -7833,11 +8002,11 @@ msgstr ""
"deduplicate, --eol"
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<kho> [<mẫu>...]]"
@@ -7853,8 +8022,11 @@ msgstr "đường dẫn của git-upload-pack trên máy chủ"
msgid "limit to tags"
msgstr "giới hạn tới các thẻ"
-msgid "limit to heads"
-msgstr "giới hạn cho các đầu"
+msgid "limit to branches"
+msgstr "giới hạn tới các nhánh"
+
+msgid "deprecated synonym for --branches"
+msgstr "trước đây là đồng nghĩa với --branches"
msgid "do not show peeled tags"
msgstr "không hiển thị thẻ bị peel (gọt bỏ)"
@@ -8694,7 +8866,7 @@ msgid "Write/edit the notes for the following object:"
msgstr "Ghi hay sửa ghi chú cho đối tượng sau đây:"
msgid "could not read 'show' output"
-msgstr "không thể đọc kết xuất 'show'"
+msgstr "không thể đọc đầu ra 'show'"
#, c-format
msgid "failed to finish 'show' for object '%s'"
@@ -9171,7 +9343,7 @@ msgid "use threads when searching for best delta matches"
msgstr "sử dụng các tuyến trình khi tìm kiếm cho các mẫu khớp delta tốt nhất"
msgid "do not create an empty pack output"
-msgstr "không thể tạo kết xuất gói trống rỗng"
+msgstr "không thể tạo đầu ra gói trống rỗng"
msgid "read revision arguments from standard input"
msgstr "đọc tham số 'revision' từ stdin"
@@ -9300,7 +9472,7 @@ msgid ""
"Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
"reused %<PRIu32> (from %<PRIuMAX>)"
msgstr ""
-"Tổng %<PRIu32> (delta %<PRIu32>), dùng lại %<PRIu32> (delta %<PRIu32>),dùng "
+"Tổng %<PRIu32> (delta %<PRIu32>), dùng lại %<PRIu32> (delta %<PRIu32>), dùng "
"lại pack %<PRIu32> (trong số %<PRIuMAX>)"
msgid ""
@@ -9862,10 +10034,10 @@ msgid "passed to 'git log'"
msgstr "chuyển cho 'git log'"
msgid "only emit output related to the first range"
-msgstr "chỉ phát ra kết xuất liên quan đến vùng đầu tiên"
+msgstr "chỉ phát ra kết quả liên quan đến vùng đầu tiên"
msgid "only emit output related to the second range"
-msgstr "chỉ phát ra kết xuất liên quan đến vùng thứ hai"
+msgstr "chỉ phát ra kết quả liên quan đến vùng thứ hai"
#, c-format
msgid "not a revision: '%s'"
@@ -10029,7 +10201,7 @@ msgstr ""
"không thể tổ hợp các tùy chọn áp dụng với các tùy chọn hòa trộn với nhau"
msgid "--empty=ask is deprecated; use '--empty=stop' instead."
-msgstr "không cho dùng --empty=ask nữa; hãy thay thế bằng '--empty=stop'."
+msgstr "không còn dùng --empty=ask nữa; hãy thay thế bằng '--empty=stop'."
#, c-format
msgid ""
@@ -10499,6 +10671,22 @@ msgstr "chưa chỉ ra reflog để xóa"
msgid "invalid ref format: %s"
msgstr "định dạng tham chiếu không hợp lệ: %s"
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<định dạng> [--dry-run]"
+
+msgid "specify the reference format to convert to"
+msgstr "chỉ định định dạng tham chiếu để chuyển đổi sang"
+
+msgid "perform a non-destructive dry-run"
+msgstr "chạy thử mà không thay đổi gì"
+
+msgid "missing --ref-format=<format>"
+msgstr "thiếu --ref-format=<định dạng>"
+
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "kho đã dùng định dạng '%s'"
+
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <name> <url>"
@@ -10778,9 +10966,6 @@ msgstr "* máy chủ %s"
msgid " Fetch URL: %s"
msgstr " URL để lấy về: %s"
-msgid "(no URL)"
-msgstr "(không có URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -10789,6 +10974,9 @@ msgstr "(không có URL)"
msgid " Push URL: %s"
msgstr " URL để đẩy lên: %s"
+msgid "(no URL)"
+msgstr "(không có URL)"
+
#, c-format
msgid " HEAD branch: %s"
msgstr " Nhánh HEAD: %s"
@@ -10891,10 +11079,6 @@ msgstr "truy vấn đẩy URL thay vì lấy"
msgid "return all URLs"
msgstr "trả về mọi URL"
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "không có URL nào được cấu hình cho nhánh '%s'"
-
msgid "manipulate push URLs"
msgstr "đẩy các 'URL' bằng tay"
@@ -11260,7 +11444,7 @@ msgid "--convert-graft-file takes no argument"
msgstr "--convert-graft-file không nhận đối số"
msgid "only one pattern can be given with -l"
-msgstr "chỉ một mẫu được chỉ ra với tùy chọn -l"
+msgstr "chỉ được chỉ định một mẫu cùng với tùy chọn -l"
msgid "need some commits to replay"
msgstr "cần các chuyển giao để phát lại"
@@ -11422,7 +11606,7 @@ msgstr "Gặp lỗi khi phân giải '%s' như là một cây (tree) hợp lệ.
msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
msgstr ""
-"không cho dùng --mixed với các đường dẫn nữa; hãy thay thế bằng lệnh 'git "
+"không còn dùng --mixed với các đường dẫn nữa; hãy thay thế bằng lệnh 'git "
"reset -- </các/đường/dẫn>'."
#, c-format
@@ -11434,7 +11618,7 @@ msgid "%s reset is not allowed in a bare repository"
msgstr "%s reset không được phép trên kho chứa bare"
msgid "Unstaged changes after reset:"
-msgstr "Những thay đổi được đưa ra khỏi bệ phóng sau khi reset:"
+msgstr "Những thay đổi được đưa ra khỏi vùng chờ sau khi reset:"
#, c-format
msgid ""
@@ -11477,7 +11661,7 @@ msgid "stop parsing after the first non-option argument"
msgstr "dừng đọc sau đối số đầu tiên không có tùy chọn"
msgid "output in stuck long form"
-msgstr "kết xuất trong định dạng gậy dài"
+msgstr "kết quả có định dạng dài"
msgid "premature end of input"
msgstr "đầu vào kết thúc bất thường"
@@ -11646,7 +11830,7 @@ msgid_plural ""
"the following files have staged content different from both the\n"
"file and the HEAD:"
msgstr[0] ""
-"các tập tin sau đây có khác biệt nội dung đã đưa lên bệ phóng\n"
+"các tập tin sau đây có khác biệt nội dung đã đưa vào vùng chờ\n"
"từ cả tập tin và cả HEAD:"
msgid ""
@@ -11751,7 +11935,7 @@ msgid "group by committer rather than author"
msgstr "nhóm theo người chuyển giao thay vì tác giả"
msgid "sort output according to the number of commits per author"
-msgstr "sắp xếp kết xuất tuân theo số lượng chuyển giao trên mỗi tác giả"
+msgstr "sắp xếp kết quả theo số lượng chuyển giao trên mỗi tác giả"
msgid "suppress commit descriptions, only provides commit count"
msgstr "chặn mọi mô tả lần chuyển giao, chỉ đưa ra số lượng lần chuyển giao"
@@ -11883,12 +12067,12 @@ msgstr "Không hiểu thuật toán băm dữ liệu"
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<mẫu>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<mẫu>...]"
msgid ""
"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
@@ -11911,10 +12095,10 @@ msgstr "tham chiếu không tồn tại"
msgid "failed to look up reference"
msgstr "gặp lỗi khi tìm tham chiếu"
-msgid "only show tags (can be combined with heads)"
-msgstr "chỉ hiển thị thẻ (có thể tổ hợp cùng với đầu)"
+msgid "only show tags (can be combined with branches)"
+msgstr "chỉ hiển thị thẻ (có thể tổ hợp cùng với nhánh)"
-msgid "only show heads (can be combined with tags)"
+msgid "only show branches (can be combined with tags)"
msgstr "chỉ hiển thị đầu (có thể tổ hợp cùng với thẻ)"
msgid "check for reference existence without resolving"
@@ -12229,7 +12413,7 @@ msgid "\"git stash store\" requires one <commit> argument"
msgstr "\"git stash store\" cần một đối số <lần chuyển giao>"
msgid "No staged changes"
-msgstr "Không có thay đổi đã được đưa lên bệ phóng"
+msgstr "Không có thay đổi đã được đưa vào vùng chờ"
msgid "No changes selected"
msgstr "Chưa có thay đổi nào được chọn"
@@ -12247,7 +12431,7 @@ msgid "Cannot save the current worktree state"
msgstr "Không thể ghi lại trạng thái cây-làm-việc hiện hành"
msgid "Cannot save the current staged state"
-msgstr "Không thể ghi lại trạng thái bệ phóng hiện hành"
+msgstr "Không thể ghi lại trạng thái vùng chờ hiện hành"
msgid "Cannot record working tree state"
msgstr "Không thể ghi lại trạng thái cây làm việc hiện hành"
@@ -12281,7 +12465,7 @@ msgid "keep index"
msgstr "giữ nguyên chỉ mục"
msgid "stash staged changes only"
-msgstr "chỉ tạm cất đi các thay đổi đã đưa lên bệ phóng"
+msgstr "chỉ tạm cất đi các thay đổi đã đưa vào vùng chờ"
msgid "stash in patch mode"
msgstr "cất đi ở chế độ vá"
@@ -12344,7 +12528,7 @@ msgstr ""
"."
msgid "suppress output of entering each submodule command"
-msgstr "chặn kết xuất của từng lệnh mô-đun-con"
+msgstr "chặn đầu ra của từng lệnh mô-đun-con"
msgid "recurse into nested submodules"
msgstr "đệ quy vào trong mô-đun-con lồng nhau"
@@ -12369,7 +12553,7 @@ msgid "Failed to register update mode for submodule path '%s'"
msgstr "Gặp lỗi khi đăng ký chế độ cập nhật cho đường dẫn mô-đun-con '%s'"
msgid "suppress output for initializing a submodule"
-msgstr "chặn kết xuất của khởi tạo một mô-đun-con"
+msgstr "chặn đầu ra của khởi tạo một mô-đun-con"
msgid "git submodule init [<options>] [<path>]"
msgstr "git submodule init [<các tùy chọn>] [</đường/dẫn>]"
@@ -12389,7 +12573,7 @@ msgid "failed to recurse into submodule '%s'"
msgstr "gặp lỗi khi đệ quy vào trong mô-đun-con '%s'"
msgid "suppress submodule status output"
-msgstr "chặn kết xuất về tình trạng mô-đun-con"
+msgstr "chặn đầu ra về tình trạng mô-đun-con"
msgid ""
"use commit stored in the index instead of the one stored in the submodule "
@@ -12458,7 +12642,7 @@ msgid "failed to update remote for submodule '%s'"
msgstr "gặp lỗi khi cập nhật cho mô-đun-con '%s'"
msgid "suppress output of synchronizing submodule url"
-msgstr "chặn kết xuất của url mô-đun-con đồng bộ"
+msgstr "chặn đầu ra của url mô-đun-con đồng bộ"
msgid "git submodule sync [--quiet] [--recursive] [<path>]"
msgstr "git submodule sync [--quiet] [--recursive] [</đường/dẫn>]"
@@ -12545,14 +12729,14 @@ msgid "refusing to create/use '%s' in another submodule's git dir"
msgstr "từ chối tạo/dùng '%s' trong một thư mục git của mô đun con"
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "việc sao '%s' vào đường dẫn mô-đun-con '%s' gặp lỗi"
-
-#, c-format
msgid "directory not empty: '%s'"
msgstr "thư mục không trống: '%s'"
#, c-format
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "việc sao '%s' vào đường dẫn mô-đun-con '%s' gặp lỗi"
+
+#, c-format
msgid "could not get submodule directory for '%s'"
msgstr "không thể lấy thư mục mô-đun-con cho '%s'"
@@ -12902,7 +13086,7 @@ msgid "delete symbolic ref"
msgstr "xóa tham chiếu mềm"
msgid "shorten ref output"
-msgstr "làm ngắn kết xuất ref (tham chiếu)"
+msgstr "làm ngắn kết quả ref (tham chiếu)"
msgid "recursively dereference (default)"
msgstr "chế độ giải tham chiếu đệ quy (mặc định)"
@@ -12915,9 +13099,11 @@ msgstr "lý do cập nhật"
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <tập-tin>] [-e]\n"
+" [(--trailer <token>[(=|:)<giá-trị>])...]\n"
" <tên-thẻ> [<lần chuyển giao> | <đối tượng> ]"
msgid "git tag -d <tagname>..."
@@ -13353,7 +13539,7 @@ msgid "print commit contents"
msgstr "hiển thị nội dung của lần chuyển giao"
msgid "print raw gpg status output"
-msgstr "in kết xuất trạng thái gpg dạng thô"
+msgstr "in đầu ra trạng thái gpg dạng thô"
msgid "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idx..."
msgstr "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <gói>.idx..."
@@ -13764,9 +13950,6 @@ msgstr "phần đầu không được thừa nhận: %s%s (%d)"
msgid "Repository lacks these prerequisite commits:"
msgstr "Kho chứa thiếu những lần chuyển giao tiên quyết này:"
-msgid "need a repository to verify a bundle"
-msgstr "cần một kho chứa để thẩm tra một bundle"
-
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -14029,7 +14212,7 @@ msgstr ""
"Rút trích mã số lần chuyển giao từ một kho nén đã được tạo bởi git-archive"
msgid "Print lines matching a pattern"
-msgstr "In ra những dòng khớp với một mẫu"
+msgstr "In ra những dòng khớp với mẫu"
msgid "A portable graphical interface to Git"
msgstr "Một giao diện đồ họa khả chuyển cho Git"
@@ -14174,6 +14357,9 @@ msgstr "Nhận cái mà được đẩy vào trong kho"
msgid "Manage reflog information"
msgstr "Quản lý thông tin reflog"
+msgid "Low-level access to refs"
+msgstr "Truy cập tới tham chiếu ở mức thấp"
+
msgid "Manage set of tracked repositories"
msgstr "Quản lý tập hợp các kho chứa đã được theo dõi"
@@ -14219,16 +14405,16 @@ msgid "Push objects over Git protocol to another repository"
msgstr "Đẩy các đối tượng lên thông qua giao thức Git đến kho chứa khác"
msgid "Git's i18n setup code for shell scripts"
-msgstr "Mã cài đặt quốc tế hóa của Git cho văn lệnh hệ vỏ"
+msgstr "Mã cài đặt quốc tế hóa của Git cho shell script"
msgid "Common Git shell script setup code"
-msgstr "Mã cài đặt văn lệnh hệ vỏ Git chung"
+msgstr "Mã cài đặt shell script Git chung"
msgid "Restricted login shell for Git-only SSH access"
-msgstr "Hệ vỏ đăng nhập có hạn chế cho truy cập SSH chỉ-Git"
+msgstr "Shell đăng nhập có hạn chế cho truy cập SSH chỉ-Git"
msgid "Summarize 'git log' output"
-msgstr "Kết xuất 'git log' dạng tóm tắt"
+msgstr "Tóm tắt kết quả 'git log'"
msgid "Show various types of objects"
msgstr "Hiển thị các kiểu khác nhau của các đối tượng"
@@ -14248,7 +14434,7 @@ msgstr ""
"dõi"
msgid "Add file contents to the staging area"
-msgstr "Thêm nội dung tập tin vào vùng bệ phóng"
+msgstr "Thêm nội dung tập tin vào vùng vùng chờ"
msgid "Stash the changes in a dirty working directory away"
msgstr "Tạm cất đi các thay đổi trong một thư mục làm việc bẩn"
@@ -14266,7 +14452,7 @@ msgid "Bidirectional operation between a Subversion repository and Git"
msgstr "Thao tác hai hướng giữ hai kho Subversion và Git"
msgid "Switch branches"
-msgstr "Các nhánh chuyển"
+msgstr "Chuyển sang nhánh khác"
msgid "Read, modify and delete symbolic refs"
msgstr "Đọc, sửa và xóa tham chiếu mềm"
@@ -14335,7 +14521,7 @@ msgid "Git for CVS users"
msgstr "Git dành cho những người dùng CVS"
msgid "Tweaking diff output"
-msgstr "Chỉnh kết xuất diff"
+msgstr "Tinh chỉnh đầu ra diff"
msgid "A useful minimum set of commands for Everyday Git"
msgstr "Tập hợp lệnh hữu dụng tối thiểu để dùng Git hàng ngày"
@@ -14478,6 +14664,14 @@ msgstr "đồ-thị-chuyển-giao thiếu chunk OID lookup cần thiết hoặc
msgid "commit-graph required commit data chunk missing or corrupted"
msgstr "đồ-thị-chuyển-giao thiếu chunk commit data cần thiết hoặc bị hỏng"
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr ""
+"vô hiệu hoá bộ lọc Bloom cho đồ thị chuyển giao '%s' do tuỳ chọn không tương "
+"thích"
+
msgid "commit-graph has no base graphs chunk"
msgstr "đồ thị chuyển giao không có chunk đồ thị cơ sở"
@@ -14604,8 +14798,15 @@ msgstr "Đang hòa trộn đồ-thị-chuyển-giao"
msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr ""
-"cố gắng để ghi một đồ thị các lần chuyển giao, nhưng 'core.commitGraph' bị "
-"vô hiệu hóa"
+"đang thử ghi đồ thị chuyển giao, nhưng 'core.commitGraph' bị vô hiệu hóa"
+
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr ""
+"đang thử ghi đồ thị chuyển giao, nhưng 'commitGraph.changedPathsVersion' "
+"(%d) không được hỗ trợ"
msgid "too many commits to write graph"
msgstr "có quá nhiều lần chuyển giao để ghi đồ thị"
@@ -15765,7 +15966,7 @@ msgid "bad --word-diff argument: %s"
msgstr "đối số --word-diff sai: %s"
msgid "Diff output format options"
-msgstr "Các tùy chọn định dạng khi xuất các khác biệt"
+msgstr "Các tùy chọn định dạng kết quả khác biệt"
msgid "generate patch"
msgstr "tạo bản vá"
@@ -15789,14 +15990,14 @@ msgid "machine friendly --stat"
msgstr "--stat thuận tiện cho máy đọc"
msgid "output only the last line of --stat"
-msgstr "chỉ xuất những dòng cuối của --stat"
+msgstr "chỉ in ra những dòng cuối của --stat"
msgid "<param1>,<param2>..."
msgstr "<tham_số_1>,<tham_số_2>..."
msgid ""
"output the distribution of relative amount of changes for each sub-directory"
-msgstr "đầu ra phân phối của số lượng thay đổi tương đối cho mỗi thư mục con"
+msgstr "in ra phân phối số lượng thay đổi tương đối cho mỗi thư mục con"
msgid "synonym for --dirstat=cumulative"
msgstr "đồng nghĩa với --dirstat=cumulative"
@@ -15845,7 +16046,7 @@ msgid "generate compact summary in diffstat"
msgstr "tạo tổng hợp xúc tích trong diffstat"
msgid "output a binary diff that can be applied"
-msgstr "xuất ra một khác biệt dạng nhị phân cái mà có thể được áp dụng"
+msgstr "in ra một khác biệt dạng nhị phân có thể được áp dụng"
msgid "show full pre- and post-image object names on the \"index\" lines"
msgstr ""
@@ -15882,7 +16083,7 @@ msgid "show the given destination prefix instead of \"b/\""
msgstr "hiển thị tiền tố đích đã cho thay cho \"b/\""
msgid "prepend an additional prefix to every line of output"
-msgstr "treo vào trước một tiền tố bổ sung cho mỗi dòng kết xuất"
+msgstr "thêm vào trước một tiền tố bổ sung cho mỗi dòng đầu ra"
msgid "do not show any source or destination prefix"
msgstr "đừng hiển thị bất kỳ tiền tố nguồn hay đích"
@@ -16023,7 +16224,7 @@ msgid "exit with 1 if there were differences, 0 otherwise"
msgstr "thoát với mã 1 nếu không có khác biệt gì, 0 nếu ngược lại"
msgid "disable all output of the program"
-msgstr "tắt mọi kết xuất của chương trình"
+msgstr "tắt mọi đầu ra của chương trình"
msgid "allow an external diff helper to be executed"
msgstr "cho phép mộ helper xuất khác biệt ở bên ngoài được phép thực thi"
@@ -16075,7 +16276,7 @@ msgid "treat <string> in -S as extended POSIX regular expression"
msgstr "coi <chuỗi> trong -S là biểu thức chính quy POSIX mở rộng"
msgid "control the order in which files appear in the output"
-msgstr "điều khiển thứ tự xuất hiện các tập tin trong đầu ra"
+msgstr "điều khiển thứ tự xuất hiện các tập tin trong kết quả"
msgid "<path>"
msgstr "<đường-dẫn>"
@@ -16084,7 +16285,7 @@ msgid "show the change in the specified path first"
msgstr "hiển thị các thay đổi trong đường dẫn đã cho ở đầu"
msgid "skip the output to the specified path"
-msgstr "bỏ qua đầu ra với đường dẫn đã cho"
+msgstr "bỏ qua kết quả với đường dẫn đã cho"
msgid "<object-id>"
msgstr "<mã-số-đối-tượng>"
@@ -16284,7 +16485,7 @@ msgid "fetch-pack: unable to fork off %s"
msgstr "fetch-pack: không thể rẽ nhánh %s"
msgid "fetch-pack: invalid index-pack output"
-msgstr "fetch-pack: kết xuất index-pack không hợp lệ"
+msgstr "fetch-pack: đầu ra index-pack không hợp lệ"
#, c-format
msgid "%s failed"
@@ -16441,19 +16642,23 @@ msgstr ""
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C </đường/dẫn/>] [-c <tên>=<giá trị>]\n"
" [--exec-path[=</đường/dẫn/>]] [--html-path] [--man-path] [--info-"
"path]\n"
-" [-p | --paginate | -P --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=</đường/dẫn/>] [--work-tree=</đường/dẫn/>] [--"
-"namespace=<tên>]\n"
-" [--config-env=<tên>=<envvar>] <lệnh> [<các tham số>]"
+" [-p | --paginate | -P --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=</đường/"
+"dẫn/>]\n"
+" [--work-tree=</đường/dẫn/>] [--namespace=<tên>] [--config-"
+"env=<tên>=<envvar>]\n"
+" <lệnh> [<các tham số>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -16780,16 +16985,16 @@ msgid ""
"The '%s' hook was ignored because it's not set as executable.\n"
"You can disable this warning with `git config advice.ignoredHook false`."
msgstr ""
-"Móc '%s' bị bỏ qua bởi vì nó không thể đặt là thực thi được.\n"
+"Móc '%s' bị bỏ qua bởi vì nó không có cờ thực thi được.\n"
"Bạn có thể tắt cảnh báo này bằng 'git config advice.ignoredHook false'."
+msgid "not a git repository"
+msgstr "không phải là kho git"
+
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "tham số cho --packfile phải là một giá trị băm hợp lệ (có '%s')"
-msgid "not a git repository"
-msgstr "không phải là kho git"
-
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
msgstr "giá trị âm cho http.postBuffer; đặt thành mặc định là %d"
@@ -16800,6 +17005,9 @@ msgstr "Điều khiển giao quyền không được hỗ trợ với cURL < 7.2
msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "Chốt khóa công không được hỗ trợ với cURL < 7.39.0"
+msgid "Unknown value for http.proactiveauth"
+msgstr "không hiểu giá trị cho http.proactiveauth"
+
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "CURLSSLOPT_NO_REVOKE không được hỗ trợ với cURL < 7.44.0"
@@ -16819,6 +17027,12 @@ msgstr ""
msgid "Could not set SSL backend to '%s': already set"
msgstr "Không thể đặt ứng dụng chạy sau SSL cho '%s': đã đặt rồi"
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "từ chối đọc cookie từ http.cookiefile '-'"
+
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "bỏ qua tuỳ chọn http.savecookies vì http.cookiefile để trống"
+
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -16992,8 +17206,8 @@ msgid "Failed to merge submodule %s (commits not present)"
msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (lần chuyển giao không hiện diện)"
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (kho chứa hỏng)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "lỗi: gặp lỗi khi hòa trộn mô-đun-con %s (kho chứa hỏng)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -17022,12 +17236,13 @@ msgstr ""
"Gặp lỗi khi hòa trộn mô-đun-con %s, nhưng có nhiều cách giải quyết:\n"
"%s"
-msgid "failed to execute internal merge"
-msgstr "Gặp lỗi khi thực hiện trộn nội bộ"
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "lỗi: Gặp lỗi khi thực hiện trộn nội bộ %s"
#, c-format
-msgid "unable to add %s to database"
-msgstr "Không thể thêm %s vào cơ sở dữ liệu"
+msgid "error: unable to add %s to database"
+msgstr "lỗi: không thể thêm %s vào cơ sở dữ liệu"
#, c-format
msgid "Auto-merging %s"
@@ -17120,20 +17335,20 @@ msgstr ""
"XUNG ĐỘT (đổi-tên/xóa): Đổi tên %s->%s trong %s, nhưng lại bị xóa trong %s."
#, c-format
-msgid "cannot read object %s"
-msgstr "không thể đọc đối tượng %s"
+msgid "error: cannot read object %s"
+msgstr "lỗi: không thể đọc đối tượng %s"
#, c-format
-msgid "object %s is not a blob"
-msgstr "đối tượng %s không phải là một blob"
+msgid "error: object %s is not a blob"
+msgstr "lỗi: đối tượng %s không phải là một blob"
#, c-format
msgid ""
"CONFLICT (file/directory): directory in the way of %s from %s; moving it to "
"%s instead."
msgstr ""
-"XUNG ĐỘT (tập tin/thư mục): thư mục theo cách của %s từ %s; thay vào đó, di "
-"chuyển nó đến %s."
+"XUNG ĐỘT (tập tin/thư mục): thư mục khác nằm trên %s từ %s; thay vào đó sẽ "
+"di chuyển nó đến %s."
#, c-format
msgid ""
@@ -17141,15 +17356,15 @@ msgid ""
"of them so each can be recorded somewhere."
msgstr ""
"XUNG ĐỘT (các kiểu riêng biệt): %s có các kiểu khác nhau ở mỗi bên; đã đổi "
-"tên cả hai trong số chúng để mỗi cái có thể được ghi lại ở đâu đó."
+"tên cả hai để có thể ghi lại cả hai."
#, c-format
msgid ""
"CONFLICT (distinct types): %s had different types on each side; renamed one "
"of them so each can be recorded somewhere."
msgstr ""
-"XUNG ĐỘT (các kiểu riêng biệt): %s có các loại khác nhau ở mỗi bên; đã đổi "
-"tên một trong số chúng để mỗi cái có thể được ghi lại ở đâu đó."
+"XUNG ĐỘT (các kiểu riêng biệt): %s có các kiểu khác nhau ở mỗi bên; đã đổi "
+"tên một trong số chúng để có thể ghi lại cả hai."
msgid "content"
msgstr "nội dung"
@@ -17262,6 +17477,10 @@ msgid "do not know what to do with %06o %s '%s'"
msgstr "không hiểu phải làm gì với %06o %s '%s'"
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (kho chứa hỏng)"
+
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "Chuyển-tiếp-nhanh mô-đun-con '%s' đến lần chuyển giao sau đây:"
@@ -17302,6 +17521,13 @@ msgstr ""
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Gặp lỗi khi hòa trộn mô-đun-con '%s' (thấy nhiều hòa trộn đa trùng)"
+msgid "failed to execute internal merge"
+msgstr "Gặp lỗi khi thực hiện trộn nội bộ"
+
+#, c-format
+msgid "unable to add %s to database"
+msgstr "Không thể thêm %s vào cơ sở dữ liệu"
+
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr ""
@@ -17405,6 +17631,14 @@ msgstr ""
"XUNG ĐỘT (đổi-tên/đổi-tên): Đổi tên thư mục %s->%s trong %s. Đổi tên thư mục "
"%s->%s trong %s"
+#, c-format
+msgid "cannot read object %s"
+msgstr "không thể đọc đối tượng %s"
+
+#, c-format
+msgid "object %s is not a blob"
+msgstr "đối tượng %s không phải là một blob"
+
msgid "modify"
msgstr "sửa đổi"
@@ -17488,9 +17722,6 @@ msgstr "không hiểu cú pháp dòng: %s"
msgid "malformed line: %s"
msgstr "dòng sai quy cách: %s"
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "bỏ qua multi-pack-index sẵn có; tổng kiểm không khớp"
-
msgid "could not load pack"
msgstr "không thể tải gói"
@@ -17498,6 +17729,9 @@ msgstr "không thể tải gói"
msgid "could not open index for %s"
msgstr "không thể mở chỉ mục cho %s"
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "bỏ qua multi-pack-index sẵn có; tổng kiểm không khớp"
+
msgid "Adding packfiles to multi-pack-index"
msgstr "Đang thêm tập tin gói từ multi-pack-index"
@@ -18103,6 +18337,17 @@ msgstr "không thể đọc đối tượng: '%s'"
msgid "hash mismatch %s"
msgstr "mã băm không khớp %s"
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "đối tượng trùng lặp khi ghi chỉ mục bitmap: %s"
+
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "đã cố ghi lần chuyển giao không được chọn: '%s'"
+
+msgid "too many pseudo-merges"
+msgstr "có quá nhiều lần pseudo-merge"
+
msgid "trying to write commit not in index"
msgstr "đã thử ghi lần chuyển giao nằm ngoài chỉ mục"
@@ -18125,6 +18370,17 @@ msgstr "tập tin chỉ mục bitmap bị hỏng (quá ngắn để chứa bộ
msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr "tập tin chỉ mục bitmap bị hỏng (quá ngắn để chứa bảng tìm kiếm)"
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr ""
+"tập tin chỉ mục bitmap bị hỏng (quá ngắn để chứa đề mục bảng pseudo-merge)"
+
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr "tập tin chỉ mục bitmap bị hỏng (quá ngắn để chứa bảng pseudo-merge)"
+
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "tập tin chỉ mục bitmap bị hỏng, bảng pseudo-merge quá ngắn"
+
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "đối tượng trùng lặp trong bitmap: '%s'"
@@ -18215,6 +18471,10 @@ msgid "mismatch in bitmap results"
msgstr "kết quả bitmap không khớp"
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "chỉ mục pseudo-merge vượt ngoài phạm vi (%<PRIu32> >= %<PRIuMAX>)"
+
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "không thể tìm thấy '%s' trong gói '%s' tại vị trí %<PRIuMAX>"
@@ -18579,6 +18839,9 @@ msgstr "không thể tạo tiến trình lstat: %s"
msgid "unable to parse --pretty format"
msgstr "không thể đọc định dạng --pretty"
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "vô hiệu lazy fetching; một số đối tượng sẽ không có sẵn"
+
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote: không thể rẽ nhánh tuyến trình con fetch"
@@ -18602,6 +18865,62 @@ msgstr "object-info: cần đẩy dữ liệu lên đĩa sau các tham số"
msgid "Removing duplicate objects"
msgstr "Đang gỡ các đối tượng trùng lặp"
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "gặp lỗi khi đọc biểu thức chính quy pseudo-merge cho %s: '%s'"
+
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s phải không âm, dùng mặc định thay thế"
+
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s nên giữa 0 và 1, dùng mặc định thay thế"
+
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s phải dương, dùng mặc định thay thế"
+
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "nhóm pseudo-merge '%s' thiếu mẫu bắt buộc"
+
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr "nhóm pseudo-merge '%s' có unstable threshold trước stable"
+
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr ""
+"biểu thức chính quy pseudo-merge từ cấu hình có quá nhiều nhóm chọn (tối "
+"đa=%<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "extended pseudo-merge đọc ngoài biên (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "mục extended pseudo-merge quá ngắn (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr ""
+"không thể tìm pseudo-merge cho lần chuyển giao %s tại vị trí %<PRIuMAX>"
+
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr "extended pseudo-merge lookup vượt ngoài biên (%<PRIu32> >= %<PRIu32>)"
+
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "đọc ngoài biên (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "không thể đọc bảng extended pseudo-merge cho lần chuyển giao %s"
+
msgid "could not start `log`"
msgstr "không thể khởi chạy `log`"
@@ -18844,7 +19163,7 @@ msgstr ""
" chỉ giữ ghi chú của lần chuyển giao này; -c giống như -C "
"nhưng\n"
" mở trình biên soạn\n"
-"x, exec <commit> = chạy lệnh (phần còn lại của dòng) dùng hệ vỏ\n"
+"x, exec <commit> = chạy lệnh (phần còn lại của dòng) dùng shell\n"
"b, break = dừng tại đây (tiếp tục cải tổ sau này bằng 'git rebase --"
"continue')\n"
"d, drop <commit> = xóa bỏ lần chuyển giao\n"
@@ -19206,11 +19525,18 @@ msgstr "nhật ký cho tham chiếu %s kết thúc bất ngờ trên %s"
msgid "log for %s is empty"
msgstr "nhật ký cho %s trống rỗng"
+msgid "refusing to force and skip creation of reflog"
+msgstr "từ chối bỏ qua việc tạo log tham chiếu"
+
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "từ chối cập nhật tham chiếu với tên sai '%s'"
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "từ chối cập nhật tham chiếu ảo '%s'"
+
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "update_ref bị lỗi cho ref '%s': %s"
@@ -19241,6 +19567,25 @@ msgid "could not delete references: %s"
msgstr "không thể xóa bỏ tham chiếu: %s"
#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "Đã hoàn thành thử chạy di cư tham chiếu, kết quả tại '%s'\n"
+
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "không thể xoá thư mục tạm thời '%s'"
+
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "ydam chiếu đã di cư tại '%s'"
+
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr ""
+"không thể lock tham chiếu '%s': cần tham chiếu mềm tới '%s': nhưng lại là "
+"tham chiếu thường"
+
+#, c-format
msgid "refname is dangerous: %s"
msgstr "tên tham chiếu không an toàn: %s"
@@ -19599,7 +19944,7 @@ msgstr "không thể tìm thấy tham chiếu máy chủ %s"
#, c-format
msgid "* Ignoring funny ref '%s' locally"
-msgstr "* Đang bỏ qua tham chiếu thú vị nội bộ '%s'"
+msgstr "* Đang bỏ qua tham chiếu nội bộ '%s'"
#, c-format
msgid "Your branch is based on '%s', but the upstream is gone.\n"
@@ -20062,9 +20407,9 @@ msgid ""
"To abort and get back to the state before \"git rebase\", run \"git rebase --"
"abort\"."
msgstr ""
-"Giải quyết vấn đề này thủ công, hãy đanh dấu chúng đã được giải quyết bằng\n"
-"hãy chạy lệnh \"git add/rm <các_tập tin_xung_đột>\", sau đó chạy \"git "
-"rebase --continue\".\n"
+"Hãy giải quyết vấn đề này bằng tay, đánh dấu chúng đã được giải quyết bằng\n"
+"lệnh \"git add/rm <các_tập tin_xung_đột>\", sau đó chạy \"git rebase --"
+"continue\".\n"
"Bạn có thể bỏ qua bản vá, chạy \"git rebase --skip\".\n"
"Để huỷ bỏ và quay trở lại trạng thái trước \"git rebase\", chạy \"git rebase "
"--abort\"."
@@ -20183,7 +20528,7 @@ msgid ""
"\n"
" git rebase --continue\n"
msgstr ""
-"bạn có các thay đổi so với trong bệ phóng trong thư mục làm việc của bạn.\n"
+"bạn có các thay đổi so với trong vùng chờ trong thư mục làm việc của bạn.\n"
"Nếu các thay đổi này là muốn squash vào lần chuyển giao kế trước, chạy:\n"
"\n"
" git commit --amend %s\n"
@@ -20397,6 +20742,47 @@ msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s"
msgstr "update-ref yêu cầu tên tham chiếu đầy đủ v.d. refs/heads/%s"
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "'%s' không nhận đối số lần chuyển giao hoà trộn"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"'pick' không cho phép dùng lần chuyển giao hoà trộn. Nếu như cần phát lại\n"
+"lần hoà trộn, hày dùng 'merge -C'."
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"'reword' không cho phép dùng lần chuyển giao hoà trộn. Nếu như cần phát lại\n"
+"lần hoà trộn và sửa nội dung, hãy dùng 'merge -c'."
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"'pick' không cho phép dùng lần chuyển giao hoà trộn. Nếu như cần phát lại\n"
+"lần hoà trộn, hày dùng 'merge -C', sau đó 'break' để dùng lệnh\n"
+"'git commit --amend && git rebase --continue'."
+
+msgid "cannot squash merge commit into another commit"
+msgstr "không thể squash lần chuyển giao hoà trộn vào lần chuyển giao khác"
+
+#, c-format
msgid "invalid command '%.*s'"
msgstr "lệnh không hợp lệ '%.*s'"
@@ -20512,9 +20898,8 @@ msgstr ""
msgid "cannot read HEAD"
msgstr "không thể đọc HEAD"
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "không thể sao chép '%s' sang '%s'"
+msgid "could not write commit message file"
+msgstr "không thể ghi tập tin chú thích lần chuyển giao"
#, c-format
msgid ""
@@ -20744,7 +21129,7 @@ msgid "Successfully rebased and updated %s.\n"
msgstr "Cài tổ và cập nhật %s một cách thành công.\n"
msgid "cannot rebase: You have unstaged changes."
-msgstr "không thể cải tổ: Bạn có các thay đổi chưa được đưa lên bệ phóng."
+msgstr "không thể cải tổ: Bạn có các thay đổi chưa được đưa vào vùng chờ."
msgid "cannot amend non-existing commit"
msgstr "không thể tu sửa lần chuyển giao không tồn tại"
@@ -20774,7 +21159,7 @@ msgid "could not remove CHERRY_PICK_HEAD"
msgstr "không thể xóa bỏ CHERRY_PICK_HEAD"
msgid "could not commit staged changes."
-msgstr "không thể chuyển giao các thay đổi đã đưa lên bệ phóng."
+msgstr "không thể chuyển giao các thay đổi đã đưa vào vùng chờ."
#, c-format
msgid "%s: can't cherry-pick a %s"
@@ -20915,6 +21300,18 @@ msgstr "không thể quay lại thư mục làm việc hiện hành"
msgid "failed to stat '%*s%s%s'"
msgstr "gặp lỗi khi stat'%*s%s%s'"
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"kho lưu trữ '%s' thuộc sở hữu của người khác\n"
+"%sĐể thêm ngoại lệ cho thư mục này, hãy gọi:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
msgid "Unable to read current working directory"
msgstr "Không thể đọc thư mục làm việc hiện hành"
@@ -20937,18 +21334,6 @@ msgstr ""
"được đặt)."
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"kho lưu trữ '%s' thuộc sở hữu của người khác\n"
-"%sĐể thêm ngoại lệ cho thư mục này, hãy gọi:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr "không thể dùng kho chứa bare '%s' (safe.bareRepository là '%s')"
@@ -21249,6 +21634,15 @@ msgid "submodule git dir '%s' is inside git dir '%.*s'"
msgstr "thư mục git mô đun con '%s' là bên trong git DIR '%.*s'"
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr ""
+"cần '%.*s' trong đường dẫn tới mô-đun-con '%s' không phải là liên kết mềm"
+
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "cần đường dẫn tới mô-đun-con '%s' không phải là liên kết mềm"
+
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr ""
@@ -21287,10 +21681,6 @@ msgstr "gặp lỗi khi lstat '%s'"
msgid "no remote configured to get bundle URIs from"
msgstr "không có máy chủ để lấy URI bundle"
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "máy chủ '%s' không có cấu hình URL"
-
msgid "could not get the bundle-uri list"
msgstr "không thể lấy về danh sách bundle-uri"
@@ -21915,7 +22305,7 @@ msgid "error: unable to format message: %s\n"
msgstr "lỗi: không thể định dạng thông điệp: %s\n"
msgid "usage: "
-msgstr "cách dùng: %s"
+msgstr "cách dùng: "
msgid "fatal: "
msgstr "lỗi nghiêm trọng: "
@@ -22033,7 +22423,7 @@ msgid "Unmerged paths:"
msgstr "Những đường dẫn chưa được hòa trộn:"
msgid " (use \"git restore --staged <file>...\" to unstage)"
-msgstr " (dùng \"git restore --staged <tập-tin>...\" để bỏ ra khỏi bệ phóng)"
+msgstr " (dùng \"git restore --staged <tập-tin>...\" để bỏ ra khỏi vùng chờ)"
#, c-format
msgid " (use \"git restore --source=%s --staged <file>...\" to unstage)"
@@ -22042,7 +22432,7 @@ msgstr ""
"phóng)"
msgid " (use \"git rm --cached <file>...\" to unstage)"
-msgstr " (dùng \"git rm --cached <tập-tin>...\" để bỏ ra khỏi bệ phóng)"
+msgstr " (dùng \"git rm --cached <tập-tin>...\" để bỏ ra khỏi vùng chờ)"
msgid " (use \"git add <file>...\" to mark resolution)"
msgstr " (dùng \"git add <tập-tin>...\" để đánh dấu là muốn thêm)"
@@ -22057,7 +22447,7 @@ msgid "Changes to be committed:"
msgstr "Những thay đổi sẽ được chuyển giao:"
msgid "Changes not staged for commit:"
-msgstr "Các thay đổi chưa được đặt lên bệ phóng để chuyển giao:"
+msgstr "Các thay đổi chưa được đặt vào vùng chờ để chuyển giao:"
msgid " (use \"git add <file>...\" to update what will be committed)"
msgstr ""
@@ -22465,7 +22855,7 @@ msgstr "đứng trước "
#. TRANSLATORS: the action is e.g. "pull with rebase"
#, c-format
msgid "cannot %s: You have unstaged changes."
-msgstr "không thể %s: Bạn có các thay đổi chưa được đưa lên bệ phóng."
+msgstr "không thể %s: Bạn có các thay đổi chưa được đưa vào vùng chờ."
msgid "additionally, your index contains uncommitted changes."
msgstr "ngoài ra, chỉ mục của bạn có chứa các thay đổi chưa được chuyển giao."
@@ -22526,11 +22916,11 @@ msgstr ""
msgid "Cannot rewrite branches: You have unstaged changes."
msgstr ""
-"Không thể ghi lại các nhánh: Bạn có các thay đổi chưa được đưa lên bệ phóng."
+"Không thể ghi lại các nhánh: Bạn có các thay đổi chưa được đưa vào vùng chờ."
#, sh-format
msgid "Cannot $action: You have unstaged changes."
-msgstr "Không thể $action: Bạn có các thay đổi chưa được đưa lên bệ phóng."
+msgstr "Không thể $action: Bạn có các thay đổi chưa được đưa vào vùng chờ."
#, sh-format
msgid "Cannot $action: Your index contains uncommitted changes."
@@ -22751,7 +23141,7 @@ msgstr ""
#. translation. The program will only accept English input
#. at this point.
msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
-msgstr "Gửi email này chứ? ([y]có|[n]không|[e]sửa|[q]thoát|[a]tất): "
+msgstr "Gửi email này chứ? ([y]có|[n]không|[e]sửa|[q]thoát|[a]tất cả): "
msgid "Send this email reply required"
msgstr "Hãy trả lời yêu cầu gửi email"
@@ -22776,24 +23166,24 @@ msgid "Failed to send %s\n"
msgstr "Gặp lỗi khi gửi %s\n"
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "Thử gửi %s\n"
+msgid "Dry-Sent %s"
+msgstr "Thử gửi %s"
#, perl-format
-msgid "Sent %s\n"
-msgstr "Gửi %s\n"
+msgid "Sent %s"
+msgstr "Gửi %s"
-msgid "Dry-OK. Log says:\n"
-msgstr "Thử gửi OK. Nhật ký ghi lại:\n"
+msgid "Dry-OK. Log says:"
+msgstr "Thử gửi OK. Nhật ký ghi lại:"
-msgid "OK. Log says:\n"
-msgstr "OK. Nhật ký ghi lại:\n"
+msgid "OK. Log says:"
+msgstr "OK. Nhật ký ghi lại:"
msgid "Result: "
msgstr "Kết quả: "
-msgid "Result: OK\n"
-msgstr "Kết quả: OK\n"
+msgid "Result: OK"
+msgstr "Kết quả: OK"
#, perl-format
msgid "can't open file %s"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 4838c19b0b..91b8b79de8 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -154,8 +154,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-28 19:59+0800\n"
-"PO-Revision-Date: 2024-04-28 20:31+0800\n"
+"POT-Creation-Date: 2024-07-27 22:28+0800\n"
+"PO-Revision-Date: 2024-07-28 19:52+0800\n"
"Last-Translator: Teng Long <dyroneteng@gmail.com>\n"
"Language-Team: GitHub <https://github.com/dyrone/git/>\n"
"Language: zh_CN\n"
@@ -252,12 +252,12 @@ msgstr[1] "增加了 %d 个路径\n"
msgid "ignoring unmerged: %s"
msgstr "忽略未合入的:%s"
-#: add-interactive.c add-patch.c
+#: add-interactive.c
#, c-format
msgid "Only binary files changed.\n"
msgstr "只有二进制文件被修改。\n"
-#: add-interactive.c add-patch.c
+#: add-interactive.c
#, c-format
msgid "No changes.\n"
msgstr "没有修改。\n"
@@ -799,6 +799,11 @@ msgstr ""
"? - 显示帮助\n"
#: add-patch.c
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "预期只有一个字母,得到 '%s'"
+
+#: add-patch.c
msgid "No previous hunk"
msgstr "没有前一个块"
@@ -861,9 +866,22 @@ msgid "Sorry, cannot edit this hunk"
msgstr "对不起,不能编辑这个块"
#: add-patch.c
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "未知命令 '%s'(使用 '?' 寻求帮助)"
+
+#: add-patch.c
msgid "'git apply' failed"
msgstr "'git apply' 失败"
+#: add-patch.c
+msgid "No changes."
+msgstr "没有修改。"
+
+#: add-patch.c
+msgid "Only binary files changed."
+msgstr "只有二进制文件被修改。"
+
#: advice.c
#, c-format
msgid ""
@@ -1036,7 +1054,7 @@ msgid "unclosed quote"
msgstr "未关闭的引号"
#: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c
-#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c
+#: builtin/receive-pack.c builtin/refs.c builtin/tag.c t/helper/test-pkt-line.c
msgid "too many arguments"
msgstr "太多参数"
@@ -1918,6 +1936,10 @@ msgid "ignoring overly large gitattributes blob '%s'"
msgstr "忽略过大的 gitattributes 数据对象 '%s'"
#: attr.c
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "无法在没有存储库的情况下使用 --attr-source 或 GIT_ATTR_SOURCE"
+
+#: attr.c
msgid "bad --attr-source or GIT_ATTR_SOURCE"
msgstr "错误的 --attr-source 或 GIT_ATTR_SOURCE"
@@ -2278,14 +2300,6 @@ msgid "Unstaged changes after refreshing the index:"
msgstr "刷新索引之后尚未被暂存的变更:"
#: builtin/add.c
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"设置 add.interactive.useBuiltin 已经被移除!\n"
-"查看 'git help config' 中的相关条目以获取更多信息。"
-
-#: builtin/add.c
msgid "could not read the index"
msgstr "不能读取索引"
@@ -2720,7 +2734,7 @@ msgid ""
"Not rewinding to ORIG_HEAD"
msgstr "您好像在上一次 'am' 失败后移动了 HEAD。未回退至 ORIG_HEAD"
-#: builtin/am.c builtin/bisect.c worktree.c
+#: builtin/am.c builtin/bisect.c builtin/tag.c worktree.c
#, c-format
msgid "failed to read '%s'"
msgstr "无法读取 '%s'"
@@ -2798,8 +2812,8 @@ msgstr "n"
#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c
-#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c
+#: builtin/tag.c builtin/verify-tag.c
msgid "format"
msgstr "格式"
@@ -2836,6 +2850,10 @@ msgid "show the patch being applied"
msgstr "显示正在应用的补丁"
#: builtin/am.c
+msgid "try to apply current patch again"
+msgstr "尝试再次应用当前补丁"
+
+#: builtin/am.c
msgid "record the empty patch as an empty commit"
msgstr "把空补丁记录为空提交"
@@ -2907,10 +2925,6 @@ msgid "could not redirect output"
msgstr "不能重定向输出"
#: builtin/archive.c
-msgid "git archive: Remote with no URL"
-msgstr "git archive:未提供远程 URL"
-
-#: builtin/archive.c
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive:期望是 ACK/NAK,却得到 flush 包"
@@ -4024,6 +4038,10 @@ msgstr "需要一个仓库来创建归档包。"
msgid "do not show bundle details"
msgstr "不显示归档包的细节"
+#: builtin/bundle.c bundle.c
+msgid "need a repository to verify a bundle"
+msgstr "需要一个仓库来校验一个归档包"
+
#: builtin/bundle.c
#, c-format
msgid "%s is okay\n"
@@ -5064,9 +5082,9 @@ msgstr "交互式清除"
msgid "remove whole directories"
msgstr "删除整个目录"
-#: builtin/clean.c builtin/describe.c builtin/grep.c builtin/log.c
-#: builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c builtin/show-ref.c
-#: ref-filter.h
+#: builtin/clean.c builtin/config.c builtin/describe.c builtin/grep.c
+#: builtin/log.c builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c
+#: builtin/show-ref.c ref-filter.h
msgid "pattern"
msgstr "模式"
@@ -5284,6 +5302,16 @@ msgstr "无法删除 '%s'"
#: builtin/clone.c
#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "无法检查 '%s' 处的硬链接"
+
+#: builtin/clone.c
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "硬链接与 '%s' 处的源不同"
+
+#: builtin/clone.c
+#, c-format
msgid "failed to create link '%s'"
msgstr "无法创建链接 '%s'"
@@ -5358,7 +5386,7 @@ msgstr "太多参数。"
msgid "You must specify a repository to clone."
msgstr "您必须指定一个仓库来克隆。"
-#: builtin/clone.c builtin/init-db.c setup.c
+#: builtin/clone.c builtin/init-db.c builtin/refs.c setup.c
#, c-format
msgid "unknown ref storage format '%s'"
msgstr "未知的引用存储格式 '%s'"
@@ -5967,7 +5995,7 @@ msgstr "%s提交者:%.*s <%.*s>"
msgid "Cannot read index"
msgstr "无法读取索引"
-#: builtin/commit.c
+#: builtin/commit.c builtin/tag.c
msgid "unable to pass trailers to --trailers"
msgstr "无法将尾注传递给 --trailers"
@@ -6177,11 +6205,11 @@ msgstr "使用自动挤压格式的提交说明用以挤压至指定的提交"
msgid "the commit is authored by me now (used with -C/-c/--amend)"
msgstr "现在将该提交的作者改为我(和 -C/-c/--amend 参数共用)"
-#: builtin/commit.c builtin/interpret-trailers.c
+#: builtin/commit.c builtin/interpret-trailers.c builtin/tag.c
msgid "trailer"
msgstr "尾注"
-#: builtin/commit.c
+#: builtin/commit.c builtin/tag.c
msgid "add custom trailer(s)"
msgstr "添加自定义尾注"
@@ -6293,17 +6321,57 @@ msgstr ""
"磁盘配额已耗尽,然后执行 \"git restore --staged :/\" 恢复。"
#: builtin/config.c
-msgid "git config [<options>]"
-msgstr "git config [<选项>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<文件选项>] [<显示选项>] [--includes]"
#: builtin/config.c
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "未能识别的 --type 参数,%s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<文件选项>] [<显示选项>] [--includes] [--all] [--regexp=<正则"
+"表达式>] [--value=<值>] [--fixed-value] [--default=<默认值>] <名称>"
#: builtin/config.c
-msgid "only one type at a time"
-msgstr "一次只能一个类型"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<文件选项>] [--type=<类型>] [--all] [--value=<值>] [--fixed-"
+"value] <名称> <值>"
+
+#: builtin/config.c
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<文件选项>] [--all] [--value=<值>] [--fixed-value] <名称> <"
+"值>"
+
+#: builtin/config.c
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<文件选项>] <旧名称> <新名称>"
+
+#: builtin/config.c
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<文件选项>] <名称>"
+
+#: builtin/config.c
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<文件选项>]"
+
+#: builtin/config.c
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr "git config [<文件选项>] --get-colorbool <名称> [<标准输出为tty>]"
+
+#: builtin/config.c
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<文件选项>] [--type=<类型>] [--comment=<消息>] [--all] [--"
+"value=<值>] [--fixed-value] <名称> <值>"
#: builtin/config.c
msgid "Config file location"
@@ -6338,70 +6406,6 @@ msgid "read config from given blob object"
msgstr "从给定的数据对象读取配置"
#: builtin/config.c
-msgid "Action"
-msgstr "操作"
-
-#: builtin/config.c
-msgid "get value: name [value-pattern]"
-msgstr "获取值:名称 [值模式]"
-
-#: builtin/config.c
-msgid "get all values: key [value-pattern]"
-msgstr "获得所有的值:键 [值模式]"
-
-#: builtin/config.c
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "根据正则表达式获得值:名称正则 [值模式]"
-
-#: builtin/config.c
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "获得 URL 取值:section[.var] URL"
-
-#: builtin/config.c
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "替换所有匹配的变量:名称 值 [值模式]"
-
-#: builtin/config.c
-msgid "add a new variable: name value"
-msgstr "添加一个新的变量:名称 值"
-
-#: builtin/config.c
-msgid "remove a variable: name [value-pattern]"
-msgstr "删除一个变量:名称 [值模式]"
-
-#: builtin/config.c
-msgid "remove all matches: name [value-pattern]"
-msgstr "删除所有匹配项:名称 [值模式]"
-
-#: builtin/config.c
-msgid "rename section: old-name new-name"
-msgstr "重命名小节:old-name new-name"
-
-#: builtin/config.c
-msgid "remove a section: name"
-msgstr "删除一个小节:name"
-
-#: builtin/config.c
-msgid "list all"
-msgstr "列出所有"
-
-#: builtin/config.c
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "在比较值与 '值模式' 时,使用字符串字面比较"
-
-#: builtin/config.c
-msgid "open an editor"
-msgstr "打开一个编辑器"
-
-#: builtin/config.c
-msgid "find the color configured: slot [default]"
-msgstr "获得配置的颜色:配置 [默认]"
-
-#: builtin/config.c
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "获得颜色设置:配置 [stdout-is-tty]"
-
-#: builtin/config.c
msgid "Type"
msgstr "类型"
@@ -6438,8 +6442,8 @@ msgid "value is an expiry date"
msgstr "值是一个到期日期"
#: builtin/config.c
-msgid "Other"
-msgstr "其它"
+msgid "Display options"
+msgstr "显示选项"
#: builtin/config.c
msgid "terminate values with NUL byte"
@@ -6450,10 +6454,6 @@ msgid "show variable names only"
msgstr "只显示变量名"
#: builtin/config.c
-msgid "respect include directives on lookup"
-msgstr "查询时参照 include 指令递归查找"
-
-#: builtin/config.c
msgid "show origin of config (file, standard input, blob, command line)"
msgstr "显示配置的来源(文件、标准输入、数据对象,或命令行)"
@@ -6462,16 +6462,17 @@ msgid "show scope of config (worktree, local, global, system, command)"
msgstr "显示配置的作用域(工作区、本地、全局、系统、命令)"
#: builtin/config.c
-msgid "value"
-msgstr "取值"
+msgid "show config keys in addition to their values"
+msgstr "显示配置键及其值"
#: builtin/config.c
-msgid "with --get, use default value when missing entry"
-msgstr "使用 --get 参数,当缺少设置时使用默认值"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "未能识别的 --type 参数,%s"
#: builtin/config.c
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr "人类可读的注释字符串(# 将根据需要添加到前面)"
+msgid "only one type at a time"
+msgstr "一次只能一个类型"
#: builtin/config.c
#, c-format
@@ -6564,56 +6565,93 @@ msgstr ""
"详情请阅读“git help worktree”的“CONFIGURATION FILE”小节"
#: builtin/config.c
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color 和变量类型不兼容"
+msgid "Other"
+msgstr "其它"
#: builtin/config.c
-msgid "only one action at a time"
-msgstr "一次只能有一个动作"
+msgid "respect include directives on lookup"
+msgstr "查询时参照 include 指令递归查找"
#: builtin/config.c
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only 仅适用于 --list 或 --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "无法读取配置文件 '%s'"
#: builtin/config.c
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr "--show-origin 仅适用于 --get、--get-all、--get-regexp 和 --list"
+msgid "error processing config file(s)"
+msgstr "处理配置文件出错"
#: builtin/config.c
-msgid "--default is only applicable to --get"
-msgstr "--default 仅适用于 --get"
+msgid "Filter options"
+msgstr "过滤选项"
#: builtin/config.c
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment 仅适用于 add/set/replace 操作"
+msgid "return all values for multi-valued config options"
+msgstr "返回多值配置选项的所有值"
+
+#: builtin/config.c
+msgid "interpret the name as a regular expression"
+msgstr "将名称解释为正则表达式"
+
+#: builtin/config.c
+msgid "show config with values matching the pattern"
+msgstr "显示值与模式匹配的配置"
+
+#: builtin/config.c
+msgid "use string equality when comparing values to value pattern"
+msgstr "在将值与值模式进行比较时使用字符串相等性"
+
+#: builtin/config.c
+msgid "URL"
+msgstr "URL"
+
+#: builtin/config.c
+msgid "show config matching the given URL"
+msgstr "显示与给定 URL 匹配的配置"
+
+#: builtin/config.c
+msgid "value"
+msgstr "值"
+
+#: builtin/config.c
+msgid "use default value when missing entry"
+msgstr "缺少条目时使用默认值"
#: builtin/config.c
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value 仅适用于有 '值模式'"
#: builtin/config.c
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "无法读取配置文件 '%s'"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= 不能与 --all 或 --url= 一起使用"
#: builtin/config.c
-msgid "error processing config file(s)"
-msgstr "处理配置文件出错"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= 不能与 --all、--regexp 或 --value 一起使用"
#: builtin/config.c
-msgid "editing stdin is not supported"
-msgstr "不支持编辑标准输入"
+msgid "Filter"
+msgstr "过滤器"
#: builtin/config.c
-msgid "editing blobs is not supported"
-msgstr "不支持编辑数据对象"
+msgid "replace multi-valued config option with new value"
+msgstr "将多值配置选项替换为新值"
#: builtin/config.c
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "不能创建配置文件 %s"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "人类可读的注释字符串(# 将根据需要添加到前面)"
+
+#: builtin/config.c
+msgid "add a new line without altering any existing values"
+msgstr "添加新行而不更改任何现有值"
+
+#: builtin/config.c
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value 只能与 --value=<模式> 配合使用"
+
+#: builtin/config.c
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append 不能与 --value=<模式> 一起使用"
#: builtin/config.c
#, c-format
@@ -6629,6 +6667,109 @@ msgstr ""
msgid "no such section: %s"
msgstr "无此小节:%s"
+#: builtin/config.c
+msgid "editing stdin is not supported"
+msgstr "不支持编辑标准输入"
+
+#: builtin/config.c
+msgid "editing blobs is not supported"
+msgstr "不支持编辑数据对象"
+
+#: builtin/config.c
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "不能创建配置文件 %s"
+
+#: builtin/config.c
+msgid "Action"
+msgstr "操作"
+
+#: builtin/config.c
+msgid "get value: name [<value-pattern>]"
+msgstr "获取值:name [<值模式>]"
+
+#: builtin/config.c
+msgid "get all values: key [<value-pattern>]"
+msgstr "获取所有值:key [<值模式>]"
+
+#: builtin/config.c
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "获取正则表达式的值:name-regex [<值模式>]"
+
+#: builtin/config.c
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "获得 URL 取值:section[.var] URL"
+
+#: builtin/config.c
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "替换所有匹配的变量:name value [<值模式>]"
+
+#: builtin/config.c
+msgid "add a new variable: name value"
+msgstr "添加一个新的变量:名称 值"
+
+#: builtin/config.c
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "删除一个变量:名称 [<值模式>]"
+
+#: builtin/config.c
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "删除所有匹配项:名称 [<值模式>]"
+
+#: builtin/config.c
+msgid "rename section: old-name new-name"
+msgstr "重命名小节:old-name new-name"
+
+#: builtin/config.c
+msgid "remove a section: name"
+msgstr "删除一个小节:name"
+
+#: builtin/config.c
+msgid "list all"
+msgstr "列出所有"
+
+#: builtin/config.c
+msgid "open an editor"
+msgstr "打开编辑器"
+
+#: builtin/config.c
+msgid "find the color configured: slot [<default>]"
+msgstr "找到配置的颜色:slot [<默认>]"
+
+#: builtin/config.c
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "找到颜色设置:slot [<stdout-is-tty>]"
+
+#: builtin/config.c
+msgid "with --get, use default value when missing entry"
+msgstr "使用 --get 参数,当缺少设置时使用默认值"
+
+#: builtin/config.c
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color 和变量类型不兼容"
+
+#: builtin/config.c
+msgid "no action specified"
+msgstr "未指定任何操作"
+
+#: builtin/config.c
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only 仅适用于 --list 或 --get-regexp"
+
+#: builtin/config.c
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr "--show-origin 仅适用于 --get、--get-all、--get-regexp 和 --list"
+
+#: builtin/config.c
+msgid "--default is only applicable to --get"
+msgstr "--default 仅适用于 --get"
+
+#: builtin/config.c
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment 仅适用于 add/set/replace 操作"
+
#: builtin/count-objects.c
msgid "print sizes in human readable format"
msgstr "以用户可读的格式显示大小"
@@ -7655,6 +7796,10 @@ msgid "config key storing a list of repository paths"
msgstr "存储着仓库路径列表的配置项键名"
#: builtin/for-each-repo.c
+msgid "keep going even if command fails in a repository"
+msgstr "即使存储库中的命令失败,仍继续执行"
+
+#: builtin/for-each-repo.c
msgid "missing --config=<config>"
msgstr "缺少 --config=<配置>"
@@ -9489,8 +9634,12 @@ msgid "max length of output filename"
msgstr "输出文件名的最大长度"
#: builtin/log.c
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "使用 [RFC PATCH] 代替 [PATCH]"
+msgid "rfc"
+msgstr "RFC"
+
+#: builtin/log.c
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "在 'PATCH' 之前添加 <RFC> (默认为 'RFC')"
#: builtin/log.c
msgid "cover-from-description-mode"
@@ -9834,11 +9983,11 @@ msgstr ""
#: builtin/ls-remote.c
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<可执行文件>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<可执行文件>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<键>]\n"
" [--symref] [<仓库> [<模式>...]]"
@@ -9859,9 +10008,13 @@ msgid "limit to tags"
msgstr "仅限于标签"
#: builtin/ls-remote.c
-msgid "limit to heads"
+msgid "limit to branches"
msgstr "仅限于分支"
+#: builtin/ls-remote.c builtin/show-ref.c
+msgid "deprecated synonym for --branches"
+msgstr "已弃用的 --branches 同义词"
+
#: builtin/ls-remote.c
msgid "do not show peeled tags"
msgstr "不显示已解析的标签"
@@ -13048,6 +13201,27 @@ msgstr "未指定要删除的引用日志"
msgid "invalid ref format: %s"
msgstr "无效的引用格式:%s"
+#: builtin/refs.c
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<格式> [--dry-run]"
+
+#: builtin/refs.c
+msgid "specify the reference format to convert to"
+msgstr "指定要转换的引用格式"
+
+#: builtin/refs.c
+msgid "perform a non-destructive dry-run"
+msgstr "进行非破坏性的试运行(dry-run)"
+
+#: builtin/refs.c
+msgid "missing --ref-format=<format>"
+msgstr "缺少 --ref-format=<格式>"
+
+#: builtin/refs.c
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "仓库已使用 '%s' 格式"
+
#: builtin/remote.c
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
@@ -13392,10 +13566,6 @@ msgstr "* 远程 %s"
msgid " Fetch URL: %s"
msgstr " 获取地址:%s"
-#: builtin/remote.c
-msgid "(no URL)"
-msgstr "(无 URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -13406,6 +13576,10 @@ msgid " Push URL: %s"
msgstr " 推送地址:%s"
#: builtin/remote.c
+msgid "(no URL)"
+msgstr "(无 URL)"
+
+#: builtin/remote.c
#, c-format
msgid " HEAD branch: %s"
msgstr " HEAD 分支:%s"
@@ -13542,11 +13716,6 @@ msgid "return all URLs"
msgstr "返回所有 URL 地址"
#: builtin/remote.c
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "没有给远程仓库 '%s' 设定 URL"
-
-#: builtin/remote.c
msgid "manipulate push URLs"
msgstr "操作推送 URLS"
@@ -14793,12 +14962,12 @@ msgstr "未知的哈希算法"
#: builtin/show-ref.c
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<模式>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<模式>...]"
#: builtin/show-ref.c
msgid ""
@@ -14827,12 +14996,12 @@ msgid "failed to look up reference"
msgstr "无法找到引用"
#: builtin/show-ref.c
-msgid "only show tags (can be combined with heads)"
-msgstr "只显示标签(可以和头共用)"
+msgid "only show tags (can be combined with branches)"
+msgstr "仅显示标签(可与分支组合使用)"
#: builtin/show-ref.c
-msgid "only show heads (can be combined with tags)"
-msgstr "只显示头(可以和标签共用)"
+msgid "only show branches (can be combined with tags)"
+msgstr "仅显示分支(可以和标签组合使用)"
#: builtin/show-ref.c
msgid "check for reference existence without resolving"
@@ -15579,20 +15748,20 @@ msgstr "不能识别 submodule.alternateErrorStrategy 的取值 '%s'"
msgid "Value '%s' for submodule.alternateLocation is not recognized"
msgstr "不能识别 submodule.alternateLocation 的取值 '%s'"
-#: builtin/submodule--helper.c
+#: builtin/submodule--helper.c submodule.c
#, c-format
msgid "refusing to create/use '%s' in another submodule's git dir"
msgstr "拒绝在另一个子模组的 git 目录中创建/使用 '%s'"
#: builtin/submodule--helper.c
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "无法克隆 '%s' 到子模组路径 '%s'"
+msgid "directory not empty: '%s'"
+msgstr "目录非空:'%s'"
#: builtin/submodule--helper.c
#, c-format
-msgid "directory not empty: '%s'"
-msgstr "目录非空:'%s'"
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "无法克隆 '%s' 到子模组路径 '%s'"
#: builtin/submodule--helper.c
#, c-format
@@ -16033,9 +16202,11 @@ msgstr "更新的原因"
#: builtin/tag.c
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
-"git tag [-a | -s | -u <私钥 ID>] [-f] [-m <消息> | -F <文件>] [-e]\n"
+"git tag [-a | -s | -u <私钥 id>] [-f] [-m <消息> | -F <文件>] [-e]\n"
+" [(--trailer <令牌>[(=|:)<值>])...]\n"
" <标签名> [<提交> | <对象>]"
#: builtin/tag.c
@@ -17080,10 +17251,6 @@ msgid "Repository lacks these prerequisite commits:"
msgstr "仓库中缺少这些必备的提交:"
#: bundle.c
-msgid "need a repository to verify a bundle"
-msgstr "需要一个仓库来校验一个归档包"
-
-#: bundle.c
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -17604,6 +17771,10 @@ msgid "Manage reflog information"
msgstr "管理 reflog 信息"
#: command-list.h
+msgid "Low-level access to refs"
+msgstr "对引用的低级访问"
+
+#: command-list.h
msgid "Manage set of tracked repositories"
msgstr "管理已跟踪仓库"
@@ -18000,6 +18171,13 @@ msgid "commit-graph required commit data chunk missing or corrupted"
msgstr "提交图所需的提交数据块缺失或损坏"
#: commit-graph.c
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr "由于不兼容的设置,正在禁用提交图层 '%s' 的布隆过滤器"
+
+#: commit-graph.c
msgid "commit-graph has no base graphs chunk"
msgstr "提交图没有基础图形块"
@@ -18159,6 +18337,13 @@ msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
msgstr "正尝试写提交图,但是 'core.commitGraph' 被禁用"
#: commit-graph.c
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' "
+"(%d) is not supported"
+msgstr "尝试写入提交图,但不支持 'commitGraph.changedPathsVersion' (%d)"
+
+#: commit-graph.c
msgid "too many commits to write graph"
msgstr "提交太多不能画图"
@@ -20418,16 +20603,19 @@ msgstr "因为缺少 Unix 套接字支持,套接字目录 '%s' 与 fsmonitor �
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C <路径>] [-c <名称>=<取值>]\n"
" [--exec-path[=<路径>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<路径>] [--work-tree=<路径>] [--namespace=<名称>]\n"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [\"--"
+"no-lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<路径>]\n"
+" [--work-tree=<路径>] [--namespace=<名称>]\n"
" [--config-env=<名称>=<环境变量>] <命令> [<参数>]"
#: git.c
@@ -20834,14 +21022,14 @@ msgstr ""
"配置 `git config advice.ignoredHook false` 来关闭这条警告。"
#: http-fetch.c
+msgid "not a git repository"
+msgstr "不是 git 仓库"
+
+#: http-fetch.c
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "--packfile 的参数必须是有效的哈希值(得到 '%s')"
-#: http-fetch.c
-msgid "not a git repository"
-msgstr "不是 git 仓库"
-
#: http.c
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
@@ -20856,6 +21044,10 @@ msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "不支持公钥文件锁定,因为 cURL < 7.39.0"
#: http.c
+msgid "Unknown value for http.proactiveauth"
+msgstr "http.proactiveauth 为未知取值"
+
+#: http.c
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "不支持 CURLSSLOPT_NO_REVOKE,因为 cURL < 7.44.0"
@@ -20875,6 +21067,14 @@ msgid "Could not set SSL backend to '%s': already set"
msgstr "无法将 SSL 后端设置为 '%s':已经设置"
#: http.c
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "拒绝从 http.cookiefile '-' 读取 cookies"
+
+#: http.c
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "因为 http.cookiefile 为空,忽略 http.savecookies"
+
+#: http.c
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -21080,10 +21280,10 @@ msgstr "无法合并子模组 %s (没有合并基线)"
msgid "Failed to merge submodule %s (commits not present)"
msgstr "无法合并子模组 %s(提交不存在)"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "无法合并子模组 %s(仓库损坏)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "错误:无法合并子模组 %s(仓库损坏)"
#: merge-ort.c merge-recursive.c
#, c-format
@@ -21115,14 +21315,15 @@ msgstr ""
"无法合并子模组 %s,但是存在多个可能的合并:\n"
"%s"
-#: merge-ort.c merge-recursive.c
-msgid "failed to execute internal merge"
-msgstr "无法执行内部合并"
+#: merge-ort.c
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "错误:无法为 %s 执行内部合并"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "unable to add %s to database"
-msgstr "不能添加 %s 至对象库"
+msgid "error: unable to add %s to database"
+msgstr "错误:不能添加 %s 至对象库"
#: merge-ort.c merge-recursive.c
#, c-format
@@ -21220,15 +21421,15 @@ msgstr ""
msgid "CONFLICT (rename/delete): %s renamed to %s in %s, but deleted in %s."
msgstr "冲突(重命名/删除):%1$s 在 %3$s 中重命名为 %2$s,但在 %4$s 中删除。"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "cannot read object %s"
-msgstr "不能读取对象 %s"
+msgid "error: cannot read object %s"
+msgstr "错误:不能读取对象 %s"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "object %s is not a blob"
-msgstr "对象 %s 不是一个数据对象"
+msgid "error: object %s is not a blob"
+msgstr "错误:对象 %s 不是一个数据对象"
#: merge-ort.c
#, c-format
@@ -21384,6 +21585,11 @@ msgstr "不知道如何处理 %06o %s '%s'"
#: merge-recursive.c
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "无法合并子模组 %s(仓库损坏)"
+
+#: merge-recursive.c
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "子模组 %s 快进到如下提交:"
@@ -21428,6 +21634,15 @@ msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "无法合并子模组 %s (发现多个合并)"
#: merge-recursive.c
+msgid "failed to execute internal merge"
+msgstr "无法执行内部合并"
+
+#: merge-recursive.c
+#, c-format
+msgid "unable to add %s to database"
+msgstr "不能添加 %s 至对象库"
+
+#: merge-recursive.c
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr "错误:拒绝丢失未跟踪文件 '%s',而是写入 %s。"
@@ -21541,6 +21756,16 @@ msgstr ""
"%4$s->%5$s"
#: merge-recursive.c
+#, c-format
+msgid "cannot read object %s"
+msgstr "不能读取对象 %s"
+
+#: merge-recursive.c
+#, c-format
+msgid "object %s is not a blob"
+msgstr "对象 %s 不是一个数据对象"
+
+#: merge-recursive.c
msgid "modify"
msgstr "修改"
@@ -21645,10 +21870,6 @@ msgid "malformed line: %s"
msgstr "格式错误的行:%s"
#: midx-write.c
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "忽略已存在的多包索引,校验码不匹配"
-
-#: midx-write.c
msgid "could not load pack"
msgstr "不能载入包"
@@ -21658,6 +21879,10 @@ msgid "could not open index for %s"
msgstr "不能打开 %s 的索引"
#: midx-write.c
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "忽略已存在的多包索引,校验码不匹配"
+
+#: midx-write.c
msgid "Adding packfiles to multi-pack-index"
msgstr "添加包文件到多包索引"
@@ -22394,6 +22619,20 @@ msgid "hash mismatch %s"
msgstr "哈希值与 %s 不匹配"
#: pack-bitmap-write.c
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "写入位图索引时存在重复条目:'%s'"
+
+#: pack-bitmap-write.c
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "尝试存储未选定的提交:'%s'"
+
+#: pack-bitmap-write.c
+msgid "too many pseudo-merges"
+msgstr "太多伪合并"
+
+#: pack-bitmap-write.c
msgid "trying to write commit not in index"
msgstr "尝试写入未在索引中的提交"
@@ -22423,6 +22662,19 @@ msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr "损坏的位图索引(太小,容不下查询表)"
#: pack-bitmap.c
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr "损坏的位图索引文件(太短而无法容纳伪合并表头)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr "损坏的位图索引(太短而无法容纳伪合并表)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "损坏的位图索引,伪合并表过短"
+
+#: pack-bitmap.c
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "位图索引中的重复条目:'%s'"
@@ -22537,6 +22789,11 @@ msgstr "位图结果不一致"
#: pack-bitmap.c
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "伪合并索引超出范围 (%<PRIu32> >= %<PRIuMAX>)"
+
+#: pack-bitmap.c
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "无法在包 '%2$s' 偏移 %3$<PRIuMAX> 中找到 '%1$s'"
@@ -22988,6 +23245,10 @@ msgid "unable to parse --pretty format"
msgstr "不能解析 --pretty 格式"
#: promisor-remote.c
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "禁用延迟获取,某些对象可能不可用"
+
+#: promisor-remote.c
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote:无法派生 fetch 子进程"
@@ -23017,6 +23278,72 @@ msgstr "object-info:在参数之后应有一个 flush"
msgid "Removing duplicate objects"
msgstr "正在删除重复对象"
+#: pseudo-merge.c
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "未能加载 %s 的伪合并正则表达式:'%s'"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s 必须为非负整数,使用默认值"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s 必须介于 0 到 1 之间,使用默认值"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s 必须为正数,使用默认值"
+
+#: pseudo-merge.c
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "伪合并组 '%s' 缺少所需的模式"
+
+#: pseudo-merge.c
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr "伪合并组 '%s' 在稳定阈值之前有不稳定阈值"
+
+#: pseudo-merge.c
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr "来自 config 的伪合并正则表达式有太多的捕获组(最多 %<PRIuMAX> 个)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "扩展伪合并读取越界 (%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "扩展伪合并条目太短(%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr "无法在提交 %1$s 的偏移 %2$<PRIuMAX> 中找到伪合并"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr "扩展伪合并查找越界 (%<PRIu32> >= %<PRIu32>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "越界读取:(%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "无法读取提交 %s 的扩展伪合并表"
+
#: range-diff.c
msgid "could not start `log`"
msgstr "不能启动 `log`"
@@ -23726,12 +24053,21 @@ msgid "log for %s is empty"
msgstr "%s 的日志为空"
#: refs.c
+msgid "refusing to force and skip creation of reflog"
+msgstr "拒绝既强制又跳过创建引用日志"
+
+#: refs.c
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "拒绝更新有错误名称 '%s' 的引用"
#: refs.c
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "拒绝更新伪引用 '%s'"
+
+#: refs.c
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "对引用 '%s' 执行 update_ref 失败:%s"
@@ -23768,6 +24104,27 @@ msgstr "无法删除引用 %s:%s"
msgid "could not delete references: %s"
msgstr "无法删除引用:%s"
+#: refs.c
+#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "已完成 refs 的试运行迁移,结果可在 '%s' 处找到\n"
+
+#: refs.c
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "无法删除临时迁移目录 '%s'"
+
+#: refs.c
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "迁移的引用可以在 '%s' 处找到"
+
+#: refs/files-backend.c refs/reftable-backend.c
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr "无法锁定引用 '%s':预期目标为 '%s' 的符号引用:但是是普通引用"
+
#: refs/reftable-backend.c
#, c-format
msgid "refname is dangerous: %s"
@@ -25159,6 +25516,53 @@ msgstr "update-ref 需要一个完整的引用名,例如:refs/heads/%s"
#: sequencer.c
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "'%s' 不接受合并提交"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+#: sequencer.c
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"'pick' 不接受合并提交。如果您想要重放合并,\n"
+"请在提交上使用 'merge -C'。"
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+#: sequencer.c
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"'reword' 不接受合并提交。如果您想重放合并并重写提交消息,\n"
+"请在提交上使用 'merge -c'"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+#: sequencer.c
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"'edit”' 不接受合并提交。如果您想要重放合并,\n"
+"请在提交上使用 'merge -C',然后使用 'break'\n"
+"将控制权交还给您,以便您可以执行\n"
+"'git commit --amend && git rebase --continue'。"
+
+#: sequencer.c
+msgid "cannot squash merge commit into another commit"
+msgstr "无法将合并提交压缩到另一个提交中"
+
+#: sequencer.c
+#, c-format
msgid "invalid command '%.*s'"
msgstr "无效命令 '%.*s'"
@@ -25307,9 +25711,8 @@ msgid "cannot read HEAD"
msgstr "不能读取 HEAD"
#: sequencer.c
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "无法拷贝 '%s' 至 '%s'"
+msgid "could not write commit message file"
+msgstr "无法写入提交说明文件"
#: sequencer.c
#, c-format
@@ -25788,6 +26191,19 @@ msgid "failed to stat '%*s%s%s'"
msgstr "无法获取 '%*s%s%s' 状态(stat)"
#: setup.c
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"在 '%s' 检测到可疑的仓库所有权\n"
+"%s要为本仓库创建特例,请运行:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
+#: setup.c
msgid "Unable to read current working directory"
msgstr "不能读取当前工作目录"
@@ -25812,19 +26228,6 @@ msgstr ""
#: setup.c
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"在 '%s' 检测到可疑的仓库所有权\n"
-"%s要为本仓库创建特例,请运行:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#: setup.c
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
msgstr "无法使用纯仓库 '%s' (safe.bareRepository 为 '%s')"
@@ -26189,6 +26592,16 @@ msgstr "子模组 git 目录 '%s' 位于 git 目录 '%.*s' 中"
#: submodule.c
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr "期望子模组的父目录 '%.*s' 不是一个符号链接,子模组路径为 '%s'"
+
+#: submodule.c
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "预期子模组路径 '%s' 不是符号链接"
+
+#: submodule.c
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr "不支持对有多个工作区的子模组 '%s' 执行 relocate_gitdir"
@@ -26233,11 +26646,6 @@ msgid "no remote configured to get bundle URIs from"
msgstr "没有远程被设置为可以获取归档包 URI"
#: t/helper/test-bundle-uri.c
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "远程 '%s' 没有设置 URL"
-
-#: t/helper/test-bundle-uri.c
msgid "could not get the bundle-uri list"
msgstr "无法获取 bundle-uri 列表"
@@ -28025,29 +28433,29 @@ msgstr "无法发送 %s\n"
#: git-send-email.perl
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "演习发送 %s\n"
+msgid "Dry-Sent %s"
+msgstr "演习发送 %s"
#: git-send-email.perl
#, perl-format
-msgid "Sent %s\n"
-msgstr "正发送 %s\n"
+msgid "Sent %s"
+msgstr "已发送 %s"
#: git-send-email.perl
-msgid "Dry-OK. Log says:\n"
-msgstr "演习成功。日志说:\n"
+msgid "Dry-OK. Log says:"
+msgstr "演习成功。日志说:"
#: git-send-email.perl
-msgid "OK. Log says:\n"
-msgstr "OK。日志说:\n"
+msgid "OK. Log says:"
+msgstr "成功。日志说:"
#: git-send-email.perl
msgid "Result: "
msgstr "结果:"
#: git-send-email.perl
-msgid "Result: OK\n"
-msgstr "结果:OK\n"
+msgid "Result: OK"
+msgstr "结果:成功"
#: git-send-email.perl
#, perl-format
diff --git a/po/zh_TW.po b/po/zh_TW.po
index f554381a7a..abf7157a99 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -21,14 +21,17 @@
#
# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023, 2024.
# Kaiyang Wu <self@origincode.me>, 2022.
-# lumynou5 <lumynou5.tw@gmail.com>, 2023, 2024.
+# Lumynous <lumynou5.tw@gmail.com>, 2023, 2024.
# Kisaragi Hiu <mail@kisaragi-hiu.com>, 2024.
+# Ngoo Ka-iu <willy04wu69@gmail.com>, 2024.
+# Nightfeather Chen <slat@nightfeather.me>, 2024.
+# hms5232 <hms5232@hhming.moe>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2024-04-28 18:52+0800\n"
-"PO-Revision-Date: 2024-04-28 18:44+0800\n"
+"POT-Creation-Date: 2024-07-19 15:00+0800\n"
+"PO-Revision-Date: 2024-07-24 08:21+0000\n"
"Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n"
"Language-Team: Chinese (Traditional) <http://weblate.slat.org/projects/git-"
"po/git-cli/zh_Hant/>\n"
@@ -37,7 +40,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Weblate 5.6.2\n"
"X-ZhConverter: 繁化姬 dict-f4bc617e-r910 @ 2019/11/16 20:23:12 | https://"
"zhconvert.org\n"
@@ -69,7 +72,7 @@ msgstr "更新"
#: add-interactive.c
#, c-format
msgid "could not stage '%s'"
-msgstr "無法暫存 “%s”"
+msgstr "無法暫存「%s」"
#: add-interactive.c builtin/stash.c reset.c sequencer.c
msgid "could not write index"
@@ -89,7 +92,7 @@ msgstr "註:現已不再追蹤 %s。\n"
#: add-interactive.c apply.c builtin/checkout.c builtin/reset.c
#, c-format
msgid "make_cache_entry failed for path '%s'"
-msgstr "對 “%s” 路徑執行 make_cache_entry 失敗"
+msgstr "對「%s」路徑執行 make_cache_entry 失敗"
#: add-interactive.c
msgid "Revert"
@@ -125,12 +128,12 @@ msgstr[0] "已加入 %d 個路徑\n"
msgid "ignoring unmerged: %s"
msgstr "忽略未合併項目:%s"
-#: add-interactive.c add-patch.c
+#: add-interactive.c
#, c-format
msgid "Only binary files changed.\n"
msgstr "只有二進位檔案更動了。\n"
-#: add-interactive.c add-patch.c
+#: add-interactive.c
#, c-format
msgid "No changes.\n"
msgstr "沒有更動。\n"
@@ -543,7 +546,7 @@ msgstr ""
#: add-patch.c
#, c-format
msgid "could not parse hunk header '%.*s'"
-msgstr "無法解析區塊標頭 “%.*s”"
+msgstr "無法解析區塊標頭「%.*s」"
#: add-patch.c
msgid "could not parse diff"
@@ -556,7 +559,7 @@ msgstr "無法解析上色過的差異"
#: add-patch.c
#, c-format
msgid "failed to run '%s'"
-msgstr "無法執行 “%s”"
+msgstr "無法執行「%s」"
#: add-patch.c
msgid "mismatched output from interactive.diffFilter"
@@ -625,7 +628,7 @@ msgstr "無法解析區塊標頭"
#: add-patch.c
msgid "'git apply --cached' failed"
-msgstr "“git apply --cached” 失敗"
+msgstr "「git apply --cached」失敗"
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input at this point.
@@ -636,7 +639,7 @@ msgstr "“git apply --cached” 失敗"
#: add-patch.c
msgid ""
"Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
-msgstr "未套用您編輯的區塊。是否重新編輯(輸入 “no” 捨棄!) [y/n]? "
+msgstr "未套用您編輯的區塊。是否重新編輯(輸入「no」捨棄!) [y/n]? "
#: add-patch.c
msgid "The selected hunks do not apply to the index!"
@@ -675,6 +678,11 @@ msgstr ""
"? - 顯示說明\n"
#: add-patch.c
+#, c-format
+msgid "Only one letter is expected, got '%s'"
+msgstr "預期收到一個字母,卻收到「%s」"
+
+#: add-patch.c
msgid "No previous hunk"
msgstr "沒有上一個區塊"
@@ -697,7 +705,7 @@ msgstr "跳轉到哪個區塊? "
#: add-patch.c
#, c-format
msgid "Invalid number: '%s'"
-msgstr "無效數字:“%s”"
+msgstr "無效數字:「%s」"
#: add-patch.c
#, c-format
@@ -736,8 +744,21 @@ msgid "Sorry, cannot edit this hunk"
msgstr "對不起,無法編輯這個區塊"
#: add-patch.c
+#, c-format
+msgid "Unknown command '%s' (use '?' for help)"
+msgstr "未知命令「%s」(使用「?」獲取幫助)"
+
+#: add-patch.c
msgid "'git apply' failed"
-msgstr "“git apply” 失敗"
+msgstr "「git apply」失敗"
+
+#: add-patch.c
+msgid "No changes."
+msgstr "沒有更動。"
+
+#: add-patch.c
+msgid "Only binary files changed."
+msgstr "只有二進位檔案更動了。"
#: advice.c
#, c-format
@@ -746,7 +767,7 @@ msgid ""
"Disable this message with \"git config advice.%s false\""
msgstr ""
"\n"
-"請使用 “git config advice.%s false” 停用此訊息"
+"請使用「git config advice.%s false」停用此訊息"
#: advice.c
#, c-format
@@ -782,7 +803,7 @@ msgid ""
"Fix them up in the work tree, and then use 'git add/rm <file>'\n"
"as appropriate to mark resolution and make a commit."
msgstr ""
-"請在工作區修正檔案,然後視情況使用 “git add/rm <file>”\n"
+"請在工作區修正檔案,然後視情況使用「git add/rm <file>」\n"
"命令標記解決方案並提交。"
#: advice.c
@@ -866,7 +887,7 @@ msgid ""
"false\n"
"\n"
msgstr ""
-"註:切換至 “%s”。\n"
+"註:切換至「%s」。\n"
"\n"
"您正處於「分離 HEAD」狀態。您可以檢視、進行實驗性修改並提交,\n"
"而且您可以在切回分支時,捨棄在此狀態下所做的提交\n"
@@ -901,8 +922,8 @@ msgid ""
"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
msgstr ""
"若要更正這些路徑的稀疏狀態,請:\n"
-"* 使用 “git add --sparse <路徑” 更新索引\n"
-"* 使用 “git sparse-checkout reapply” 套用稀疏規則"
+"* 使用「git add --sparse <路徑>」更新索引\n"
+"* 使用「git sparse-checkout reapply」套用稀疏規則"
#: alias.c
msgid "cmdline ends with \\"
@@ -913,19 +934,19 @@ msgid "unclosed quote"
msgstr "未閉合的引號"
#: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c
-#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c
+#: builtin/receive-pack.c builtin/refs.c builtin/tag.c t/helper/test-pkt-line.c
msgid "too many arguments"
msgstr "引數過多"
#: apply.c
#, c-format
msgid "unrecognized whitespace option '%s'"
-msgstr "空白字元選項 “%s” 無法識別"
+msgstr "空白字元選項「%s」無法識別"
#: apply.c
#, c-format
msgid "unrecognized whitespace ignore option '%s'"
-msgstr "空白字元忽略選項 “%s” 無法識別"
+msgstr "空白字元忽略選項「%s」無法識別"
#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c
#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c
@@ -939,12 +960,12 @@ msgstr "空白字元忽略選項 “%s” 無法識別"
#: range-diff.c revision.c
#, c-format
msgid "options '%s' and '%s' cannot be used together"
-msgstr "無法同時使用 “%s” 和 “%s” 選項"
+msgstr "無法同時使用「%s」和「%s」選項"
#: apply.c
#, c-format
msgid "'%s' outside a repository"
-msgstr "“%s” 在版本庫之外"
+msgstr "「%s」在版本庫之外"
#: apply.c
msgid "failed to read patch"
@@ -1080,7 +1101,7 @@ msgstr "無法開啟或讀取 %s"
#: apply.c
#, c-format
msgid "invalid start of line: '%c'"
-msgstr "無效的列首字元:“%c”"
+msgstr "無效的列首字元:「%c」"
#: apply.c
#, c-format
@@ -1105,43 +1126,43 @@ msgstr ""
#: apply.c
#, c-format
msgid "missing binary patch data for '%s'"
-msgstr "缺少 “%s” 的二進位修補檔資料"
+msgstr "缺少「%s」的二進位修補檔資料"
#: apply.c
#, c-format
msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'"
-msgstr "無法反向套用一個缺少至 “%s” 的反向資料區塊的二進位修補檔"
+msgstr "無法反向套用一個缺少至「%s」的反向資料區塊的二進位修補檔"
#: apply.c
#, c-format
msgid "cannot apply binary patch to '%s' without full index line"
-msgstr "無法在 “%s” 上套用沒有完整索引列的二進位修補檔"
+msgstr "無法在「%s」上套用沒有完整索引列的二進位修補檔"
#: apply.c
#, c-format
msgid ""
"the patch applies to '%s' (%s), which does not match the current contents."
-msgstr "修補檔要套用到 “%s”(%s),但與目前內容不符。"
+msgstr "修補檔要套用到「%s」(%s),但與目前內容不符。"
#: apply.c
#, c-format
msgid "the patch applies to an empty '%s' but it is not empty"
-msgstr "修補檔要套用至空檔案 “%s”,但其非空檔案"
+msgstr "修補檔要套用至空檔案「%s」,但其非空檔案"
#: apply.c
#, c-format
msgid "the necessary postimage %s for '%s' cannot be read"
-msgstr "無法讀取 “%2$s” 必須的目標檔案 %1$s"
+msgstr "無法讀取「%2$s」必須的目標檔案 %1$s"
#: apply.c
#, c-format
msgid "binary patch does not apply to '%s'"
-msgstr "二進位修補檔未套用到 “%s”"
+msgstr "二進位修補檔未套用到「%s」"
#: apply.c
#, c-format
msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
-msgstr "修補 “%s” 的二進位修補檔,產生了不正確的結果(預期 %s,卻為 %s)"
+msgstr "修補「%s」的二進位修補檔,產生了不正確的結果(預期 %s,卻為 %s)"
#: apply.c
#, c-format
@@ -1161,7 +1182,7 @@ msgstr "無法讀取 %s"
#: apply.c
#, c-format
msgid "reading from '%s' beyond a symbolic link"
-msgstr "讀取符號連結背後的 “%s”"
+msgstr "讀取符號連結背後的「%s」"
#: apply.c
#, c-format
@@ -1190,7 +1211,7 @@ msgstr "正在進行三方合併……\n"
#: apply.c
#, c-format
msgid "cannot read the current contents of '%s'"
-msgstr "無法讀取 “%s” 目前的內容"
+msgstr "無法讀取「%s」目前的內容"
#: apply.c
#, c-format
@@ -1200,12 +1221,12 @@ msgstr "無法進行三方合併……\n"
#: apply.c
#, c-format
msgid "Applied patch to '%s' with conflicts.\n"
-msgstr "已套用對 “%s” 的修補檔,但有衝突。\n"
+msgstr "已套用對「%s」的修補檔,但有衝突。\n"
#: apply.c
#, c-format
msgid "Applied patch to '%s' cleanly.\n"
-msgstr "已完全套用對 “%s” 的修補檔。\n"
+msgstr "已完全套用對「%s」的修補檔。\n"
#: apply.c
#, c-format
@@ -1229,7 +1250,7 @@ msgstr "%s 的類型是 %o,預期是 %o"
#: apply.c read-cache.c
#, c-format
msgid "invalid path '%s'"
-msgstr "路徑 “%s” 無效"
+msgstr "路徑「%s」無效"
#: apply.c
#, c-format
@@ -1254,7 +1275,7 @@ msgstr "%2$s 的新模式(%1$o)和 %4$s 的舊模式(%3$o)不符"
#: apply.c
#, c-format
msgid "affected file '%s' is beyond a symbolic link"
-msgstr "受影響的檔案 “%s” 在符號連結後"
+msgstr "受影響的檔案「%s」在符號連結後"
#: apply.c
#, c-format
@@ -1304,7 +1325,7 @@ msgstr "修補 %s 子模組的修補檔損壞"
#: apply.c
#, c-format
msgid "unable to stat newly created file '%s'"
-msgstr "無法對剛建立的檔案 “%s” 執行 stat"
+msgstr "無法對剛建立的檔案「%s」執行 stat"
#: apply.c
#, c-format
@@ -1319,17 +1340,17 @@ msgstr "無法為 %s 加入快取項目"
#: apply.c builtin/bisect.c builtin/gc.c
#, c-format
msgid "failed to write to '%s'"
-msgstr "無法寫入 “%s”"
+msgstr "無法寫入「%s」"
#: apply.c
#, c-format
msgid "closing file '%s'"
-msgstr "關閉檔案 “%s”"
+msgstr "關閉檔案「%s」"
#: apply.c
#, c-format
msgid "unable to write file '%s' mode %o"
-msgstr "無法以模式 %2$o 寫入 “%1$s” 檔案"
+msgstr "無法以模式 %2$o 寫入「%1$s」檔案"
#: apply.c
#, c-format
@@ -1354,7 +1375,7 @@ msgstr "無法開啟 %s"
#: apply.c rerere.c
#, c-format
msgid "cannot unlink '%s'"
-msgstr "無法刪除 “%s”"
+msgstr "無法刪除「%s」"
#: apply.c
#, c-format
@@ -1369,11 +1390,11 @@ msgstr "拒絕第 #%d 個區塊。"
#: apply.c
#, c-format
msgid "Skipped patch '%s'."
-msgstr "略過修補檔 “%s”。"
+msgstr "略過修補檔「%s」。"
#: apply.c
msgid "No valid patches in input (allow with \"--allow-empty\")"
-msgstr "輸入沒有有效的修補檔內容(傳入 “--allow-empty” 允許此行為)"
+msgstr "輸入沒有有效的修補檔內容(傳入「--allow-empty」允許此行為)"
#: apply.c t/helper/test-cache-tree.c
msgid "unable to read index file"
@@ -1382,7 +1403,7 @@ msgstr "無法讀取索引檔案"
#: apply.c
#, c-format
msgid "can't open patch '%s': %s"
-msgstr "無法開啟修補檔 “%s”:%s"
+msgstr "無法開啟修補檔「%s」:%s"
#: apply.c
#, c-format
@@ -1545,7 +1566,7 @@ msgstr "壓縮錯誤 (%d)"
#: archive-tar.c
#, c-format
msgid "unable to start '%s' filter"
-msgstr "無法啟動 “%s” 過濾器"
+msgstr "無法啟動「%s」過濾器"
#: archive-tar.c
msgid "unable to redirect descriptor"
@@ -1554,7 +1575,7 @@ msgstr "無法重新導向描述元"
#: archive-tar.c
#, c-format
msgid "'%s' filter reported error"
-msgstr "“%s” 過濾器回報錯誤"
+msgstr "「%s」過濾器回報錯誤"
#: archive-zip.c
#, c-format
@@ -1588,17 +1609,17 @@ msgstr "git archive --remote <repo> [--exec <cmd>] --list"
#: archive.c builtin/gc.c builtin/notes.c builtin/tag.c
#, c-format
msgid "cannot read '%s'"
-msgstr "無法讀取 “%s”"
+msgstr "無法讀取「%s」"
#: archive.c
#, c-format
msgid "pathspec '%s' matches files outside the current directory"
-msgstr "符合路徑規格 “%s” 的檔案在目前目錄之外"
+msgstr "符合路徑規格「%s」的檔案在目前目錄之外"
#: archive.c builtin/add.c builtin/rm.c
#, c-format
msgid "pathspec '%s' did not match any files"
-msgstr "路徑規格 “%s” 未符合任何檔案"
+msgstr "路徑規格「%s」未符合任何檔案"
#: archive.c
#, c-format
@@ -1628,17 +1649,17 @@ msgstr "不是一般檔案:%s"
#: archive.c
#, c-format
msgid "unclosed quote: '%s'"
-msgstr "未閉合的引號:“%s”"
+msgstr "未閉合的引號:「%s」"
#: archive.c
#, c-format
msgid "missing colon: '%s'"
-msgstr "缺少冒號:“%s”"
+msgstr "缺少冒號:「%s」"
#: archive.c
#, c-format
msgid "empty file name: '%s'"
-msgstr "檔案名稱空白:“%s”"
+msgstr "檔案名稱空白:「%s」"
#: archive.c
msgid "fmt"
@@ -1725,7 +1746,7 @@ msgstr "非預期選項 --remote"
#: revision.c
#, c-format
msgid "the option '%s' requires '%s'"
-msgstr "“%s” 選項需要 “%s”"
+msgstr "「%s」選項需要「%s」"
#: archive.c
msgid "Unexpected option --output"
@@ -1734,17 +1755,17 @@ msgstr "非預期選項 --output"
#: archive.c
#, c-format
msgid "extra command line parameter '%s'"
-msgstr "多出命令列參數 “%s”"
+msgstr "多出命令列參數「%s」"
#: archive.c
#, c-format
msgid "Unknown archive format '%s'"
-msgstr "封存格式 “%s” 未知"
+msgstr "封存格式「%s」未知"
#: archive.c
#, c-format
msgid "Argument not supported for format '%s': -%d"
-msgstr "引數不支援 “%s” 格式:-%d"
+msgstr "引數不支援「%s」格式:-%d"
#: attr.c
#, c-format
@@ -1771,22 +1792,26 @@ msgid ""
"Use '\\!' for literal leading exclamation."
msgstr ""
"git attributes 會忽略反向模式\n"
-"當字串確定要以驚嘆號開始時,請使用 “\\!”。"
+"當字串確定要以驚嘆號開始時,請使用「\\!」。"
#: attr.c
#, c-format
msgid "cannot fstat gitattributes file '%s'"
-msgstr "無法 fstat gitattributes 檔案 “%s”"
+msgstr "無法 fstat gitattributes 檔案「%s」"
#: attr.c
#, c-format
msgid "ignoring overly large gitattributes file '%s'"
-msgstr "忽略過大的 gitattributes 檔案 “%s”"
+msgstr "忽略過大的 gitattributes 檔案「%s」"
#: attr.c
#, c-format
msgid "ignoring overly large gitattributes blob '%s'"
-msgstr "忽略過大的 gitattributes 資料物件 “%s”"
+msgstr "忽略過大的 gitattributes 資料物件「%s」"
+
+#: attr.c
+msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo"
+msgstr "沒有版本庫無法使用 --attr-source 或 GIT_ATTR_SOURCE"
#: attr.c
msgid "bad --attr-source or GIT_ATTR_SOURCE"
@@ -1795,18 +1820,18 @@ msgstr "無效的 --attr-source 或 GIT_ATTR_SOURCE"
#: attr.c read-cache.c
#, c-format
msgid "unable to stat '%s'"
-msgstr "無法對 %s 執行 stat"
+msgstr "無法統計「%s」"
#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c
#: builtin/pack-objects.c combine-diff.c rerere.c
#, c-format
msgid "unable to read %s"
-msgstr "不能讀 %s"
+msgstr "無法讀取 %s"
#: bisect.c
#, c-format
msgid "Badly quoted content in file '%s': %s"
-msgstr "檔案 “%s” 包含無效的引用內容:%s"
+msgstr "檔案「%s」包含無效的引用內容:%s"
#: bisect.c
#, c-format
@@ -1843,7 +1868,7 @@ msgid ""
"This means the first '%s' commit is between %s and [%s].\n"
msgstr ""
"合併基礎 %s 是 %s。\n"
-"這意味著第一個 “%s” 提交位於 %s 和 [%s] 之間。\n"
+"這意味著第一個「%s」提交位於 %s 和 [%s] 之間。\n"
#: bisect.c
#, c-format
@@ -1880,17 +1905,17 @@ msgstr "需要一個 %s 修訂版"
#: bisect.c
#, c-format
msgid "could not create file '%s'"
-msgstr "無法建立 “%s” 檔案"
+msgstr "無法建立「%s」檔案"
#: bisect.c builtin/notes.c
#, c-format
msgid "unable to start 'show' for object '%s'"
-msgstr "不能為物件 '%s' 開始 'show'"
+msgstr "無法為物件「%s」開始「show」"
#: bisect.c builtin/merge.c
#, c-format
msgid "could not read file '%s'"
-msgstr "無法讀取 “%s” 檔案"
+msgstr "無法讀取「%s」檔案"
#: bisect.c
msgid "reading bisect refs failed"
@@ -1963,22 +1988,22 @@ msgstr "請求重定基底時,無法繼承多個引用的上游追蹤設定"
#: branch.c
#, c-format
msgid "not setting branch '%s' as its own upstream"
-msgstr "未將 “%s” 分支設為其自己的上游"
+msgstr "未將「%s」分支設為其自己的上游"
#: branch.c
#, c-format
msgid "branch '%s' set up to track '%s' by rebasing."
-msgstr "已藉由重訂基底,將 “%s” 分支設定為追蹤 “%s”。"
+msgstr "已藉由重訂基底,將「%s」分支設定為追蹤「%s」。"
#: branch.c
#, c-format
msgid "branch '%s' set up to track '%s'."
-msgstr "已將 “%s” 分支設定為追蹤 “%s”。"
+msgstr "已將「%s」分支設定為追蹤「%s」。"
#: branch.c
#, c-format
msgid "branch '%s' set up to track:"
-msgstr "“%s” 分支已設定追蹤:"
+msgstr "「%s」分支已設定追蹤:"
#: branch.c
msgid "unable to write upstream branch configuration"
@@ -1997,17 +2022,17 @@ msgstr ""
#: branch.c
#, c-format
msgid "asked to inherit tracking from '%s', but no remote is set"
-msgstr "請求繼承 “%s” 的追蹤設定,但未設定遠端"
+msgstr "請求繼承「%s」的追蹤設定,但未設定遠端"
#: branch.c
#, c-format
msgid "asked to inherit tracking from '%s', but no merge configuration is set"
-msgstr "請求繼承 “%s” 的追蹤設定,但未設定合併設定"
+msgstr "請求繼承「%s」的追蹤設定,但未設定合併設定"
#: branch.c
#, c-format
msgid "not tracking: ambiguous information for ref '%s'"
-msgstr "未追蹤:“%s” 引用有歧義"
+msgstr "未追蹤:「%s」引用有歧義"
# 譯者:為保證在輸出中對齊,注意調整句中空格!
#. #-#-#-#-# branch.c.po #-#-#-#-#
@@ -2042,7 +2067,7 @@ msgid ""
"tracking namespaces."
msgstr ""
"有多個遠端的抓取引用規格,映射到\n"
-"遠端追蹤引用 “%s” 的規格:\n"
+"遠端追蹤引用「%s」的規格:\n"
"%s\n"
"這通常是設定錯誤。\n"
"\n"
@@ -2052,7 +2077,7 @@ msgstr ""
#: branch.c
#, c-format
msgid "'%s' is not a valid branch name"
-msgstr "“%s” 不是有效的分支名稱"
+msgstr "「%s」不是有效的分支名稱"
#: branch.c builtin/branch.c
msgid "See `man git check-ref-format`"
@@ -2061,22 +2086,22 @@ msgstr "請參閱「man git check-ref-format」"
#: branch.c
#, c-format
msgid "a branch named '%s' already exists"
-msgstr "已有同名 “%s” 分支"
+msgstr "已有同名「%s」分支"
#: branch.c
#, c-format
msgid "cannot force update the branch '%s' used by worktree at '%s'"
-msgstr "無法強制更新被位於 “%2$s” 的工作區使用的 “%1$s” 分支"
+msgstr "無法強制更新被位於「%2$s」的工作區使用的分支「%1$s」"
#: branch.c
#, c-format
msgid "cannot set up tracking information; starting point '%s' is not a branch"
-msgstr "無法設定追蹤資訊:起始點 “%s” 不是分支"
+msgstr "無法設定追蹤資訊:起始點「%s」不是分支"
#: branch.c
#, c-format
msgid "the requested upstream branch '%s' does not exist"
-msgstr "請求的上游分支 “%s” 不存在"
+msgstr "請求的上游分支「%s」不存在"
#: branch.c
msgid ""
@@ -2100,22 +2125,22 @@ msgstr ""
#: branch.c builtin/replace.c
#, c-format
msgid "not a valid object name: '%s'"
-msgstr "物件名稱無效:“%s”"
+msgstr "物件名稱無效:「%s」"
#: branch.c
#, c-format
msgid "ambiguous object name: '%s'"
-msgstr "物件名稱有歧義:“%s”"
+msgstr "物件名稱有歧義:「%s」"
#: branch.c
#, c-format
msgid "not a valid branch point: '%s'"
-msgstr "分支點無效:“%s”"
+msgstr "分支點無效:「%s」"
#: branch.c
#, c-format
msgid "submodule '%s': unable to find submodule"
-msgstr "“%s” 子模組:找不到子模組"
+msgstr "「%s」子模組:找不到子模組"
#: branch.c
#, c-format
@@ -2123,18 +2148,18 @@ msgid ""
"You may try updating the submodules using 'git checkout --no-recurse-"
"submodules %s && git submodule update --init'"
msgstr ""
-"您可以使用 “git checkout --no-recurse-submodules %s && git submodule update "
-"--init” 命令嘗試更新子模組"
+"您可以使用「git checkout --no-recurse-submodules %s && git submodule update "
+"--init」命令嘗試更新子模組"
#: branch.c
#, c-format
msgid "submodule '%s': cannot create branch '%s'"
-msgstr "“%s” 子模組:無法建立 “%s” 分支"
+msgstr "「%s」子模組:無法建立「%s」分支"
#: branch.c
#, c-format
msgid "'%s' is already used by worktree at '%s'"
-msgstr "“%s” 已被位於 “%s” 的工作區使用"
+msgstr "「%s」已被位於「%s」的工作區使用"
#: builtin/add.c
msgid "git add [<options>] [--] <pathspec>..."
@@ -2150,14 +2175,6 @@ msgid "Unstaged changes after refreshing the index:"
msgstr "重新整理索引之後,尚未被暫存的更動:"
#: builtin/add.c
-msgid ""
-"the add.interactive.useBuiltin setting has been removed!\n"
-"See its entry in 'git help config' for details."
-msgstr ""
-"add.interactive.useBuiltin 設定已被移除!\n"
-"深入了解請參閱 “git help config” 中的對應條目。"
-
-#: builtin/add.c
msgid "could not read the index"
msgstr "無法讀取索引"
@@ -2168,7 +2185,7 @@ msgstr "編輯修補檔失敗"
#: builtin/add.c read-cache.c
#, c-format
msgid "could not stat '%s'"
-msgstr "不能對 '%s' 呼叫 stat"
+msgstr "無法統計「%s」"
#: builtin/add.c
msgid "empty patch. aborted"
@@ -2177,7 +2194,7 @@ msgstr "修補檔空白。中止"
#: builtin/add.c
#, c-format
msgid "could not apply '%s'"
-msgstr "無法套用 “%s”"
+msgstr "無法套用「%s」"
#: builtin/add.c
msgid "The following paths are ignored by one of your .gitignore files:\n"
@@ -2284,7 +2301,7 @@ msgstr ""
"\n"
"\tgit rm --cached %s\n"
"\n"
-"參見 “git help submodule” 深入了解。"
+"參見「git help submodule」深入了解。"
#: builtin/add.c
#, c-format
@@ -2293,7 +2310,7 @@ msgstr "正在加入嵌入式 git 版本庫:%s"
#: builtin/add.c
msgid "Use -f if you really want to add them."
-msgstr "如果您確定想要加入他們,請使用「-f」。"
+msgstr "如果您確定想要加入它們,請使用 -f。"
#: builtin/add.c
msgid "adding files failed"
@@ -2302,13 +2319,13 @@ msgstr "加入檔案失敗"
#: builtin/add.c
#, c-format
msgid "--chmod param '%s' must be either -x or +x"
-msgstr "--chmod 的參數 “%s” 必須是 -x 或 +x"
+msgstr "--chmod 的參數「%s」必須是 -x 或 +x"
#: builtin/add.c builtin/checkout.c builtin/commit.c builtin/reset.c
#: builtin/rm.c builtin/stash.c
#, c-format
msgid "'%s' and pathspec arguments cannot be used together"
-msgstr "“%s” 和路徑規格引數不得同時使用"
+msgstr "「%s」和路徑規格引數不得同時使用"
#: builtin/add.c
#, c-format
@@ -2334,19 +2351,19 @@ msgstr "無法寫入新的索引檔案"
#: builtin/am.c builtin/mailinfo.c mailinfo.c
#, c-format
msgid "bad action '%s' for '%s'"
-msgstr "“%s” 動作對 “%s” 無效"
+msgstr "「%s」動作對「%s」無效"
#: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c
#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c
#: ls-refs.c parallel-checkout.c sequencer.c setup.c
#, c-format
msgid "invalid value for '%s': '%s'"
-msgstr "“%s” 的值無效:“%s”"
+msgstr "「%s」的值無效:「%s」"
#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c
#, c-format
msgid "could not read '%s'"
-msgstr "無法讀取 “%s”"
+msgstr "無法讀取「%s」"
#: builtin/am.c
msgid "could not parse author script"
@@ -2360,17 +2377,17 @@ msgstr "無法解析 %s"
#: builtin/am.c
#, c-format
msgid "'%s' was deleted by the applypatch-msg hook"
-msgstr "“%s” 被 applypatch-msg 掛鉤刪除"
+msgstr "「%s」被 applypatch-msg 掛鉤刪除"
#: builtin/am.c
#, c-format
msgid "Malformed input line: '%s'."
-msgstr "格式錯誤的輸入列:“%s”。"
+msgstr "格式錯誤的輸入列:「%s」。"
#: builtin/am.c
#, c-format
msgid "Failed to copy notes from '%s' to '%s'"
-msgstr "從 “%s” 拷貝註解到 “%s” 失敗"
+msgstr "從「%s」拷貝註解到「%s」失敗"
#: builtin/am.c
msgid "fseek failed"
@@ -2379,17 +2396,17 @@ msgstr "fseek 失敗"
#: builtin/am.c builtin/rebase.c sequencer.c wrapper.c
#, c-format
msgid "could not open '%s' for reading"
-msgstr "無法開啟 “%s” 進行讀取"
+msgstr "無法開啟「%s」進行讀取"
#: builtin/am.c builtin/rebase.c editor.c sequencer.c wrapper.c
#, c-format
msgid "could not open '%s' for writing"
-msgstr "無法開啟 “%s” 進行寫入"
+msgstr "無法開啟「%s」進行寫入"
#: builtin/am.c
#, c-format
msgid "could not parse patch '%s'"
-msgstr "無法解析修補檔 “%s”"
+msgstr "無法解析修補檔「%s」"
#: builtin/am.c
msgid "Only one StGIT patch series can be applied at once"
@@ -2414,7 +2431,7 @@ msgstr "修補檔格式偵測失敗。"
#: builtin/am.c builtin/clone.c
#, c-format
msgid "failed to create directory '%s'"
-msgstr "無法建立目錄 “%s”"
+msgstr "無法建立目錄「%s」"
#: builtin/am.c
msgid "Failed to split patches."
@@ -2439,7 +2456,7 @@ msgstr "若要將空白修補檔錄入為空白提交,請執行「%s --allow-e
#: builtin/am.c
#, c-format
msgid "To restore the original branch and stop patching, run \"%s --abort\"."
-msgstr "若要還原至原始分支,並停止修補動作,請執行 “%s --abort”。"
+msgstr "若要還原至原始分支,並停止修補動作,請執行「%s --abort」。"
#: builtin/am.c
msgid "Patch sent with format=flowed; space at the end of lines might be lost."
@@ -2554,7 +2571,7 @@ msgstr "在 %s %.*s 處修補失敗"
#: builtin/am.c
msgid "Use 'git am --show-current-patch=diff' to see the failed patch"
-msgstr "使用 “git am --show-current-patch=diff” 命令檢視失敗的修補檔"
+msgstr "使用「git am --show-current-patch=diff」命令檢視失敗的修補檔"
#: builtin/am.c
msgid "No changes - recorded it as an empty commit."
@@ -2566,7 +2583,7 @@ msgid ""
"If there is nothing left to stage, chances are that something else\n"
"already introduced the same changes; you might want to skip this patch."
msgstr ""
-"沒有變更:是否忘記執行 “git add”?\n"
+"沒有變更:是否忘記執行「git add」?\n"
"如果沒有其他要新增到暫存區的,則很可能是其它提交\n"
"已經引入了相同的變更。您也許想要略過這個修補檔。"
@@ -2584,7 +2601,7 @@ msgstr ""
#: builtin/am.c builtin/reset.c
#, c-format
msgid "Could not parse object '%s'."
-msgstr "無法解析 “%s” 物件。"
+msgstr "無法解析「%s」物件。"
#: builtin/am.c
msgid "failed to clean index"
@@ -2595,13 +2612,13 @@ msgid ""
"You seem to have moved HEAD since the last 'am' failure.\n"
"Not rewinding to ORIG_HEAD"
msgstr ""
-"您似乎在上一次 “am” 失敗後移動了 HEAD。\n"
+"您似乎在上一次「am」失敗後移動了 HEAD。\n"
"未倒轉回 ORIG_HEAD"
-#: builtin/am.c builtin/bisect.c worktree.c
+#: builtin/am.c builtin/bisect.c builtin/tag.c worktree.c
#, c-format
msgid "failed to read '%s'"
-msgstr "無法讀取 “%s”"
+msgstr "無法讀取「%s」"
#: builtin/am.c
msgid "git am [<options>] [(<mbox> | <Maildir>)...]"
@@ -2676,8 +2693,8 @@ msgstr "n"
#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c
-#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c
+#: builtin/tag.c builtin/verify-tag.c
msgid "format"
msgstr "format"
@@ -2714,6 +2731,10 @@ msgid "show the patch being applied"
msgstr "顯示正在套用的修補檔"
#: builtin/am.c
+msgid "try to apply current patch again"
+msgstr "再次嘗試套用目前修補檔"
+
+#: builtin/am.c
msgid "record the empty patch as an empty commit"
msgstr "將空白修補檔錄入為空白提交"
@@ -2766,7 +2787,7 @@ msgid ""
"Use \"git am --abort\" to remove it."
msgstr ""
"發現失散的 %s 目錄。\n"
-"使用 “git am --abort” 移除。"
+"使用「git am --abort」移除。"
#: builtin/am.c
msgid "Resolve operation not in progress, we are not resuming."
@@ -2785,10 +2806,6 @@ msgid "could not redirect output"
msgstr "無法重新導向輸出"
#: builtin/archive.c
-msgid "git archive: Remote with no URL"
-msgstr "git archive: 未提供遠端 URL"
-
-#: builtin/archive.c
msgid "git archive: expected ACK/NAK, got a flush packet"
msgstr "git archive:預期是 ACK/NAK,卻收到 flush 封包"
@@ -2836,32 +2853,32 @@ msgstr "git bisect run <cmd> [<arg>...]"
#: builtin/bisect.c
#, c-format
msgid "cannot open file '%s' in mode '%s'"
-msgstr "無法以 “%2$s” 模式開啟 “%1$s” 檔案"
+msgstr "無法以「%2$s」模式開啟「%1$s」檔案"
#: builtin/bisect.c
#, c-format
msgid "could not write to file '%s'"
-msgstr "無法寫入 “%s” 檔案"
+msgstr "無法寫入「%s」檔案"
#: builtin/bisect.c
#, c-format
msgid "cannot open file '%s' for reading"
-msgstr "無法開啟 “%s” 檔案進行讀取"
+msgstr "無法開啟「%s」檔案進行讀取"
#: builtin/bisect.c
#, c-format
msgid "'%s' is not a valid term"
-msgstr "“%s” 不是有效術語"
+msgstr "「%s」不是有效術語"
#: builtin/bisect.c
#, c-format
msgid "can't use the builtin command '%s' as a term"
-msgstr "不能將內建命令 “%s” 當作術語使用"
+msgstr "不能將內建命令「%s」當作術語使用"
#: builtin/bisect.c
#, c-format
msgid "can't change the meaning of the term '%s'"
-msgstr "不能變更術語 “%s” 的含義"
+msgstr "不能變更術語「%s」的含義"
#: builtin/bisect.c
msgid "please use two different terms"
@@ -2875,13 +2892,13 @@ msgstr "我們沒有在二分搜尋。\n"
#: builtin/bisect.c
#, c-format
msgid "'%s' is not a valid commit"
-msgstr "“%s” 不是有效的提交"
+msgstr "「%s」不是有效的提交"
#: builtin/bisect.c
#, c-format
msgid ""
"could not check out original HEAD '%s'. Try 'git bisect reset <commit>'."
-msgstr "不能簽出原始 HEAD “%s”。請嘗試 “git bisect reset <commit>”。"
+msgstr "不能簽出原始 HEAD「%s」。請嘗試「git bisect reset <commit>」。"
#: builtin/bisect.c
#, c-format
@@ -2891,12 +2908,12 @@ msgstr "bisect_write 引數無效:%s"
#: builtin/bisect.c
#, c-format
msgid "couldn't get the oid of the rev '%s'"
-msgstr "無法取得修訂版 “%s” 的物件 ID"
+msgstr "無法取得修訂版「%s」的物件 ID"
#: builtin/bisect.c
#, c-format
msgid "couldn't open the file '%s'"
-msgstr "無法開啟檔案 “%s”"
+msgstr "無法開啟檔案「%s」"
#: builtin/bisect.c
#, c-format
@@ -2910,7 +2927,7 @@ msgid ""
"You can use \"git bisect %s\" and \"git bisect %s\" for that."
msgstr ""
"需指定至少一個 %s 和一個 %s 修訂版。\n"
-"為此您可以用 “git bisect %s” 和 “git bisect %s”。"
+"為此您可以用「git bisect %s」和「git bisect %s」。"
#: builtin/bisect.c
#, c-format
@@ -2919,9 +2936,9 @@ msgid ""
"You then need to give me at least one %s and %s revision.\n"
"You can use \"git bisect %s\" and \"git bisect %s\" for that."
msgstr ""
-"要開始,請執行 “git bisect start”。\n"
+"要開始,請執行「git bisect start」。\n"
"接著提供至少一個 %s 和一個 %s 修訂版。\n"
-"為此您可以用 “git bisect %s” 和 “git bisect %s”。"
+"為此您可以用「git bisect %s」和「git bisect %s」。"
#: builtin/bisect.c
#, c-format
@@ -2970,7 +2987,7 @@ msgid ""
"invalid argument %s for 'git bisect terms'.\n"
"Supported options are: --term-good|--term-old and --term-bad|--term-new."
msgstr ""
-"傳入 “git bisect terms” 的 %s 引數無效。\n"
+"傳入「git bisect terms」的 %s 引數無效。\n"
"支援的選項有:--term-good|--term-old 和 --term-bad|--term-new。"
#: builtin/bisect.c
@@ -2980,21 +2997,21 @@ msgstr "修訂版遍歷設定失敗\n"
#: builtin/bisect.c
#, c-format
msgid "could not open '%s' for appending"
-msgstr "無法開啟 “%s” 進行附加"
+msgstr "無法開啟「%s」進行附加"
#: builtin/bisect.c
msgid "'' is not a valid term"
-msgstr "“ ” 不是有效術語"
+msgstr "「 」不是有效術語"
#: builtin/bisect.c
#, c-format
msgid "unrecognized option: '%s'"
-msgstr "無法識別選項:“%s”"
+msgstr "無法識別選項:「%s」"
#: builtin/bisect.c
#, c-format
msgid "'%s' does not appear to be a valid revision"
-msgstr "“%s” 似乎不是有效修訂版"
+msgstr "「%s」似乎不是有效修訂版"
#: builtin/bisect.c
msgid "bad HEAD - I need a HEAD"
@@ -3003,7 +3020,7 @@ msgstr "HEAD 無效 — 需要一個 HEAD"
#: builtin/bisect.c
#, c-format
msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'."
-msgstr "簽出 “%s” 失敗。請嘗試 “git bisect start <valid-branch>”。"
+msgstr "簽出「%s」失敗。請嘗試「git bisect start <valid-branch>」。"
#: builtin/bisect.c
msgid "bad HEAD - strange symbolic ref"
@@ -3012,11 +3029,11 @@ msgstr "HEAD 無效 — 異常符號引用"
#: builtin/bisect.c
#, c-format
msgid "invalid ref: '%s'"
-msgstr "引用無效:“%s”"
+msgstr "引用無效:「%s」"
#: builtin/bisect.c
msgid "You need to start by \"git bisect start\"\n"
-msgstr "要開始,請執行 “git bisect start”\n"
+msgstr "要開始,請執行「git bisect start」\n"
# 譯者:請維持句尾空格
#. TRANSLATORS: Make sure to include [Y] and [n] in your
@@ -3034,7 +3051,7 @@ msgstr "要呼叫 `--bisect-state`,請傳入一個以上的引數"
#: builtin/bisect.c
#, c-format
msgid "'git bisect %s' can take only one argument."
-msgstr "“git bisect %s” 只取一個引數。"
+msgstr "「git bisect %s」只取一個引數。"
#: builtin/bisect.c
#, c-format
@@ -3087,7 +3104,7 @@ msgstr "二分搜尋執行失敗:%2$s 回傳的結束代碼 %1$d 小於 0 或�
#: builtin/bisect.c
#, c-format
msgid "cannot open file '%s' for writing"
-msgstr "無法開啟 “%s” 檔案進行寫入"
+msgstr "無法開啟「%s」檔案進行寫入"
#: builtin/bisect.c
msgid "bisect run cannot continue any more"
@@ -3104,22 +3121,22 @@ msgstr "二分搜尋發現到第一個有問題的提交"
#: builtin/bisect.c
#, c-format
msgid "bisect run failed: 'git bisect %s' exited with error code %d"
-msgstr "二分搜尋執行失敗:“git bisect %s” 以錯誤碼 %d 離開"
+msgstr "二分搜尋執行失敗:「git bisect %s」以錯誤碼 %d 離開"
#: builtin/bisect.c
#, c-format
msgid "'%s' requires either no argument or a commit"
-msgstr "“%s” 不需要引數,或者得傳入一個提交"
+msgstr "「%s」不需要引數,或者得傳入一個提交"
#: builtin/bisect.c
#, c-format
msgid "'%s' requires 0 or 1 argument"
-msgstr "“%s” 需要 0 或 1 個引數"
+msgstr "「%s」需要 0 或 1 個引數"
#: builtin/bisect.c
#, c-format
msgid "'%s' requires 0 arguments"
-msgstr "“%s” 不需引數"
+msgstr "「%s」不需引數"
#: builtin/bisect.c
msgid "no logfile given"
@@ -3128,7 +3145,7 @@ msgstr "未提供日誌檔案"
#: builtin/bisect.c
#, c-format
msgid "'%s' failed: no command provided."
-msgstr "“%s” 失敗:沒有提供命令。"
+msgstr "「%s」失敗:沒有提供命令。"
#: builtin/bisect.c
msgid "need a command"
@@ -3137,7 +3154,7 @@ msgstr "需要提供命令"
#: builtin/bisect.c builtin/cat-file.c
#, c-format
msgid "unknown command: '%s'"
-msgstr "未知命令:“%s”"
+msgstr "未知命令:「%s」"
#: builtin/blame.c
msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
@@ -3352,8 +3369,8 @@ msgid ""
"deleting branch '%s' that has been merged to\n"
" '%s', but not yet merged to HEAD"
msgstr ""
-"將要刪除的 “%s” 分支已經被合併到\n"
-" “%s”,但尚未合併到 HEAD"
+"將要刪除的分支「%s」已經被合併到\n"
+" 「%s」,但尚未合併到 HEAD"
# 譯者:保持原換行格式,在輸出時 %s 的替代內容會讓字串變長
#: builtin/branch.c
@@ -3362,23 +3379,23 @@ msgid ""
"not deleting branch '%s' that is not yet merged to\n"
" '%s', even though it is merged to HEAD"
msgstr ""
-"並未刪除分支 “%s”, 雖然已經合併到 HEAD,\n"
-" 卻尚未被合併至 “%s” 分支"
+"並未刪除分支「%s」,雖然已經合併到 HEAD,\n"
+" 卻尚未被合併至「%s」分支"
#: builtin/branch.c
#, c-format
msgid "couldn't look up commit object for '%s'"
-msgstr "無法查詢 “%s” 指向的提交物件"
+msgstr "無法查詢「%s」指向的提交物件"
#: builtin/branch.c
#, c-format
msgid "the branch '%s' is not fully merged"
-msgstr "分支 “%s” 沒有完全合併"
+msgstr "分支「%s」沒有完全合併"
#: builtin/branch.c
#, c-format
msgid "If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr "如果確定要刪除它,請執行 “git branch -D %s”"
+msgstr "如果確定要刪除它,請執行「git branch -D %s」"
#: builtin/branch.c
msgid "update of config-file failed"
@@ -3391,12 +3408,12 @@ msgstr "不能將 -a 和 -d 同時使用"
#: builtin/branch.c
#, c-format
msgid "cannot delete branch '%s' used by worktree at '%s'"
-msgstr "無法刪除被位於 “%2$s” 的工作區使用的 “%1$s” 分支"
+msgstr "無法刪除被位於「%2$s」的工作區使用的分支「%1$s」"
#: builtin/branch.c
#, c-format
msgid "remote-tracking branch '%s' not found"
-msgstr "找不到 “%s” 遠端追蹤分支"
+msgstr "找不到遠端追蹤分支「%s」"
#: builtin/branch.c
#, c-format
@@ -3404,13 +3421,13 @@ msgid ""
"branch '%s' not found.\n"
"Did you forget --remote?"
msgstr ""
-"找不到 “%s” 分支。\n"
-"您可能要加上 --remote?"
+"找不到分支「%s」。\n"
+"您可能想加上 --remote?"
#: builtin/branch.c
#, c-format
msgid "branch '%s' not found"
-msgstr "找不到 “%s” 分支"
+msgstr "找不到分支「%s」"
#: builtin/branch.c
#, c-format
@@ -3428,42 +3445,42 @@ msgstr "無法解析格式化字串"
#: builtin/branch.c
msgid "could not resolve HEAD"
-msgstr "無法解析 HEAD 指針"
+msgstr "無法解析 HEAD 指標"
#: builtin/branch.c
#, c-format
msgid "HEAD (%s) points outside of refs/heads/"
-msgstr "HEAD 指針 (%s) 指向 refs/heads/ 之外"
+msgstr "HEAD 指標 (%s) 指向 refs/heads/ 之外"
#: builtin/branch.c
#, c-format
msgid "branch %s is being rebased at %s"
-msgstr "%s 分支正在重定基底至 %s"
+msgstr "分支 %s 正在重定基底至 %s"
#: builtin/branch.c
#, c-format
msgid "branch %s is being bisected at %s"
-msgstr "%s 分支正於 %s 進行二分搜尋"
+msgstr "分支 %s 正於 %s 進行二分搜尋"
#: builtin/branch.c
#, c-format
msgid "HEAD of working tree %s is not updated"
-msgstr "%s 工作區的 HEAD 指針未被更新"
+msgstr "%s 工作區的 HEAD 指標未被更新"
#: builtin/branch.c
#, c-format
msgid "invalid branch name: '%s'"
-msgstr "分支名稱無效:“%s”"
+msgstr "分支名稱無效:「%s」"
#: builtin/branch.c
#, c-format
msgid "no commit on branch '%s' yet"
-msgstr "分支 “%s” 尚無提交"
+msgstr "分支「%s」尚無提交"
#: builtin/branch.c
#, c-format
msgid "no branch named '%s'"
-msgstr "沒有名為 “%s” 的分支"
+msgstr "沒有名為「%s」的分支"
#: builtin/branch.c
msgid "branch rename failed"
@@ -3476,17 +3493,17 @@ msgstr "分支拷貝失敗"
#: builtin/branch.c
#, c-format
msgid "created a copy of a misnamed branch '%s'"
-msgstr "已為誤命名的 “%s” 分支建立拷貝"
+msgstr "已為誤命名的分支「%s」建立拷貝"
#: builtin/branch.c
#, c-format
msgid "renamed a misnamed branch '%s' away"
-msgstr "已更改誤命名的 “%s” 分支的名稱"
+msgstr "已更改誤命名的分支「%s」的名稱"
#: builtin/branch.c
#, c-format
msgid "branch renamed to %s, but HEAD is not updated"
-msgstr "分支已重新命名為 %s,但 HEAD 指針尚未更新"
+msgstr "分支已重新命名為 %s,但 HEAD 指標尚未更新"
#: builtin/branch.c
msgid "branch is renamed, but update of config-file failed"
@@ -3581,7 +3598,7 @@ msgstr "即使目標已存在,仍移動或重新命名分支"
#: builtin/branch.c builtin/for-each-ref.c builtin/tag.c
msgid "do not output a newline after empty formatted refs"
-msgstr "在格式化引用結果為空之後,不要輸出換列符號"
+msgstr "在格式化結果為空的引用之後,不要輸出換列符號"
#: builtin/branch.c
msgid "copy a branch and its reflog"
@@ -3650,7 +3667,7 @@ msgstr "無法將 HEAD 解析為有效引用"
#: builtin/branch.c builtin/clone.c
msgid "HEAD not found below refs/heads!"
-msgstr "HEAD 指針不在 /refs/heads 中!"
+msgstr "HEAD 指標不在 /refs/heads 中!"
#: builtin/branch.c
msgid ""
@@ -3669,7 +3686,7 @@ msgstr "必須提供分支名稱"
#: builtin/branch.c
msgid "cannot give description to detached HEAD"
-msgstr "無法向分離 HEAD 指針提供描述"
+msgstr "無法向分離 HEAD 指標提供描述"
#: builtin/branch.c
msgid "cannot edit description of more than one branch"
@@ -3704,12 +3721,12 @@ msgstr "無法將 HEAD 的上游設為 %s:其未指向任何分支"
#: builtin/branch.c
#, c-format
msgid "no such branch '%s'"
-msgstr "無 “%s” 分支"
+msgstr "無「%s」分支"
#: builtin/branch.c
#, c-format
msgid "branch '%s' does not exist"
-msgstr "沒有 “%s” 分支"
+msgstr "沒有「%s」分支"
#: builtin/branch.c
msgid "too many arguments to unset upstream"
@@ -3722,21 +3739,22 @@ msgstr "無法取消設定 HEAD 的上游:其未指向任何分支"
#: builtin/branch.c
#, c-format
msgid "branch '%s' has no upstream information"
-msgstr "分支 “%s” 沒有上游資訊"
+msgstr "分支「%s」沒有上游資訊"
#: builtin/branch.c
msgid ""
"the -a, and -r, options to 'git branch' do not take a branch name.\n"
"Did you mean to use: -a|-r --list <pattern>?"
msgstr ""
-"“git branch” 的 -a 和 -r 選項不取分支名稱。\n"
+"「git branch」的 -a 和 -r 選項不取分支名稱。\n"
"您是想使用:-a|-r --list <pattern> 嗎?"
#: builtin/branch.c
msgid ""
"the '--set-upstream' option is no longer supported. Please use '--track' or "
"'--set-upstream-to' instead"
-msgstr "不再支援選項 “--set-upstream”。請改用 “--track” 或 “--set-upstream-to”"
+msgstr ""
+"不再支援選項「--set-upstream」。請改用「--track」或「--set-upstream-to」"
#: builtin/bugreport.c
msgid "git version:\n"
@@ -3745,7 +3763,7 @@ msgstr "git 版本:\n"
#: builtin/bugreport.c
#, c-format
msgid "uname() failed with error '%s' (%d)\n"
-msgstr "uname() 失敗,錯誤:“%s” (%d)\n"
+msgstr "uname() 失敗,錯誤:「%s」(%d)\n"
#: builtin/bugreport.c
msgid "compiler info: "
@@ -3811,7 +3829,7 @@ msgstr "mode"
#: builtin/bugreport.c
msgid ""
"create an additional zip archive of detailed diagnostics (default 'stats')"
-msgstr "另外建立有詳細診斷資訊的 ZIP 封存檔(預設值 “stats”)"
+msgstr "另外建立有詳細診斷資訊的 ZIP 封存檔(預設值「stats」)"
#: builtin/bugreport.c
msgid "specify a destination for the bugreport file(s)"
@@ -3824,12 +3842,12 @@ msgstr "指定用於檔名的 strftime 格式後綴"
#: builtin/bugreport.c
#, c-format
msgid "unknown argument `%s'"
-msgstr "未知引數 “%s”"
+msgstr "未知引數「%s」"
#: builtin/bugreport.c builtin/diagnose.c
#, c-format
msgid "could not create leading directories for '%s'"
-msgstr "無法建立 “%s” 的前置目錄"
+msgstr "無法建立「%s」的前置目錄"
#: builtin/bugreport.c builtin/diagnose.c
#, c-format
@@ -3852,7 +3870,7 @@ msgstr "無法寫入 %s"
#: builtin/bugreport.c
#, c-format
msgid "Created new report at '%s'.\n"
-msgstr "已在 “%s” 建立新報告。\n"
+msgstr "已在「%s」建立新報告。\n"
#: builtin/bundle.c
msgid ""
@@ -3906,6 +3924,10 @@ msgstr "需要版本庫來建立套件包。"
msgid "do not show bundle details"
msgstr "不顯示套件包的詳細資訊"
+#: builtin/bundle.c bundle.c
+msgid "need a repository to verify a bundle"
+msgstr "需要版本庫驗證套件包"
+
#: builtin/bundle.c
#, c-format
msgid "%s is okay\n"
@@ -3922,7 +3944,7 @@ msgstr "正在拆分物件"
#: builtin/cat-file.c merge-recursive.c
#, c-format
msgid "cannot read object %s '%s'"
-msgstr "無法讀取物件 %s “%s”"
+msgstr "無法讀取物件 %s「%s」"
#: builtin/cat-file.c
msgid "flush is only for --buffer mode"
@@ -3935,7 +3957,7 @@ msgstr "輸入中沒有命令"
#: builtin/cat-file.c
#, c-format
msgid "whitespace before command: '%s'"
-msgstr "命令前有空格:“%s”"
+msgstr "命令前有空格:「%s」"
#: builtin/cat-file.c
#, c-format
@@ -4001,7 +4023,8 @@ msgstr "輸出 [損壞的] ([broken]) 物件屬性"
#: builtin/cat-file.c
msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"
-msgstr "顯示物件類型(可以是 “blob”、“tree”、“commit”、“tag” 等其中一個)"
+msgstr ""
+"顯示物件類型(可以是「blob」、「tree」、「commit」、「tag」等其中一個)"
#: builtin/cat-file.c
msgid "show object size"
@@ -4079,12 +4102,12 @@ msgstr "blob|tree"
#: builtin/cat-file.c
msgid "use a <path> for (--textconv | --filters); Not with 'batch'"
-msgstr "請在 (--textconv | --filters) 使用 <path>,而非 “batch”"
+msgstr "請在 (--textconv | --filters) 使用 <path>,而非「batch」"
#: builtin/cat-file.c
#, c-format
msgid "'%s=<%s>' needs '%s' or '%s'"
-msgstr "“%s=<%s>” 需要 “%s” 或 “%s”"
+msgstr "「%s=<%s>」需要「%s」或「%s」"
#: builtin/cat-file.c
msgid "path|tree-ish"
@@ -4093,12 +4116,12 @@ msgstr "path|tree-ish"
#: builtin/cat-file.c
#, c-format
msgid "'%s' requires a batch mode"
-msgstr "“%s” 需要批次處理模式"
+msgstr "「%s」需要批次處理模式"
#: builtin/cat-file.c
#, c-format
msgid "'-%c' is incompatible with batch mode"
-msgstr "“-%c” 與批次處理模式不相容"
+msgstr "「-%c」與批次處理模式不相容"
#: builtin/cat-file.c
msgid "batch modes take no arguments"
@@ -4107,12 +4130,12 @@ msgstr "批次處理模式不取引數"
#: builtin/cat-file.c
#, c-format
msgid "<rev> required with '%s'"
-msgstr "“%s” 需要 <rev>"
+msgstr "「%s」需要 <rev>"
#: builtin/cat-file.c
#, c-format
msgid "<object> required with '-%c'"
-msgstr "“-%c” 需要 <object>"
+msgstr "「-%c」需要 <object>"
#: builtin/cat-file.c
#, c-format
@@ -4286,32 +4309,32 @@ msgstr "git restore [<options>] [--source=<branch>] <file>..."
#: builtin/checkout.c
#, c-format
msgid "path '%s' does not have our version"
-msgstr "“%s” 路徑沒有我們的版本"
+msgstr "「%s」路徑沒有我們的版本"
#: builtin/checkout.c
#, c-format
msgid "path '%s' does not have their version"
-msgstr "“%s” 路徑沒有他們的版本"
+msgstr "「%s」路徑沒有他們的版本"
#: builtin/checkout.c
#, c-format
msgid "path '%s' does not have all necessary versions"
-msgstr "“%s” 路徑沒有所有必須的版本"
+msgstr "「%s」路徑沒有所有必須的版本"
#: builtin/checkout.c
#, c-format
msgid "path '%s' does not have necessary versions"
-msgstr "“%s” 路徑沒有必須的版本"
+msgstr "「%s」路徑沒有必須的版本"
#: builtin/checkout.c
#, c-format
msgid "path '%s': cannot merge"
-msgstr "path “%s”:無法合併"
+msgstr "path「%s」:無法合併"
#: builtin/checkout.c
#, c-format
msgid "Unable to add merge result for '%s'"
-msgstr "無法為 “%s” 加上合併結果"
+msgstr "無法為「%s」加上合併結果"
#: builtin/checkout.c
#, c-format
@@ -4334,37 +4357,37 @@ msgstr[0] "已從索引區更新 %d 個路徑"
#: builtin/checkout.c
#, c-format
msgid "'%s' cannot be used with updating paths"
-msgstr "無法在更新路徑時使用 “%s”"
+msgstr "無法在更新路徑時使用「%s」"
#: builtin/checkout.c
#, c-format
msgid "Cannot update paths and switch to branch '%s' at the same time."
-msgstr "無法同時更新路徑和切換至 “%s” 分支。"
+msgstr "無法同時更新路徑和切換至「%s」分支。"
#: builtin/checkout.c
#, c-format
msgid "neither '%s' or '%s' is specified"
-msgstr "“%s” 或 “%s” 皆未指定"
+msgstr "「%s」或「%s」皆未指定"
#: builtin/checkout.c
#, c-format
msgid "'%s' must be used when '%s' is not specified"
-msgstr "未指定 “%2$s” 時,必須使用 “%1$s”"
+msgstr "未指定「%2$s」時,必須使用「%1$s」"
#: builtin/checkout.c
#, c-format
msgid "'%s' or '%s' cannot be used with %s"
-msgstr "“%s” 或 “%s” 無法與 %s 一起使用"
+msgstr "「%s」或「%s」無法與 %s 一起使用"
#: builtin/checkout.c
#, c-format
msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree"
-msgstr "“%s”、“%s” 或 “%s” 無法在簽出樹狀物件時使用"
+msgstr "「%s」、「%s」或「%s」無法在簽出樹狀物件時使用"
#: builtin/checkout.c
#, c-format
msgid "path '%s' is unmerged"
-msgstr "路徑 “%s” 未合併"
+msgstr "路徑「%s」未合併"
#: builtin/checkout.c builtin/grep.c builtin/merge-tree.c builtin/reset.c
#: merge-ort.c reset.c sequencer.c tree-walk.c
@@ -4388,7 +4411,7 @@ msgstr ""
#: builtin/checkout.c
#, c-format
msgid "Can not do reflog for '%s': %s\n"
-msgstr "無法對 “%s” 執行 reflog 動作:%s\n"
+msgstr "無法對「%s」執行 reflog 動作:%s\n"
#: builtin/checkout.c
msgid "HEAD is now at"
@@ -4401,27 +4424,27 @@ msgstr "無法更新 HEAD"
#: builtin/checkout.c
#, c-format
msgid "Reset branch '%s'\n"
-msgstr "重設分支 “%s”\n"
+msgstr "重設分支「%s」\n"
#: builtin/checkout.c
#, c-format
msgid "Already on '%s'\n"
-msgstr "已經位於 “%s”\n"
+msgstr "已經位於「%s」\n"
#: builtin/checkout.c
#, c-format
msgid "Switched to and reset branch '%s'\n"
-msgstr "已切換並重設分支 “%s”\n"
+msgstr "已切換並重設分支「%s」\n"
#: builtin/checkout.c
#, c-format
msgid "Switched to a new branch '%s'\n"
-msgstr "已切換至新分支 “%s”\n"
+msgstr "已切換至新分支「%s」\n"
#: builtin/checkout.c
#, c-format
msgid "Switched to branch '%s'\n"
-msgstr "已切換至分支 “%s”\n"
+msgstr "已切換至分支「%s」\n"
# 譯者:請維持前導空格
#: builtin/checkout.c
@@ -4474,7 +4497,7 @@ msgstr "在修訂版遍歷時遇到內部錯誤"
#: builtin/checkout.c
msgid "Previous HEAD position was"
-msgstr "之前的 HEAD 指針位置在"
+msgstr "之前的 HEAD 指標位置在"
#: builtin/checkout.c
msgid "You are on a branch yet to be born"
@@ -4486,7 +4509,7 @@ msgid ""
"'%s' could be both a local file and a tracking branch.\n"
"Please use -- (and optionally --no-guess) to disambiguate"
msgstr ""
-"“%s” 既可以是本機檔案,也可以是追蹤分支。\n"
+"「%s」既可以是本機檔案,也可以是追蹤分支。\n"
"請使用 --(和可選的 --no-guess)來消除歧義"
#: builtin/checkout.c
@@ -4500,19 +4523,19 @@ msgid ""
"one remote, e.g. the 'origin' remote, consider setting\n"
"checkout.defaultRemote=origin in your config."
msgstr ""
-"如果您想要簽出遠端追蹤分支,例如 “origin”,\n"
+"如果您想要簽出遠端追蹤分支,例如「origin」,\n"
"您可以使用 --track 選項寫出全名:\n"
"\n"
" git checkout --track origin/<name>\n"
"\n"
"如果您平時比較想要使用模糊的簡短分支名稱 <name>,\n"
-"而不太想寫如 “origin” 的遠端版本庫名稱,\n"
+"而不太想寫如「origin」的遠端版本庫名稱,\n"
"可以在組態中設定 checkout.defaultRemote=origin。"
#: builtin/checkout.c
#, c-format
msgid "'%s' matched multiple (%d) remote tracking branches"
-msgstr "“%s” 符合多個 (%d) 遠端追蹤分支"
+msgstr "「%s」符合多個 (%d) 遠端追蹤分支"
#: builtin/checkout.c
msgid "only one reference expected"
@@ -4536,27 +4559,27 @@ msgstr "引用不是樹狀物件:%s"
#: builtin/checkout.c
#, c-format
msgid "a branch is expected, got tag '%s'"
-msgstr "預期收到分支,卻收到標籤 “%s”"
+msgstr "預期收到分支,卻收到標籤「%s」"
#: builtin/checkout.c
#, c-format
msgid "a branch is expected, got remote branch '%s'"
-msgstr "預期收到分支,卻收到遠端分支 “%s”"
+msgstr "預期收到分支,卻收到遠端分支「%s」"
#: builtin/checkout.c
#, c-format
msgid "a branch is expected, got '%s'"
-msgstr "預期收到分支,卻收到 “%s”"
+msgstr "預期收到分支,卻收到「%s」"
#: builtin/checkout.c
#, c-format
msgid "a branch is expected, got commit '%s'"
-msgstr "預期收到分支,卻收到提交 “%s”"
+msgstr "預期收到分支,卻收到提交「%s」"
#: builtin/checkout.c
msgid ""
"If you want to detach HEAD at the commit, try again with the --detach option."
-msgstr "若您想要在此提交分離 HEAD 指針,請傳入 --detach 選項重試。"
+msgstr "若您想要在此提交分離 HEAD 指標,請傳入 --detach 選項重試。"
#: builtin/checkout.c
msgid ""
@@ -4564,7 +4587,7 @@ msgid ""
"Consider \"git merge --quit\" or \"git worktree add\"."
msgstr ""
"無法在合併時切換分支\n"
-"請試試 “git merge --quit” 或 “git worktree add”。"
+"請試試「git merge --quit」或「git worktree add」。"
#: builtin/checkout.c
msgid ""
@@ -4572,7 +4595,7 @@ msgid ""
"Consider \"git am --quit\" or \"git worktree add\"."
msgstr ""
"無法在 am 工作階段期間時切換分支\n"
-"請試試 “git am --quit” 或 “git worktree add”。"
+"請試試「git am --quit」或「git worktree add」。"
#: builtin/checkout.c
msgid ""
@@ -4580,7 +4603,7 @@ msgid ""
"Consider \"git rebase --quit\" or \"git worktree add\"."
msgstr ""
"無法在重定基底時切換分支\n"
-"請試試 “git rebase --quit” 或 “git worktree add”。"
+"請試試「git rebase --quit」或「git worktree add」。"
#: builtin/checkout.c
msgid ""
@@ -4588,7 +4611,7 @@ msgid ""
"Consider \"git cherry-pick --quit\" or \"git worktree add\"."
msgstr ""
"無法在揀選時切換分支\n"
-"請試試 “git cherry-pick --quit” 或 “git worktree add”。"
+"請試試「git cherry-pick --quit」或「git worktree add」。"
#: builtin/checkout.c
msgid ""
@@ -4596,7 +4619,7 @@ msgid ""
"Consider \"git revert --quit\" or \"git worktree add\"."
msgstr ""
"無法在還原時切換分支\n"
-"請試試 “git revert --quit” 或 “git worktree add”。"
+"請試試「git revert --quit」或「git worktree add」。"
#: builtin/checkout.c
msgid "you are switching branch while bisecting"
@@ -4609,22 +4632,22 @@ msgstr "路徑不能與切換分支同時使用"
#: builtin/checkout.c
#, c-format
msgid "'%s' cannot be used with switching branches"
-msgstr "“%s” 不能與切換分支同時使用"
+msgstr "「%s」不能與切換分支同時使用"
#: builtin/checkout.c
#, c-format
msgid "'%s' cannot be used with '%s'"
-msgstr "“%s” 不能與 “%s” 同時使用"
+msgstr "「%s」不能與「%s」同時使用"
#: builtin/checkout.c
#, c-format
msgid "'%s' cannot take <start-point>"
-msgstr "“%s” 不取 <start-point>"
+msgstr "「%s」不取 <start-point>"
#: builtin/checkout.c
#, c-format
msgid "Cannot switch branch to a non-commit '%s'"
-msgstr "無法將分支切換至非提交項目 “%s”"
+msgstr "無法將分支切換至非提交項目「%s」"
#: builtin/checkout.c
msgid "missing branch or commit argument"
@@ -4649,7 +4672,7 @@ msgstr "衝突輸出風格(merge、diff3 或 zdiff3)"
#: builtin/checkout.c builtin/worktree.c
msgid "detach HEAD at named commit"
-msgstr "自指定提交分離 HEAD 指針"
+msgstr "自指定提交分離 HEAD 指標"
#: builtin/checkout.c
msgid "force checkout (throw away local modifications)"
@@ -4686,7 +4709,7 @@ msgstr "對路徑規格不做稀疏簽出的限制"
#: builtin/checkout.c
#, c-format
msgid "options '-%c', '-%c', and '%s' cannot be used together"
-msgstr "“-%c”、“-%c” 和 “%s” 選項不得同時使用"
+msgstr "「-%c」、「-%c」和「%s」選項不得同時使用"
#: builtin/checkout.c
msgid "--track needs a branch name"
@@ -4709,12 +4732,12 @@ msgstr "無效的路徑規格"
#: builtin/checkout.c
#, c-format
msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
-msgstr "“%s” 不是提交,因此不能以這為基礎建立 “%s” 分支"
+msgstr "「%s」不是提交,因此不能以這為基礎建立「%s」分支"
#: builtin/checkout.c
#, c-format
msgid "git checkout: --detach does not take a path argument '%s'"
-msgstr "git checkout:--detach 不取路徑引數 “%s”"
+msgstr "git checkout:--detach 不取路徑引數「%s」"
#: builtin/checkout.c
msgid ""
@@ -4747,7 +4770,7 @@ msgstr "為新分支建立引用日誌"
#: builtin/checkout.c
msgid "second guess 'git checkout <no-such-branch>' (default)"
-msgstr "二次猜測 “git checkout <無此分支>”(預設值)"
+msgstr "二次猜測「git checkout <無此分支>」(預設值)"
#: builtin/checkout.c
msgid "use overlay mode (default)"
@@ -4763,7 +4786,7 @@ msgstr "建立/重設並切換至指定分支"
#: builtin/checkout.c
msgid "second guess 'git switch <no-such-branch>'"
-msgstr "二次猜測 “git switch <無此分支>”"
+msgstr "二次猜測「git switch <無此分支>」"
#: builtin/checkout.c
msgid "throw away local modifications"
@@ -4907,7 +4930,7 @@ msgstr ""
"clean - 開始清理\n"
"filter by pattern - 透過範本排除要刪除的條目\n"
"select by numbers - 透過數字選擇要刪除的條目\n"
-"ask each - 針對刪除逐一詢問(就像 “rm -i”)\n"
+"ask each - 針對刪除逐一詢問(就像「rm -i」)\n"
"quit - 停止刪除並離開\n"
"help - 顯示本輔助說明\n"
"? - 顯示如何在提示下選擇的協助"
@@ -4937,9 +4960,9 @@ msgstr "互動式清除"
msgid "remove whole directories"
msgstr "移除整個目錄"
-#: builtin/clean.c builtin/describe.c builtin/grep.c builtin/log.c
-#: builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c builtin/show-ref.c
-#: ref-filter.h
+#: builtin/clean.c builtin/config.c builtin/describe.c builtin/grep.c
+#: builtin/log.c builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c
+#: builtin/show-ref.c ref-filter.h
msgid "pattern"
msgstr "pattern"
@@ -5027,7 +5050,7 @@ msgstr "name"
#: builtin/clone.c
msgid "use <name> instead of 'origin' to track upstream"
-msgstr "使用 <name> 而不是 “origin” 追蹤上游"
+msgstr "使用 <name> 而不是「origin」追蹤上游"
#: builtin/clone.c
msgid "checkout <branch> instead of the remote's HEAD"
@@ -5138,7 +5161,7 @@ msgstr "%s 存在且不是一個目錄"
#: builtin/clone.c
#, c-format
msgid "'%s' is a symlink, refusing to clone with --local"
-msgstr "“%s” 是個符號連結,故不能使用 --local 複製"
+msgstr "「%s」是個符號連結,故不能使用 --local 複製"
#: builtin/clone.c
#, c-format
@@ -5153,7 +5176,17 @@ msgstr "「%s」符號連結已存在,拒絕使用 --local 複製"
#: builtin/clone.c compat/precompose_utf8.c
#, c-format
msgid "failed to unlink '%s'"
-msgstr "無法刪除 “%s”"
+msgstr "無法刪除「%s」"
+
+#: builtin/clone.c
+#, c-format
+msgid "hardlink cannot be checked at '%s'"
+msgstr "無法檢查位於「%s」的硬連結"
+
+#: builtin/clone.c
+#, c-format
+msgid "hardlink different from source at '%s'"
+msgstr "硬連結與位於 '%s' 的來源不同"
#: builtin/clone.c
#, c-format
@@ -5231,10 +5264,10 @@ msgstr "太多參數。"
msgid "You must specify a repository to clone."
msgstr "您必須指定要複製的版本庫。"
-#: builtin/clone.c builtin/init-db.c setup.c
+#: builtin/clone.c builtin/init-db.c builtin/refs.c setup.c
#, c-format
msgid "unknown ref storage format '%s'"
-msgstr "未知的引用儲存格式 “%s”"
+msgstr "未知的引用儲存格式「%s」"
#: builtin/clone.c
#, c-format
@@ -5331,7 +5364,7 @@ msgstr "無法初始化版本庫,略過套件包 URI"
#: builtin/clone.c
#, c-format
msgid "failed to fetch objects from bundle URI '%s'"
-msgstr "無法從套件包 URL “%s” 抓取物件"
+msgstr "無法從套件包 URL「%s」抓取物件"
#: builtin/clone.c
msgid "failed to fetch advertised bundles"
@@ -5391,7 +5424,7 @@ msgstr "--command 必須是第一個參數"
msgid ""
"git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]"
msgstr ""
-"git commit-graph verify [--object-dir <目錄>] [--shallow] [--[no-]progress]"
+"git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]"
#: builtin/commit-graph.c
msgid ""
@@ -5415,21 +5448,21 @@ msgstr "目錄"
#: builtin/commit-graph.c
msgid "the object directory to store the graph"
-msgstr "儲存圖形的物件目錄"
+msgstr "儲存圖的物件目錄"
#: builtin/commit-graph.c
msgid "if the commit-graph is split, only verify the tip file"
-msgstr "如果提交圖形被分割,只驗證頭一個檔案"
+msgstr "如果提交圖被分割,只驗證頭一個檔案"
#: builtin/commit-graph.c
#, c-format
msgid "Could not open commit-graph '%s'"
-msgstr "無法開啟提交圖形 '%s'"
+msgstr "無法開啟提交圖「%s」"
#: builtin/commit-graph.c
#, c-format
msgid "could not open commit-graph chain '%s'"
-msgstr "無法開啟提交圖鏈 “%s”"
+msgstr "無法開啟提交圖鏈「%s」"
#: builtin/commit-graph.c
#, c-format
@@ -5465,7 +5498,7 @@ msgstr "從標準輸入中的提交開始掃描"
#: builtin/commit-graph.c
msgid "include all commits already in the commit-graph file"
-msgstr "包含 commit-graph 檔案中已有所有提交"
+msgstr "包含提交圖檔案中所有已有的提交"
#: builtin/commit-graph.c
msgid "enable computation for changed paths"
@@ -5473,15 +5506,15 @@ msgstr "啟用已變更路徑的計算"
#: builtin/commit-graph.c
msgid "allow writing an incremental commit-graph file"
-msgstr "允許寫一個增量提交圖形檔案"
+msgstr "允許寫一個增量提交圖檔案"
#: builtin/commit-graph.c
msgid "maximum number of commits in a non-base split commit-graph"
-msgstr "在非基本分割提交圖形中的最大提交數"
+msgstr "在非基礎分割提交圖中的最大提交數"
#: builtin/commit-graph.c
msgid "maximum ratio between two levels of a split commit-graph"
-msgstr "一個分割提交圖形的兩個級別之間的最大比率"
+msgstr "一個分割提交圖的兩個級別之間的最大比率"
#: builtin/commit-graph.c
msgid "only expire files older than a given date-time"
@@ -5719,7 +5752,7 @@ msgstr "無法選擇一個未被目前提交說明使用的備註字元"
#: builtin/commit.c
#, c-format
msgid "could not lookup commit '%s'"
-msgstr "無法查詢提交 “%s”"
+msgstr "無法查詢提交「%s」"
#: builtin/commit.c builtin/shortlog.c
#, c-format
@@ -5845,7 +5878,7 @@ msgstr "%s提交者:%.*s <%.*s>"
msgid "Cannot read index"
msgstr "無法讀取索引"
-#: builtin/commit.c
+#: builtin/commit.c builtin/tag.c
msgid "unable to pass trailers to --trailers"
msgstr "無法將尾部署名傳遞至 --trailers"
@@ -6056,11 +6089,11 @@ msgstr "使用 autosquash 格式的提交說明用以壓縮至指定的提交"
msgid "the commit is authored by me now (used with -C/-c/--amend)"
msgstr "現在將該提交的作者改為我(和 -C/-c/--amend 參數共用)"
-#: builtin/commit.c builtin/interpret-trailers.c
+#: builtin/commit.c builtin/interpret-trailers.c builtin/tag.c
msgid "trailer"
msgstr "尾部署名"
-#: builtin/commit.c
+#: builtin/commit.c builtin/tag.c
msgid "add custom trailer(s)"
msgstr "加入自訂尾部署名"
@@ -6169,20 +6202,60 @@ msgid ""
"not exceeded, and then \"git restore --staged :/\" to recover."
msgstr ""
"版本庫已更新,但無法寫入新的索引檔案。請檢查磁碟是否\n"
-"已滿或磁碟配額已耗盡,然後執行 “git restore --staged :/” 復原。"
+"已滿或磁碟配額已耗盡,然後執行「git restore --staged :/」復原。"
#: builtin/config.c
-msgid "git config [<options>]"
-msgstr "git config [<選項>]"
+msgid "git config list [<file-option>] [<display-option>] [--includes]"
+msgstr "git config list [<檔案選項>] [<顯示選項>] [--includes]"
#: builtin/config.c
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr "無法識別的 --type 參數,%s"
+msgid ""
+"git config get [<file-option>] [<display-option>] [--includes] [--all] [--"
+"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] "
+"<name>"
+msgstr ""
+"git config get [<檔案選項>] [<顯示選項>] [--includes] [--all] [--regexp=<常規"
+"表示式>] [--value=<值>] [--fixed-value] [--default=<預設值>] <名稱>"
#: builtin/config.c
-msgid "only one type at a time"
-msgstr "一次只能一個類型"
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--"
+"fixed-value] <name> <value>"
+msgstr ""
+"git config set [<檔案選項>] [--type=<類型>] [--all] [--value=<值>] [--fixed-"
+"value] <名稱> <值>"
+
+#: builtin/config.c
+msgid ""
+"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] "
+"<name> <value>"
+msgstr ""
+"git config unset [<檔案選項>] [--all] [--value=<值>] [--fixed-value] <名稱> <"
+"值>"
+
+#: builtin/config.c
+msgid "git config rename-section [<file-option>] <old-name> <new-name>"
+msgstr "git config rename-section [<檔案選項>] <舊名稱> <新名稱>"
+
+#: builtin/config.c
+msgid "git config remove-section [<file-option>] <name>"
+msgstr "git config remove-section [<檔案選項>] <名稱>"
+
+#: builtin/config.c
+msgid "git config edit [<file-option>]"
+msgstr "git config edit [<檔案選項>]"
+
+#: builtin/config.c
+msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+msgstr "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"
+
+#: builtin/config.c
+msgid ""
+"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] "
+"[--value=<value>] [--fixed-value] <name> <value>"
+msgstr ""
+"git config set [<檔案選項>] [--type=<類型>] [--comment=<備註>] [--all] [--"
+"value=<值>] [--fixed-value] <名稱> <值>"
#: builtin/config.c
msgid "Config file location"
@@ -6217,70 +6290,6 @@ msgid "read config from given blob object"
msgstr "從提供的資料物件讀取設定"
#: builtin/config.c
-msgid "Action"
-msgstr "動作"
-
-#: builtin/config.c
-msgid "get value: name [value-pattern]"
-msgstr "取得值:name [value-pattern]"
-
-#: builtin/config.c
-msgid "get all values: key [value-pattern]"
-msgstr "取得所有值:key [value-pattern]"
-
-#: builtin/config.c
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr "根據常規表示式取得值:name-regex [value-pattern]"
-
-#: builtin/config.c
-msgid "get value specific for the URL: section[.var] URL"
-msgstr "獲得 URL 取值:section[.var] URL"
-
-#: builtin/config.c
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr "取代所有符合的變數:name value [value-pattern]"
-
-#: builtin/config.c
-msgid "add a new variable: name value"
-msgstr "新增一個新的變數:name value"
-
-#: builtin/config.c
-msgid "remove a variable: name [value-pattern]"
-msgstr "移除一個變數:name [value-pattern]"
-
-#: builtin/config.c
-msgid "remove all matches: name [value-pattern]"
-msgstr "移除所有符合項目:name [value-pattern]"
-
-#: builtin/config.c
-msgid "rename section: old-name new-name"
-msgstr "重新命名小節:old-name new-name"
-
-#: builtin/config.c
-msgid "remove a section: name"
-msgstr "刪除一個小節:name"
-
-#: builtin/config.c
-msgid "list all"
-msgstr "全部列出"
-
-#: builtin/config.c
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "比較「value-pattern」的值時,使用字串相等比較"
-
-#: builtin/config.c
-msgid "open an editor"
-msgstr "開啟一個編輯器"
-
-#: builtin/config.c
-msgid "find the color configured: slot [default]"
-msgstr "獲得設定的顏色:設定 [預設值]"
-
-#: builtin/config.c
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr "獲得顏色設定:設定 [stdout-is-tty]"
-
-#: builtin/config.c
msgid "Type"
msgstr "類型"
@@ -6317,8 +6326,8 @@ msgid "value is an expiry date"
msgstr "值是一個到期日期"
#: builtin/config.c
-msgid "Other"
-msgstr "其它"
+msgid "Display options"
+msgstr "顯示選項"
#: builtin/config.c
msgid "terminate values with NUL byte"
@@ -6329,10 +6338,6 @@ msgid "show variable names only"
msgstr "只顯示變數名"
#: builtin/config.c
-msgid "respect include directives on lookup"
-msgstr "查詢時引用 include 指令遞迴尋找"
-
-#: builtin/config.c
msgid "show origin of config (file, standard input, blob, command line)"
msgstr "顯示設定的來源(檔案、標準輸入、資料物件,或命令列)"
@@ -6343,16 +6348,17 @@ msgstr ""
"令 command)"
#: builtin/config.c
-msgid "value"
-msgstr "取值"
+msgid "show config keys in addition to their values"
+msgstr "除了顯示組態值,額外顯示其鍵名"
#: builtin/config.c
-msgid "with --get, use default value when missing entry"
-msgstr "使用 --get 但未指定參數時所使用的預設值"
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "無法識別的 --type 參數,%s"
#: builtin/config.c
-msgid "human-readable comment string (# will be prepended as needed)"
-msgstr "人類可讀的備註字串(將按需插入 # 至前方)"
+msgid "only one type at a time"
+msgstr "一次只能一個類型"
#: builtin/config.c
#, c-format
@@ -6445,56 +6451,93 @@ msgstr ""
"詳情請閱讀「git help worktree」的「CONFIGURATION FILE」小節"
#: builtin/config.c
-msgid "--get-color and variable type are incoherent"
-msgstr "--get-color 和變數類型不相容"
+msgid "Other"
+msgstr "其它"
#: builtin/config.c
-msgid "only one action at a time"
-msgstr "一次只能有一個動作"
+msgid "respect include directives on lookup"
+msgstr "查詢時引用 include 指令遞迴尋找"
#: builtin/config.c
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr "--name-only 僅適用於 --list 或 --get-regexp"
+#, c-format
+msgid "unable to read config file '%s'"
+msgstr "無法讀取設定檔案 '%s'"
#: builtin/config.c
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr "--show-origin 僅適用於 --get、--get-all、--get-regexp 和 --list"
+msgid "error processing config file(s)"
+msgstr "處理設定檔案發生錯誤"
#: builtin/config.c
-msgid "--default is only applicable to --get"
-msgstr "--default 僅適用於 --get"
+msgid "Filter options"
+msgstr "過濾選項"
#: builtin/config.c
-msgid "--comment is only applicable to add/set/replace operations"
-msgstr "--comment 只能用於加入、設定和取代動作"
+msgid "return all values for multi-valued config options"
+msgstr "回傳有多項值之組態選項的所有值"
+
+#: builtin/config.c
+msgid "interpret the name as a regular expression"
+msgstr "將名稱當作常規表示式解讀"
+
+#: builtin/config.c
+msgid "show config with values matching the pattern"
+msgstr "顯示值符合模式的組態"
+
+#: builtin/config.c
+msgid "use string equality when comparing values to value pattern"
+msgstr "使用字串相等比較值和模式"
+
+#: builtin/config.c
+msgid "URL"
+msgstr "URL"
+
+#: builtin/config.c
+msgid "show config matching the given URL"
+msgstr "顯示符合提供 URL 的組態"
+
+#: builtin/config.c
+msgid "value"
+msgstr "取值"
+
+#: builtin/config.c
+msgid "use default value when missing entry"
+msgstr "未指定參數時所使用的預設值"
#: builtin/config.c
msgid "--fixed-value only applies with 'value-pattern'"
msgstr "--fixed-value 僅套用至 'value-pattern'"
#: builtin/config.c
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr "無法讀取設定檔案 '%s'"
+msgid "--default= cannot be used with --all or --url="
+msgstr "--default= 無法和 --all 或 --url= 一起使用"
#: builtin/config.c
-msgid "error processing config file(s)"
-msgstr "處理設定檔案發生錯誤"
+msgid "--url= cannot be used with --all, --regexp or --value"
+msgstr "--url= 無法和 --all、--regexp、--value 一起使用"
#: builtin/config.c
-msgid "editing stdin is not supported"
-msgstr "不支援編輯標準輸入"
+msgid "Filter"
+msgstr "過濾器"
#: builtin/config.c
-msgid "editing blobs is not supported"
-msgstr "不支援編輯資料物件"
+msgid "replace multi-valued config option with new value"
+msgstr "以新值取代有多項值的組態選項"
#: builtin/config.c
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr "不能建立設定檔案 %s"
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "人類可讀的備註字串(將按需插入 # 至前方)"
+
+#: builtin/config.c
+msgid "add a new line without altering any existing values"
+msgstr "在不更動任何現有值的情況下新增一行"
+
+#: builtin/config.c
+msgid "--fixed-value only applies with --value=<pattern>"
+msgstr "--fixed-value 僅套用至 --value=<模式>"
+
+#: builtin/config.c
+msgid "--append cannot be used with --value=<pattern>"
+msgstr "--append 無法和 --value=<模式> 一起使用"
#: builtin/config.c
#, c-format
@@ -6510,6 +6553,109 @@ msgstr ""
msgid "no such section: %s"
msgstr "無此小節:%s"
+#: builtin/config.c
+msgid "editing stdin is not supported"
+msgstr "不支援編輯標準輸入"
+
+#: builtin/config.c
+msgid "editing blobs is not supported"
+msgstr "不支援編輯資料物件"
+
+#: builtin/config.c
+#, c-format
+msgid "cannot create configuration file %s"
+msgstr "不能建立設定檔案 %s"
+
+#: builtin/config.c
+msgid "Action"
+msgstr "動作"
+
+#: builtin/config.c
+msgid "get value: name [<value-pattern>]"
+msgstr "取得值:name [<value-pattern>]"
+
+#: builtin/config.c
+msgid "get all values: key [<value-pattern>]"
+msgstr "取得所有值:key [<value-pattern>]"
+
+#: builtin/config.c
+msgid "get values for regexp: name-regex [<value-pattern>]"
+msgstr "根據常規表示式取得值:name-regex [<value-pattern>]"
+
+#: builtin/config.c
+msgid "get value specific for the URL: section[.var] URL"
+msgstr "獲得 URL 取值:section[.var] URL"
+
+#: builtin/config.c
+msgid "replace all matching variables: name value [<value-pattern>]"
+msgstr "取代所有符合的變數:name value [<value-pattern>]"
+
+#: builtin/config.c
+msgid "add a new variable: name value"
+msgstr "新增一個新的變數:name value"
+
+#: builtin/config.c
+msgid "remove a variable: name [<value-pattern>]"
+msgstr "移除一個變數:name [<value-pattern>]"
+
+#: builtin/config.c
+msgid "remove all matches: name [<value-pattern>]"
+msgstr "移除所有符合項目:name [<value-pattern>]"
+
+#: builtin/config.c
+msgid "rename section: old-name new-name"
+msgstr "重新命名小節:old-name new-name"
+
+#: builtin/config.c
+msgid "remove a section: name"
+msgstr "刪除一個小節:name"
+
+#: builtin/config.c
+msgid "list all"
+msgstr "全部列出"
+
+#: builtin/config.c
+msgid "open an editor"
+msgstr "開啟一個編輯器"
+
+#: builtin/config.c
+msgid "find the color configured: slot [<default>]"
+msgstr "獲得設定的顏色:設定 [<預設值>]"
+
+#: builtin/config.c
+msgid "find the color setting: slot [<stdout-is-tty>]"
+msgstr "獲得顏色設定:設定 [<stdout-is-tty>]"
+
+#: builtin/config.c
+msgid "with --get, use default value when missing entry"
+msgstr "使用 --get 但未指定參數時所使用的預設值"
+
+#: builtin/config.c
+msgid "--get-color and variable type are incoherent"
+msgstr "--get-color 和變數類型不相容"
+
+#: builtin/config.c
+msgid "no action specified"
+msgstr "未指定動作"
+
+#: builtin/config.c
+msgid "--name-only is only applicable to --list or --get-regexp"
+msgstr "--name-only 僅適用於 --list 或 --get-regexp"
+
+#: builtin/config.c
+msgid ""
+"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
+"list"
+msgstr "--show-origin 僅適用於 --get、--get-all、--get-regexp 和 --list"
+
+#: builtin/config.c
+msgid "--default is only applicable to --get"
+msgstr "--default 僅適用於 --get"
+
+#: builtin/config.c
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment 只能用於加入、設定和取代動作"
+
#: builtin/count-objects.c
msgid "print sizes in human readable format"
msgstr "以使用者可讀的格式顯示大小"
@@ -6694,11 +6840,11 @@ msgstr "標記"
#: builtin/describe.c
msgid "append <mark> on dirty working tree (default: \"-dirty\")"
-msgstr "對於髒工作區,追加 <標記>(預設值:”-dirty\")"
+msgstr "對於髒工作區,追加 <標記>(預設值:」-dirty\")"
#: builtin/describe.c
msgid "append <mark> on broken working tree (default: \"-broken\")"
-msgstr "對於損壞的工作區,追加 <標記>(預設值:”-broken\")"
+msgstr "對於損壞的工作區,追加 <標記>(預設值:」-broken\")"
#: builtin/describe.c
msgid "No names found, cannot describe anything."
@@ -7363,7 +7509,7 @@ msgstr "在所有更新分支上檢查強制更新"
#: builtin/fetch.c
msgid "write the commit-graph after fetching"
-msgstr "抓取後寫入分支圖"
+msgstr "抓取後寫入提交圖"
#: builtin/fetch.c
msgid "accept refspecs from stdin"
@@ -7539,6 +7685,10 @@ msgid "config key storing a list of repository paths"
msgstr "儲存版本庫路徑清單的設定鍵"
#: builtin/for-each-repo.c
+msgid "keep going even if command fails in a repository"
+msgstr "命令在版本庫中失敗時仍繼續執行"
+
+#: builtin/for-each-repo.c
msgid "missing --config=<config>"
msgstr "缺少 --config=<設定>"
@@ -7753,12 +7903,12 @@ msgstr "%s:%s 的 resolve-undo 中的 sha1 指標無效"
#: builtin/fsck.c
#, c-format
msgid "unable to load rev-index for pack '%s'"
-msgstr "無法讀取 “%s” 封裝的修訂版索引 (rev-index)"
+msgstr "無法讀取「%s」封裝的修訂版索引 (rev-index)"
#: builtin/fsck.c
#, c-format
msgid "invalid rev-index for pack '%s'"
-msgstr "“%s” 封裝的修訂版索引 (rev-index) 無效"
+msgstr "「%s」封裝的修訂版索引 (rev-index) 無效"
#: builtin/fsck.c
msgid ""
@@ -8065,7 +8215,7 @@ msgstr "無法識別的 --schedule 引數 '%s'"
#: builtin/gc.c
msgid "failed to write commit-graph"
-msgstr "無法寫入提交圖形"
+msgstr "無法寫入提交圖"
#: builtin/gc.c
msgid "failed to prefetch remotes"
@@ -8192,7 +8342,7 @@ msgstr "無法啟動 schtasks"
#: builtin/gc.c
msgid "failed to run 'crontab -l'; your system might not support 'cron'"
-msgstr "無法執行 “crontab -l”;您的系統可能不支援 “cron”"
+msgstr "無法執行「crontab -l」;您的系統可能不支援「cron」"
#: builtin/gc.c
msgid "failed to create crontab temporary file"
@@ -8204,11 +8354,11 @@ msgstr "無法開啟暫存檔"
#: builtin/gc.c
msgid "failed to run 'crontab'; your system might not support 'cron'"
-msgstr "無法執行 “crontab”;您的系統可能不支援 “cron”"
+msgstr "無法執行「crontab」;您的系統可能不支援「cron」"
#: builtin/gc.c
msgid "'crontab' died"
-msgstr "“crontab” 結束運作"
+msgstr "「crontab」結束運作"
#: builtin/gc.c builtin/worktree.c
#, c-format
@@ -9135,7 +9285,7 @@ msgstr "--only-trailers --only-input --unfold 的別名"
#: builtin/interpret-trailers.c
msgid "do not treat \"---\" as the end of input"
-msgstr "不要把 “---” 當作輸入結尾"
+msgstr "不要把「---」當作輸入結尾"
#: builtin/interpret-trailers.c
msgid "trailer(s) to add"
@@ -9250,7 +9400,7 @@ msgstr "不是一個範圍"
#: builtin/log.c
#, c-format
msgid "unable to read branch description file '%s'"
-msgstr "無法讀取分支描述檔 “%s”"
+msgstr "無法讀取分支描述檔「%s」"
#: builtin/log.c
msgid "cover letter needs email format"
@@ -9367,8 +9517,12 @@ msgid "max length of output filename"
msgstr "輸出檔名的最大長度"
#: builtin/log.c
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "使用 [RFC PATCH] 代替 [PATCH]"
+msgid "rfc"
+msgstr "rfc"
+
+#: builtin/log.c
+msgid "add <rfc> (default 'RFC') before 'PATCH'"
+msgstr "在「PATCH」前冠上 <rfc>(預設為「RFC」)"
#: builtin/log.c
msgid "cover-from-description-mode"
@@ -9711,11 +9865,11 @@ msgstr ""
#: builtin/ls-remote.c
msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
msgstr ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
+"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<patterns>...]]"
@@ -9736,9 +9890,13 @@ msgid "limit to tags"
msgstr "僅限於標籤"
#: builtin/ls-remote.c
-msgid "limit to heads"
+msgid "limit to branches"
msgstr "僅限於分支"
+#: builtin/ls-remote.c builtin/show-ref.c
+msgid "deprecated synonym for --branches"
+msgstr "--branches 已棄用的同義詞"
+
#: builtin/ls-remote.c
msgid "do not show peeled tags"
msgstr "不顯示已解析的標籤"
@@ -9963,7 +10121,7 @@ msgstr "為 檔案1/初始檔案/檔案2 設定標籤"
#: builtin/merge-file.c
#, c-format
msgid "object '%s' does not exist"
-msgstr "物件 “%s” 不存在"
+msgstr "物件「%s」不存在"
#: builtin/merge-file.c
msgid "Could not write object file"
@@ -11215,7 +11373,7 @@ msgstr "不一致的差異計數"
#: builtin/pack-objects.c
#, c-format
msgid "invalid pack.allowPackReuse value: '%s'"
-msgstr "無效的 pack.allowPackReuse 值:“%s”"
+msgstr "無效的 pack.allowPackReuse 值:「%s」"
#: builtin/pack-objects.c
#, c-format
@@ -11223,8 +11381,8 @@ msgid ""
"value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
"hash> <uri>' (got '%s')"
msgstr ""
-"uploadpack.blobpackfileuri 的值格式必須為 '<object-hash> <pack-hash> <uri>' "
-"(收到 '%s')"
+"uploadpack.blobpackfileuri 的值格式必須為 '<object-hash> <pack-hash> "
+"<uri>' (收到 '%s')"
#: builtin/pack-objects.c
#, c-format
@@ -11860,7 +12018,7 @@ msgid ""
"To choose either option permanently, see push.default in 'git help config'.\n"
msgstr ""
"\n"
-"若要永久選擇某個選項,請參閱 “git help config” 中的 push.default。\n"
+"若要永久選擇某個選項,請參閱「git help config」中的 push.default。\n"
#: builtin/push.c
msgid ""
@@ -11871,8 +12029,8 @@ msgid ""
msgstr ""
"\n"
"若要避免在名稱與本機分支不同時自動設定上游分支,\n"
-"請參閱 “git help config” 中 branch.autoSetupMerge 的\n"
-"“simple” 選項。\n"
+"請參閱「git help config」中 branch.autoSetupMerge 的\n"
+"「simple」選項。\n"
#: builtin/push.c
#, c-format
@@ -11919,8 +12077,8 @@ msgid ""
"upstream, see 'push.autoSetupRemote' in 'git help config'.\n"
msgstr ""
"\n"
-"若要使沒有追蹤上游的分支自動配置,請參閱 “git help config” 中的\n"
-"“push.autoSetupRemote”。\n"
+"若要使沒有追蹤上游的分支自動配置,請參閱「git help config」中的\n"
+"「push.autoSetupRemote」。\n"
#: builtin/push.c
#, c-format
@@ -11965,8 +12123,8 @@ msgid ""
"See the 'Note about fast-forwards' in 'git push --help' for details."
msgstr ""
"更新被拒絕,因為您目前分支的最新提交落後於其對應的遠端分支。\n"
-"如果您想要整合遠端更動,請在再次推送前使用 “git pull”。詳見\n"
-"“git push --help” 中的〈Note about fast-forwards〉小節。"
+"如果您想要整合遠端更動,請在再次推送前使用「git pull」。詳見\n"
+"「git push --help」中的〈Note about fast-forwards〉小節。"
#: builtin/push.c
msgid ""
@@ -11976,8 +12134,8 @@ msgid ""
"See the 'Note about fast-forwards' in 'git push --help' for details."
msgstr ""
"更新被拒絕,因為推送的某分支的最新提交落後於其對應的遠端分支。\n"
-"如果您想要整合遠端更動,請在再次推送前使用 “git pull”。詳見\n"
-"“git push --help” 中的〈Note about fast-forwards〉小節。"
+"如果您想要整合遠端更動,請在再次推送前使用「git pull」。詳見\n"
+"「git push --help」中的〈Note about fast-forwards〉小節。"
#: builtin/push.c
msgid ""
@@ -11989,7 +12147,7 @@ msgid ""
msgstr ""
"更新被拒絕,因為遠端包含您本機沒有的提交。這通常是因為\n"
"另一個版本庫有推送更動到同個引用。如果您想要整合遠端更動,\n"
-"請在再次推送前使用 “git pull”。詳見 “git push --help” 中的\n"
+"請在再次推送前使用「git pull」。詳見「git push --help」中的\n"
"〈Note about fast-forwards〉小節。"
#: builtin/push.c
@@ -12013,8 +12171,8 @@ msgid ""
"See the 'Note about fast-forwards' in 'git push --help' for details."
msgstr ""
"更新被拒絕,因為遠端追蹤分支的最新提交自上次簽出後有改變。\n"
-"如果您想要整合遠端更動,請在再次推送前使用 “git pull”。\n"
-"詳見 “git push --help” 中的〈Note about fast-forwards〉小節。"
+"如果您想要整合遠端更動,請在再次推送前使用「git pull」。\n"
+"詳見「git push --help」中的〈Note about fast-forwards〉小節。"
#: builtin/push.c
#, c-format
@@ -12607,8 +12765,8 @@ msgid ""
"which is no longer supported; use 'merges' instead"
msgstr ""
"--preserve-merges 已被 --rebase-merges 取代\n"
-"註:您的 `pull.rebase` 設定可能也被設定為不受支援的 “preserve”;\n"
-"請改用 “merges”"
+"註:您的 `pull.rebase` 設定可能也被設定為不受支援的「preserve」;\n"
+"請改用「merges」"
#: builtin/rebase.c
msgid "no rebase in progress"
@@ -12928,6 +13086,27 @@ msgstr "未指定要刪除的引用日誌"
msgid "invalid ref format: %s"
msgstr "無效的引用格式:%s"
+#: builtin/refs.c
+msgid "git refs migrate --ref-format=<format> [--dry-run]"
+msgstr "git refs migrate --ref-format=<格式> [--dry-run]"
+
+#: builtin/refs.c
+msgid "specify the reference format to convert to"
+msgstr "指定要轉換成的引用格式"
+
+#: builtin/refs.c
+msgid "perform a non-destructive dry-run"
+msgstr "進行非破壞性的試執行"
+
+#: builtin/refs.c
+msgid "missing --ref-format=<format>"
+msgstr "缺少 --ref-format=<格式>"
+
+#: builtin/refs.c
+#, c-format
+msgid "repository already uses '%s' format"
+msgstr "版本庫已經使用 '%s' 格式"
+
#: builtin/remote.c
msgid ""
"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
@@ -13273,10 +13452,6 @@ msgstr "* 遠端 %s"
msgid " Fetch URL: %s"
msgstr " 取得位址:%s"
-#: builtin/remote.c
-msgid "(no URL)"
-msgstr "(無 URL)"
-
#. TRANSLATORS: the colon ':' should align
#. with the one in " Fetch URL: %s"
#. translation.
@@ -13287,6 +13462,10 @@ msgid " Push URL: %s"
msgstr " 推送位址:%s"
#: builtin/remote.c
+msgid "(no URL)"
+msgstr "(無 URL)"
+
+#: builtin/remote.c
#, c-format
msgid " HEAD branch: %s"
msgstr " HEAD 分支:%s"
@@ -13421,11 +13600,6 @@ msgid "return all URLs"
msgstr "返回所有 URL 位址"
#: builtin/remote.c
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr "沒有給遠端版本庫 '%s' 設定 URL"
-
-#: builtin/remote.c
msgid "manipulate push URLs"
msgstr "動作推送 URLS"
@@ -13632,7 +13806,7 @@ msgstr "不能刪除珍品版本庫中的封包"
#: builtin/repack.c
#, c-format
msgid "option '%s' can only be used along with '%s'"
-msgstr "“%s” 選項只能與 “%s” 一起使用"
+msgstr "「%s」選項只能與「%s」一起使用"
#: builtin/repack.c
msgid "Nothing new to pack."
@@ -13646,7 +13820,7 @@ msgstr "無法將包重新命名為「%s」"
#: builtin/repack.c
#, c-format
msgid "pack-objects did not write a '%s' file for pack %s-%s"
-msgstr "pack-objects 沒有為 %2$s-%3$s 套件包寫入 “%1$s” 檔案"
+msgstr "pack-objects 沒有為 %2$s-%3$s 套件包寫入「%1$s」檔案"
#: builtin/repack.c sequencer.c
#, c-format
@@ -13955,7 +14129,7 @@ msgstr "必須傳入 --onto 或 --advance 選項"
msgid ""
"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
"will be forced"
-msgstr "將覆寫部分修訂版遍歷選項,強制使用 “struct rev_info” 的 “%s” 位元"
+msgstr "將覆寫部分修訂版遍歷選項,強制使用「struct rev_info」的「%s」位元"
#: builtin/replay.c
msgid "error preparing revisions"
@@ -14345,7 +14519,7 @@ msgstr "已棄用:請改用 --empty=keep"
#: builtin/revert.c
msgid "use the 'reference' format to refer to commits"
-msgstr "請使用 “reference” 格式參考提交"
+msgstr "請使用「reference」格式參考提交"
#: builtin/revert.c
msgid "revert failed"
@@ -14669,12 +14843,12 @@ msgstr "未知的雜湊算法"
#: builtin/show-ref.c
msgid ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
msgstr ""
"git show-ref [--head] [-d | --dereference]\n"
-" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
-" [--heads] [--] [<pattern>...]"
+" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n"
+" [--] [<pattern>...]"
#: builtin/show-ref.c
msgid ""
@@ -14703,12 +14877,12 @@ msgid "failed to look up reference"
msgstr "無法查詢引用"
#: builtin/show-ref.c
-msgid "only show tags (can be combined with heads)"
-msgstr "只顯示標籤(可以和頭共用)"
+msgid "only show tags (can be combined with branches)"
+msgstr "只顯示標籤(可以和分支共用)"
#: builtin/show-ref.c
-msgid "only show heads (can be combined with tags)"
-msgstr "只顯示頭(可以和標籤共用)"
+msgid "only show branches (can be combined with tags)"
+msgstr "只顯示分支(可以和標籤共用)"
#: builtin/show-ref.c
msgid "check for reference existence without resolving"
@@ -15440,7 +15614,7 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
msgid "could not get a repository handle for gitdir '%s'"
-msgstr "無法取得 gitdir “%s” 的版本庫控點"
+msgstr "無法取得 gitdir「%s」的版本庫控點"
#: builtin/submodule--helper.c
#, c-format
@@ -15457,20 +15631,20 @@ msgstr "不能識別 submodule.alternateErrorStrategy 的取值 '%s'"
msgid "Value '%s' for submodule.alternateLocation is not recognized"
msgstr "不能識別 submodule.alternateLocation 的取值 '%s'"
-#: builtin/submodule--helper.c
+#: builtin/submodule--helper.c submodule.c
#, c-format
msgid "refusing to create/use '%s' in another submodule's git dir"
msgstr "拒絕在其他子模組的 git 路徑建立/使用「%s」"
#: builtin/submodule--helper.c
#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "無法複製 '%s' 到子模組路徑 '%s'"
+msgid "directory not empty: '%s'"
+msgstr "目錄不是空的:「%s」"
#: builtin/submodule--helper.c
#, c-format
-msgid "directory not empty: '%s'"
-msgstr "目錄不是空的:「%s」"
+msgid "clone of '%s' into submodule path '%s' failed"
+msgstr "無法複製 '%s' 到子模組路徑 '%s'"
#: builtin/submodule--helper.c
#, c-format
@@ -15542,7 +15716,7 @@ msgstr "略過子模組 '%s'"
#: builtin/submodule--helper.c
#, c-format
msgid "cannot clone submodule '%s' without a URL"
-msgstr "無法在沒有網址的情況下複製 “%s” 子模組"
+msgstr "無法在沒有網址的情況下複製「%s」子模組"
#: builtin/submodule--helper.c
#, c-format
@@ -15660,15 +15834,15 @@ msgstr "不從遠端站台取得新物件"
#: builtin/submodule--helper.c
msgid "use the 'checkout' update strategy (default)"
-msgstr "使用 “checkout” 更新策略(預設值)"
+msgstr "使用「checkout」更新策略(預設值)"
#: builtin/submodule--helper.c
msgid "use the 'merge' update strategy"
-msgstr "使用 “merge” 更新策略"
+msgstr "使用「merge」更新策略"
#: builtin/submodule--helper.c
msgid "use the 'rebase' update strategy"
-msgstr "使用 “rebase” 更新策略"
+msgstr "使用「rebase」更新策略"
#: builtin/submodule--helper.c
msgid "create a shallow clone truncated to the specified number of revisions"
@@ -15911,9 +16085,11 @@ msgstr "更新的原因"
#: builtin/tag.c
msgid ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
msgstr ""
"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+" [(--trailer <token>[(=|:)<value>])...]\n"
" <tagname> [<commit> | <object>]"
#: builtin/tag.c
@@ -16081,7 +16257,7 @@ msgstr "只列印指向該物件的標籤"
#: builtin/tag.c
msgid "could not start 'git column'"
-msgstr "無法啟動 “git column”"
+msgstr "無法啟動「git column」"
#: builtin/tag.c
#, c-format
@@ -16511,7 +16687,7 @@ msgstr "git worktree unlock <worktree>"
#: builtin/worktree.c
msgid "No possible source branch, inferring '--orphan'"
-msgstr "沒有可能的來源分支,推測為 “--orphan”"
+msgstr "沒有可能的來源分支,推測為「--orphan」"
#: builtin/worktree.c
#, c-format
@@ -16646,8 +16822,8 @@ msgid ""
"HEAD contents: '%s'"
msgstr ""
"HEAD 指向無效(或孤立)引用。\n"
-"HEAD 路徑:“%s”\n"
-"HEAD 內容:“%s”"
+"HEAD 路徑:「%s」\n"
+"HEAD 內容:「%s」"
#: builtin/worktree.c
msgid ""
@@ -16655,7 +16831,7 @@ msgid ""
"present, stopping; use 'add -f' to override or fetch a remote first"
msgstr ""
"即使有提供一個遠端,卻不存在本機或遠端引用,\n"
-"故停止。使用 “add -f” 先覆蓋或抓取遠端"
+"故停止。使用「add -f」先覆蓋或抓取遠端"
#: builtin/worktree.c
msgid "checkout <branch> even if already checked out in other worktree"
@@ -16866,12 +17042,12 @@ msgstr "core.fsyncMethod = batch 不支援本平台"
#: bundle-uri.c
#, c-format
msgid "could not parse bundle list key %s with value '%s'"
-msgstr "無法解析套件包清單鍵 %s 的值 “%s”"
+msgstr "無法解析套件包清單鍵 %s 的值「%s」"
#: bundle-uri.c
#, c-format
msgid "bundle list at '%s' has no mode"
-msgstr "位於 “%s” 的套件包清單沒有模式"
+msgstr "位於「%s」的套件包清單沒有模式"
#: bundle-uri.c
msgid "failed to create temporary file"
@@ -16884,7 +17060,7 @@ msgstr "功能不足"
#: bundle-uri.c
#, c-format
msgid "file downloaded from '%s' is not a bundle"
-msgstr "從 “%s” 下載的檔案不是套件包"
+msgstr "從「%s」下載的檔案不是套件包"
#: bundle-uri.c
msgid "failed to store maximum creation token"
@@ -16893,7 +17069,7 @@ msgstr "無法儲存最大的建立權杖"
#: bundle-uri.c
#, c-format
msgid "unrecognized bundle mode from URI '%s'"
-msgstr "無法識別從 URI “%s” 取回的套件包模式"
+msgstr "無法識別從 URI「%s」取回的套件包模式"
#: bundle-uri.c
#, c-format
@@ -16903,17 +17079,17 @@ msgstr "超出套件包 URI 遞迴限制 (%d)"
#: bundle-uri.c
#, c-format
msgid "failed to download bundle from URI '%s'"
-msgstr "無法從 “%s” URI 下載套件包"
+msgstr "無法從「%s」URI 下載套件包"
#: bundle-uri.c
#, c-format
msgid "file at URI '%s' is not a bundle or bundle list"
-msgstr "位於 URI “%s” 的檔案不是套件包或套件包清單"
+msgstr "位於 URI「%s」的檔案不是套件包或套件包清單"
#: bundle-uri.c
#, c-format
msgid "bundle-uri: unexpected argument: '%s'"
-msgstr "bundle-uri: 非預期的引數:“%s”"
+msgstr "bundle-uri: 非預期的引數:「%s」"
#: bundle-uri.c
msgid "bundle-uri: expected flush after arguments"
@@ -16925,7 +17101,7 @@ msgstr "bundle-uri: 收到空白列"
#: bundle-uri.c
msgid "bundle-uri: line is not of the form 'key=value'"
-msgstr "bundle-uri: 列的格式不是 “key=value”"
+msgstr "bundle-uri: 列的格式不是「key=value」"
#: bundle-uri.c
msgid "bundle-uri: line has empty key or value"
@@ -16944,7 +17120,7 @@ msgstr "未知功能「%s」"
#: bundle.c
#, c-format
msgid "'%s' does not look like a v2 or v3 bundle file"
-msgstr "“%s” 不像是一個 v2 或 v3 版本的套件包檔案"
+msgstr "「%s」不像是一個 v2 或 v3 版本的套件包檔案"
#: bundle.c
#, c-format
@@ -16956,10 +17132,6 @@ msgid "Repository lacks these prerequisite commits:"
msgstr "版本庫中缺少這些必備的提交:"
#: bundle.c
-msgid "need a repository to verify a bundle"
-msgstr "需要版本庫驗證套件包"
-
-#: bundle.c
msgid ""
"some prerequisite commits exist in the object store, but are not connected "
"to the repository's history"
@@ -17478,6 +17650,10 @@ msgid "Manage reflog information"
msgstr "管理 reflog 訊息"
#: command-list.h
+msgid "Low-level access to refs"
+msgstr "對引用的低階存取"
+
+#: command-list.h
msgid "Manage set of tracked repositories"
msgstr "管理已追蹤版本庫"
@@ -17572,7 +17748,7 @@ msgstr "將工作區限縮至只包含追蹤檔案的子集"
#: command-list.h
msgid "Add file contents to the staging area"
-msgstr "將檔案內容新增到索引"
+msgstr "將檔案內容新增到暫存區"
#: command-list.h
msgid "Stash the changes in a dirty working directory away"
@@ -17720,7 +17896,7 @@ msgstr "Git 封包格式"
#: command-list.h
msgid "Git cryptographic signature formats"
-msgstr "Git 密碼編譯簽章格式"
+msgstr "Git 數位簽章格式"
#: command-list.h
msgid "A Git Glossary"
@@ -17808,104 +17984,111 @@ msgstr "用來管理大型 Git 版本庫的工具"
#: commit-graph.c
msgid "commit-graph file is too small"
-msgstr "提交圖形檔案太小"
+msgstr "提交圖檔案太小"
#: commit-graph.c
msgid "commit-graph oid fanout chunk is wrong size"
-msgstr "提交圖形 OID 扇出區塊大小有誤"
+msgstr "提交圖 OID 扇出區塊大小有誤"
#: commit-graph.c
msgid "commit-graph fanout values out of order"
-msgstr "提交圖形扇出的數值失序"
+msgstr "提交圖扇出的數值失序"
#: commit-graph.c
msgid "commit-graph OID lookup chunk is the wrong size"
-msgstr "提交圖形 OID 查詢區塊的大小有誤"
+msgstr "提交圖 OID 查詢區塊的大小有誤"
#: commit-graph.c
msgid "commit-graph commit data chunk is wrong size"
-msgstr "提交圖形的提交資料區塊大小有誤"
+msgstr "提交圖的提交資料區塊大小有誤"
#: commit-graph.c
msgid "commit-graph generations chunk is wrong size"
-msgstr "提交圖形的世代區塊大小有誤"
+msgstr "提交圖的世代區塊大小有誤"
#: commit-graph.c
msgid "commit-graph changed-path index chunk is too small"
-msgstr "提交圖形的更動路徑索引區塊過小"
+msgstr "提交圖的更動路徑索引區塊過小"
#: commit-graph.c
#, c-format
msgid ""
"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
"graph file"
-msgstr "忽略提交圖形檔案中過小的更動路徑區塊 (%<PRIuMAX> < %<PRIuMAX>)"
+msgstr "忽略提交圖檔案中過小的更動路徑區塊(%<PRIuMAX> < %<PRIuMAX>)"
#: commit-graph.c
#, c-format
msgid "commit-graph signature %X does not match signature %X"
-msgstr "提交圖形簽名 %X 和簽名 %X 不符合"
+msgstr "提交圖簽章 %X 和簽章 %X 不符"
#: commit-graph.c
#, c-format
msgid "commit-graph version %X does not match version %X"
-msgstr "提交圖形版本 %X 和版本 %X 不符合"
+msgstr "提交圖版本 %X 和版本 %X 不符"
#: commit-graph.c
#, c-format
msgid "commit-graph hash version %X does not match version %X"
-msgstr "提交圖形雜湊版本 %X 和版本 %X 不符合"
+msgstr "提交圖雜湊版本 %X 和版本 %X 不符"
#: commit-graph.c
#, c-format
msgid "commit-graph file is too small to hold %u chunks"
-msgstr "提交圖形檔案不夠放置 %u 個區塊"
+msgstr "提交圖檔案不夠放置 %u 個區塊"
#: commit-graph.c
msgid "commit-graph required OID fanout chunk missing or corrupted"
-msgstr "提交圖形需要的 OID 扇出區塊遺失或損壞"
+msgstr "提交圖需要的 OID 扇出區塊遺失或損壞"
#: commit-graph.c
msgid "commit-graph required OID lookup chunk missing or corrupted"
-msgstr "提交圖形需要的 OID 查詢區塊遺失或損壞"
+msgstr "提交圖需要的 OID 查詢區塊遺失或損壞"
#: commit-graph.c
msgid "commit-graph required commit data chunk missing or corrupted"
-msgstr "提交圖形需要的提交資料區塊遺失或損壞"
+msgstr "提交圖需要的提交資料區塊遺失或損壞"
+
+#: commit-graph.c
+#, c-format
+msgid ""
+"disabling Bloom filters for commit-graph layer '%s' due to incompatible "
+"settings"
+msgstr "由於不相容的設定,停用提交圖層 '%s' 的布隆過濾器"
#: commit-graph.c
msgid "commit-graph has no base graphs chunk"
-msgstr "提交圖形沒有基礎圖形區塊"
+msgstr "提交圖沒有基礎圖區塊"
#: commit-graph.c
msgid "commit-graph base graphs chunk is too small"
-msgstr "提交圖形的基礎圖形區塊過小"
+msgstr "提交圖的基礎圖區塊過小"
#: commit-graph.c
msgid "commit-graph chain does not match"
-msgstr "提交圖形鏈不符合"
+msgstr "提交圖鏈不符"
#: commit-graph.c
#, c-format
msgid "commit count in base graph too high: %<PRIuMAX>"
-msgstr "基礎圖 (base graph) 中的提交數過多:%<PRIuMAX>"
+msgstr "基礎圖中的提交數過多:%<PRIuMAX>"
#: commit-graph.c
msgid "commit-graph chain file too small"
-msgstr "提交圖形鏈檔案過小"
+msgstr "提交圖鏈檔案過小"
#: commit-graph.c
#, c-format
msgid "invalid commit-graph chain: line '%s' not a hash"
-msgstr "無效的提交圖形鏈:「%s」列不是雜湊值"
+msgstr "無效的提交圖鏈:「%s」列不是雜湊值"
#: commit-graph.c
msgid "unable to find all commit-graph files"
-msgstr "無法找到所有提交圖形檔案"
+msgstr "無法找到所有提交圖檔案"
#: commit-graph.c
msgid "invalid commit position. commit-graph is likely corrupt"
-msgstr "無效的提交位置。提交圖形可能已損壞"
+msgstr "無效的提交位置。提交圖可能已損壞"
#: commit-graph.c
#, c-format
@@ -17914,15 +18097,15 @@ msgstr "無法找到提交 %s"
#: commit-graph.c
msgid "commit-graph requires overflow generation data but has none"
-msgstr "提交圖需要比目前更多的世代資料,但沒有相關資料"
+msgstr "缺少提交圖需要的溢位世代資料"
#: commit-graph.c
msgid "commit-graph overflow generation data is too small"
-msgstr "提交圖形的溢出世代資料過小"
+msgstr "提交圖的溢位世代資料過小"
#: commit-graph.c
msgid "commit-graph extra-edges pointer out of bounds"
-msgstr "提交圖形的延伸邊界指針超出範圍"
+msgstr "提交圖額外的邊指標超出範圍"
#: commit-graph.c
msgid "Loading known commits in commit graph"
@@ -17930,7 +18113,7 @@ msgstr "正在載入提交圖中的已知提交"
#: commit-graph.c
msgid "Expanding reachable commits in commit graph"
-msgstr "正在展開提交圖中的可以取得的提交"
+msgstr "正在展開提交圖中的可觸及提交"
#: commit-graph.c
msgid "Clearing commit marks in commit graph"
@@ -17938,11 +18121,11 @@ msgstr "正在清除提交圖中的提交標記"
#: commit-graph.c
msgid "Computing commit graph topological levels"
-msgstr "正在計算提交圖拓樸級別"
+msgstr "正在計算提交圖的拓樸層級"
#: commit-graph.c
msgid "Computing commit graph generation numbers"
-msgstr "正在計算提交圖世代數字"
+msgstr "正在計算提交圖的世代數"
#: commit-graph.c
msgid "Computing commit changed paths Bloom filters"
@@ -17970,7 +18153,7 @@ msgstr "為 %s 開啟索引發生錯誤"
#: commit-graph.c
msgid "Finding commits for commit graph among packed objects"
-msgstr "正在打包物件中尋找提交圖的提交"
+msgstr "正在從打包物件中尋找提交圖的提交"
#: commit-graph.c
msgid "Finding extra edges in commit graph"
@@ -17978,11 +18161,11 @@ msgstr "正在尋找提交圖中額外的邊"
#: commit-graph.c
msgid "failed to write correct number of base graph ids"
-msgstr "無法寫入正確數量的基礎圖形 ID"
+msgstr "無法寫入正確數量的基礎圖 ID"
#: commit-graph.c
msgid "unable to create temporary graph layer"
-msgstr "無法建立暫時的圖形層"
+msgstr "無法建立暫時性圖層"
#: commit-graph.c
#, c-format
@@ -17997,25 +18180,25 @@ msgstr[0] "正在用 %d 步寫出提交圖"
#: commit-graph.c
msgid "unable to open commit-graph chain file"
-msgstr "無法開啟提交圖形鏈檔案"
+msgstr "無法開啟提交圖鏈檔案"
#: commit-graph.c
msgid "failed to rename base commit-graph file"
-msgstr "無法重新命名基礎提交圖形檔案"
+msgstr "無法重新命名基礎提交圖檔案"
#: commit-graph.c
msgid "failed to rename temporary commit-graph file"
-msgstr "無法重新命名暫時提交圖形檔案"
+msgstr "無法重新命名暫時性提交圖檔案"
#: commit-graph.c
#, c-format
msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits"
-msgstr "無法將圖與 %<PRIuMAX>, %<PRIuMAX> 個提交進行合併"
+msgstr "無法合併圖,兩者分別有 %<PRIuMAX>、%<PRIuMAX> 個提交"
#: commit-graph.c
#, c-format
msgid "cannot merge graph %s, too many commits: %<PRIuMAX>"
-msgstr "無法合併 %s 圖,太多提交:%<PRIuMAX>"
+msgstr "無法合併圖 %s,太多提交:%<PRIuMAX>"
#: commit-graph.c
msgid "Scanning merged commits"
@@ -18023,15 +18206,22 @@ msgstr "正在掃描合併提交"
#: commit-graph.c
msgid "Merging commit-graph"
-msgstr "正在合併提交圖形"
+msgstr "正在合併提交圖"
#: commit-graph.c
msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
-msgstr "嘗試寫入提交圖形,但 “core.commitGraph” 已被停用"
+msgstr "嘗試寫入提交圖,但「core.commitGraph」已停用"
+
+#: commit-graph.c
+#, c-format
+msgid ""
+"attempting to write a commit-graph, but 'commitGraph."
+"changedPathsVersion' (%d) is not supported"
+msgstr "嘗試寫入提交圖,但不支援「commitGraph.changedPathsVersion」(%d)"
#: commit-graph.c
msgid "too many commits to write graph"
-msgstr "提交太多不能畫圖"
+msgstr "提交過多無法畫圖"
#: commit-graph.c
msgid "the commit-graph file has incorrect checksum and is likely corrupt"
@@ -18040,59 +18230,59 @@ msgstr "提交圖檔案的總和檢查碼錯誤,可能已經損壞"
#: commit-graph.c
#, c-format
msgid "commit-graph has incorrect OID order: %s then %s"
-msgstr "提交圖形的物件 ID 順序不正確:%s 然後 %s"
+msgstr "提交圖的物件 ID 順序不正確:%s 然後 %s"
#: commit-graph.c
#, c-format
msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u"
-msgstr "提交圖形有不正確的扇出值:fanout[%d] = %u != %u"
+msgstr "提交圖有不正確的扇出值:fanout[%d] = %u != %u"
#: commit-graph.c
#, c-format
msgid "failed to parse commit %s from commit-graph"
-msgstr "無法從提交圖形中解析提交 %s"
+msgstr "無法從提交圖中解析提交 %s"
#: commit-graph.c
#, c-format
msgid "failed to parse commit %s from object database for commit-graph"
-msgstr "無法從提交圖形的物件庫中解析提交 %s"
+msgstr "無法從提交圖的物件資料庫中解析提交 %s"
#: commit-graph.c
#, c-format
msgid "root tree OID for commit %s in commit-graph is %s != %s"
-msgstr "提交圖形中的提交 %s 的根樹狀物件 ID 是 %s != %s"
+msgstr "提交圖中的提交 %s 的根樹狀物件 ID 是 %s != %s"
#: commit-graph.c
#, c-format
msgid "commit-graph parent list for commit %s is too long"
-msgstr "提交 %s 的提交圖形父提交列表太長了"
+msgstr "提交 %s 的提交圖上級清單過長"
#: commit-graph.c
#, c-format
msgid "commit-graph parent for %s is %s != %s"
-msgstr "%s 的提交圖形父提交是 %s != %s"
+msgstr "%s 的提交圖上級是 %s != %s"
#: commit-graph.c
#, c-format
msgid "commit-graph parent list for commit %s terminates early"
-msgstr "提交 %s 的提交圖形父提交列表過早終止"
+msgstr "提交 %s 的提交圖上級清單過早終止"
#: commit-graph.c
#, c-format
msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>"
-msgstr "提交 %s 的提交圖形處於 %<PRIuMAX> < %<PRIuMAX> 世代"
+msgstr "提交 %s 位於 %<PRIuMAX> < %<PRIuMAX> 提交圖世代"
#: commit-graph.c
#, c-format
msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>"
-msgstr "提交圖形中提交 %s 的提交日期是 %<PRIuMAX> != %<PRIuMAX>"
+msgstr "提交圖中的提交 %s 提交日期是 %<PRIuMAX> != %<PRIuMAX>"
#: commit-graph.c
#, c-format
msgid ""
"commit-graph has both zero and non-zero generations (e.g., commits '%s' and "
"'%s')"
-msgstr "提交圖形中包含 0 和非 0 兩個世代號(例如 “%s” 和 “%s” 提交)"
+msgstr "提交圖中包含 0 和非 0 兩個世代數(例如提交「%s」和「%s」)"
#: commit-graph.c
msgid "Verifying commits in commit graph"
@@ -18131,7 +18321,7 @@ msgstr ""
#: commit.c
#, c-format
msgid "commit %s exists in commit-graph but not in the object database"
-msgstr "%s 提交在提交圖形中,但不在物件資料庫中"
+msgstr "%s 提交在提交圖中,但不在物件資料庫中"
#: commit.c
#, c-format
@@ -18174,37 +18364,37 @@ msgstr "沒有可用的 libc 資訊\n"
#: compat/disk.h
#, c-format
msgid "could not determine free disk size for '%s'"
-msgstr "無法判斷 “%s” 的剩餘磁碟大小"
+msgstr "無法判斷「%s」的剩餘磁碟大小"
#: compat/disk.h
#, c-format
msgid "could not get info for '%s'"
-msgstr "無法取得 “%s” 的資訊"
+msgstr "無法取得「%s」的資訊"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
-msgstr "[GLE %ld] 健康監聽執行緒無法開啟 “%ls”"
+msgstr "[GLE %ld] 健康監聽執行緒無法開啟「%ls」"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "[GLE %ld] health thread getting BHFI for '%ls'"
-msgstr "[GLE %ld] 健康監聽執行緒取得 “%ls” 的 BHFI"
+msgstr "[GLE %ld] 健康監聽執行緒取得「%ls」的 BHFI"
#: compat/fsmonitor/fsm-health-win32.c compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "could not convert to wide characters: '%s'"
-msgstr "無法轉換至較寬字元:“%s”"
+msgstr "無法轉換至較寬字元:「%s」"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "BHFI changed '%ls'"
-msgstr "BHFI 更改了 “%ls”"
+msgstr "BHFI 更改了「%ls」"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "unhandled case in 'has_worktree_moved': %d"
-msgstr "“has_worktree_moved” 中有未處置的情況:%d"
+msgstr "「has_worktree_moved」中有未處置的情況:%d"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
@@ -18232,22 +18422,22 @@ msgstr "[GLE %ld] 無法將路徑轉換為 UTF-8:「%.*ls」"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "[GLE %ld] could not watch '%s'"
-msgstr "[GLE %ld] 無法監聽 “%s”"
+msgstr "[GLE %ld] 無法監聽「%s」"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "[GLE %ld] could not get longname of '%s'"
-msgstr "[GLE %ld] 無法取得 “%s” 的 longname"
+msgstr "[GLE %ld] 無法取得「%s」的 longname"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "ReadDirectoryChangedW failed on '%s' [GLE %ld]"
-msgstr "在 “%s” 上呼叫 ReadDirectoryChangedW 失敗 [GLE %ld]"
+msgstr "在「%s」上呼叫 ReadDirectoryChangedW 失敗 [GLE %ld]"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "GetOverlappedResult failed on '%s' [GLE %ld]"
-msgstr "在 “%s” 上呼叫 GetOverlappedResult 失敗 [GLE %ld]"
+msgstr "在「%s」上呼叫 GetOverlappedResult 失敗 [GLE %ld]"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
@@ -18292,7 +18482,7 @@ msgstr "無法複製 SID (%ld)"
#: compat/mingw.c
#, c-format
msgid "failed to get owner for '%s' (%ld)"
-msgstr "無法取得 “%s” 的所有者 (%ld)"
+msgstr "無法取得「%s」的所有者 (%ld)"
#: compat/obstack.c
msgid "memory exhausted"
@@ -18381,7 +18571,7 @@ msgstr "無法讀取 IPC 回應"
#: compat/simple-ipc/ipc-unix-socket.c
#, c-format
msgid "could not start accept_thread '%s'"
-msgstr "無法啟動 accept_thread “%s”"
+msgstr "無法啟動 accept_thread「%s」"
#: compat/simple-ipc/ipc-unix-socket.c
#, c-format
@@ -18391,26 +18581,26 @@ msgstr "無法啟動「%s」的 worker[0]"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "ConnectNamedPipe failed for '%s' (%lu)"
-msgstr "對 “%s” 進行 ConnectNamedPipe 失敗 (%lu)"
+msgstr "對「%s」進行 ConnectNamedPipe 失敗 (%lu)"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "could not create fd from pipe for '%s'"
-msgstr "無法為 “%s” 從管道建立 fd"
+msgstr "無法為「%s」從管道建立 fd"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "could not start thread[0] for '%s'"
-msgstr "無法為 “%s” 啟動 thread[0]"
+msgstr "無法為「%s」啟動 thread[0]"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "wait for hEvent failed for '%s'"
-msgstr "等待 “%s” 的 hEvent 失敗"
+msgstr "等待「%s」的 hEvent 失敗"
#: compat/terminal.c
msgid "cannot resume in the background, please use 'fg' to resume"
-msgstr "無法在背景繼續;請使用 “fg” 繼續"
+msgstr "無法在背景繼續;請使用「fg」繼續"
#: compat/terminal.c
msgid "cannot restore terminal settings"
@@ -18602,7 +18792,7 @@ msgstr "%s 變數的值無效"
#: config.c
#, c-format
msgid "ignoring unknown core.fsync component '%s'"
-msgstr "忽略未知的 core.fsync 組件「%s」"
+msgstr "忽略未知的 core.fsync 元件「%s」"
#: config.c
#, c-format
@@ -18778,7 +18968,7 @@ msgstr "無效的小節名稱:%s"
#: config.c
#, c-format
msgid "refusing to work with overly long line in '%s' on line %<PRIuMAX>"
-msgstr "因為第 %2$<PRIuMAX> 列中 “%1$s” 的文字列太長,故拒絕運作"
+msgstr "因為第 %2$<PRIuMAX> 列中「%1$s」的文字列太長,故拒絕運作"
#: config.c
#, c-format
@@ -18992,7 +19182,7 @@ msgstr "%s 中的 CRLF 將被 LF 取代"
msgid ""
"in the working copy of '%s', CRLF will be replaced by LF the next time Git "
"touches it"
-msgstr "在 “%s” 的工作複本中,下次 Git 接觸到時會用 LF 取代 CRLF"
+msgstr "在「%s」的工作複本中,下次 Git 接觸到時會用 LF 取代 CRLF"
#: convert.c
#, c-format
@@ -19004,7 +19194,7 @@ msgstr "檔案 %s 中的 LF 將被 CRLF 取代"
msgid ""
"in the working copy of '%s', LF will be replaced by CRLF the next time Git "
"touches it"
-msgstr "在 “%s” 的工作複本中,下次 Git 接觸到時會用 CRLF 取代 LF"
+msgstr "在「%s」的工作複本中,下次 Git 接觸到時會用 CRLF 取代 LF"
#: convert.c
#, c-format
@@ -19225,7 +19415,7 @@ msgstr "不能開啟目錄 '%s'"
#: diagnose.c
#, c-format
msgid "skipping '%s', which is neither file nor directory"
-msgstr "略過 “%s”,其非檔案或目錄"
+msgstr "略過「%s」,其非檔案或目錄"
#: diagnose.c
msgid "could not duplicate stdout"
@@ -19523,7 +19713,7 @@ msgstr "使用提供的檔案名長度生成差異統計"
#: diff.c
msgid "generate diffstat with a given graph width"
-msgstr "使用提供的圖形長度生成差異統計"
+msgstr "產出限制為提供的寬度的差異統計圖形"
#: diff.c
msgid "<count>"
@@ -20159,7 +20349,7 @@ msgstr "預期 '%s',得到 '%s'"
#: fetch-pack.c
#, c-format
msgid "expected '%s'"
-msgstr "預期 “%s”"
+msgstr "預期「%s」"
#: fetch-pack.c
#, c-format
@@ -20251,45 +20441,49 @@ msgstr "無法將「%s」命令傳送到 fsmonitor--daemon"
#: fsmonitor-settings.c
#, c-format
msgid "bare repository '%s' is incompatible with fsmonitor"
-msgstr "純版本庫 “%s” 與 fsmonitor 不相容"
+msgstr "純版本庫「%s」與 fsmonitor 不相容"
#: fsmonitor-settings.c
#, c-format
msgid "repository '%s' is incompatible with fsmonitor due to errors"
-msgstr "版本庫 “%s” 因錯誤而與 fsmonitor 不相容"
+msgstr "版本庫「%s」因錯誤而與 fsmonitor 不相容"
#: fsmonitor-settings.c
#, c-format
msgid "remote repository '%s' is incompatible with fsmonitor"
-msgstr "遠端版本庫 “%s” 與 fsmonitor 不相容"
+msgstr "遠端版本庫「%s」與 fsmonitor 不相容"
#: fsmonitor-settings.c
#, c-format
msgid "virtual repository '%s' is incompatible with fsmonitor"
-msgstr "虛擬版本庫 “%s” 與 fsmonitor 不相容"
+msgstr "虛擬版本庫「%s」與 fsmonitor 不相容"
#: fsmonitor-settings.c
#, c-format
msgid ""
"socket directory '%s' is incompatible with fsmonitor due to lack of Unix "
"sockets support"
-msgstr "通訊端 “%s” 因缺少 Unix 通訊端支援,而與 fsmonitor 不相容"
+msgstr "通訊端「%s」因缺少 Unix 通訊端支援,而與 fsmonitor 不相容"
#: git.c
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
msgstr ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-" [--config-env=<name>=<envvar>] <command> [<args>]"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-"
+"lazy-fetch]\n"
+" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
+" [--work-tree=<path>] [--namespace=<name>] [--config-"
+"env=<name>=<envvar>]\n"
+" <command> [<args>]"
#: git.c
msgid ""
@@ -20493,7 +20687,7 @@ msgstr "無法從「%s」讀取 SSH 簽名資料緩衝區"
#: graph.c
#, c-format
msgid "ignored invalid color '%.*s' in log.graphColors"
-msgstr "已忽略 log.graphColors 中無效的 “%.*s” 色彩"
+msgstr "已忽略 log.graphColors 中無效的「%.*s」色彩"
#: grep.c
msgid ""
@@ -20689,14 +20883,14 @@ msgstr ""
"設定 `git config advice.ignoredHook false` 來關閉這條警告。"
#: http-fetch.c
+msgid "not a git repository"
+msgstr "不是一個 git 版本庫"
+
+#: http-fetch.c
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "傳入 --packfile 的參數必須是有效的雜湊 (收到 '%s')"
-#: http-fetch.c
-msgid "not a git repository"
-msgstr "不是一個 git 版本庫"
-
#: http.c
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
@@ -20711,6 +20905,10 @@ msgid "Public key pinning not supported with cURL < 7.39.0"
msgstr "不支援公鑰檔案鎖定,因為 cURL < 7.39.0"
#: http.c
+msgid "Unknown value for http.proactiveauth"
+msgstr "http.proactiveauth 的值未知"
+
+#: http.c
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
msgstr "不支援 CURLSSLOPT_NO_REVOKE,因為 cURL < 7.44.0"
@@ -20730,6 +20928,14 @@ msgid "Could not set SSL backend to '%s': already set"
msgstr "無法將 SSL 後端設定為 '%s':已經設定"
#: http.c
+msgid "refusing to read cookies from http.cookiefile '-'"
+msgstr "不允許從 http.cookiefile 的設定值「-」處讀取 cookie"
+
+#: http.c
+msgid "ignoring http.savecookies for empty http.cookiefile"
+msgstr "http.cookiefile 空白,忽略 http.savecookies"
+
+#: http.c
#, c-format
msgid ""
"unable to update url base from redirection:\n"
@@ -20813,7 +21019,7 @@ msgstr "sparse:path 過濾器支援已被刪除"
#: list-objects-filter-options.c
#, c-format
msgid "'%s' for 'object:type=<type>' is not a valid object type"
-msgstr "“object:type=<type>” 的 “%s” 不是有效的物件格式"
+msgstr "「object:type=<type>」的「%s」不是有效的物件格式"
#: list-objects-filter-options.c
#, c-format
@@ -20937,10 +21143,10 @@ msgstr "無法合併 %s 子模組(沒有合併基底)"
msgid "Failed to merge submodule %s (commits not present)"
msgstr "無法合併子模組 %s(提交不存在)"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "Failed to merge submodule %s (repository corrupt)"
-msgstr "無法合併子模組 %s (版本庫損壞)"
+msgid "error: failed to merge submodule %s (repository corrupt)"
+msgstr "錯誤:無法合併子模組 %s (版本庫損壞)"
#: merge-ort.c merge-recursive.c
#, c-format
@@ -20972,14 +21178,15 @@ msgstr ""
"無法合併 %s 子模組,但有找到幾個可行的合併方案:\n"
"%s"
-#: merge-ort.c merge-recursive.c
-msgid "failed to execute internal merge"
-msgstr "無法執行內部合併"
+#: merge-ort.c
+#, c-format
+msgid "error: failed to execute internal merge for %s"
+msgstr "錯誤:無法對 %s 執行內部合併"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "unable to add %s to database"
-msgstr "無法將 %s 加進資料庫"
+msgid "error: unable to add %s to database"
+msgstr "錯誤:無法將 %s 加進資料庫"
#: merge-ort.c merge-recursive.c
#, c-format
@@ -21079,15 +21286,15 @@ msgid "CONFLICT (rename/delete): %s renamed to %s in %s, but deleted in %s."
msgstr ""
"衝突(重新命名/刪除):%1$s 已重新命名為 %3$s 中的 %2$s 卻在 %4$s 中被刪除。"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "cannot read object %s"
-msgstr "不能讀取物件 %s"
+msgid "error: cannot read object %s"
+msgstr "錯誤:無法讀取物件 %s"
-#: merge-ort.c merge-recursive.c
+#: merge-ort.c
#, c-format
-msgid "object %s is not a blob"
-msgstr "物件 %s 不是一個資料物件"
+msgid "error: object %s is not a blob"
+msgstr "錯誤:物件 %s 不是一個資料物件"
#: merge-ort.c
#, c-format
@@ -21243,6 +21450,11 @@ msgstr "不知道如何處理 %06o %s '%s'"
#: merge-recursive.c
#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "無法合併子模組 %s (版本庫損壞)"
+
+#: merge-recursive.c
+#, c-format
msgid "Fast-forwarding submodule %s to the following commit:"
msgstr "子模組 %s 快轉到如下提交:"
@@ -21287,6 +21499,15 @@ msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "無法合併子模組 %s (發現多個合併)"
#: merge-recursive.c
+msgid "failed to execute internal merge"
+msgstr "無法執行內部合併"
+
+#: merge-recursive.c
+#, c-format
+msgid "unable to add %s to database"
+msgstr "無法將 %s 加進資料庫"
+
+#: merge-recursive.c
#, c-format
msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
msgstr "錯誤:拒絕遺失未追蹤檔案 '%s',而是寫入 %s。"
@@ -21401,6 +21622,16 @@ msgstr ""
"命名目錄 %4$s->%5$s"
#: merge-recursive.c
+#, c-format
+msgid "cannot read object %s"
+msgstr "不能讀取物件 %s"
+
+#: merge-recursive.c
+#, c-format
+msgid "object %s is not a blob"
+msgstr "物件 %s 不是一個資料物件"
+
+#: merge-recursive.c
msgid "modify"
msgstr "修改"
@@ -21504,10 +21735,6 @@ msgid "malformed line: %s"
msgstr "橫列格式錯誤:%s"
#: midx-write.c
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "忽略現有的多包索引:總和檢查碼不符"
-
-#: midx-write.c
msgid "could not load pack"
msgstr "無法載入包"
@@ -21517,6 +21744,10 @@ msgid "could not open index for %s"
msgstr "無法開啟 %s 的索引"
#: midx-write.c
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "忽略現有的多包索引:總和檢查碼不符"
+
+#: midx-write.c
msgid "Adding packfiles to multi-pack-index"
msgstr "正在新增 packfile 至多包索引"
@@ -22254,6 +22485,20 @@ msgid "hash mismatch %s"
msgstr "雜湊值與 %s 不符合"
#: pack-bitmap-write.c
+#, c-format
+msgid "duplicate entry when writing bitmap index: %s"
+msgstr "寫入位圖索引中時發現重複項目:%s"
+
+#: pack-bitmap-write.c
+#, c-format
+msgid "attempted to store non-selected commit: '%s'"
+msgstr "嘗試儲存未選取的提交:「%s」"
+
+#: pack-bitmap-write.c
+msgid "too many pseudo-merges"
+msgstr "偽合併過多"
+
+#: pack-bitmap-write.c
msgid "trying to write commit not in index"
msgstr "嘗試寫入不在索引的提交"
@@ -22272,7 +22517,7 @@ msgstr "位圖索引檔案損壞(標頭錯誤)"
#: pack-bitmap.c
#, c-format
msgid "unsupported version '%d' for bitmap index file"
-msgstr "位圖索引檔案的版本 “%d” 不支援"
+msgstr "位圖索引檔案的版本「%d」不支援"
#: pack-bitmap.c
msgid "corrupted bitmap index file (too short to fit hash cache)"
@@ -22283,6 +22528,19 @@ msgid "corrupted bitmap index file (too short to fit lookup table)"
msgstr "位圖索引檔案損壞(不夠長,無法置入查詢表)"
#: pack-bitmap.c
+msgid ""
+"corrupted bitmap index file (too short to fit pseudo-merge table header)"
+msgstr "位圖索引檔案損壞(不夠長,無法置入偽合併表標頭)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit pseudo-merge table)"
+msgstr "位圖索引檔案損壞(不夠長,無法置入偽合併表)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file, pseudo-merge table too short"
+msgstr "位圖索引檔案損壞,偽合併表太短"
+
+#: pack-bitmap.c
#, c-format
msgid "duplicate entry in bitmap index: '%s'"
msgstr "位圖索引中有重複項目:「%s」"
@@ -22347,7 +22605,7 @@ msgstr "位圖查詢表損壞:提交索引 %u 超出範圍"
#: pack-bitmap.c
#, c-format
msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
-msgstr "ewah 位圖損壞:提交 “%s” 之位圖的標頭遭截斷"
+msgstr "ewah 位圖損壞:提交「%s」之位圖的標頭遭截斷"
#: pack-bitmap.c
#, c-format
@@ -22397,6 +22655,11 @@ msgstr "位圖結果中有不符項目"
#: pack-bitmap.c
#, c-format
+msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)"
+msgstr "偽合併索引超出範圍(%<PRIu32> >= %<PRIuMAX>)"
+
+#: pack-bitmap.c
+#, c-format
msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "在「%2$s」封包,位移 %3$<PRIuMAX> 的地方找不到「%1$s」"
@@ -22408,7 +22671,7 @@ msgstr "無法取得「%s」的磁碟用量"
#: pack-bitmap.c
#, c-format
msgid "bitmap file '%s' has invalid checksum"
-msgstr "“%s” 位圖檔案的總和檢查碼無效"
+msgstr "「%s」位圖檔案的總和檢查碼無效"
#: pack-mtimes.c
#, c-format
@@ -22751,7 +23014,7 @@ msgstr "%s:'literal' 和 'glob' 不相容"
#: pathspec.c
#, c-format
msgid "'%s' is outside the directory tree"
-msgstr "“%s” 在目錄樹之外"
+msgstr "「%s」在目錄樹之外"
#: pathspec.c
#, c-format
@@ -22848,6 +23111,10 @@ msgid "unable to parse --pretty format"
msgstr "不能解析 --pretty 格式"
#: promisor-remote.c
+msgid "lazy fetching disabled; some objects may not be available"
+msgstr "延後抓取已被停用;某些物件可能無法使用"
+
+#: promisor-remote.c
msgid "promisor-remote: unable to fork off fetch subprocess"
msgstr "promisor-remote: 無法 fork fetch 子處理程序"
@@ -22877,6 +23144,72 @@ msgstr "object-info:引數後預期要有 flush"
msgid "Removing duplicate objects"
msgstr "正在刪除重複物件"
+#: pseudo-merge.c
+#, c-format
+msgid "failed to load pseudo-merge regex for %s: '%s'"
+msgstr "未能載入 %s 的偽合併常規表示式:%s"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be non-negative, using default"
+msgstr "%s 須為非負數,將採用預設值"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be between 0 and 1, using default"
+msgstr "%s 須介於 0 到 1 之間,將採用預設值"
+
+#: pseudo-merge.c
+#, c-format
+msgid "%s must be positive, using default"
+msgstr "%s 須為正數,將採用預設值"
+
+#: pseudo-merge.c
+#, c-format
+msgid "pseudo-merge group '%s' missing required pattern"
+msgstr "偽合併群組「%s」缺少必須的模式"
+
+#: pseudo-merge.c
+#, c-format
+msgid "pseudo-merge group '%s' has unstable threshold before stable one"
+msgstr "偽合併群組「%s」的非穩定閾值位於穩定者之前"
+
+#: pseudo-merge.c
+#, c-format
+msgid ""
+"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)"
+msgstr "來自組態的偽合併常規表示式包含太多的擷取群組(最多 %<PRIuMAX> 個)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "延伸偽合併讀取超出範圍(%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "延伸偽合併項目過短(%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>"
+msgstr "無法在偏移 %2$<PRIuMAX> 處找到提交 %1$s 的偽合併"
+
+#: pseudo-merge.c
+#, c-format
+msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)"
+msgstr "延伸偽合併查詢超出範圍(%<PRIu32> >= %<PRIu32>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)"
+msgstr "讀取超出範圍:(%<PRIuMAX> >= %<PRIuMAX>)"
+
+#: pseudo-merge.c
+#, c-format
+msgid "could not read extended pseudo-merge table for commit %s"
+msgstr "無法讀取提交 %s 的延伸偽合併表"
+
#: range-diff.c
msgid "could not start `log`"
msgstr "不能啟動 `log`"
@@ -22914,7 +23247,7 @@ msgstr "不能解析 '%s' 的日誌"
#: reachable.c
#, c-format
msgid "invalid extra cruft tip: '%s'"
-msgstr "無效的額外廢棄提交修訂版:“%s”"
+msgstr "無效的額外廢棄提交修訂版:「%s」"
#: reachable.c
msgid "unable to enumerate additional recent objects"
@@ -23106,7 +23439,7 @@ msgstr "非預期的 diff 狀態 %c"
#: read-cache.c
#, c-format
msgid "remove '%s'\n"
-msgstr "移除 “%s”\n"
+msgstr "移除「%s」\n"
#: rebase-interactive.c
msgid ""
@@ -23156,11 +23489,11 @@ msgstr ""
"r, reword <提交> = 使用提交,但編輯提交說明\n"
"e, edit <提交> = 使用提交,但不直接修補 (amend) \n"
"s, squash <提交> = 使用提交,但融合至上個提交\n"
-"f, fixup [-C | -c] <提交> = 跟 “squash” 相似,但除非傳入 -C,\n"
+"f, fixup [-C | -c] <提交> = 跟「squash」相似,但除非傳入 -C,\n"
" 否則只保留上一個提交的日誌訊息。傳入 -C 表示只保留這個\n"
" 提交的訊息;傳入 -c 與 -C 功能相同,但會開啟編輯器\n"
"x, exec <命令> = 使用 shell 執行命令(這一列的剩餘部分)\n"
-"b, break = 在此停止(使用 “git rebase --continue” 繼續重定基底)\n"
+"b, break = 在此停止(使用「git rebase --continue」繼續重定基底)\n"
"d, drop <提交> = 移除提交\n"
"l, label <標籤> = 為目前 HEAD 打上指定名字標籤\n"
"t, reset <標籤> = 重設 HEAD 到指定標籤\n"
@@ -23432,7 +23765,7 @@ msgstr "--format=%.*s 不能和 --python、--shell、--tcl 一起使用"
#: ref-filter.c
msgid "failed to run 'describe'"
-msgstr "無法執行 “describe”"
+msgstr "無法執行「describe」"
#: ref-filter.c
#, c-format
@@ -23550,8 +23883,8 @@ msgstr ""
"\n"
"\tgit config --global init.defaultBranch <name>\n"
"\n"
-"除了 “master” 外,常用的分支名稱有 “main”, “trunk” 以及\n"
-"“development”。剛建立的分支可以用這個命令重新命名:\n"
+"除了「master」外,常用的分支名稱有「main」,「trunk」以及\n"
+"「development」。剛建立的分支可以用這個命令重新命名:\n"
"\n"
"\tgit branch -m <name>\n"
@@ -23586,12 +23919,21 @@ msgid "log for %s is empty"
msgstr "%s 的日誌為空"
#: refs.c
+msgid "refusing to force and skip creation of reflog"
+msgstr "拒絕強制並略過建立引用日誌"
+
+#: refs.c
#, c-format
msgid "refusing to update ref with bad name '%s'"
msgstr "拒絕更新有錯誤名稱 '%s' 的引用"
#: refs.c
#, c-format
+msgid "refusing to update pseudoref '%s'"
+msgstr "拒絕更新偽引用「%s」"
+
+#: refs.c
+#, c-format
msgid "update_ref failed for ref '%s': %s"
msgstr "對引用 '%s' 執行 update_ref 失敗:%s"
@@ -23628,6 +23970,27 @@ msgstr "無法刪除引用 %s:%s"
msgid "could not delete references: %s"
msgstr "無法刪除引用:%s"
+#: refs.c
+#, c-format
+msgid "Finished dry-run migration of refs, the result can be found at '%s'\n"
+msgstr "完成引用移轉的測試執行,可以在「%s」找到結果\n"
+
+#: refs.c
+#, c-format
+msgid "could not remove temporary migration directory '%s'"
+msgstr "無法移除暫時性遷移目錄「%s」"
+
+#: refs.c
+#, c-format
+msgid "migrated refs can be found at '%s'"
+msgstr "可以在「%s」找到已遷移的引用"
+
+#: refs/files-backend.c refs/reftable-backend.c
+#, c-format
+msgid ""
+"cannot lock ref '%s': expected symref with target '%s': but is a regular ref"
+msgstr "無法鎖定引用「%s」:預期是指向「%s」的符號引用,但這個是一般引用"
+
#: refs/reftable-backend.c
#, c-format
msgid "refname is dangerous: %s"
@@ -23839,7 +24202,7 @@ msgstr "協定錯誤:預期是「<URL> <路徑>」,但缺少空白"
#: remote-curl.c
#, c-format
msgid "failed to download file at URL '%s'"
-msgstr "無法下載位於 URL “%s” 的檔案"
+msgstr "無法下載位於 URL「%s」的檔案"
#: remote-curl.c
msgid "git-http-push failed"
@@ -23878,12 +24241,12 @@ msgstr "提供了一個以上的 uploadpack,使用第一個"
#: remote.c
#, c-format
msgid "unrecognized value transfer.credentialsInUrl: '%s'"
-msgstr "數值 transfer.credentialsInUrl 無法識別:“%s”"
+msgstr "數值 transfer.credentialsInUrl 無法識別:「%s」"
#: remote.c
#, c-format
msgid "URL '%s' uses plaintext credentials"
-msgstr "URL “%s” 使用明文憑證"
+msgstr "URL「%s」使用明文憑證"
#: remote.c
#, c-format
@@ -24124,7 +24487,7 @@ msgstr[0] ""
#: remote.c
msgid ""
" (use \"git pull\" if you want to integrate the remote branch with yours)\n"
-msgstr " (使用 “git pull” 來將遠端分支整合進您的分支)\n"
+msgstr " (使用「git pull」來將遠端分支整合進您的分支)\n"
#: remote.c
#, c-format
@@ -24197,7 +24560,7 @@ msgstr "使用之前的解決方案解決 '%s'。"
#: rerere.c
#, c-format
msgid "cannot unlink stray '%s'"
-msgstr "無法刪除失散檔案 “%s”"
+msgstr "無法刪除失散檔案「%s」"
#: rerere.c
#, c-format
@@ -24280,7 +24643,7 @@ msgstr "--unpacked=<packfile> 已不受支援"
#: revision.c
#, c-format
msgid "invalid option '%s' in --stdin mode"
-msgstr "在 --stdin 模式下,“%s” 選項無效"
+msgstr "在 --stdin 模式下,「%s」選項無效"
#: revision.c
msgid "your current branch appears to be broken"
@@ -24394,7 +24757,7 @@ msgstr "只下載會簽出的分支中介資料"
#: scalar.c
msgid "create repository within 'src' directory"
-msgstr "在 “src” 目錄建立版本庫"
+msgstr "在「src」目錄建立版本庫"
#: scalar.c
msgid ""
@@ -24464,27 +24827,27 @@ msgstr "--all 或 <enlistment> 但不能傳入兩者"
#: scalar.c
#, c-format
msgid "could not remove stale scalar.repo '%s'"
-msgstr "無法移除過時的 scalar.repo “%s”"
+msgstr "無法移除過時的 scalar.repo「%s」"
#: scalar.c
#, c-format
msgid "removed stale scalar.repo '%s'"
-msgstr "已移除過時的 scalar.repo “%s”"
+msgstr "已移除過時的 scalar.repo「%s」"
#: scalar.c
#, c-format
msgid "repository at '%s' has different owner"
-msgstr "位於 “%s” 的版本庫有不同的擁有者"
+msgstr "位於「%s」的版本庫有不同的擁有者"
#: scalar.c
#, c-format
msgid "repository at '%s' has a format issue"
-msgstr "位於 “%s” 的版本庫有格式問題"
+msgstr "位於「%s」的版本庫有格式問題"
#: scalar.c
#, c-format
msgid "repository not found in '%s'"
-msgstr "版本庫不在 “%s”"
+msgstr "版本庫不在「%s」"
#: scalar.c
#, c-format
@@ -25008,12 +25371,12 @@ msgstr "git %s:無法重新整理索引"
#: sequencer.c
#, c-format
msgid "'%s' is not a valid label"
-msgstr "“%s” 不是有效的標籤"
+msgstr "「%s」不是有效的標籤"
#: sequencer.c
#, c-format
msgid "'%s' is not a valid refname"
-msgstr "“%s” 不是有效的引用名稱"
+msgstr "「%s」不是有效的引用名稱"
#: sequencer.c
#, c-format
@@ -25022,8 +25385,56 @@ msgstr "update-ref 需要完全限定的引用名稱,比如:refs/heads/%s"
#: sequencer.c
#, c-format
+msgid "'%s' does not accept merge commits"
+msgstr "「%s」不接受合併提交"
+
+#. TRANSLATORS: 'pick' and 'merge -C' should not be
+#. translated.
+#.
+#: sequencer.c
+msgid ""
+"'pick' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit."
+msgstr ""
+"不能使用「pick」選擇一個合併提交。\n"
+"如果你想要重放這個合併,請對這個提交使用「merge -C」。"
+
+#. TRANSLATORS: 'reword' and 'merge -c' should not be
+#. translated.
+#.
+#: sequencer.c
+msgid ""
+"'reword' does not take a merge commit. If you wanted to\n"
+"replay the merge and reword the commit message, use\n"
+"'merge -c' on the commit"
+msgstr ""
+"「reword」並無法使用合併提交作為參數。\n"
+"如果你希望合併並改寫提交訊息,\n"
+"請對這個提交使用「merge -c」"
+
+#. TRANSLATORS: 'edit', 'merge -C' and 'break' should
+#. not be translated.
+#.
+#: sequencer.c
+msgid ""
+"'edit' does not take a merge commit. If you wanted to\n"
+"replay the merge, use 'merge -C' on the commit, and then\n"
+"'break' to give the control back to you so that you can\n"
+"do 'git commit --amend && git rebase --continue'."
+msgstr ""
+"「edit」並無法使用合併提交作為參數。\n"
+"如果你希望重放這個合併,請對這個提交使用「merge -C」,\n"
+"並使用「break」取回控制權,\n"
+"這樣才能執行「git commit --amend && git rebase --continue」。"
+
+#: sequencer.c
+msgid "cannot squash merge commit into another commit"
+msgstr "無法將一個合併提交壓扁進其他提交"
+
+#: sequencer.c
+#, c-format
msgid "invalid command '%.*s'"
-msgstr "無效的命令 “%.*s”"
+msgstr "無效的命令「%.*s」"
#: sequencer.c
#, c-format
@@ -25170,9 +25581,8 @@ msgid "cannot read HEAD"
msgstr "不能讀取 HEAD"
#: sequencer.c
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr "無法複製 '%s' 至 '%s'"
+msgid "could not write commit message file"
+msgstr "無法寫入提交訊息檔案"
#: sequencer.c
#, c-format
@@ -25299,7 +25709,7 @@ msgstr "合併:無法寫入新索引檔案"
#, c-format
msgid ""
"another 'rebase' process appears to be running; '%s.lock' already exists"
-msgstr "似乎有另一個 “rebase” 程序正在進行;“%s.lock” 已經存在"
+msgstr "似乎有另一個「rebase」程序正在進行;「%s.lock」已經存在"
#: sequencer.c
#, c-format
@@ -25650,6 +26060,19 @@ msgid "failed to stat '%*s%s%s'"
msgstr "取得 '%*s%s%s' 狀態(stat)失敗"
#: setup.c
+#, c-format
+msgid ""
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+msgstr ""
+"在位於「%s」的版本庫偵測到可疑所有權\n"
+"%s若要放行本目錄,請呼叫:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
+#: setup.c
msgid "Unable to read current working directory"
msgstr "不能讀取目前工作目錄"
@@ -25674,21 +26097,8 @@ msgstr ""
#: setup.c
#, c-format
-msgid ""
-"detected dubious ownership in repository at '%s'\n"
-"%sTo add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-"在位於「%s」的版本庫偵測到可疑所有權\n"
-"%s若要放行本目錄,請呼叫:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-
-#: setup.c
-#, c-format
msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
-msgstr "無法使用 “%s” 純版本庫(safe.bareRepository 是 “%s”)"
+msgstr "無法使用「%s」純版本庫(safe.bareRepository 是「%s」)"
#: setup.c
#, c-format
@@ -26049,6 +26459,16 @@ msgstr "「%s」子模組 git 目錄在「%.*s」git 路徑中"
#: submodule.c
#, c-format
+msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link"
+msgstr "預期「%.*s」(位於子模組路徑「%s」)不是象徵式連結"
+
+#: submodule.c
+#, c-format
+msgid "expected submodule path '%s' not to be a symbolic link"
+msgstr "預期子模組路徑「%s」不是象徵式連結"
+
+#: submodule.c
+#, c-format
msgid ""
"relocate_gitdir for submodule '%s' with more than one worktree not supported"
msgstr "不支援對有多個工作區的子模組 '%s' 執行 relocate_gitdir"
@@ -26086,18 +26506,13 @@ msgstr "ls-tree 返回未知返回值 %d"
#: symlinks.c
#, c-format
msgid "failed to lstat '%s'"
-msgstr "無法 lstat “%s”"
+msgstr "無法 lstat「%s」"
#: t/helper/test-bundle-uri.c
msgid "no remote configured to get bundle URIs from"
msgstr "沒有設定可以用來取得套件包 URIs 的遠端"
#: t/helper/test-bundle-uri.c
-#, c-format
-msgid "remote '%s' has no configured URL"
-msgstr "“%s” 遠端未設定 URL"
-
-#: t/helper/test-bundle-uri.c
msgid "could not get the bundle-uri list"
msgstr "無法取得 bundle-uri 清單"
@@ -27439,7 +27854,7 @@ msgstr "列舉未追蹤檔案花費 %.2f 秒。"
#: wt-status.c
msgid "See 'git help status' for information on how to improve this."
-msgstr "請參閱 “git help status” 深入了解如何改善。"
+msgstr "請參閱「git help status」深入了解如何改善。"
#: wt-status.c
#, c-format
@@ -27885,29 +28300,29 @@ msgstr "無法傳送 %s\n"
#: git-send-email.perl
#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr "測試執行傳送 %s\n"
+msgid "Dry-Sent %s"
+msgstr "試執行傳送 %s"
#: git-send-email.perl
#, perl-format
-msgid "Sent %s\n"
-msgstr "正傳送 %s\n"
+msgid "Sent %s"
+msgstr "正傳送 %s"
#: git-send-email.perl
-msgid "Dry-OK. Log says:\n"
-msgstr "測試執行成功。日誌說:\n"
+msgid "Dry-OK. Log says:"
+msgstr "試執行成功。日誌說:"
#: git-send-email.perl
-msgid "OK. Log says:\n"
-msgstr "OK。日誌說:\n"
+msgid "OK. Log says:"
+msgstr "OK。日誌說:"
#: git-send-email.perl
msgid "Result: "
msgstr "結果: "
#: git-send-email.perl
-msgid "Result: OK\n"
-msgstr "結果:OK\n"
+msgid "Result: OK"
+msgstr "結果:OK"
#: git-send-email.perl
#, perl-format
@@ -27942,7 +28357,7 @@ msgstr "(%s) 不能執行 '%s'"
#: git-send-email.perl
#, perl-format
msgid "(%s) Malformed output from '%s'"
-msgstr "(%s) 從 “%s” 讀到格式錯誤的輸出"
+msgstr "(%s) 從「%s」讀到格式錯誤的輸出"
#: git-send-email.perl
#, perl-format
@@ -27998,6 +28413,34 @@ msgstr "略過 %s 含備份後綴 '%s'。\n"
msgid "Do you really want to send %s? [y|N]: "
msgstr "您真的要傳送 %s?[y|N]: "
+#~ msgid ""
+#~ "the add.interactive.useBuiltin setting has been removed!\n"
+#~ "See its entry in 'git help config' for details."
+#~ msgstr ""
+#~ "add.interactive.useBuiltin 設定已被移除!\n"
+#~ "深入了解請參閱 “git help config” 中的對應條目。"
+
+#~ msgid "git archive: Remote with no URL"
+#~ msgstr "git archive: 未提供遠端 URL"
+
+#~ msgid "only one action at a time"
+#~ msgstr "一次只能有一個動作"
+
+#~ msgid "use [RFC PATCH] instead of [PATCH]"
+#~ msgstr "使用 [RFC PATCH] 代替 [PATCH]"
+
+#, c-format
+#~ msgid "no URLs configured for remote '%s'"
+#~ msgstr "沒有給遠端版本庫 '%s' 設定 URL"
+
+#, c-format
+#~ msgid "unable to copy '%s' to '%s'"
+#~ msgstr "無法複製 '%s' 至 '%s'"
+
+#, c-format
+#~ msgid "remote '%s' has no configured URL"
+#~ msgstr "“%s” 遠端未設定 URL"
+
#, c-format
#~ msgid "truncating .rej filename to %.*s.rej"
#~ msgstr "正在將 .rej 檔案名稱截短為 %.*s.rej"
@@ -28045,9 +28488,6 @@ msgstr "您真的要傳送 %s?[y|N]: "
#~ msgid "core.commentChar should only be one ASCII character"
#~ msgstr "core.commentChar 應該是一個 ASCII 字元"
-#~ msgid "-x and -X cannot be used together"
-#~ msgstr "-x 和 -X 不能同時使用"
-
#~ msgid ""
#~ "--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
#~ "exclude"
diff --git a/read-cache.c b/read-cache.c
index 48bf24f87c..1f67bb755b 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2963,7 +2963,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
if (err) {
free(ieot);
- return err;
+ goto cleanup;
}
offset = hashfile_total(f);
@@ -2992,8 +2992,14 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
free(ieot);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
if (write_extensions & WRITE_SPLIT_INDEX_EXTENSION &&
@@ -3008,8 +3014,14 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
sb.len) < 0;
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_link_extension() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
if (write_extensions & WRITE_CACHE_TREE_EXTENSION &&
!drop_cache_tree && istate->cache_tree) {
@@ -3019,8 +3031,14 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
err = write_index_ext_header(f, eoie_c, CACHE_EXT_TREE, sb.len) < 0;
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
if (write_extensions & WRITE_RESOLVE_UNDO_EXTENSION &&
istate->resolve_undo) {
@@ -3031,8 +3049,14 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
sb.len) < 0;
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
if (write_extensions & WRITE_UNTRACKED_CACHE_EXTENSION &&
istate->untracked) {
@@ -3043,8 +3067,14 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
sb.len) < 0;
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
if (write_extensions & WRITE_FSMONITOR_EXTENSION &&
istate->fsmonitor_last_update) {
@@ -3054,12 +3084,25 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
err = write_index_ext_header(f, eoie_c, CACHE_EXT_FSMONITOR, sb.len) < 0;
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
if (istate->sparse_index) {
- if (write_index_ext_header(f, eoie_c, CACHE_EXT_SPARSE_DIRECTORIES, 0) < 0)
- return -1;
+ err = write_index_ext_header(f, eoie_c, CACHE_EXT_SPARSE_DIRECTORIES, 0);
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
/*
@@ -3075,8 +3118,14 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
err = write_index_ext_header(f, NULL, CACHE_EXT_ENDOFINDEXENTRIES, sb.len) < 0;
hashwrite(f, sb.buf, sb.len);
strbuf_release(&sb);
- if (err)
- return -1;
+ /*
+ * NEEDSWORK: write_index_ext_header() never returns a failure,
+ * and this part may want to be simplified.
+ */
+ if (err) {
+ err = -1;
+ goto cleanup;
+ }
}
csum_fsync_flag = 0;
@@ -3085,13 +3134,16 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
finalize_hashfile(f, istate->oid.hash, FSYNC_COMPONENT_INDEX,
CSUM_HASH_IN_STREAM | csum_fsync_flag);
+ f = NULL;
if (close_tempfile_gently(tempfile)) {
- error(_("could not close '%s'"), get_tempfile_path(tempfile));
- return -1;
+ err = error(_("could not close '%s'"), get_tempfile_path(tempfile));
+ goto cleanup;
+ }
+ if (stat(get_tempfile_path(tempfile), &st)) {
+ err = error_errno(_("could not stat '%s'"), get_tempfile_path(tempfile));
+ goto cleanup;
}
- if (stat(get_tempfile_path(tempfile), &st))
- return -1;
istate->timestamp.sec = (unsigned int)st.st_mtime;
istate->timestamp.nsec = ST_MTIME_NSEC(st);
trace_performance_since(start, "write index, changed mask = %x", istate->cache_changed);
@@ -3106,6 +3158,11 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
istate->cache_nr);
return 0;
+
+cleanup:
+ if (f)
+ discard_hashfile(f);
+ return err;
}
void set_alternate_index_output(const char *name)
diff --git a/ref-filter.c b/ref-filter.c
index 8c5e673fc0..54880a2497 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1628,6 +1628,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
timestamp = parse_timestamp(eoemail + 2, &zone, 10);
if (timestamp == TIME_MAX)
goto bad;
+ errno = 0;
tz = strtol(zone, NULL, 10);
if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
goto bad;
diff --git a/reflog.c b/reflog.c
index 5ca944529b..eeccd5fab4 100644
--- a/reflog.c
+++ b/reflog.c
@@ -332,7 +332,8 @@ void reflog_expiry_prepare(const char *refname,
if (!cb->cmd.expire_unreachable || is_head(refname)) {
cb->unreachable_expire_kind = UE_HEAD;
} else {
- commit = lookup_commit(the_repository, oid);
+ commit = lookup_commit_reference_gently(the_repository,
+ oid, 1);
if (commit && is_null_oid(&commit->object.oid))
commit = NULL;
cb->unreachable_expire_kind = commit ? UE_NORMAL : UE_ALWAYS;
diff --git a/refs.c b/refs.c
index bb90a18875..e082fc59b0 100644
--- a/refs.c
+++ b/refs.c
@@ -2,8 +2,6 @@
* The backend-independent part of the reference module.
*/
-#define USE_THE_REPOSITORY_VARIABLE
-
#include "git-compat-util.h"
#include "advice.h"
#include "config.h"
@@ -1754,8 +1752,8 @@ static int refs_read_special_head(struct ref_store *ref_store,
goto done;
}
- result = parse_loose_ref_contents(content.buf, oid, referent, type,
- failure_errno);
+ result = parse_loose_ref_contents(ref_store->repo->hash_algo, content.buf,
+ oid, referent, type, failure_errno);
done:
strbuf_release(&full_path);
@@ -1838,7 +1836,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
failure_errno != ENOTDIR)
return NULL;
- oidclr(oid, the_repository->hash_algo);
+ oidclr(oid, refs->repo->hash_algo);
if (*flags & REF_BAD_NAME)
*flags |= REF_ISBROKEN;
return refname;
@@ -1848,7 +1846,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
if (!(read_flags & REF_ISSYMREF)) {
if (*flags & REF_BAD_NAME) {
- oidclr(oid, the_repository->hash_algo);
+ oidclr(oid, refs->repo->hash_algo);
*flags |= REF_ISBROKEN;
}
return refname;
@@ -1856,7 +1854,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
refname = sb_refname.buf;
if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
- oidclr(oid, the_repository->hash_algo);
+ oidclr(oid, refs->repo->hash_algo);
return refname;
}
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
@@ -2011,7 +2009,7 @@ struct ref_store *repo_get_submodule_ref_store(struct repository *repo,
free(subrepo);
goto done;
}
- refs = ref_store_init(subrepo, the_repository->ref_storage_format,
+ refs = ref_store_init(subrepo, repo->ref_storage_format,
submodule_sb.buf,
REF_STORE_READ | REF_STORE_ODB);
register_ref_store_map(&repo->submodule_ref_stores, "submodule",
@@ -2045,7 +2043,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
common_path.buf, REF_STORE_ALL_CAPS);
strbuf_release(&common_path);
} else {
- refs = ref_store_init(wt->repo, the_repository->ref_storage_format,
+ refs = ref_store_init(wt->repo, wt->repo->ref_storage_format,
wt->repo->commondir, REF_STORE_ALL_CAPS);
}
@@ -2844,6 +2842,14 @@ int repo_migrate_ref_storage_format(struct repository *repo,
}
/*
+ * Release the new ref store such that any potentially-open files will
+ * be closed. This is required for platforms like Cygwin, where
+ * renaming an open file results in EPERM.
+ */
+ ref_store_release(new_refs);
+ FREE_AND_NULL(new_refs);
+
+ /*
* Until now we were in the non-destructive phase, where we only
* populated the new ref store. From hereon though we are about
* to get hands by deleting the old ref store and then moving
@@ -2874,10 +2880,14 @@ int repo_migrate_ref_storage_format(struct repository *repo,
*/
initialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);
- free(new_refs->gitdir);
- new_refs->gitdir = xstrdup(old_refs->gitdir);
- repo->refs_private = new_refs;
+ /*
+ * Unset the old ref store and release it. `get_main_ref_store()` will
+ * make sure to lazily re-initialize the repository's ref store with
+ * the new format.
+ */
ref_store_release(old_refs);
+ FREE_AND_NULL(old_refs);
+ repo->refs_private = NULL;
ret = 0;
@@ -2888,8 +2898,10 @@ done:
new_gitdir.buf);
}
- if (ret && new_refs)
+ if (new_refs) {
ref_store_release(new_refs);
+ free(new_refs);
+ }
ref_transaction_free(transaction);
strbuf_release(&new_gitdir);
return ret;
diff --git a/refs.h b/refs.h
index 0ecba21b4a..9fbd2cdb2c 100644
--- a/refs.h
+++ b/refs.h
@@ -1086,211 +1086,4 @@ int repo_migrate_ref_storage_format(struct repository *repo,
unsigned int flags,
struct strbuf *err);
-/*
- * The following functions have been removed in Git v2.45 in favor of functions
- * that receive a `ref_store` as parameter. The intent of this section is
- * merely to help patch authors of in-flight series to have a reference what
- * they should be migrating to. The section will be removed in Git v2.46.
- */
-#if 0
-static char *resolve_refdup(const char *refname, int resolve_flags,
- struct object_id *oid, int *flags)
-{
- return refs_resolve_refdup(get_main_ref_store(the_repository),
- refname, resolve_flags,
- oid, flags);
-}
-
-static int read_ref_full(const char *refname, int resolve_flags,
- struct object_id *oid, int *flags)
-{
- return refs_read_ref_full(get_main_ref_store(the_repository), refname,
- resolve_flags, oid, flags);
-}
-
-static int read_ref(const char *refname, struct object_id *oid)
-{
- return refs_read_ref(get_main_ref_store(the_repository), refname, oid);
-}
-
-static int ref_exists(const char *refname)
-{
- return refs_ref_exists(get_main_ref_store(the_repository), refname);
-}
-
-static int for_each_tag_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static int for_each_branch_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static int for_each_remote_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static int head_ref_namespaced(each_ref_fn fn, void *cb_data)
-{
- return refs_head_ref_namespaced(get_main_ref_store(the_repository),
- fn, cb_data);
-}
-
-static int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
- const char *prefix, void *cb_data)
-{
- return refs_for_each_glob_ref_in(get_main_ref_store(the_repository),
- fn, pattern, prefix, cb_data);
-}
-
-static int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
-{
- return refs_for_each_glob_ref(get_main_ref_store(the_repository),
- fn, pattern, cb_data);
-}
-
-static int delete_ref(const char *msg, const char *refname,
- const struct object_id *old_oid, unsigned int flags)
-{
- return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
- old_oid, flags);
-}
-
-static struct ref_transaction *ref_transaction_begin(struct strbuf *err)
-{
- return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
-}
-
-static int update_ref(const char *msg, const char *refname,
- const struct object_id *new_oid,
- const struct object_id *old_oid,
- unsigned int flags, enum action_on_err onerr)
-{
- return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
- old_oid, flags, onerr);
-}
-
-static char *shorten_unambiguous_ref(const char *refname, int strict)
-{
- return refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
- refname, strict);
-}
-
-static int head_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static int for_each_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
-}
-
-static int for_each_fullref_in(const char *prefix,
- const char **exclude_patterns,
- each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_fullref_in(get_main_ref_store(the_repository),
- prefix, exclude_patterns, fn, cb_data);
-}
-
-static int for_each_namespaced_ref(const char **exclude_patterns,
- each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_namespaced_ref(get_main_ref_store(the_repository),
- exclude_patterns, fn, cb_data);
-}
-
-static int for_each_rawref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
- struct object_id *oid, int *flags)
-{
- return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
- resolve_flags, oid, flags);
-}
-
-static int create_symref(const char *ref_target, const char *refs_heads_master,
- const char *logmsg)
-{
- return refs_create_symref(get_main_ref_store(the_repository), ref_target,
- refs_heads_master, logmsg);
-}
-
-static int for_each_reflog(each_reflog_fn fn, void *cb_data)
-{
- return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-static int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
- void *cb_data)
-{
- return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository),
- refname, fn, cb_data);
-}
-
-static int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
- void *cb_data)
-{
- return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname,
- fn, cb_data);
-}
-
-static int reflog_exists(const char *refname)
-{
- return refs_reflog_exists(get_main_ref_store(the_repository), refname);
-}
-
-static int safe_create_reflog(const char *refname, struct strbuf *err)
-{
- return refs_create_reflog(get_main_ref_store(the_repository), refname,
- err);
-}
-
-static int delete_reflog(const char *refname)
-{
- return refs_delete_reflog(get_main_ref_store(the_repository), refname);
-}
-
-static int reflog_expire(const char *refname,
- unsigned int flags,
- reflog_expiry_prepare_fn prepare_fn,
- reflog_expiry_should_prune_fn should_prune_fn,
- reflog_expiry_cleanup_fn cleanup_fn,
- void *policy_cb_data)
-{
- return refs_reflog_expire(get_main_ref_store(the_repository),
- refname, flags,
- prepare_fn, should_prune_fn,
- cleanup_fn, policy_cb_data);
-}
-
-static int delete_refs(const char *msg, struct string_list *refnames,
- unsigned int flags)
-{
- return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags);
-}
-
-static int rename_ref(const char *oldref, const char *newref, const char *logmsg)
-{
- return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
-}
-
-static int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
-{
- return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
-}
-#endif
-
#endif /* REFS_H */
diff --git a/refs/files-backend.c b/refs/files-backend.c
index aa52d9be7c..6380dff443 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1,5 +1,3 @@
-#define USE_THE_REPOSITORY_VARIABLE
-
#include "../git-compat-util.h"
#include "../copy.h"
#include "../environment.h"
@@ -157,6 +155,7 @@ static void files_ref_store_release(struct ref_store *ref_store)
free_ref_cache(refs->loose);
free(refs->gitcommondir);
ref_store_release(refs->packed_ref_store);
+ free(refs->packed_ref_store);
}
static void files_reflog_path(struct files_ref_store *refs,
@@ -248,7 +247,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,
if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,
&oid, &flag)) {
- oidclr(&oid, the_repository->hash_algo);
+ oidclr(&oid, refs->base.repo->hash_algo);
flag |= REF_ISBROKEN;
} else if (is_null_oid(&oid)) {
/*
@@ -265,7 +264,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
if (!refname_is_safe(refname))
die("loose refname is dangerous: %s", refname);
- oidclr(&oid, the_repository->hash_algo);
+ oidclr(&oid, refs->base.repo->hash_algo);
flag |= REF_BAD_NAME | REF_ISBROKEN;
}
add_entry_to_dir(dir, create_ref_entry(refname, &oid, flag));
@@ -552,7 +551,8 @@ stat_ref:
strbuf_rtrim(&sb_contents);
buf = sb_contents.buf;
- ret = parse_loose_ref_contents(buf, oid, referent, type, &myerr);
+ ret = parse_loose_ref_contents(ref_store->repo->hash_algo, buf,
+ oid, referent, type, &myerr);
out:
if (ret && !myerr)
@@ -586,7 +586,8 @@ static int files_read_symbolic_ref(struct ref_store *ref_store, const char *refn
return !(type & REF_ISSYMREF);
}
-int parse_loose_ref_contents(const char *buf, struct object_id *oid,
+int parse_loose_ref_contents(const struct git_hash_algo *algop,
+ const char *buf, struct object_id *oid,
struct strbuf *referent, unsigned int *type,
int *failure_errno)
{
@@ -604,7 +605,7 @@ int parse_loose_ref_contents(const char *buf, struct object_id *oid,
/*
* FETCH_HEAD has additional data after the sha.
*/
- if (parse_oid_hex(buf, oid, &p) ||
+ if (parse_oid_hex_algop(buf, oid, &p, algop) ||
(*p != '\0' && !isspace(*p))) {
*type |= REF_ISBROKEN;
*failure_errno = EINVAL;
@@ -1152,7 +1153,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
if (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0,
&lock->old_oid, NULL))
- oidclr(&lock->old_oid, the_repository->hash_algo);
+ oidclr(&lock->old_oid, refs->base.repo->hash_algo);
goto out;
error_return:
@@ -1998,7 +1999,8 @@ static int files_delete_reflog(struct ref_store *ref_store,
return ret;
}
-static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data)
+static int show_one_reflog_ent(struct files_ref_store *refs, struct strbuf *sb,
+ each_reflog_ent_fn fn, void *cb_data)
{
struct object_id ooid, noid;
char *email_end, *message;
@@ -2008,8 +2010,8 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c
/* old SP new SP name <email> SP time TAB msg LF */
if (!sb->len || sb->buf[sb->len - 1] != '\n' ||
- parse_oid_hex(p, &ooid, &p) || *p++ != ' ' ||
- parse_oid_hex(p, &noid, &p) || *p++ != ' ' ||
+ parse_oid_hex_algop(p, &ooid, &p, refs->base.repo->hash_algo) || *p++ != ' ' ||
+ parse_oid_hex_algop(p, &noid, &p, refs->base.repo->hash_algo) || *p++ != ' ' ||
!(email_end = strchr(p, '>')) ||
email_end[1] != ' ' ||
!(timestamp = parse_timestamp(email_end + 2, &message, 10)) ||
@@ -2108,7 +2110,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
strbuf_splice(&sb, 0, 0, bp + 1, endp - (bp + 1));
scanp = bp;
endp = bp + 1;
- ret = show_one_reflog_ent(&sb, fn, cb_data);
+ ret = show_one_reflog_ent(refs, &sb, fn, cb_data);
strbuf_reset(&sb);
if (ret)
break;
@@ -2120,7 +2122,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
* Process it, and we can end the loop.
*/
strbuf_splice(&sb, 0, 0, buf, endp - buf);
- ret = show_one_reflog_ent(&sb, fn, cb_data);
+ ret = show_one_reflog_ent(refs, &sb, fn, cb_data);
strbuf_reset(&sb);
break;
}
@@ -2170,7 +2172,7 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
return -1;
while (!ret && !strbuf_getwholeline(&sb, logfp, '\n'))
- ret = show_one_reflog_ent(&sb, fn, cb_data);
+ ret = show_one_reflog_ent(refs, &sb, fn, cb_data);
fclose(logfp);
strbuf_release(&sb);
return ret;
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index a0666407cd..89976aa359 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -1,5 +1,3 @@
-#define USE_THE_REPOSITORY_VARIABLE
-
#include "../git-compat-util.h"
#include "../config.h"
#include "../dir.h"
@@ -794,7 +792,7 @@ static int packed_read_raw_ref(struct ref_store *ref_store, const char *refname,
return -1;
}
- if (get_oid_hex(rec, oid))
+ if (get_oid_hex_algop(rec, oid, ref_store->repo->hash_algo))
die_invalid_line(refs->path, rec, snapshot->eof - rec);
*type = REF_ISPACKED;
@@ -879,7 +877,7 @@ static int next_record(struct packed_ref_iterator *iter)
p = iter->pos;
if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 2 ||
- parse_oid_hex(p, &iter->oid, &p) ||
+ parse_oid_hex_algop(p, &iter->oid, &p, iter->repo->hash_algo) ||
!isspace(*p++))
die_invalid_line(iter->snapshot->refs->path,
iter->pos, iter->eof - iter->pos);
@@ -896,7 +894,7 @@ static int next_record(struct packed_ref_iterator *iter)
if (!refname_is_safe(iter->base.refname))
die("packed refname is dangerous: %s",
iter->base.refname);
- oidclr(&iter->oid, the_repository->hash_algo);
+ oidclr(&iter->oid, iter->repo->hash_algo);
iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN;
}
if (iter->snapshot->peeled == PEELED_FULLY ||
@@ -909,7 +907,7 @@ static int next_record(struct packed_ref_iterator *iter)
if (iter->pos < iter->eof && *iter->pos == '^') {
p = iter->pos + 1;
if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 1 ||
- parse_oid_hex(p, &iter->peeled, &p) ||
+ parse_oid_hex_algop(p, &iter->peeled, &p, iter->repo->hash_algo) ||
*p++ != '\n')
die_invalid_line(iter->snapshot->refs->path,
iter->pos, iter->eof - iter->pos);
@@ -921,13 +919,13 @@ static int next_record(struct packed_ref_iterator *iter)
* we suppress it if the reference is broken:
*/
if ((iter->base.flags & REF_ISBROKEN)) {
- oidclr(&iter->peeled, the_repository->hash_algo);
+ oidclr(&iter->peeled, iter->repo->hash_algo);
iter->base.flags &= ~REF_KNOWS_PEELED;
} else {
iter->base.flags |= REF_KNOWS_PEELED;
}
} else {
- oidclr(&iter->peeled, the_repository->hash_algo);
+ oidclr(&iter->peeled, iter->repo->hash_algo);
}
return ITER_OK;
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index fa975d69aa..309b382284 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -705,7 +705,8 @@ struct ref_store {
* Parse contents of a loose ref file. *failure_errno maybe be set to EINVAL for
* invalid contents.
*/
-int parse_loose_ref_contents(const char *buf, struct object_id *oid,
+int parse_loose_ref_contents(const struct git_hash_algo *algop,
+ const char *buf, struct object_id *oid,
struct strbuf *referent, unsigned int *type,
int *failure_errno);
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index fbe74c239d..bf4446afd3 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -1,5 +1,3 @@
-#define USE_THE_REPOSITORY_VARIABLE
-
#include "../git-compat-util.h"
#include "../abspath.h"
#include "../chdir-notify.h"
@@ -201,7 +199,8 @@ static void fill_reftable_log_record(struct reftable_log_record *log, const stru
log->value.update.tz_offset = sign * atoi(tz_begin);
}
-static int read_ref_without_reload(struct reftable_stack *stack,
+static int read_ref_without_reload(struct reftable_ref_store *refs,
+ struct reftable_stack *stack,
const char *refname,
struct object_id *oid,
struct strbuf *referent,
@@ -220,7 +219,7 @@ static int read_ref_without_reload(struct reftable_stack *stack,
*type |= REF_ISSYMREF;
} else if (reftable_ref_record_val1(&ref)) {
oidread(oid, reftable_ref_record_val1(&ref),
- the_repository->hash_algo);
+ refs->base.repo->hash_algo);
} else {
/* We got a tombstone, which should not happen. */
BUG("unhandled reference value type %d", ref.value_type);
@@ -487,16 +486,16 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
switch (iter->ref.value_type) {
case REFTABLE_REF_VAL1:
oidread(&iter->oid, iter->ref.value.val1,
- the_repository->hash_algo);
+ refs->base.repo->hash_algo);
break;
case REFTABLE_REF_VAL2:
oidread(&iter->oid, iter->ref.value.val2.value,
- the_repository->hash_algo);
+ refs->base.repo->hash_algo);
break;
case REFTABLE_REF_SYMREF:
if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname,
RESOLVE_REF_READING, &iter->oid, &flags))
- oidclr(&iter->oid, the_repository->hash_algo);
+ oidclr(&iter->oid, refs->base.repo->hash_algo);
break;
default:
BUG("unhandled reference value type %d", iter->ref.value_type);
@@ -508,7 +507,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
if (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) {
if (!refname_is_safe(iter->ref.refname))
die(_("refname is dangerous: %s"), iter->ref.refname);
- oidclr(&iter->oid, the_repository->hash_algo);
+ oidclr(&iter->oid, refs->base.repo->hash_algo);
flags |= REF_BAD_NAME | REF_ISBROKEN;
}
@@ -551,7 +550,7 @@ static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,
if (iter->ref.value_type == REFTABLE_REF_VAL2) {
oidread(peeled, iter->ref.value.val2.target_value,
- the_repository->hash_algo);
+ iter->refs->base.repo->hash_algo);
return 0;
}
@@ -659,7 +658,7 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store,
if (ret)
return ret;
- ret = read_ref_without_reload(stack, refname, oid, referent, type);
+ ret = read_ref_without_reload(refs, stack, refname, oid, referent, type);
if (ret < 0)
return ret;
if (ret > 0) {
@@ -868,8 +867,8 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
goto done;
}
- ret = read_ref_without_reload(stack_for(refs, "HEAD", NULL), "HEAD", &head_oid,
- &head_referent, &head_type);
+ ret = read_ref_without_reload(refs, stack_for(refs, "HEAD", NULL), "HEAD",
+ &head_oid, &head_referent, &head_type);
if (ret < 0)
goto done;
ret = 0;
@@ -936,7 +935,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
string_list_insert(&affected_refnames, new_update->refname);
}
- ret = read_ref_without_reload(stack, rewritten_ref,
+ ret = read_ref_without_reload(refs, stack, rewritten_ref,
&current_oid, &referent, &u->type);
if (ret < 0)
goto done;
@@ -1500,7 +1499,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
logs_nr++;
- ret = read_ref_without_reload(arg->stack, "HEAD", &head_oid, &head_referent, &head_type);
+ ret = read_ref_without_reload(arg->refs, arg->stack, "HEAD", &head_oid,
+ &head_referent, &head_type);
if (ret < 0)
goto done;
append_head_reflog = (head_type & REF_ISSYMREF) && !strcmp(head_referent.buf, arg->oldname);
@@ -1790,15 +1790,16 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store *
ref_iterator_select, NULL);
}
-static int yield_log_record(struct reftable_log_record *log,
+static int yield_log_record(struct reftable_ref_store *refs,
+ struct reftable_log_record *log,
each_reflog_ent_fn fn,
void *cb_data)
{
struct object_id old_oid, new_oid;
const char *full_committer;
- oidread(&old_oid, log->value.update.old_hash, the_repository->hash_algo);
- oidread(&new_oid, log->value.update.new_hash, the_repository->hash_algo);
+ oidread(&old_oid, log->value.update.old_hash, refs->base.repo->hash_algo);
+ oidread(&new_oid, log->value.update.new_hash, refs->base.repo->hash_algo);
/*
* When both the old object ID and the new object ID are null
@@ -1841,7 +1842,7 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store,
break;
}
- ret = yield_log_record(&log, fn, cb_data);
+ ret = yield_log_record(refs, &log, fn, cb_data);
if (ret)
break;
}
@@ -1886,7 +1887,7 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
}
for (i = logs_nr; i--;) {
- ret = yield_log_record(&logs[i], fn, cb_data);
+ ret = yield_log_record(refs, &logs[i], fn, cb_data);
if (ret)
goto done;
}
@@ -2200,7 +2201,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
goto done;
if (reftable_ref_record_val1(&ref_record))
oidread(&oid, reftable_ref_record_val1(&ref_record),
- the_repository->hash_algo);
+ ref_store->repo->hash_algo);
prepare_fn(refname, &oid, policy_cb_data);
while (1) {
@@ -2216,9 +2217,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
}
oidread(&old_oid, log.value.update.old_hash,
- the_repository->hash_algo);
+ ref_store->repo->hash_algo);
oidread(&new_oid, log.value.update.new_hash,
- the_repository->hash_algo);
+ ref_store->repo->hash_algo);
/*
* Skip over the reflog existence marker. We will add it back
@@ -2250,9 +2251,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
*dest = logs[i];
oidread(&old_oid, logs[i].value.update.old_hash,
- the_repository->hash_algo);
+ ref_store->repo->hash_algo);
oidread(&new_oid, logs[i].value.update.new_hash,
- the_repository->hash_algo);
+ ref_store->repo->hash_algo);
if (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email,
(timestamp_t)logs[i].value.update.time,
@@ -2269,7 +2270,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash &&
reftable_ref_record_val1(&ref_record))
- oidread(&arg.update_oid, last_hash, the_repository->hash_algo);
+ oidread(&arg.update_oid, last_hash, ref_store->repo->hash_algo);
arg.refs = refs;
arg.records = rewritten;
diff --git a/reftable/pq.c b/reftable/pq.c
index 7fb45d8c60..2b5b7d1c0e 100644
--- a/reftable/pq.c
+++ b/reftable/pq.c
@@ -22,27 +22,21 @@ int pq_less(struct pq_entry *a, struct pq_entry *b)
struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq)
{
- int i = 0;
+ size_t i = 0;
struct pq_entry e = pq->heap[0];
pq->heap[0] = pq->heap[pq->len - 1];
pq->len--;
- i = 0;
while (i < pq->len) {
- int min = i;
- int j = 2 * i + 1;
- int k = 2 * i + 2;
- if (j < pq->len && pq_less(&pq->heap[j], &pq->heap[i])) {
+ size_t min = i;
+ size_t j = 2 * i + 1;
+ size_t k = 2 * i + 2;
+ if (j < pq->len && pq_less(&pq->heap[j], &pq->heap[i]))
min = j;
- }
- if (k < pq->len && pq_less(&pq->heap[k], &pq->heap[min])) {
+ if (k < pq->len && pq_less(&pq->heap[k], &pq->heap[min]))
min = k;
- }
-
- if (min == i) {
+ if (min == i)
break;
- }
-
SWAP(pq->heap[i], pq->heap[min]);
i = min;
}
@@ -52,20 +46,17 @@ struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq)
void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e)
{
- int i = 0;
+ size_t i = 0;
REFTABLE_ALLOC_GROW(pq->heap, pq->len + 1, pq->cap);
pq->heap[pq->len++] = *e;
i = pq->len - 1;
while (i > 0) {
- int j = (i - 1) / 2;
- if (pq_less(&pq->heap[j], &pq->heap[i])) {
+ size_t j = (i - 1) / 2;
+ if (pq_less(&pq->heap[j], &pq->heap[i]))
break;
- }
-
SWAP(pq->heap[j], pq->heap[i]);
-
i = j;
}
}
diff --git a/reftable/pq.h b/reftable/pq.h
index f796c23179..707bd26767 100644
--- a/reftable/pq.h
+++ b/reftable/pq.h
@@ -22,7 +22,6 @@ struct merged_iter_pqueue {
size_t cap;
};
-void merged_iter_pqueue_check(struct merged_iter_pqueue pq);
struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq);
void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e);
void merged_iter_pqueue_release(struct merged_iter_pqueue *pq);
diff --git a/reftable/pq_test.c b/reftable/pq_test.c
deleted file mode 100644
index b7d3c80cc7..0000000000
--- a/reftable/pq_test.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-Copyright 2020 Google LLC
-
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file or at
-https://developers.google.com/open-source/licenses/bsd
-*/
-
-#include "system.h"
-
-#include "basics.h"
-#include "constants.h"
-#include "pq.h"
-#include "record.h"
-#include "reftable-tests.h"
-#include "test_framework.h"
-
-void merged_iter_pqueue_check(struct merged_iter_pqueue pq)
-{
- int i;
- for (i = 1; i < pq.len; i++) {
- int parent = (i - 1) / 2;
-
- EXPECT(pq_less(&pq.heap[parent], &pq.heap[i]));
- }
-}
-
-static void test_pq(void)
-{
- struct merged_iter_pqueue pq = { NULL };
- struct reftable_record recs[54];
- int N = ARRAY_SIZE(recs) - 1, i;
- char *last = NULL;
-
- for (i = 0; i < N; i++) {
- struct strbuf refname = STRBUF_INIT;
- strbuf_addf(&refname, "%02d", i);
-
- reftable_record_init(&recs[i], BLOCK_TYPE_REF);
- recs[i].u.ref.refname = strbuf_detach(&refname, NULL);
- }
-
- i = 1;
- do {
- struct pq_entry e = {
- .rec = &recs[i],
- };
-
- merged_iter_pqueue_add(&pq, &e);
- merged_iter_pqueue_check(pq);
-
- i = (i * 7) % N;
- } while (i != 1);
-
- while (!merged_iter_pqueue_is_empty(pq)) {
- struct pq_entry e = merged_iter_pqueue_remove(&pq);
- merged_iter_pqueue_check(pq);
-
- EXPECT(reftable_record_type(e.rec) == BLOCK_TYPE_REF);
- if (last)
- EXPECT(strcmp(last, e.rec->u.ref.refname) < 0);
- last = e.rec->u.ref.refname;
- }
-
- for (i = 0; i < N; i++)
- reftable_record_release(&recs[i]);
- merged_iter_pqueue_release(&pq);
-}
-
-int pq_test_main(int argc, const char *argv[])
-{
- RUN_TEST(test_pq);
- return 0;
-}
diff --git a/reftable/record_test.c b/reftable/record_test.c
deleted file mode 100644
index 58290bdba3..0000000000
--- a/reftable/record_test.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- Copyright 2020 Google LLC
-
- Use of this source code is governed by a BSD-style
- license that can be found in the LICENSE file or at
- https://developers.google.com/open-source/licenses/bsd
-*/
-
-#include "record.h"
-
-#include "system.h"
-#include "basics.h"
-#include "constants.h"
-#include "test_framework.h"
-#include "reftable-tests.h"
-
-static void test_copy(struct reftable_record *rec)
-{
- struct reftable_record copy;
- uint8_t typ;
-
- typ = reftable_record_type(rec);
- reftable_record_init(&copy, typ);
- reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
- /* do it twice to catch memory leaks */
- reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
- EXPECT(reftable_record_equal(rec, &copy, GIT_SHA1_RAWSZ));
-
- puts("testing print coverage:\n");
- reftable_record_print(&copy, GIT_SHA1_RAWSZ);
-
- reftable_record_release(&copy);
-}
-
-static void test_varint_roundtrip(void)
-{
- uint64_t inputs[] = { 0,
- 1,
- 27,
- 127,
- 128,
- 257,
- 4096,
- ((uint64_t)1 << 63),
- ((uint64_t)1 << 63) + ((uint64_t)1 << 63) - 1 };
- int i = 0;
- for (i = 0; i < ARRAY_SIZE(inputs); i++) {
- uint8_t dest[10];
-
- struct string_view out = {
- .buf = dest,
- .len = sizeof(dest),
- };
- uint64_t in = inputs[i];
- int n = put_var_int(&out, in);
- uint64_t got = 0;
-
- EXPECT(n > 0);
- out.len = n;
- n = get_var_int(&got, &out);
- EXPECT(n > 0);
-
- EXPECT(got == in);
- }
-}
-
-static void set_hash(uint8_t *h, int j)
-{
- int i = 0;
- for (i = 0; i < hash_size(GIT_SHA1_FORMAT_ID); i++) {
- h[i] = (j >> i) & 0xff;
- }
-}
-
-static void test_reftable_ref_record_roundtrip(void)
-{
- struct strbuf scratch = STRBUF_INIT;
- int i = 0;
-
- for (i = REFTABLE_REF_DELETION; i < REFTABLE_NR_REF_VALUETYPES; i++) {
- struct reftable_record in = {
- .type = BLOCK_TYPE_REF,
- };
- struct reftable_record out = { .type = BLOCK_TYPE_REF };
- struct strbuf key = STRBUF_INIT;
- uint8_t buffer[1024] = { 0 };
- struct string_view dest = {
- .buf = buffer,
- .len = sizeof(buffer),
- };
- int n, m;
-
- in.u.ref.value_type = i;
- switch (i) {
- case REFTABLE_REF_DELETION:
- break;
- case REFTABLE_REF_VAL1:
- set_hash(in.u.ref.value.val1, 1);
- break;
- case REFTABLE_REF_VAL2:
- set_hash(in.u.ref.value.val2.value, 1);
- set_hash(in.u.ref.value.val2.target_value, 2);
- break;
- case REFTABLE_REF_SYMREF:
- in.u.ref.value.symref = xstrdup("target");
- break;
- }
- in.u.ref.refname = xstrdup("refs/heads/master");
-
- test_copy(&in);
-
- EXPECT(reftable_record_val_type(&in) == i);
-
- reftable_record_key(&in, &key);
- n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
- EXPECT(n > 0);
-
- /* decode into a non-zero reftable_record to test for leaks. */
- m = reftable_record_decode(&out, key, i, dest, GIT_SHA1_RAWSZ, &scratch);
- EXPECT(n == m);
-
- EXPECT(reftable_ref_record_equal(&in.u.ref, &out.u.ref,
- GIT_SHA1_RAWSZ));
- reftable_record_release(&in);
-
- strbuf_release(&key);
- reftable_record_release(&out);
- }
-
- strbuf_release(&scratch);
-}
-
-static void test_reftable_log_record_equal(void)
-{
- struct reftable_log_record in[2] = {
- {
- .refname = xstrdup("refs/heads/master"),
- .update_index = 42,
- },
- {
- .refname = xstrdup("refs/heads/master"),
- .update_index = 22,
- }
- };
-
- EXPECT(!reftable_log_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
- in[1].update_index = in[0].update_index;
- EXPECT(reftable_log_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
- reftable_log_record_release(&in[0]);
- reftable_log_record_release(&in[1]);
-}
-
-static void test_reftable_log_record_roundtrip(void)
-{
- int i;
- struct reftable_log_record in[] = {
- {
- .refname = xstrdup("refs/heads/master"),
- .update_index = 42,
- .value_type = REFTABLE_LOG_UPDATE,
- .value = {
- .update = {
- .name = xstrdup("han-wen"),
- .email = xstrdup("hanwen@google.com"),
- .message = xstrdup("test"),
- .time = 1577123507,
- .tz_offset = 100,
- },
- }
- },
- {
- .refname = xstrdup("refs/heads/master"),
- .update_index = 22,
- .value_type = REFTABLE_LOG_DELETION,
- },
- {
- .refname = xstrdup("branch"),
- .update_index = 33,
- .value_type = REFTABLE_LOG_UPDATE,
- }
- };
- struct strbuf scratch = STRBUF_INIT;
-
- set_test_hash(in[0].value.update.new_hash, 1);
- set_test_hash(in[0].value.update.old_hash, 2);
- set_test_hash(in[2].value.update.new_hash, 3);
- set_test_hash(in[2].value.update.old_hash, 4);
- for (i = 0; i < ARRAY_SIZE(in); i++) {
- struct reftable_record rec = { .type = BLOCK_TYPE_LOG };
- struct strbuf key = STRBUF_INIT;
- uint8_t buffer[1024] = { 0 };
- struct string_view dest = {
- .buf = buffer,
- .len = sizeof(buffer),
- };
- /* populate out, to check for leaks. */
- struct reftable_record out = {
- .type = BLOCK_TYPE_LOG,
- .u.log = {
- .refname = xstrdup("old name"),
- .value_type = REFTABLE_LOG_UPDATE,
- .value = {
- .update = {
- .name = xstrdup("old name"),
- .email = xstrdup("old@email"),
- .message = xstrdup("old message"),
- },
- },
- },
- };
- int n, m, valtype;
-
- rec.u.log = in[i];
-
- test_copy(&rec);
-
- reftable_record_key(&rec, &key);
-
- n = reftable_record_encode(&rec, dest, GIT_SHA1_RAWSZ);
- EXPECT(n >= 0);
- valtype = reftable_record_val_type(&rec);
- m = reftable_record_decode(&out, key, valtype, dest,
- GIT_SHA1_RAWSZ, &scratch);
- EXPECT(n == m);
-
- EXPECT(reftable_log_record_equal(&in[i], &out.u.log,
- GIT_SHA1_RAWSZ));
- reftable_log_record_release(&in[i]);
- strbuf_release(&key);
- reftable_record_release(&out);
- }
-
- strbuf_release(&scratch);
-}
-
-static void test_key_roundtrip(void)
-{
- uint8_t buffer[1024] = { 0 };
- struct string_view dest = {
- .buf = buffer,
- .len = sizeof(buffer),
- };
- struct strbuf last_key = STRBUF_INIT;
- struct strbuf key = STRBUF_INIT;
- struct strbuf roundtrip = STRBUF_INIT;
- int restart;
- uint8_t extra;
- int n, m;
- uint8_t rt_extra;
-
- strbuf_addstr(&last_key, "refs/heads/master");
- strbuf_addstr(&key, "refs/tags/bla");
- extra = 6;
- n = reftable_encode_key(&restart, dest, last_key, key, extra);
- EXPECT(!restart);
- EXPECT(n > 0);
-
- strbuf_addstr(&roundtrip, "refs/heads/master");
- m = reftable_decode_key(&roundtrip, &rt_extra, dest);
- EXPECT(n == m);
- EXPECT(0 == strbuf_cmp(&key, &roundtrip));
- EXPECT(rt_extra == extra);
-
- strbuf_release(&last_key);
- strbuf_release(&key);
- strbuf_release(&roundtrip);
-}
-
-static void test_reftable_obj_record_roundtrip(void)
-{
- uint8_t testHash1[GIT_SHA1_RAWSZ] = { 1, 2, 3, 4, 0 };
- uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
- struct reftable_obj_record recs[3] = {
- {
- .hash_prefix = testHash1,
- .hash_prefix_len = 5,
- .offsets = till9,
- .offset_len = 3,
- },
- {
- .hash_prefix = testHash1,
- .hash_prefix_len = 5,
- .offsets = till9,
- .offset_len = 9,
- },
- {
- .hash_prefix = testHash1,
- .hash_prefix_len = 5,
- },
- };
- struct strbuf scratch = STRBUF_INIT;
- int i = 0;
-
- for (i = 0; i < ARRAY_SIZE(recs); i++) {
- uint8_t buffer[1024] = { 0 };
- struct string_view dest = {
- .buf = buffer,
- .len = sizeof(buffer),
- };
- struct reftable_record in = {
- .type = BLOCK_TYPE_OBJ,
- .u = {
- .obj = recs[i],
- },
- };
- struct strbuf key = STRBUF_INIT;
- struct reftable_record out = { .type = BLOCK_TYPE_OBJ };
- int n, m;
- uint8_t extra;
-
- test_copy(&in);
- reftable_record_key(&in, &key);
- n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
- EXPECT(n > 0);
- extra = reftable_record_val_type(&in);
- m = reftable_record_decode(&out, key, extra, dest,
- GIT_SHA1_RAWSZ, &scratch);
- EXPECT(n == m);
-
- EXPECT(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
- strbuf_release(&key);
- reftable_record_release(&out);
- }
-
- strbuf_release(&scratch);
-}
-
-static void test_reftable_index_record_roundtrip(void)
-{
- struct reftable_record in = {
- .type = BLOCK_TYPE_INDEX,
- .u.idx = {
- .offset = 42,
- .last_key = STRBUF_INIT,
- },
- };
- uint8_t buffer[1024] = { 0 };
- struct string_view dest = {
- .buf = buffer,
- .len = sizeof(buffer),
- };
- struct strbuf scratch = STRBUF_INIT;
- struct strbuf key = STRBUF_INIT;
- struct reftable_record out = {
- .type = BLOCK_TYPE_INDEX,
- .u.idx = { .last_key = STRBUF_INIT },
- };
- int n, m;
- uint8_t extra;
-
- strbuf_addstr(&in.u.idx.last_key, "refs/heads/master");
- reftable_record_key(&in, &key);
- test_copy(&in);
-
- EXPECT(0 == strbuf_cmp(&key, &in.u.idx.last_key));
- n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
- EXPECT(n > 0);
-
- extra = reftable_record_val_type(&in);
- m = reftable_record_decode(&out, key, extra, dest, GIT_SHA1_RAWSZ,
- &scratch);
- EXPECT(m == n);
-
- EXPECT(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
-
- reftable_record_release(&out);
- strbuf_release(&key);
- strbuf_release(&scratch);
- strbuf_release(&in.u.idx.last_key);
-}
-
-int record_test_main(int argc, const char *argv[])
-{
- RUN_TEST(test_reftable_log_record_equal);
- RUN_TEST(test_reftable_log_record_roundtrip);
- RUN_TEST(test_reftable_ref_record_roundtrip);
- RUN_TEST(test_varint_roundtrip);
- RUN_TEST(test_key_roundtrip);
- RUN_TEST(test_reftable_obj_record_roundtrip);
- RUN_TEST(test_reftable_index_record_roundtrip);
- return 0;
-}
diff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h
index 114cc3d053..4b666810af 100644
--- a/reftable/reftable-tests.h
+++ b/reftable/reftable-tests.h
@@ -11,12 +11,9 @@ https://developers.google.com/open-source/licenses/bsd
int basics_test_main(int argc, const char **argv);
int block_test_main(int argc, const char **argv);
-int merged_test_main(int argc, const char **argv);
-int pq_test_main(int argc, const char **argv);
int record_test_main(int argc, const char **argv);
int readwrite_test_main(int argc, const char **argv);
int stack_test_main(int argc, const char **argv);
-int tree_test_main(int argc, const char **argv);
int reftable_dump_main(int argc, char *const *argv);
#endif
diff --git a/reftable/tree.c b/reftable/tree.c
index 528f33ae38..5ffb2e0d69 100644
--- a/reftable/tree.c
+++ b/reftable/tree.c
@@ -39,25 +39,20 @@ struct tree_node *tree_search(void *key, struct tree_node **rootp,
void infix_walk(struct tree_node *t, void (*action)(void *arg, void *key),
void *arg)
{
- if (t->left) {
+ if (t->left)
infix_walk(t->left, action, arg);
- }
action(arg, t->key);
- if (t->right) {
+ if (t->right)
infix_walk(t->right, action, arg);
- }
}
void tree_free(struct tree_node *t)
{
- if (!t) {
+ if (!t)
return;
- }
- if (t->left) {
+ if (t->left)
tree_free(t->left);
- }
- if (t->right) {
+ if (t->right)
tree_free(t->right);
- }
reftable_free(t);
}
diff --git a/reftable/tree_test.c b/reftable/tree_test.c
deleted file mode 100644
index 6961a657ad..0000000000
--- a/reftable/tree_test.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-Copyright 2020 Google LLC
-
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file or at
-https://developers.google.com/open-source/licenses/bsd
-*/
-
-#include "system.h"
-#include "tree.h"
-
-#include "test_framework.h"
-#include "reftable-tests.h"
-
-static int test_compare(const void *a, const void *b)
-{
- return (char *)a - (char *)b;
-}
-
-struct curry {
- void *last;
-};
-
-static void check_increasing(void *arg, void *key)
-{
- struct curry *c = arg;
- if (c->last) {
- EXPECT(test_compare(c->last, key) < 0);
- }
- c->last = key;
-}
-
-static void test_tree(void)
-{
- struct tree_node *root = NULL;
-
- void *values[11] = { NULL };
- struct tree_node *nodes[11] = { NULL };
- int i = 1;
- struct curry c = { NULL };
- do {
- nodes[i] = tree_search(values + i, &root, &test_compare, 1);
- i = (i * 7) % 11;
- } while (i != 1);
-
- for (i = 1; i < ARRAY_SIZE(nodes); i++) {
- EXPECT(values + i == nodes[i]->key);
- EXPECT(nodes[i] ==
- tree_search(values + i, &root, &test_compare, 0));
- }
-
- infix_walk(root, check_increasing, &c);
- tree_free(root);
-}
-
-int tree_test_main(int argc, const char *argv[])
-{
- RUN_TEST(test_tree);
- return 0;
-}
diff --git a/repo-settings.c b/repo-settings.c
index a0b590bc6c..2b4e68731b 100644
--- a/repo-settings.c
+++ b/repo-settings.c
@@ -23,6 +23,7 @@ void prepare_repo_settings(struct repository *r)
int value;
const char *strval;
int manyfiles;
+ int read_changed_paths;
if (!r->gitdir)
BUG("Cannot add settings for uninitialized repository");
@@ -54,7 +55,10 @@ void prepare_repo_settings(struct repository *r)
/* Commit graph config or default, does not cascade (simple) */
repo_cfg_bool(r, "core.commitgraph", &r->settings.core_commit_graph, 1);
repo_cfg_int(r, "commitgraph.generationversion", &r->settings.commit_graph_generation_version, 2);
- repo_cfg_bool(r, "commitgraph.readchangedpaths", &r->settings.commit_graph_read_changed_paths, 1);
+ repo_cfg_bool(r, "commitgraph.readchangedpaths", &read_changed_paths, 1);
+ repo_cfg_int(r, "commitgraph.changedpathsversion",
+ &r->settings.commit_graph_changed_paths_version,
+ read_changed_paths ? -1 : 0);
repo_cfg_bool(r, "gc.writecommitgraph", &r->settings.gc_write_commit_graph, 1);
repo_cfg_bool(r, "fetch.writecommitgraph", &r->settings.fetch_write_commit_graph, 0);
diff --git a/repository.h b/repository.h
index 6ce6826c26..af6ea0a62c 100644
--- a/repository.h
+++ b/repository.h
@@ -37,7 +37,7 @@ struct repo_settings {
int core_commit_graph;
int commit_graph_generation_version;
- int commit_graph_read_changed_paths;
+ int commit_graph_changed_paths_version;
int gc_write_commit_graph;
int fetch_write_commit_graph;
int command_requires_full_index;
diff --git a/rerere.c b/rerere.c
index 597256fa5b..525ed6cc1e 100644
--- a/rerere.c
+++ b/rerere.c
@@ -851,6 +851,8 @@ static int do_plain_rerere(struct repository *r,
if (update.nr)
update_paths(r, &update);
+ string_list_clear(&conflict, 0);
+ string_list_clear(&update, 0);
return write_rr(rr, fd);
}
@@ -914,6 +916,7 @@ int repo_rerere(struct repository *r, int flags)
return 0;
status = do_plain_rerere(r, &merge_rr, fd);
free_rerere_dirs();
+ string_list_clear(&merge_rr, 1);
return status;
}
@@ -1104,7 +1107,7 @@ fail_exit:
int rerere_forget(struct repository *r, struct pathspec *pathspec)
{
- int i, fd;
+ int i, fd, ret;
struct string_list conflict = STRING_LIST_INIT_DUP;
struct string_list merge_rr = STRING_LIST_INIT_DUP;
@@ -1129,7 +1132,12 @@ int rerere_forget(struct repository *r, struct pathspec *pathspec)
continue;
rerere_forget_one_path(r->index, it->string, &merge_rr);
}
- return write_rr(&merge_rr, fd);
+
+ ret = write_rr(&merge_rr, fd);
+
+ string_list_clear(&conflict, 0);
+ string_list_clear(&merge_rr, 1);
+ return ret;
}
/*
diff --git a/revision.c b/revision.c
index 3959ccc3d9..1c0192f522 100644
--- a/revision.c
+++ b/revision.c
@@ -847,17 +847,28 @@ static int rev_compare_tree(struct rev_info *revs,
return tree_difference;
}
-static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
+static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit,
+ int nth_parent)
{
struct tree *t1 = repo_get_commit_tree(the_repository, commit);
+ int bloom_ret = -1;
if (!t1)
return 0;
+ if (!nth_parent && revs->bloom_keys_nr) {
+ bloom_ret = check_maybe_different_in_bloom_filter(revs, commit);
+ if (!bloom_ret)
+ return 1;
+ }
+
tree_difference = REV_TREE_SAME;
revs->pruning.flags.has_changes = 0;
diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning);
+ if (bloom_ret == 1 && tree_difference == REV_TREE_SAME)
+ count_bloom_filter_false_positive++;
+
return tree_difference == REV_TREE_SAME;
}
@@ -895,7 +906,7 @@ static int compact_treesame(struct rev_info *revs, struct commit *commit, unsign
if (nth_parent != 0)
die("compact_treesame %u", nth_parent);
old_same = !!(commit->object.flags & TREESAME);
- if (rev_same_tree_as_empty(revs, commit))
+ if (rev_same_tree_as_empty(revs, commit, nth_parent))
commit->object.flags |= TREESAME;
else
commit->object.flags &= ~TREESAME;
@@ -991,7 +1002,14 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
return;
if (!commit->parents) {
- if (rev_same_tree_as_empty(revs, commit))
+ /*
+ * Pretend as if we are comparing ourselves to the
+ * (non-existent) first parent of this commit object. Even
+ * though no such parent exists, its changed-path Bloom filter
+ * (if one exists) is relative to the empty tree, using Bloom
+ * filters is allowed here.
+ */
+ if (rev_same_tree_as_empty(revs, commit, 0))
commit->object.flags |= TREESAME;
return;
}
@@ -1072,7 +1090,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
case REV_TREE_NEW:
if (revs->remove_empty_trees &&
- rev_same_tree_as_empty(revs, p)) {
+ rev_same_tree_as_empty(revs, p, nth_parent)) {
/* We are adding all the specified
* paths from this parent, so the
* history beyond this parent is not
@@ -2133,30 +2151,26 @@ static int handle_dotdot(const char *arg,
struct rev_info *revs, int flags,
int cant_be_filename)
{
- struct object_context a_oc, b_oc;
+ struct object_context a_oc = {0}, b_oc = {0};
char *dotdot = strstr(arg, "..");
int ret;
if (!dotdot)
return -1;
- memset(&a_oc, 0, sizeof(a_oc));
- memset(&b_oc, 0, sizeof(b_oc));
-
*dotdot = '\0';
ret = handle_dotdot_1(arg, dotdot, revs, flags, cant_be_filename,
&a_oc, &b_oc);
*dotdot = '.';
- free(a_oc.path);
- free(b_oc.path);
-
+ object_context_release(&a_oc);
+ object_context_release(&b_oc);
return ret;
}
static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
{
- struct object_context oc;
+ struct object_context oc = {0};
char *mark;
struct object *object;
struct object_id oid;
@@ -2164,6 +2178,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
const char *arg = arg_;
int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME;
unsigned get_sha1_flags = GET_OID_RECORD_PATH;
+ int ret;
flags = flags & UNINTERESTING ? flags | BOTTOM : flags & ~BOTTOM;
@@ -2172,17 +2187,22 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
* Just ".."? That is not a range but the
* pathspec for the parent directory.
*/
- return -1;
+ ret = -1;
+ goto out;
}
- if (!handle_dotdot(arg, revs, flags, revarg_opt))
- return 0;
+ if (!handle_dotdot(arg, revs, flags, revarg_opt)) {
+ ret = 0;
+ goto out;
+ }
mark = strstr(arg, "^@");
if (mark && !mark[2]) {
*mark = 0;
- if (add_parents_only(revs, arg, flags, 0))
- return 0;
+ if (add_parents_only(revs, arg, flags, 0)) {
+ ret = 0;
+ goto out;
+ }
*mark = '^';
}
mark = strstr(arg, "^!");
@@ -2197,8 +2217,10 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
if (mark[2]) {
if (strtol_i(mark + 2, 10, &exclude_parent) ||
- exclude_parent < 1)
- return -1;
+ exclude_parent < 1) {
+ ret = -1;
+ goto out;
+ }
}
*mark = 0;
@@ -2220,17 +2242,25 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
* should error out if we can't even get an oid, as
* `--missing=print` should be able to report missing oids.
*/
- if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc))
- return revs->ignore_missing ? 0 : -1;
+ if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc)) {
+ ret = revs->ignore_missing ? 0 : -1;
+ goto out;
+ }
if (!cant_be_filename)
verify_non_filename(revs->prefix, arg);
object = get_reference(revs, arg, &oid, flags ^ local_flags);
- if (!object)
- return (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;
+ if (!object) {
+ ret = (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;
+ goto out;
+ }
add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
add_pending_object_with_path(revs, object, arg, oc.mode, oc.path);
- free(oc.path);
- return 0;
+
+ ret = 0;
+
+out:
+ object_context_release(&oc);
+ return ret;
}
int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt)
@@ -3066,6 +3096,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
diagnose_missing_default(revs->def);
object = get_reference(revs, revs->def, &oid, 0);
add_pending_object_with_mode(revs, object, revs->def, oc.mode);
+ object_context_release(&oc);
}
/* Did the user ask for any diff output? Run the diff! */
@@ -3172,6 +3203,7 @@ void release_revisions(struct rev_info *revs)
{
free_commit_list(revs->commits);
free_commit_list(revs->ancestry_path_bottoms);
+ release_display_notes(&revs->notes_opt);
object_array_clear(&revs->pending);
object_array_clear(&revs->boundary_commits);
release_revisions_cmdline(&revs->cmdline);
@@ -3181,7 +3213,7 @@ void release_revisions(struct rev_info *revs)
release_revisions_mailmap(revs->mailmap);
free_grep_patterns(&revs->grep_filter);
graph_clear(revs->graph);
- /* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */
+ diff_free(&revs->diffopt);
diff_free(&revs->pruning);
reflog_walk_info_release(revs->reflog_info);
release_revisions_topo_walk_info(revs->topo_walk_info);
@@ -4434,6 +4466,7 @@ struct commit *get_revision(struct rev_info *revs)
reversed = NULL;
while ((c = get_revision_internal(revs)))
commit_list_insert(c, &reversed);
+ free_commit_list(revs->commits);
revs->commits = reversed;
revs->reverse = 0;
revs->reverse_output_stage = 1;
diff --git a/run-command.c b/run-command.c
index d9f80fabe6..45ba544932 100644
--- a/run-command.c
+++ b/run-command.c
@@ -274,17 +274,24 @@ int sane_execvp(const char *file, char * const argv[])
return -1;
}
+char *git_shell_path(void)
+{
+#ifndef GIT_WINDOWS_NATIVE
+ return xstrdup(SHELL_PATH);
+#else
+ char *p = locate_in_PATH("sh");
+ convert_slashes(p);
+ return p;
+#endif
+}
+
static const char **prepare_shell_cmd(struct strvec *out, const char **argv)
{
if (!argv[0])
BUG("shell command is empty");
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
-#ifndef GIT_WINDOWS_NATIVE
- strvec_push(out, SHELL_PATH);
-#else
- strvec_push(out, "sh");
-#endif
+ strvec_push_nodup(out, git_shell_path());
strvec_push(out, "-c");
/*
diff --git a/run-command.h b/run-command.h
index 55f6631a2a..03e7222d8b 100644
--- a/run-command.h
+++ b/run-command.h
@@ -196,6 +196,11 @@ int is_executable(const char *name);
int exists_in_PATH(const char *command);
/**
+ * Return the path that is used to execute Unix shell command-lines.
+ */
+char *git_shell_path(void);
+
+/**
* Start a sub-process. Takes a pointer to a `struct child_process`
* that specifies the details and returns pipe FDs (if requested).
* See below for details.
diff --git a/send-pack.c b/send-pack.c
index 713da582d7..fa2f5eec17 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -427,17 +427,26 @@ static void get_commons_through_negotiation(const char *url,
struct child_process child = CHILD_PROCESS_INIT;
const struct ref *ref;
int len = the_hash_algo->hexsz + 1; /* hash + NL */
+ int nr_negotiation_tip = 0;
child.git_cmd = 1;
child.no_stdin = 1;
child.out = -1;
strvec_pushl(&child.args, "fetch", "--negotiate-only", NULL);
for (ref = remote_refs; ref; ref = ref->next) {
- if (!is_null_oid(&ref->new_oid))
- strvec_pushf(&child.args, "--negotiation-tip=%s", oid_to_hex(&ref->new_oid));
+ if (!is_null_oid(&ref->new_oid)) {
+ strvec_pushf(&child.args, "--negotiation-tip=%s",
+ oid_to_hex(&ref->new_oid));
+ nr_negotiation_tip++;
+ }
}
strvec_push(&child.args, url);
+ if (!nr_negotiation_tip) {
+ child_process_clear(&child);
+ return;
+ }
+
if (start_command(&child))
die(_("send-pack: unable to fork off fetch subprocess"));
diff --git a/sequencer.c b/sequencer.c
index b4f055e5a8..0291920f0b 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -762,7 +762,7 @@ static int do_recursive_merge(struct repository *r,
repo_read_index(r);
- init_merge_options(&o, r);
+ init_ui_merge_options(&o, r);
o.ancestor = base ? base_label : "(empty tree)";
o.branch1 = "HEAD";
o.branch2 = next ? next_label : "(empty tree)";
@@ -1713,6 +1713,7 @@ static int try_to_commit(struct repository *r,
out:
free_commit_extra_headers(extra);
+ free_commit_list(parents);
strbuf_release(&err);
strbuf_release(&commit_msg);
free(amend_author);
@@ -4308,7 +4309,7 @@ static int do_merge(struct repository *r,
bases = reverse_commit_list(bases);
repo_read_index(r);
- init_merge_options(&o, r);
+ init_ui_merge_options(&o, r);
o.branch1 = "HEAD";
o.branch2 = ref_name.buf;
o.buffer_output = 2;
@@ -4376,6 +4377,7 @@ leave_merge:
strbuf_release(&ref_name);
rollback_lock_file(&lock);
free_commit_list(to_merge);
+ free_commit_list(bases);
return ret;
}
@@ -5207,33 +5209,47 @@ static int commit_staged_changes(struct repository *r,
struct replay_ctx *ctx = opts->ctx;
unsigned int flags = ALLOW_EMPTY | EDIT_MSG;
unsigned int final_fixup = 0, is_clean;
+ struct strbuf rev = STRBUF_INIT;
+ int ret;
- if (has_unstaged_changes(r, 1))
- return error(_("cannot rebase: You have unstaged changes."));
+ if (has_unstaged_changes(r, 1)) {
+ ret = error(_("cannot rebase: You have unstaged changes."));
+ goto out;
+ }
is_clean = !has_uncommitted_changes(r, 0);
if (!is_clean && !file_exists(rebase_path_message())) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
-
- return error(_(staged_changes_advice), gpg_opt, gpg_opt);
+ ret = error(_(staged_changes_advice), gpg_opt, gpg_opt);
+ goto out;
}
+
if (file_exists(rebase_path_amend())) {
- struct strbuf rev = STRBUF_INIT;
struct object_id head, to_amend;
- if (repo_get_oid(r, "HEAD", &head))
- return error(_("cannot amend non-existing commit"));
- if (!read_oneliner(&rev, rebase_path_amend(), 0))
- return error(_("invalid file: '%s'"), rebase_path_amend());
- if (get_oid_hex(rev.buf, &to_amend))
- return error(_("invalid contents: '%s'"),
- rebase_path_amend());
- if (!is_clean && !oideq(&head, &to_amend))
- return error(_("\nYou have uncommitted changes in your "
- "working tree. Please, commit them\n"
- "first and then run 'git rebase "
- "--continue' again."));
+ if (repo_get_oid(r, "HEAD", &head)) {
+ ret = error(_("cannot amend non-existing commit"));
+ goto out;
+ }
+
+ if (!read_oneliner(&rev, rebase_path_amend(), 0)) {
+ ret = error(_("invalid file: '%s'"), rebase_path_amend());
+ goto out;
+ }
+
+ if (get_oid_hex(rev.buf, &to_amend)) {
+ ret = error(_("invalid contents: '%s'"),
+ rebase_path_amend());
+ goto out;
+ }
+ if (!is_clean && !oideq(&head, &to_amend)) {
+ ret = error(_("\nYou have uncommitted changes in your "
+ "working tree. Please, commit them\n"
+ "first and then run 'git rebase "
+ "--continue' again."));
+ goto out;
+ }
/*
* When skipping a failed fixup/squash, we need to edit the
* commit message, the current fixup list and count, and if it
@@ -5265,9 +5281,11 @@ static int commit_staged_changes(struct repository *r,
len--;
strbuf_setlen(&ctx->current_fixups, len);
if (write_message(p, len, rebase_path_current_fixups(),
- 0) < 0)
- return error(_("could not write file: '%s'"),
- rebase_path_current_fixups());
+ 0) < 0) {
+ ret = error(_("could not write file: '%s'"),
+ rebase_path_current_fixups());
+ goto out;
+ }
/*
* If a fixup/squash in a fixup/squash chain failed, the
@@ -5297,35 +5315,38 @@ static int commit_staged_changes(struct repository *r,
* We need to update the squash message to skip
* the latest commit message.
*/
- int res = 0;
struct commit *commit;
const char *msg;
const char *path = rebase_path_squash_msg();
const char *encoding = get_commit_output_encoding();
- if (parse_head(r, &commit))
- return error(_("could not parse HEAD"));
+ if (parse_head(r, &commit)) {
+ ret = error(_("could not parse HEAD"));
+ goto out;
+ }
p = repo_logmsg_reencode(r, commit, NULL, encoding);
if (!p) {
- res = error(_("could not parse commit %s"),
+ ret = error(_("could not parse commit %s"),
oid_to_hex(&commit->object.oid));
goto unuse_commit_buffer;
}
find_commit_subject(p, &msg);
if (write_message(msg, strlen(msg), path, 0)) {
- res = error(_("could not write file: "
+ ret = error(_("could not write file: "
"'%s'"), path);
goto unuse_commit_buffer;
}
+
+ ret = 0;
+
unuse_commit_buffer:
repo_unuse_commit_buffer(r, commit, p);
- if (res)
- return res;
+ if (ret)
+ goto out;
}
}
- strbuf_release(&rev);
flags |= AMEND_MSG;
}
@@ -5333,18 +5354,29 @@ static int commit_staged_changes(struct repository *r,
if (refs_ref_exists(get_main_ref_store(r),
"CHERRY_PICK_HEAD") &&
refs_delete_ref(get_main_ref_store(r), "",
- "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF))
- return error(_("could not remove CHERRY_PICK_HEAD"));
- if (unlink(git_path_merge_msg(r)) && errno != ENOENT)
- return error_errno(_("could not remove '%s'"),
- git_path_merge_msg(r));
- if (!final_fixup)
- return 0;
+ "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF)) {
+ ret = error(_("could not remove CHERRY_PICK_HEAD"));
+ goto out;
+ }
+
+ if (unlink(git_path_merge_msg(r)) && errno != ENOENT) {
+ ret = error_errno(_("could not remove '%s'"),
+ git_path_merge_msg(r));
+ goto out;
+ }
+
+ if (!final_fixup) {
+ ret = 0;
+ goto out;
+ }
}
if (run_git_commit(final_fixup ? NULL : rebase_path_message(),
- opts, flags))
- return error(_("could not commit staged changes."));
+ opts, flags)) {
+ ret = error(_("could not commit staged changes."));
+ goto out;
+ }
+
unlink(rebase_path_amend());
unlink(git_path_merge_head(r));
refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
@@ -5362,7 +5394,12 @@ static int commit_staged_changes(struct repository *r,
strbuf_reset(&ctx->current_fixups);
ctx->current_fixup_count = 0;
}
- return 0;
+
+ ret = 0;
+
+out:
+ strbuf_release(&rev);
+ return ret;
}
int sequencer_continue(struct repository *r, struct replay_opts *opts)
@@ -5978,6 +6015,9 @@ static int make_script_with_merges(struct pretty_print_context *pp,
strbuf_release(&oneline);
strbuf_release(&buf);
+ oidset_clear(&interesting);
+ oidset_clear(&child_seen);
+ oidset_clear(&shown);
oidmap_free(&commit2todo, 1);
oidmap_free(&state.commit2label, 1);
hashmap_clear_and_free(&state.labels, struct labels_entry, entry);
diff --git a/setup.c b/setup.c
index d458edcc02..5f81d9fac0 100644
--- a/setup.c
+++ b/setup.c
@@ -1215,7 +1215,7 @@ static int canonicalize_ceiling_entry(struct string_list_item *item,
}
struct safe_directory_data {
- const char *path;
+ char *path;
int is_safe;
};
@@ -1235,17 +1235,45 @@ static int safe_directory_cb(const char *key, const char *value,
char *allowed = NULL;
if (!git_config_pathname(&allowed, key, value)) {
- const char *check = allowed ? allowed : value;
- if (ends_with(check, "/*")) {
- size_t len = strlen(check);
- if (!fspathncmp(check, data->path, len - 1))
+ char *normalized = NULL;
+
+ /*
+ * Setting safe.directory to a non-absolute path
+ * makes little sense---it won't be relative to
+ * the configuration file the item is defined in.
+ * Except for ".", which means "if we are at the top
+ * level of a repository, then it is OK", which is
+ * slightly tighter than "*" that allows discovery.
+ */
+ if (!is_absolute_path(allowed) && strcmp(allowed, ".")) {
+ warning(_("safe.directory '%s' not absolute"),
+ allowed);
+ goto next;
+ }
+
+ /*
+ * A .gitconfig in $HOME may be shared across
+ * different machines and safe.directory entries
+ * may or may not exist as paths on all of these
+ * machines. In other words, it is not a warning
+ * worthy event when there is no such path on this
+ * machine---the entry may be useful elsewhere.
+ */
+ normalized = real_pathdup(allowed, 0);
+ if (!normalized)
+ goto next;
+
+ if (ends_with(normalized, "/*")) {
+ size_t len = strlen(normalized);
+ if (!fspathncmp(normalized, data->path, len - 1))
data->is_safe = 1;
- } else if (!fspathcmp(data->path, check)) {
+ } else if (!fspathcmp(data->path, normalized)) {
data->is_safe = 1;
}
- }
- if (allowed != value)
+ next:
+ free(normalized);
free(allowed);
+ }
}
return 0;
@@ -1263,9 +1291,7 @@ static int ensure_valid_ownership(const char *gitfile,
const char *worktree, const char *gitdir,
struct strbuf *report)
{
- struct safe_directory_data data = {
- .path = worktree ? worktree : gitdir
- };
+ struct safe_directory_data data = { 0 };
if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) &&
(!gitfile || is_path_owned_by_current_user(gitfile, report)) &&
@@ -1274,12 +1300,22 @@ static int ensure_valid_ownership(const char *gitfile,
return 1;
/*
+ * normalize the data.path for comparison with normalized paths
+ * that come from the configuration file. The path is unsafe
+ * if it cannot be normalized.
+ */
+ data.path = real_pathdup(worktree ? worktree : gitdir, 0);
+ if (!data.path)
+ return 0;
+
+ /*
* data.path is the "path" that identifies the repository and it is
* constant regardless of what failed above. data.is_safe should be
* initialized to false, and might be changed by the callback.
*/
git_protected_config(safe_directory_cb, &data);
+ free(data.path);
return data.is_safe;
}
diff --git a/sparse-index.c b/sparse-index.c
index e48e40cae7..9958656ded 100644
--- a/sparse-index.c
+++ b/sparse-index.c
@@ -12,6 +12,22 @@
#include "config.h"
#include "dir.h"
#include "fsmonitor-ll.h"
+#include "advice.h"
+
+/**
+ * This global is used by expand_index() to determine if we should give the
+ * advice for advice.sparseIndexExpanded when expanding a sparse index to a full
+ * one. However, this is sometimes done on purpose, such as in the sparse-checkout
+ * builtin, even when index.sparse=false. This may be disabled in
+ * convert_to_sparse().
+ */
+static int give_advice_on_expansion = 1;
+#define ADVICE_MSG \
+ "The sparse index is expanding to a full index, a slow operation.\n" \
+ "Your working directory likely has contents that are outside of\n" \
+ "your sparse-checkout patterns. Use 'git sparse-checkout list' to\n" \
+ "see your sparse-checkout definition and compare it to your working\n" \
+ "directory contents. Running 'git clean' may assist in this cleanup."
struct modify_index_context {
struct index_state *write;
@@ -184,6 +200,12 @@ int convert_to_sparse(struct index_state *istate, int flags)
return 0;
/*
+ * If we are purposefully collapsing a full index, then don't give
+ * advice when it is expanded later.
+ */
+ give_advice_on_expansion = 0;
+
+ /*
* NEEDSWORK: If we have unmerged entries, then stay full.
* Unmerged entries prevent the cache-tree extension from working.
*/
@@ -328,6 +350,12 @@ void expand_index(struct index_state *istate, struct pattern_list *pl)
pl = NULL;
}
+ if (!pl && give_advice_on_expansion) {
+ give_advice_on_expansion = 0;
+ advise_if_enabled(ADVICE_SPARSE_INDEX_EXPANDED,
+ _(ADVICE_MSG));
+ }
+
/*
* A NULL pattern set indicates we are expanding a full index, so
* we use a special region name that indicates the full expansion.
@@ -439,96 +467,208 @@ void ensure_correct_sparsity(struct index_state *istate)
ensure_full_index(istate);
}
-static int path_found(const char *path, const char **dirname, size_t *dir_len,
- int *dir_found)
+struct path_found_data {
+ /**
+ * The path stored in 'dir', if non-empty, corresponds to the most-
+ * recent path that we checked where:
+ *
+ * 1. The path should be a directory, according to the index.
+ * 2. The path does not exist.
+ * 3. The parent path _does_ exist. (This may be the root of the
+ * working directory.)
+ */
+ struct strbuf dir;
+ size_t lstat_count;
+};
+
+#define PATH_FOUND_DATA_INIT { \
+ .dir = STRBUF_INIT \
+}
+
+static void clear_path_found_data(struct path_found_data *data)
+{
+ strbuf_release(&data->dir);
+}
+
+/**
+ * Return the length of the longest common substring that ends in a
+ * slash ('/') to indicate the longest common parent directory. Returns
+ * zero if no common directory exists.
+ */
+static size_t max_common_dir_prefix(const char *path1, const char *path2)
+{
+ size_t common_prefix = 0;
+ for (size_t i = 0; path1[i] && path2[i]; i++) {
+ if (path1[i] != path2[i])
+ break;
+
+ /*
+ * If they agree at a directory separator, then add one
+ * to make sure it is included in the common prefix string.
+ */
+ if (path1[i] == '/')
+ common_prefix = i + 1;
+ }
+
+ return common_prefix;
+}
+
+static int path_found(const char *path, struct path_found_data *data)
{
struct stat st;
- char *newdir;
- char *tmp;
+ size_t common_prefix;
/*
- * If dirname corresponds to a directory that doesn't exist, and this
- * path starts with dirname, then path can't exist.
+ * If data->dir is non-empty, then it contains a path that doesn't
+ * exist, including an ending slash ('/'). If it is a prefix of 'path',
+ * then we can return 0.
*/
- if (!*dir_found && !memcmp(path, *dirname, *dir_len))
+ if (data->dir.len && !memcmp(path, data->dir.buf, data->dir.len))
return 0;
/*
- * If path itself exists, return 1.
+ * Otherwise, we must check if the current path exists. If it does, then
+ * return 1. The cached directory will be skipped until we come across
+ * a missing path again.
*/
+ data->lstat_count++;
if (!lstat(path, &st))
return 1;
/*
- * Otherwise, path does not exist so we'll return 0...but we'll first
- * determine some info about its parent directory so we can avoid
- * lstat calls for future cache entries.
+ * At this point, we know that 'path' doesn't exist, and we know that
+ * the parent directory of 'data->dir' does exist. Let's set 'data->dir'
+ * to be the top-most non-existing directory of 'path'. If the first
+ * parent of 'path' exists, then we will act as though 'path'
+ * corresponds to a directory (by adding a slash).
*/
- newdir = strrchr(path, '/');
- if (!newdir)
- return 0; /* Didn't find a parent dir; just return 0 now. */
+ common_prefix = max_common_dir_prefix(path, data->dir.buf);
/*
- * If path starts with directory (which we already lstat'ed and found),
- * then no need to lstat parent directory again.
+ * At this point, 'path' and 'data->dir' have a common existing parent
+ * directory given by path[0..common_prefix] (which could have length 0).
+ * We "grow" the data->dir buffer by checking for existing directories
+ * along 'path'.
*/
- if (*dir_found && *dirname && memcmp(path, *dirname, *dir_len))
- return 0;
- /* Free previous dirname, and cache path's dirname */
- *dirname = path;
- *dir_len = newdir - path + 1;
+ strbuf_setlen(&data->dir, common_prefix);
+ while (1) {
+ /* Find the next directory in 'path'. */
+ const char *rest = path + data->dir.len;
+ const char *next_slash = strchr(rest, '/');
+
+ /*
+ * If there are no more slashes, then 'path' doesn't contain a
+ * non-existent _parent_ directory. Set 'data->dir' to be equal
+ * to 'path' plus an additional slash, so it can be used for
+ * caching in the future. The filename of 'path' is considered
+ * a non-existent directory.
+ *
+ * Note: if "{path}/" exists as a directory, then it will never
+ * appear as a prefix of other callers to this method, assuming
+ * the context from the clear_skip_worktree... methods. If this
+ * method is reused, then this must be reconsidered.
+ */
+ if (!next_slash) {
+ strbuf_addstr(&data->dir, rest);
+ strbuf_addch(&data->dir, '/');
+ break;
+ }
- tmp = xstrndup(path, *dir_len);
- *dir_found = !lstat(tmp, &st);
- free(tmp);
+ /*
+ * Now that we have a slash, let's grow 'data->dir' to include
+ * this slash, then test if we should stop.
+ */
+ strbuf_add(&data->dir, rest, next_slash - rest + 1);
+ /* If the parent dir doesn't exist, then stop here. */
+ data->lstat_count++;
+ if (lstat(data->dir.buf, &st))
+ return 0;
+ }
+
+ /*
+ * At this point, 'data->dir' is equal to 'path' plus a slash character,
+ * and the parent directory of 'path' definitely exists. Moreover, we
+ * know that 'path' doesn't exist, or we would have returned 1 earlier.
+ */
return 0;
}
-void clear_skip_worktree_from_present_files(struct index_state *istate)
+static int clear_skip_worktree_from_present_files_sparse(struct index_state *istate)
{
- const char *last_dirname = NULL;
- size_t dir_len = 0;
- int dir_found = 1;
+ struct path_found_data data = PATH_FOUND_DATA_INIT;
- int i;
- int path_count[2] = {0, 0};
- int restarted = 0;
-
- if (!core_apply_sparse_checkout ||
- sparse_expect_files_outside_of_patterns)
- return;
+ int path_count = 0;
+ int to_restart = 0;
- trace2_region_enter("index", "clear_skip_worktree_from_present_files",
+ trace2_region_enter("index", "clear_skip_worktree_from_present_files_sparse",
istate->repo);
-restart:
- for (i = 0; i < istate->cache_nr; i++) {
+ for (int i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
if (ce_skip_worktree(ce)) {
- path_count[restarted]++;
- if (path_found(ce->name, &last_dirname, &dir_len, &dir_found)) {
+ path_count++;
+ if (path_found(ce->name, &data)) {
if (S_ISSPARSEDIR(ce->ce_mode)) {
- if (restarted)
- BUG("ensure-full-index did not fully flatten?");
- ensure_full_index(istate);
- restarted = 1;
- goto restart;
+ to_restart = 1;
+ break;
}
ce->ce_flags &= ~CE_SKIP_WORKTREE;
}
}
}
- if (path_count[0])
- trace2_data_intmax("index", istate->repo,
- "sparse_path_count", path_count[0]);
- if (restarted)
- trace2_data_intmax("index", istate->repo,
- "sparse_path_count_full", path_count[1]);
- trace2_region_leave("index", "clear_skip_worktree_from_present_files",
+ trace2_data_intmax("index", istate->repo,
+ "sparse_path_count", path_count);
+ trace2_data_intmax("index", istate->repo,
+ "sparse_lstat_count", data.lstat_count);
+ trace2_region_leave("index", "clear_skip_worktree_from_present_files_sparse",
istate->repo);
+ clear_path_found_data(&data);
+ return to_restart;
+}
+
+static void clear_skip_worktree_from_present_files_full(struct index_state *istate)
+{
+ struct path_found_data data = PATH_FOUND_DATA_INIT;
+
+ int path_count = 0;
+
+ trace2_region_enter("index", "clear_skip_worktree_from_present_files_full",
+ istate->repo);
+ for (int i = 0; i < istate->cache_nr; i++) {
+ struct cache_entry *ce = istate->cache[i];
+
+ if (S_ISSPARSEDIR(ce->ce_mode))
+ BUG("ensure-full-index did not fully flatten?");
+
+ if (ce_skip_worktree(ce)) {
+ path_count++;
+ if (path_found(ce->name, &data))
+ ce->ce_flags &= ~CE_SKIP_WORKTREE;
+ }
+ }
+
+ trace2_data_intmax("index", istate->repo,
+ "full_path_count", path_count);
+ trace2_data_intmax("index", istate->repo,
+ "full_lstat_count", data.lstat_count);
+ trace2_region_leave("index", "clear_skip_worktree_from_present_files_full",
+ istate->repo);
+ clear_path_found_data(&data);
+}
+
+void clear_skip_worktree_from_present_files(struct index_state *istate)
+{
+ if (!core_apply_sparse_checkout ||
+ sparse_expect_files_outside_of_patterns)
+ return;
+
+ if (clear_skip_worktree_from_present_files_sparse(istate)) {
+ ensure_full_index(istate);
+ clear_skip_worktree_from_present_files_full(istate);
+ }
}
/*
diff --git a/strvec.c b/strvec.c
index d4073ec9fa..f712070f57 100644
--- a/strvec.c
+++ b/strvec.c
@@ -10,7 +10,7 @@ void strvec_init(struct strvec *array)
memcpy(array, &blank, sizeof(*array));
}
-static void strvec_push_nodup(struct strvec *array, const char *value)
+void strvec_push_nodup(struct strvec *array, char *value)
{
if (array->v == empty_strvec)
array->v = NULL;
diff --git a/strvec.h b/strvec.h
index 6c7e8b7d50..4b73c1f092 100644
--- a/strvec.h
+++ b/strvec.h
@@ -46,6 +46,9 @@ void strvec_init(struct strvec *);
/* Push a copy of a string onto the end of the array. */
const char *strvec_push(struct strvec *, const char *);
+/* Push an allocated string onto the end of the array, taking ownership. */
+void strvec_push_nodup(struct strvec *array, char *value);
+
/**
* Format a string and push it onto the end of the array. This is a
* convenience wrapper combining `strbuf_addf` and `strvec_push`.
diff --git a/t/.gitattributes b/t/.gitattributes
index b9cea1795d..7664c6e027 100644
--- a/t/.gitattributes
+++ b/t/.gitattributes
@@ -1,5 +1,5 @@
t[0-9][0-9][0-9][0-9]/* -whitespace
-/chainlint/*.expect eol=lf
+/chainlint/*.expect eol=lf -whitespace
/t0110/url-* binary
/t3206/* eol=lf
/t3900/*.txt eol=lf
diff --git a/t/Makefile b/t/Makefile
index b2eb9f770b..4c30e7c06f 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -108,20 +108,8 @@ clean-chainlint:
check-chainlint:
@mkdir -p '$(CHAINLINTTMP_SQ)' && \
- for i in $(CHAINLINTTESTS); do \
- echo "test_expect_success '$$i' '" && \
- sed -e '/^# LINT: /d' chainlint/$$i.test && \
- echo "'"; \
- done >'$(CHAINLINTTMP_SQ)'/tests && \
- { \
- echo "# chainlint: $(CHAINLINTTMP_SQ)/tests" && \
- for i in $(CHAINLINTTESTS); do \
- echo "# chainlint: $$i" && \
- cat chainlint/$$i.expect; \
- done \
- } >'$(CHAINLINTTMP_SQ)'/expect && \
- $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests | \
- sed -e 's/^[1-9][0-9]* //' >'$(CHAINLINTTMP_SQ)'/actual && \
+ '$(PERL_PATH_SQ)' chainlint-cat.pl '$(CHAINLINTTMP_SQ)' $(CHAINLINTTESTS) && \
+ { $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \
diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual
test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \
diff --git a/t/README b/t/README
index d9e0e07506..724ee58195 100644
--- a/t/README
+++ b/t/README
@@ -382,33 +382,9 @@ mapping between "TEST_PASSES_SANITIZE_LEAK=true" and those tests that
pass under "SANITIZE=leak". This is especially useful when testing a
series that fixes various memory leaks with "git rebase -x".
-GIT_TEST_SANITIZE_LEAK_LOG=true will log memory leaks to
-"test-results/$TEST_NAME.leak/trace.*" files. The logs include a
-"dedup_token" (see +"ASAN_OPTIONS=help=1 ./git") and other options to
-make logs +machine-readable.
-
-With GIT_TEST_SANITIZE_LEAK_LOG=true we'll look at the leak logs
-before exiting and exit on failure if the logs showed that we had a
-memory leak, even if the test itself would have otherwise passed. This
-allows us to catch e.g. missing &&-chaining. This is especially useful
-when combined with "GIT_TEST_PASSING_SANITIZE_LEAK", see below.
-
GIT_TEST_PASSING_SANITIZE_LEAK=check when combined with "--immediate"
will run to completion faster, and result in the same failing
-tests. The only practical reason to run
-GIT_TEST_PASSING_SANITIZE_LEAK=check without "--immediate" is to
-combine it with "GIT_TEST_SANITIZE_LEAK_LOG=true". If we stop at the
-first failing test case our leak logs won't show subsequent leaks we
-might have run into.
-
-GIT_TEST_PASSING_SANITIZE_LEAK=(true|check) will not catch all memory
-leaks unless combined with GIT_TEST_SANITIZE_LEAK_LOG=true. Some tests
-run "git" (or "test-tool" etc.) without properly checking the exit
-code, or git will invoke itself and fail to ferry the abort() exit
-code to the original caller. When the two modes are combined we'll
-look at the "test-results/$TEST_NAME.leak/trace.*" files at the end of
-the test run to see if had memory leaks which the test itself didn't
-catch.
+tests.
GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version'
default to n.
@@ -906,6 +882,14 @@ see test-lib-functions.sh for the full list and their options.
'git-write-tree should be able to write an empty tree.' \
'tree=$(git-write-tree)'
+ If <script> is `-` (a single dash), then the script to run is read
+ from stdin. This lets you more easily use single quotes within the
+ script by using a here-doc. For example:
+
+ test_expect_success 'output contains expected string' - <<\EOT
+ grep "this string has 'quotes' in it" output
+ EOT
+
If you supply three parameters the first will be taken to be a
prerequisite; see the test_set_prereq and test_have_prereq
documentation below:
diff --git a/t/chainlint-cat.pl b/t/chainlint-cat.pl
new file mode 100644
index 0000000000..388f6e1e41
--- /dev/null
+++ b/t/chainlint-cat.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/env perl
+
+my $outdir = shift;
+open(my $tests, '>', "$outdir/tests")
+ or die "unable to open $outdir/tests: $!";
+open(my $expect, '>', "$outdir/expect")
+ or die "unable to open $outdir/expect: $!";
+
+print $expect "# chainlint: $outdir/tests\n";
+
+my $offset = 0;
+for my $script (@ARGV) {
+ print $expect "# chainlint: $script\n";
+
+ open(my $expect_in, '<', "chainlint/$script.expect")
+ or die "unable to open chainlint/$script.expect: $!";
+ while (<$expect_in>) {
+ s/^\d+/$& + $offset/e;
+ print $expect $_;
+ }
+
+ open(my $test_in, '<', "chainlint/$script.test")
+ or die "unable to open chainlint/$script.test: $!";
+ while (<$test_in>) {
+ /^# LINT: / and next;
+ print $tests $_;
+ $offset++;
+ }
+}
diff --git a/t/chainlint.pl b/t/chainlint.pl
index 1bbd985b78..5361f23b1d 100755
--- a/t/chainlint.pl
+++ b/t/chainlint.pl
@@ -174,6 +174,10 @@ sub swallow_heredocs {
$$b =~ /(?:\G|\n)$indent\Q$$tag[0]\E(?:\n|\z)/gc;
if (pos($$b) > $start) {
my $body = substr($$b, $start, pos($$b) - $start);
+ $self->{parser}->{heredocs}->{$$tag[0]} = {
+ content => substr($body, 0, length($body) - length($&)),
+ start_line => $self->{lineno},
+ };
$self->{lineno} += () = $body =~ /\n/sg;
next;
}
@@ -232,7 +236,8 @@ sub new {
my $self = bless {
buff => [],
stop => [],
- output => []
+ output => [],
+ heredocs => {},
} => $class;
$self->{lexer} = Lexer->new($self, $s);
return $self;
@@ -616,14 +621,21 @@ sub unwrap {
sub check_test {
my $self = shift @_;
- my ($title, $body) = map(unwrap, @_);
+ my $title = unwrap(shift @_);
+ my $body = shift @_;
+ my $lineno = $body->[3];
+ $body = unwrap($body);
+ if ($body eq '-') {
+ my $herebody = shift @_;
+ $body = $herebody->{content};
+ $lineno = $herebody->{start_line};
+ }
$self->{ntests}++;
my $parser = TestParser->new(\$body);
my @tokens = $parser->parse();
my $problems = $parser->{problems};
return unless $emit_all || @$problems;
my $c = main::fd_colors(1);
- my $lineno = $_[1]->[3];
my $start = 0;
my $checked = '';
for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) {
@@ -649,8 +661,13 @@ sub parse_cmd {
return @tokens unless @tokens && $tokens[0]->[0] =~ /^test_expect_(?:success|failure)$/;
my $n = $#tokens;
$n-- while $n >= 0 && $tokens[$n]->[0] =~ /^(?:[;&\n|]|&&|\|\|)$/;
- $self->check_test($tokens[1], $tokens[2]) if $n == 2; # title body
- $self->check_test($tokens[2], $tokens[3]) if $n > 2; # prereq title body
+ my $herebody;
+ if ($n >= 2 && $tokens[$n-1]->[0] eq '-' && $tokens[$n]->[0] =~ /^<<-?(.+)$/) {
+ $herebody = $self->{heredocs}->{$1};
+ $n--;
+ }
+ $self->check_test($tokens[1], $tokens[2], $herebody) if $n == 2; # title body
+ $self->check_test($tokens[2], $tokens[3], $herebody) if $n > 2; # prereq title body
return @tokens;
}
@@ -762,7 +779,7 @@ sub check_script {
while (my $path = $next_script->()) {
$nscripts++;
my $fh;
- unless (open($fh, "<", $path)) {
+ unless (open($fh, "<:unix:crlf", $path)) {
$emit->("?!ERR?! $path: $!\n");
next;
}
@@ -806,8 +823,10 @@ unless (@scripts) {
show_stats($start_time, \@stats) if $show_stats;
exit;
}
+$jobs = @scripts if @scripts < $jobs;
-unless ($Config{useithreads} && eval {
+unless ($jobs > 1 &&
+ $Config{useithreads} && eval {
require threads; threads->import();
require Thread::Queue; Thread::Queue->import();
1;
diff --git a/t/chainlint/arithmetic-expansion.expect b/t/chainlint/arithmetic-expansion.expect
index 46ee1046af..338ecd5861 100644
--- a/t/chainlint/arithmetic-expansion.expect
+++ b/t/chainlint/arithmetic-expansion.expect
@@ -1,9 +1,9 @@
-(
- foo &&
- bar=$((42 + 1)) &&
- baz
-) &&
-(
- bar=$((42 + 1)) ?!AMP?!
- baz
-)
+2 (
+3 foo &&
+4 bar=$((42 + 1)) &&
+5 baz
+6 ) &&
+7 (
+8 bar=$((42 + 1)) ?!AMP?!
+9 baz
+10 )
diff --git a/t/chainlint/arithmetic-expansion.test b/t/chainlint/arithmetic-expansion.test
index 16206960d8..7b4c5c9a41 100644
--- a/t/chainlint/arithmetic-expansion.test
+++ b/t/chainlint/arithmetic-expansion.test
@@ -1,3 +1,4 @@
+test_expect_success 'arithmetic-expansion' '
(
foo &&
# LINT: closing ")" of $((...)) not misinterpreted as subshell-closing ")"
@@ -9,3 +10,4 @@
bar=$((42 + 1))
baz
)
+'
diff --git a/t/chainlint/bash-array.expect b/t/chainlint/bash-array.expect
index 4c34eaee45..435dc8bdc8 100644
--- a/t/chainlint/bash-array.expect
+++ b/t/chainlint/bash-array.expect
@@ -1,10 +1,10 @@
-(
- foo &&
- bar=(gumbo stumbo wumbo) &&
- baz
-) &&
-(
- foo &&
- bar=${#bar[@]} &&
- baz
-)
+2 (
+3 foo &&
+4 bar=(gumbo stumbo wumbo) &&
+5 baz
+6 ) &&
+7 (
+8 foo &&
+9 bar=${#bar[@]} &&
+10 baz
+11 )
diff --git a/t/chainlint/bash-array.test b/t/chainlint/bash-array.test
index 92bbb777b8..4ca977d299 100644
--- a/t/chainlint/bash-array.test
+++ b/t/chainlint/bash-array.test
@@ -1,3 +1,4 @@
+test_expect_success 'bash-array' '
(
foo &&
# LINT: ")" in Bash array assignment not misinterpreted as subshell-closing ")"
@@ -10,3 +11,4 @@
bar=${#bar[@]} &&
baz
)
+'
diff --git a/t/chainlint/blank-line-before-esac.expect b/t/chainlint/blank-line-before-esac.expect
index 056e03003d..b88ba919eb 100644
--- a/t/chainlint/blank-line-before-esac.expect
+++ b/t/chainlint/blank-line-before-esac.expect
@@ -1,18 +1,18 @@
-test_done () {
- case "$test_failure" in
- 0)
- test_at_end_hook_
-
- exit 0 ;;
-
- *)
- if test $test_external_has_tap -eq 0
- then
- say_color error "# failed $test_failure among $msg"
- say "1..$test_count"
- fi
-
- exit 1 ;;
-
- esac
-}
+2 test_done () {
+3 case "$test_failure" in
+4 0)
+5 test_at_end_hook_
+6
+7 exit 0 ;;
+8
+9 *)
+10 if test $test_external_has_tap -eq 0
+11 then
+12 say_color error "# failed $test_failure among $msg"
+13 say "1..$test_count"
+14 fi
+15
+16 exit 1 ;;
+17
+18 esac
+19 }
diff --git a/t/chainlint/blank-line-before-esac.test b/t/chainlint/blank-line-before-esac.test
index cecccad19f..51f02ea0c5 100644
--- a/t/chainlint/blank-line-before-esac.test
+++ b/t/chainlint/blank-line-before-esac.test
@@ -1,3 +1,4 @@
+test_expect_success 'blank-line-before-esac' '
# LINT: blank line before "esac"
test_done () {
case "$test_failure" in
@@ -17,3 +18,4 @@ test_done () {
esac
}
+'
diff --git a/t/chainlint/blank-line.expect b/t/chainlint/blank-line.expect
index b47827d749..6ae39dd174 100644
--- a/t/chainlint/blank-line.expect
+++ b/t/chainlint/blank-line.expect
@@ -1,8 +1,8 @@
-(
-
- nothing &&
-
- something
-
-
-)
+2 (
+3
+4 nothing &&
+5
+6 something
+7
+8
+9 )
diff --git a/t/chainlint/blank-line.test b/t/chainlint/blank-line.test
index 0fdf15b3e1..6f29a491de 100644
--- a/t/chainlint/blank-line.test
+++ b/t/chainlint/blank-line.test
@@ -1,3 +1,4 @@
+test_expect_success 'blank-line' '
(
nothing &&
@@ -8,3 +9,4 @@
)
+'
diff --git a/t/chainlint/block-comment.expect b/t/chainlint/block-comment.expect
index df2beea888..7926936c18 100644
--- a/t/chainlint/block-comment.expect
+++ b/t/chainlint/block-comment.expect
@@ -1,8 +1,8 @@
-(
- {
- # show a
- echo a &&
- # show b
- echo b
- }
-)
+2 (
+3 {
+4 # show a
+5 echo a &&
+6 # show b
+7 echo b
+8 }
+9 )
diff --git a/t/chainlint/block-comment.test b/t/chainlint/block-comment.test
index df2beea888..934ef4113a 100644
--- a/t/chainlint/block-comment.test
+++ b/t/chainlint/block-comment.test
@@ -1,3 +1,4 @@
+test_expect_success 'block-comment' '
(
{
# show a
@@ -6,3 +7,4 @@
echo b
}
)
+'
diff --git a/t/chainlint/block.expect b/t/chainlint/block.expect
index 1c87326364..b62e3d58c3 100644
--- a/t/chainlint/block.expect
+++ b/t/chainlint/block.expect
@@ -1,23 +1,23 @@
-(
- foo &&
- {
- echo a ?!AMP?!
- echo b
- } &&
- bar &&
- {
- echo c
- } ?!AMP?!
- baz
-) &&
-
-{
- echo a; ?!AMP?! echo b
-} &&
-{ echo a; ?!AMP?! echo b; } &&
-
-{
- echo "${var}9" &&
- echo "done"
-} &&
-finis
+2 (
+3 foo &&
+4 {
+5 echo a ?!AMP?!
+6 echo b
+7 } &&
+8 bar &&
+9 {
+10 echo c
+11 } ?!AMP?!
+12 baz
+13 ) &&
+14
+15 {
+16 echo a; ?!AMP?! echo b
+17 } &&
+18 { echo a; ?!AMP?! echo b; } &&
+19
+20 {
+21 echo "${var}9" &&
+22 echo "done"
+23 } &&
+24 finis
diff --git a/t/chainlint/block.test b/t/chainlint/block.test
index 4ab69a4afc..a1b6b4dd32 100644
--- a/t/chainlint/block.test
+++ b/t/chainlint/block.test
@@ -1,3 +1,4 @@
+test_expect_success 'block' '
(
# LINT: missing "&&" after first "echo"
foo &&
@@ -25,3 +26,4 @@
echo "done"
} &&
finis
+'
diff --git a/t/chainlint/broken-chain.expect b/t/chainlint/broken-chain.expect
index cfb58fb6b9..9a1838736f 100644
--- a/t/chainlint/broken-chain.expect
+++ b/t/chainlint/broken-chain.expect
@@ -1,6 +1,6 @@
-(
- foo &&
- bar ?!AMP?!
- baz &&
- wop
-)
+2 (
+3 foo &&
+4 bar ?!AMP?!
+5 baz &&
+6 wop
+7 )
diff --git a/t/chainlint/broken-chain.test b/t/chainlint/broken-chain.test
index 2a44aa73b7..1966499ef9 100644
--- a/t/chainlint/broken-chain.test
+++ b/t/chainlint/broken-chain.test
@@ -1,3 +1,4 @@
+test_expect_success 'broken-chain' '
(
foo &&
# LINT: missing "&&" from "bar"
@@ -6,3 +7,4 @@
# LINT: final statement before closing ")" legitimately lacks "&&"
wop
)
+'
diff --git a/t/chainlint/case-comment.expect b/t/chainlint/case-comment.expect
index 641c157b98..2442dd5f25 100644
--- a/t/chainlint/case-comment.expect
+++ b/t/chainlint/case-comment.expect
@@ -1,11 +1,11 @@
-(
- case "$x" in
- # found foo
- x) foo ;;
- # found other
- *)
- # treat it as bar
- bar
- ;;
- esac
-)
+2 (
+3 case "$x" in
+4 # found foo
+5 x) foo ;;
+6 # found other
+7 *)
+8 # treat it as bar
+9 bar
+10 ;;
+11 esac
+12 )
diff --git a/t/chainlint/case-comment.test b/t/chainlint/case-comment.test
index 641c157b98..3f31ae9010 100644
--- a/t/chainlint/case-comment.test
+++ b/t/chainlint/case-comment.test
@@ -1,3 +1,4 @@
+test_expect_success 'case-comment' '
(
case "$x" in
# found foo
@@ -9,3 +10,4 @@
;;
esac
)
+'
diff --git a/t/chainlint/case.expect b/t/chainlint/case.expect
index 31f280d8ce..c04c61ff36 100644
--- a/t/chainlint/case.expect
+++ b/t/chainlint/case.expect
@@ -1,19 +1,19 @@
-(
- case "$x" in
- x) foo ;;
- *) bar ;;
- esac &&
- foobar
-) &&
-(
- case "$x" in
- x) foo ;;
- *) bar ;;
- esac ?!AMP?!
- foobar
-) &&
-(
- case "$x" in 1) true;; esac &&
- case "$y" in 2) false;; esac ?!AMP?!
- foobar
-)
+2 (
+3 case "$x" in
+4 x) foo ;;
+5 *) bar ;;
+6 esac &&
+7 foobar
+8 ) &&
+9 (
+10 case "$x" in
+11 x) foo ;;
+12 *) bar ;;
+13 esac ?!AMP?!
+14 foobar
+15 ) &&
+16 (
+17 case "$x" in 1) true;; esac &&
+18 case "$y" in 2) false;; esac ?!AMP?!
+19 foobar
+20 )
diff --git a/t/chainlint/case.test b/t/chainlint/case.test
index 4cb086bf87..bea21fee4f 100644
--- a/t/chainlint/case.test
+++ b/t/chainlint/case.test
@@ -1,3 +1,4 @@
+test_expect_success 'case' '
(
# LINT: "...)" arms in "case" not misinterpreted as subshell-closing ")"
case "$x" in
@@ -21,3 +22,4 @@
case "$y" in 2) false;; esac
foobar
)
+'
diff --git a/t/chainlint/chain-break-background.expect b/t/chainlint/chain-break-background.expect
index 20d0bb5333..d06deadae7 100644
--- a/t/chainlint/chain-break-background.expect
+++ b/t/chainlint/chain-break-background.expect
@@ -1,9 +1,9 @@
-JGIT_DAEMON_PID= &&
-git init --bare empty.git &&
->empty.git/git-daemon-export-ok &&
-mkfifo jgit_daemon_output &&
-{
- jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
- JGIT_DAEMON_PID=$!
-} &&
-test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
+2 JGIT_DAEMON_PID= &&
+3 git init --bare empty.git &&
+4 >empty.git/git-daemon-export-ok &&
+5 mkfifo jgit_daemon_output &&
+6 {
+7 jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
+8 JGIT_DAEMON_PID=$!
+9 } &&
+10 test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
diff --git a/t/chainlint/chain-break-background.test b/t/chainlint/chain-break-background.test
index e10f656b05..c68e1b04d5 100644
--- a/t/chainlint/chain-break-background.test
+++ b/t/chainlint/chain-break-background.test
@@ -1,3 +1,4 @@
+test_expect_success 'chain-break-background' '
JGIT_DAEMON_PID= &&
git init --bare empty.git &&
>empty.git/git-daemon-export-ok &&
@@ -8,3 +9,4 @@ mkfifo jgit_daemon_output &&
JGIT_DAEMON_PID=$!
} &&
test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
+'
diff --git a/t/chainlint/chain-break-continue.expect b/t/chainlint/chain-break-continue.expect
index 47a3457710..4bb60aae25 100644
--- a/t/chainlint/chain-break-continue.expect
+++ b/t/chainlint/chain-break-continue.expect
@@ -1,12 +1,12 @@
-git ls-tree --name-only -r refs/notes/many_notes |
-while read path
-do
- test "$path" = "foobar/non-note.txt" && continue
- test "$path" = "deadbeef" && continue
- test "$path" = "de/adbeef" && continue
-
- if test $(expr length "$path") -ne $hexsz
- then
- return 1
- fi
-done
+2 git ls-tree --name-only -r refs/notes/many_notes |
+3 while read path
+4 do
+5 test "$path" = "foobar/non-note.txt" && continue
+6 test "$path" = "deadbeef" && continue
+7 test "$path" = "de/adbeef" && continue
+8
+9 if test $(expr length "$path") -ne $hexsz
+10 then
+11 return 1
+12 fi
+13 done
diff --git a/t/chainlint/chain-break-continue.test b/t/chainlint/chain-break-continue.test
index f0af71d8bd..de8119b204 100644
--- a/t/chainlint/chain-break-continue.test
+++ b/t/chainlint/chain-break-continue.test
@@ -1,3 +1,4 @@
+test_expect_success 'chain-break-continue' '
git ls-tree --name-only -r refs/notes/many_notes |
while read path
do
@@ -11,3 +12,4 @@ do
return 1
fi
done
+'
diff --git a/t/chainlint/chain-break-false.expect b/t/chainlint/chain-break-false.expect
index 989766fb85..4f815f8e14 100644
--- a/t/chainlint/chain-break-false.expect
+++ b/t/chainlint/chain-break-false.expect
@@ -1,9 +1,9 @@
-if condition not satisified
-then
- echo it did not work...
- echo failed!
- false
-else
- echo it went okay ?!AMP?!
- congratulate user
-fi
+2 if condition not satisified
+3 then
+4 echo it did not work...
+5 echo failed!
+6 false
+7 else
+8 echo it went okay ?!AMP?!
+9 congratulate user
+10 fi
diff --git a/t/chainlint/chain-break-false.test b/t/chainlint/chain-break-false.test
index a5aaff8c8a..f78ad911fc 100644
--- a/t/chainlint/chain-break-false.test
+++ b/t/chainlint/chain-break-false.test
@@ -1,3 +1,4 @@
+test_expect_success 'chain-break-false' '
# LINT: broken &&-chain okay if explicit "false" signals failure
if condition not satisified
then
@@ -8,3 +9,4 @@ else
echo it went okay
congratulate user
fi
+'
diff --git a/t/chainlint/chain-break-return-exit.expect b/t/chainlint/chain-break-return-exit.expect
index 4cd18e2edf..ba0ec51aa0 100644
--- a/t/chainlint/chain-break-return-exit.expect
+++ b/t/chainlint/chain-break-return-exit.expect
@@ -1,19 +1,19 @@
-case "$(git ls-files)" in
-one) echo pass one ;;
-*) echo bad one; return 1 ;;
-esac &&
-(
- case "$(git ls-files)" in
- two) echo pass two ;;
- *) echo bad two; exit 1 ;;
- esac
-) &&
-case "$(git ls-files)" in
-dir/two"$LF"one) echo pass both ;;
-*) echo bad; return 1 ;;
-esac &&
-
-for i in 1 2 3 4 ; do
- git checkout main -b $i || return $?
- test_commit $i $i $i tag$i || return $?
-done
+2 case "$(git ls-files)" in
+3 one) echo pass one ;;
+4 *) echo bad one; return 1 ;;
+5 esac &&
+6 (
+7 case "$(git ls-files)" in
+8 two) echo pass two ;;
+9 *) echo bad two; exit 1 ;;
+10 esac
+11 ) &&
+12 case "$(git ls-files)" in
+13 dir/two"$LF"one) echo pass both ;;
+14 *) echo bad; return 1 ;;
+15 esac &&
+16
+17 for i in 1 2 3 4 ; do
+18 git checkout main -b $i || return $?
+19 test_commit $i $i $i tag$i || return $?
+20 done
diff --git a/t/chainlint/chain-break-return-exit.test b/t/chainlint/chain-break-return-exit.test
index 46542edf88..b6f519bb4d 100644
--- a/t/chainlint/chain-break-return-exit.test
+++ b/t/chainlint/chain-break-return-exit.test
@@ -1,3 +1,4 @@
+test_expect_success 'chain-break-return-exit' '
case "$(git ls-files)" in
one) echo pass one ;;
# LINT: broken &&-chain okay if explicit "return 1" signals failuire
@@ -21,3 +22,4 @@ for i in 1 2 3 4 ; do
git checkout main -b $i || return $?
test_commit $i $i $i tag$i || return $?
done
+'
diff --git a/t/chainlint/chain-break-status.expect b/t/chainlint/chain-break-status.expect
index e6b3b2193e..23c0caa7d8 100644
--- a/t/chainlint/chain-break-status.expect
+++ b/t/chainlint/chain-break-status.expect
@@ -1,9 +1,9 @@
-OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
-test_match_signal 13 "$OUT" &&
-
-{ test-tool sigchain >actual; ret=$?; } &&
-{
- test_match_signal 15 "$ret" ||
- test "$ret" = 3
-} &&
-test_cmp expect actual
+2 OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
+3 test_match_signal 13 "$OUT" &&
+4
+5 { test-tool sigchain >actual; ret=$?; } &&
+6 {
+7 test_match_signal 15 "$ret" ||
+8 test "$ret" = 3
+9 } &&
+10 test_cmp expect actual
diff --git a/t/chainlint/chain-break-status.test b/t/chainlint/chain-break-status.test
index a6602a7b99..d9fee190d9 100644
--- a/t/chainlint/chain-break-status.test
+++ b/t/chainlint/chain-break-status.test
@@ -1,3 +1,4 @@
+test_expect_success 'chain-break-status' '
# LINT: broken &&-chain okay if next command handles "$?" explicitly
OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" &&
@@ -9,3 +10,4 @@ test_match_signal 13 "$OUT" &&
test "$ret" = 3
} &&
test_cmp expect actual
+'
diff --git a/t/chainlint/chained-block.expect b/t/chainlint/chained-block.expect
index 574cdceb07..a546b714a6 100644
--- a/t/chainlint/chained-block.expect
+++ b/t/chainlint/chained-block.expect
@@ -1,9 +1,9 @@
-echo nobody home && {
- test the doohicky ?!AMP?!
- right now
-} &&
-
-GIT_EXTERNAL_DIFF=echo git diff | {
- read path oldfile oldhex oldmode newfile newhex newmode &&
- test "z$oh" = "z$oldhex"
-}
+2 echo nobody home && {
+3 test the doohicky ?!AMP?!
+4 right now
+5 } &&
+6
+7 GIT_EXTERNAL_DIFF=echo git diff | {
+8 read path oldfile oldhex oldmode newfile newhex newmode &&
+9 test "z$oh" = "z$oldhex"
+10 }
diff --git a/t/chainlint/chained-block.test b/t/chainlint/chained-block.test
index 86f81ece63..71ef1d0b7f 100644
--- a/t/chainlint/chained-block.test
+++ b/t/chainlint/chained-block.test
@@ -1,3 +1,4 @@
+test_expect_success 'chained-block' '
# LINT: start of block chained to preceding command
echo nobody home && {
test the doohicky
@@ -9,3 +10,4 @@ GIT_EXTERNAL_DIFF=echo git diff | {
read path oldfile oldhex oldmode newfile newhex newmode &&
test "z$oh" = "z$oldhex"
}
+'
diff --git a/t/chainlint/chained-subshell.expect b/t/chainlint/chained-subshell.expect
index 83810ea7ec..f78b268291 100644
--- a/t/chainlint/chained-subshell.expect
+++ b/t/chainlint/chained-subshell.expect
@@ -1,10 +1,10 @@
-mkdir sub && (
- cd sub &&
- foo the bar ?!AMP?!
- nuff said
-) &&
-
-cut "-d " -f actual | (read s1 s2 s3 &&
-test -f $s1 ?!AMP?!
-test $(cat $s2) = tree2path1 &&
-test $(cat $s3) = tree3path1)
+2 mkdir sub && (
+3 cd sub &&
+4 foo the bar ?!AMP?!
+5 nuff said
+6 ) &&
+7
+8 cut "-d " -f actual | (read s1 s2 s3 &&
+9 test -f $s1 ?!AMP?!
+10 test $(cat $s2) = tree2path1 &&
+11 test $(cat $s3) = tree3path1)
diff --git a/t/chainlint/chained-subshell.test b/t/chainlint/chained-subshell.test
index 4ff6ddd8cb..1f11f65398 100644
--- a/t/chainlint/chained-subshell.test
+++ b/t/chainlint/chained-subshell.test
@@ -1,3 +1,4 @@
+test_expect_success 'chained-subshell' '
# LINT: start of subshell chained to preceding command
mkdir sub && (
cd sub &&
@@ -11,3 +12,4 @@ test -f $s1
test $(cat $s2) = tree2path1 &&
# LINT: closing subshell ")" correctly detected on same line as "$(...)"
test $(cat $s3) = tree3path1)
+'
diff --git a/t/chainlint/close-nested-and-parent-together.expect b/t/chainlint/close-nested-and-parent-together.expect
index 72d482f76d..4167e54a59 100644
--- a/t/chainlint/close-nested-and-parent-together.expect
+++ b/t/chainlint/close-nested-and-parent-together.expect
@@ -1,3 +1,3 @@
-(cd foo &&
- (bar &&
- baz))
+2 (cd foo &&
+3 (bar &&
+4 baz))
diff --git a/t/chainlint/close-nested-and-parent-together.test b/t/chainlint/close-nested-and-parent-together.test
index 72d482f76d..56b28b186b 100644
--- a/t/chainlint/close-nested-and-parent-together.test
+++ b/t/chainlint/close-nested-and-parent-together.test
@@ -1,3 +1,5 @@
+test_expect_success 'close-nested-and-parent-together' '
(cd foo &&
(bar &&
baz))
+'
diff --git a/t/chainlint/close-subshell.expect b/t/chainlint/close-subshell.expect
index 2192a2870a..a272cfe72e 100644
--- a/t/chainlint/close-subshell.expect
+++ b/t/chainlint/close-subshell.expect
@@ -1,26 +1,26 @@
-(
- foo
-) &&
-(
- bar
-) >out &&
-(
- baz
-) 2>err &&
-(
- boo
-) <input &&
-(
- bip
-) | wuzzle &&
-(
- bop
-) | fazz \
- fozz &&
-(
- bup
-) |
-fuzzle &&
-(
- yop
-)
+2 (
+3 foo
+4 ) &&
+5 (
+6 bar
+7 ) >out &&
+8 (
+9 baz
+10 ) 2>err &&
+11 (
+12 boo
+13 ) <input &&
+14 (
+15 bip
+16 ) | wuzzle &&
+17 (
+18 bop
+19 ) | fazz \
+20 fozz &&
+21 (
+22 bup
+23 ) |
+24 fuzzle &&
+25 (
+26 yop
+27 )
diff --git a/t/chainlint/close-subshell.test b/t/chainlint/close-subshell.test
index 508ca447fd..b99f80569d 100644
--- a/t/chainlint/close-subshell.test
+++ b/t/chainlint/close-subshell.test
@@ -1,3 +1,4 @@
+test_expect_success 'close-subshell' '
# LINT: closing ")" with various decorations ("&&", ">", "|", etc.)
(
foo
@@ -25,3 +26,4 @@ fuzzle &&
(
yop
)
+'
diff --git a/t/chainlint/command-substitution-subsubshell.expect b/t/chainlint/command-substitution-subsubshell.expect
index ec42f2c30c..f2a9312dc8 100644
--- a/t/chainlint/command-substitution-subsubshell.expect
+++ b/t/chainlint/command-substitution-subsubshell.expect
@@ -1,2 +1,2 @@
-OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
-test_match_signal 13 "$OUT"
+2 OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
+3 test_match_signal 13 "$OUT"
diff --git a/t/chainlint/command-substitution-subsubshell.test b/t/chainlint/command-substitution-subsubshell.test
index 321de2951c..4ea772d60a 100644
--- a/t/chainlint/command-substitution-subsubshell.test
+++ b/t/chainlint/command-substitution-subsubshell.test
@@ -1,3 +1,5 @@
+test_expect_success 'command-substitution-subsubshell' '
# LINT: subshell nested in subshell nested in command substitution
OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT"
+'
diff --git a/t/chainlint/command-substitution.expect b/t/chainlint/command-substitution.expect
index c72e4df9e7..5e31b36db6 100644
--- a/t/chainlint/command-substitution.expect
+++ b/t/chainlint/command-substitution.expect
@@ -1,9 +1,9 @@
-(
- foo &&
- bar=$(gobble) &&
- baz
-) &&
-(
- bar=$(gobble blocks) ?!AMP?!
- baz
-)
+2 (
+3 foo &&
+4 bar=$(gobble) &&
+5 baz
+6 ) &&
+7 (
+8 bar=$(gobble blocks) ?!AMP?!
+9 baz
+10 )
diff --git a/t/chainlint/command-substitution.test b/t/chainlint/command-substitution.test
index 3bbb002a4c..494d671e80 100644
--- a/t/chainlint/command-substitution.test
+++ b/t/chainlint/command-substitution.test
@@ -1,3 +1,4 @@
+test_expect_success 'command-substitution' '
(
foo &&
# LINT: closing ")" of $(...) not misinterpreted as subshell-closing ")"
@@ -9,3 +10,4 @@
bar=$(gobble blocks)
baz
)
+'
diff --git a/t/chainlint/comment.expect b/t/chainlint/comment.expect
index a68f1f9d7c..584098d6ba 100644
--- a/t/chainlint/comment.expect
+++ b/t/chainlint/comment.expect
@@ -1,8 +1,8 @@
-(
- # comment 1
- nothing &&
- # comment 2
- something
- # comment 3
- # comment 4
-)
+2 (
+3 # comment 1
+4 nothing &&
+5 # comment 2
+6 something
+7 # comment 3
+8 # comment 4
+9 )
diff --git a/t/chainlint/comment.test b/t/chainlint/comment.test
index 113c0c466f..c488beac0d 100644
--- a/t/chainlint/comment.test
+++ b/t/chainlint/comment.test
@@ -1,3 +1,4 @@
+test_expect_success 'comment' '
(
# LINT: swallow comment lines
# comment 1
@@ -9,3 +10,4 @@
# comment 3
# comment 4
)
+'
diff --git a/t/chainlint/complex-if-in-cuddled-loop.expect b/t/chainlint/complex-if-in-cuddled-loop.expect
index dac2d0fd1d..3a740103db 100644
--- a/t/chainlint/complex-if-in-cuddled-loop.expect
+++ b/t/chainlint/complex-if-in-cuddled-loop.expect
@@ -1,9 +1,9 @@
-(for i in a b c; do
- if test "$(echo $(waffle bat))" = "eleventeen" &&
- test "$x" = "$y"; then
- :
- else
- echo >file
- fi ?!LOOP?!
- done) &&
-test ! -f file
+2 (for i in a b c; do
+3 if test "$(echo $(waffle bat))" = "eleventeen" &&
+4 test "$x" = "$y"; then
+5 :
+6 else
+7 echo >file
+8 fi ?!LOOP?!
+9 done) &&
+10 test ! -f file
diff --git a/t/chainlint/complex-if-in-cuddled-loop.test b/t/chainlint/complex-if-in-cuddled-loop.test
index 5efeda58b2..f98ae4c42d 100644
--- a/t/chainlint/complex-if-in-cuddled-loop.test
+++ b/t/chainlint/complex-if-in-cuddled-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'complex-if-in-cuddled-loop' '
# LINT: "for" loop cuddled with "(" and ")" and nested "if" with complex
# LINT: multi-line condition; indented with spaces, not tabs
(for i in a b c; do
@@ -9,3 +10,4 @@
fi
done) &&
test ! -f file
+'
diff --git a/t/chainlint/cuddled-if-then-else.expect b/t/chainlint/cuddled-if-then-else.expect
index 1d8ed58c49..72da8794cb 100644
--- a/t/chainlint/cuddled-if-then-else.expect
+++ b/t/chainlint/cuddled-if-then-else.expect
@@ -1,6 +1,6 @@
-(if test -z ""; then
- echo empty
- else
- echo bizzy
- fi) &&
-echo foobar
+2 (if test -z ""; then
+3 echo empty
+4 else
+5 echo bizzy
+6 fi) &&
+7 echo foobar
diff --git a/t/chainlint/cuddled-if-then-else.test b/t/chainlint/cuddled-if-then-else.test
index 7c53f4efe3..b1b42e1aac 100644
--- a/t/chainlint/cuddled-if-then-else.test
+++ b/t/chainlint/cuddled-if-then-else.test
@@ -1,3 +1,4 @@
+test_expect_success 'cuddled-if-then-else' '
# LINT: "if" cuddled with "(" and ")"; indented with spaces, not tabs
(if test -z ""; then
echo empty
@@ -5,3 +6,4 @@
echo bizzy
fi) &&
echo foobar
+'
diff --git a/t/chainlint/cuddled-loop.expect b/t/chainlint/cuddled-loop.expect
index 9cf260708e..c38585c756 100644
--- a/t/chainlint/cuddled-loop.expect
+++ b/t/chainlint/cuddled-loop.expect
@@ -1,4 +1,4 @@
-( while read x
- do foobar bop || exit 1
- done <file ) &&
-outside subshell
+2 ( while read x
+3 do foobar bop || exit 1
+4 done <file ) &&
+5 outside subshell
diff --git a/t/chainlint/cuddled-loop.test b/t/chainlint/cuddled-loop.test
index 3c2a62f751..6fccb6ac22 100644
--- a/t/chainlint/cuddled-loop.test
+++ b/t/chainlint/cuddled-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'cuddled-loop' '
# LINT: "while" loop cuddled with "(" and ")", with embedded (allowed)
# LINT: "|| exit {n}" to exit loop early, and using redirection "<" to feed
# LINT: loop; indented with spaces, not tabs
@@ -5,3 +6,4 @@
do foobar bop || exit 1
done <file ) &&
outside subshell
+'
diff --git a/t/chainlint/cuddled.expect b/t/chainlint/cuddled.expect
index c3e0be4047..b06d638311 100644
--- a/t/chainlint/cuddled.expect
+++ b/t/chainlint/cuddled.expect
@@ -1,17 +1,17 @@
-(cd foo &&
- bar
-) &&
-
-(cd foo ?!AMP?!
- bar
-) &&
-
-(
- cd foo &&
- bar) &&
-
-(cd foo &&
- bar) &&
-
-(cd foo ?!AMP?!
- bar)
+2 (cd foo &&
+3 bar
+4 ) &&
+5
+6 (cd foo ?!AMP?!
+7 bar
+8 ) &&
+9
+10 (
+11 cd foo &&
+12 bar) &&
+13
+14 (cd foo &&
+15 bar) &&
+16
+17 (cd foo ?!AMP?!
+18 bar)
diff --git a/t/chainlint/cuddled.test b/t/chainlint/cuddled.test
index 257b5b5eed..5a6ef7a4a6 100644
--- a/t/chainlint/cuddled.test
+++ b/t/chainlint/cuddled.test
@@ -1,3 +1,4 @@
+test_expect_success 'cuddled' '
# LINT: first subshell statement cuddled with opening "("
(cd foo &&
bar
@@ -20,3 +21,4 @@
# LINT: same with missing "&&"
(cd foo
bar)
+'
diff --git a/t/chainlint/double-here-doc.expect b/t/chainlint/double-here-doc.expect
index cd584a4357..48c04ecd58 100644
--- a/t/chainlint/double-here-doc.expect
+++ b/t/chainlint/double-here-doc.expect
@@ -1,12 +1,12 @@
-run_sub_test_lib_test_err run-inv-range-start \
- "--run invalid range start" \
- --run="a-5" <<-\EOF &&
-test_expect_success "passing test #1" "true"
-test_done
-EOF
-check_sub_test_lib_test_err run-inv-range-start \
- <<-\EOF_OUT 3<<-EOF_ERR
-> FATAL: Unexpected exit with code 1
-EOF_OUT
-> error: --run: invalid non-numeric in range start: ${SQ}a-5${SQ}
-EOF_ERR
+2 run_sub_test_lib_test_err run-inv-range-start \
+3 "--run invalid range start" \
+4 --run="a-5" <<-\EOF &&
+5 test_expect_success "passing test #1" "true"
+6 test_done
+7 EOF
+8 check_sub_test_lib_test_err run-inv-range-start \
+9 <<-\EOF_OUT 3<<-EOF_ERR
+10 > FATAL: Unexpected exit with code 1
+11 EOF_OUT
+12 > error: --run: invalid non-numeric in range start: ${SQ}a-5${SQ}
+13 EOF_ERR
diff --git a/t/chainlint/double-here-doc.test b/t/chainlint/double-here-doc.test
index cd584a4357..1b69b7a651 100644
--- a/t/chainlint/double-here-doc.test
+++ b/t/chainlint/double-here-doc.test
@@ -1,3 +1,4 @@
+test_expect_success 'double-here-doc' '
run_sub_test_lib_test_err run-inv-range-start \
"--run invalid range start" \
--run="a-5" <<-\EOF &&
@@ -10,3 +11,4 @@ check_sub_test_lib_test_err run-inv-range-start \
EOF_OUT
> error: --run: invalid non-numeric in range start: ${SQ}a-5${SQ}
EOF_ERR
+'
diff --git a/t/chainlint/dqstring-line-splice.expect b/t/chainlint/dqstring-line-splice.expect
index 37eab80738..2ca1c92cd6 100644
--- a/t/chainlint/dqstring-line-splice.expect
+++ b/t/chainlint/dqstring-line-splice.expect
@@ -1,5 +1,5 @@
-
-echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' >expect &&
-test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
-test_cmp expect actual
-
+2
+3 echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' >expect &&
+4 test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
+5 test_cmp expect actual
+6
diff --git a/t/chainlint/dqstring-line-splice.test b/t/chainlint/dqstring-line-splice.test
index b40714439f..f6aa637be8 100644
--- a/t/chainlint/dqstring-line-splice.test
+++ b/t/chainlint/dqstring-line-splice.test
@@ -1,3 +1,4 @@
+test_expect_success 'dqstring-line-splice' '
# LINT: line-splice within DQ-string
'"
echo 'fatal: reword option of --fixup is mutually exclusive with'\
@@ -5,3 +6,4 @@ echo 'fatal: reword option of --fixup is mutually exclusive with'\
test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
test_cmp expect actual
"'
+'
diff --git a/t/chainlint/dqstring-no-interpolate.expect b/t/chainlint/dqstring-no-interpolate.expect
index 087eda15e4..c9f75849c5 100644
--- a/t/chainlint/dqstring-no-interpolate.expect
+++ b/t/chainlint/dqstring-no-interpolate.expect
@@ -1,12 +1,12 @@
-grep "^ ! [rejected][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
-
-grep "^\.git$" output.txt &&
-
-
-(
- cd client$version &&
- GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input)
-) >output &&
- cut -d ' ' -f 2 <output | sort >actual &&
- test_cmp expect actual
-
+2 grep "^ ! [rejected][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
+3
+4 grep "^\.git$" output.txt &&
+5
+6
+7 (
+8 cd client$version &&
+9 GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input)
+10 ) >output &&
+11 cut -d ' ' -f 2 <output | sort >actual &&
+12 test_cmp expect actual
+13
diff --git a/t/chainlint/dqstring-no-interpolate.test b/t/chainlint/dqstring-no-interpolate.test
index d2f4219cbb..7ae079b558 100644
--- a/t/chainlint/dqstring-no-interpolate.test
+++ b/t/chainlint/dqstring-no-interpolate.test
@@ -1,3 +1,4 @@
+test_expect_success 'dqstring-no-interpolate' '
# LINT: regex dollar-sign eol anchor in double-quoted string not special
grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
@@ -13,3 +14,4 @@ grep "^\\.git\$" output.txt &&
cut -d ' ' -f 2 <output | sort >actual &&
test_cmp expect actual
"'
+'
diff --git a/t/chainlint/empty-here-doc.expect b/t/chainlint/empty-here-doc.expect
index 8507721192..54b33f823a 100644
--- a/t/chainlint/empty-here-doc.expect
+++ b/t/chainlint/empty-here-doc.expect
@@ -1,4 +1,4 @@
-git ls-tree $tree path >current &&
-cat >expected <<\EOF &&
-EOF
-test_output
+2 git ls-tree $tree path >current &&
+3 cat >expected <<\EOF &&
+4 EOF
+5 test_output
diff --git a/t/chainlint/empty-here-doc.test b/t/chainlint/empty-here-doc.test
index 24fc165de3..8b7ab6eb5f 100644
--- a/t/chainlint/empty-here-doc.test
+++ b/t/chainlint/empty-here-doc.test
@@ -1,5 +1,7 @@
+test_expect_success 'empty-here-doc' '
git ls-tree $tree path >current &&
# LINT: empty here-doc
cat >expected <<\EOF &&
EOF
test_output
+'
diff --git a/t/chainlint/exclamation.expect b/t/chainlint/exclamation.expect
index 765a35bb4c..078744b61b 100644
--- a/t/chainlint/exclamation.expect
+++ b/t/chainlint/exclamation.expect
@@ -1,4 +1,4 @@
-if ! condition; then echo nope; else yep; fi &&
-test_prerequisite !MINGW &&
-mail uucp!address &&
-echo !whatever!
+2 if ! condition; then echo nope; else yep; fi &&
+3 test_prerequisite !MINGW &&
+4 mail uucp!address &&
+5 echo !whatever!
diff --git a/t/chainlint/exclamation.test b/t/chainlint/exclamation.test
index 323595b5bd..796de21b7c 100644
--- a/t/chainlint/exclamation.test
+++ b/t/chainlint/exclamation.test
@@ -1,3 +1,4 @@
+test_expect_success 'exclamation' '
# LINT: "! word" is two tokens
if ! condition; then echo nope; else yep; fi &&
# LINT: "!word" is single token, not two tokens "!" and "word"
@@ -6,3 +7,4 @@ test_prerequisite !MINGW &&
mail uucp!address &&
# LINT: "!word!" is single token, not three tokens "!", "word", and "!"
echo !whatever!
+'
diff --git a/t/chainlint/exit-loop.expect b/t/chainlint/exit-loop.expect
index f76aa60466..407278094c 100644
--- a/t/chainlint/exit-loop.expect
+++ b/t/chainlint/exit-loop.expect
@@ -1,24 +1,24 @@
-(
- for i in a b c
- do
- foo || exit 1
- bar &&
- baz
- done
-) &&
-(
- while true
- do
- foo || exit 1
- bar &&
- baz
- done
-) &&
-(
- i=0 &&
- while test $i -lt 10
- do
- echo $i || exit
- i=$(($i + 1))
- done
-)
+2 (
+3 for i in a b c
+4 do
+5 foo || exit 1
+6 bar &&
+7 baz
+8 done
+9 ) &&
+10 (
+11 while true
+12 do
+13 foo || exit 1
+14 bar &&
+15 baz
+16 done
+17 ) &&
+18 (
+19 i=0 &&
+20 while test $i -lt 10
+21 do
+22 echo $i || exit
+23 i=$(($i + 1))
+24 done
+25 )
diff --git a/t/chainlint/exit-loop.test b/t/chainlint/exit-loop.test
index 2f038207e1..7e8b68b465 100644
--- a/t/chainlint/exit-loop.test
+++ b/t/chainlint/exit-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'exit-loop' '
(
for i in a b c
do
@@ -25,3 +26,4 @@
i=$(($i + 1))
done
)
+'
diff --git a/t/chainlint/exit-subshell.expect b/t/chainlint/exit-subshell.expect
index da80339f78..793db12453 100644
--- a/t/chainlint/exit-subshell.expect
+++ b/t/chainlint/exit-subshell.expect
@@ -1,5 +1,5 @@
-(
- foo || exit 1
- bar &&
- baz
-)
+2 (
+3 foo || exit 1
+4 bar &&
+5 baz
+6 )
diff --git a/t/chainlint/exit-subshell.test b/t/chainlint/exit-subshell.test
index 4e6ab69b88..05dff55cd7 100644
--- a/t/chainlint/exit-subshell.test
+++ b/t/chainlint/exit-subshell.test
@@ -1,6 +1,8 @@
+test_expect_success 'exit-subshell' '
(
# LINT: "|| exit {n}" valid subshell escape without hurting &&-chain
foo || exit 1
bar &&
baz
)
+'
diff --git a/t/chainlint/for-loop-abbreviated.expect b/t/chainlint/for-loop-abbreviated.expect
index 02c0d15cca..5574831976 100644
--- a/t/chainlint/for-loop-abbreviated.expect
+++ b/t/chainlint/for-loop-abbreviated.expect
@@ -1,5 +1,5 @@
-for it
-do
- path=$(expr "$it" : ([^:]*)) &&
- git update-index --add "$path" || exit
-done
+2 for it
+3 do
+4 path=$(expr "$it" : ([^:]*)) &&
+5 git update-index --add "$path" || exit
+6 done
diff --git a/t/chainlint/for-loop-abbreviated.test b/t/chainlint/for-loop-abbreviated.test
index 1084eccb89..1dd14f2a44 100644
--- a/t/chainlint/for-loop-abbreviated.test
+++ b/t/chainlint/for-loop-abbreviated.test
@@ -1,6 +1,8 @@
+test_expect_success 'for-loop-abbreviated' '
# LINT: for-loop lacking optional "in [word...]" before "do"
for it
do
path=$(expr "$it" : '\([^:]*\)') &&
git update-index --add "$path" || exit
done
+'
diff --git a/t/chainlint/for-loop.expect b/t/chainlint/for-loop.expect
index d2237f1e38..908aeedf96 100644
--- a/t/chainlint/for-loop.expect
+++ b/t/chainlint/for-loop.expect
@@ -1,14 +1,14 @@
-(
- for i in a b c
- do
- echo $i ?!AMP?!
- cat <<-\EOF ?!LOOP?!
- bar
- EOF
- done ?!AMP?!
-
- for i in a b c; do
- echo $i &&
- cat $i ?!LOOP?!
- done
-)
+2 (
+3 for i in a b c
+4 do
+5 echo $i ?!AMP?!
+6 cat <<-\EOF ?!LOOP?!
+7 bar
+8 EOF
+9 done ?!AMP?!
+10
+11 for i in a b c; do
+12 echo $i &&
+13 cat $i ?!LOOP?!
+14 done
+15 )
diff --git a/t/chainlint/for-loop.test b/t/chainlint/for-loop.test
index 6cb3428158..6f2489eb19 100644
--- a/t/chainlint/for-loop.test
+++ b/t/chainlint/for-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'for-loop' '
(
# LINT: "for", "do", "done" do not need "&&"
for i in a b c
@@ -17,3 +18,4 @@
cat $i
done
)
+'
diff --git a/t/chainlint/function.expect b/t/chainlint/function.expect
index dd7c997a3c..c226246b25 100644
--- a/t/chainlint/function.expect
+++ b/t/chainlint/function.expect
@@ -1,11 +1,11 @@
-sha1_file() {
- echo "$*" | sed "s#..#.git/objects/&/#"
-} &&
-
-remove_object() {
- file=$(sha1_file "$*") &&
- test -e "$file" ?!AMP?!
- rm -f "$file"
-} ?!AMP?!
-
-sha1_file arg && remove_object arg
+2 sha1_file() {
+3 echo "$*" | sed "s#..#.git/objects/&/#"
+4 } &&
+5
+6 remove_object() {
+7 file=$(sha1_file "$*") &&
+8 test -e "$file" ?!AMP?!
+9 rm -f "$file"
+10 } ?!AMP?!
+11
+12 sha1_file arg && remove_object arg
diff --git a/t/chainlint/function.test b/t/chainlint/function.test
index 5ee59562c9..763fcf3f87 100644
--- a/t/chainlint/function.test
+++ b/t/chainlint/function.test
@@ -1,3 +1,4 @@
+test_expect_success 'function' '
# LINT: "()" in function definition not mistaken for subshell
sha1_file() {
echo "$*" | sed "s#..#.git/objects/&/#"
@@ -11,3 +12,4 @@ remove_object() {
}
sha1_file arg && remove_object arg
+'
diff --git a/t/chainlint/here-doc-body-indent.expect b/t/chainlint/here-doc-body-indent.expect
new file mode 100644
index 0000000000..4323acc93d
--- /dev/null
+++ b/t/chainlint/here-doc-body-indent.expect
@@ -0,0 +1,2 @@
+2 echo "we should find this" ?!AMP?!
+3 echo "even though our heredoc has its indent stripped"
diff --git a/t/chainlint/here-doc-body-indent.test b/t/chainlint/here-doc-body-indent.test
new file mode 100644
index 0000000000..39ff970ef3
--- /dev/null
+++ b/t/chainlint/here-doc-body-indent.test
@@ -0,0 +1,4 @@
+test_expect_success 'here-doc-body-indent' - <<-\EOT
+ echo "we should find this"
+ echo "even though our heredoc has its indent stripped"
+EOT
diff --git a/t/chainlint/here-doc-body-pathological.expect b/t/chainlint/here-doc-body-pathological.expect
new file mode 100644
index 0000000000..a93a1fa3aa
--- /dev/null
+++ b/t/chainlint/here-doc-body-pathological.expect
@@ -0,0 +1,7 @@
+2 echo "outer here-doc does not allow indented end-tag" ?!AMP?!
+3 cat >file <<-\EOF &&
+4 but this inner here-doc
+5 does allow indented EOF
+6 EOF
+7 echo "missing chain after" ?!AMP?!
+8 echo "but this line is OK because it's the end"
diff --git a/t/chainlint/here-doc-body-pathological.test b/t/chainlint/here-doc-body-pathological.test
new file mode 100644
index 0000000000..7d2daa44f9
--- /dev/null
+++ b/t/chainlint/here-doc-body-pathological.test
@@ -0,0 +1,9 @@
+test_expect_success 'here-doc-body-pathological' - <<\EOF
+ echo "outer here-doc does not allow indented end-tag"
+ cat >file <<-\EOF &&
+ but this inner here-doc
+ does allow indented EOF
+ EOF
+ echo "missing chain after"
+ echo "but this line is OK because it's the end"
+EOF
diff --git a/t/chainlint/here-doc-body.expect b/t/chainlint/here-doc-body.expect
new file mode 100644
index 0000000000..ddf1c412af
--- /dev/null
+++ b/t/chainlint/here-doc-body.expect
@@ -0,0 +1,7 @@
+2 echo "missing chain before" ?!AMP?!
+3 cat >file <<-\EOF &&
+4 inside inner here-doc
+5 these are not shell commands
+6 EOF
+7 echo "missing chain after" ?!AMP?!
+8 echo "but this line is OK because it's the end"
diff --git a/t/chainlint/here-doc-body.test b/t/chainlint/here-doc-body.test
new file mode 100644
index 0000000000..989ac2f4e1
--- /dev/null
+++ b/t/chainlint/here-doc-body.test
@@ -0,0 +1,9 @@
+test_expect_success 'here-doc-body' - <<\EOT
+ echo "missing chain before"
+ cat >file <<-\EOF &&
+ inside inner here-doc
+ these are not shell commands
+ EOF
+ echo "missing chain after"
+ echo "but this line is OK because it's the end"
+EOT
diff --git a/t/chainlint/here-doc-close-subshell.expect b/t/chainlint/here-doc-close-subshell.expect
index 7d9c2b5607..965813f463 100644
--- a/t/chainlint/here-doc-close-subshell.expect
+++ b/t/chainlint/here-doc-close-subshell.expect
@@ -1,4 +1,4 @@
-(
- cat <<-\INPUT)
- fizz
- INPUT
+2 (
+3 cat <<-\INPUT)
+4 fizz
+5 INPUT
diff --git a/t/chainlint/here-doc-close-subshell.test b/t/chainlint/here-doc-close-subshell.test
index b857ff5467..2458f3323b 100644
--- a/t/chainlint/here-doc-close-subshell.test
+++ b/t/chainlint/here-doc-close-subshell.test
@@ -1,5 +1,7 @@
+test_expect_success 'here-doc-close-subshell' '
(
# LINT: line contains here-doc and closes nested subshell
cat <<-\INPUT)
fizz
INPUT
+'
diff --git a/t/chainlint/here-doc-double.expect b/t/chainlint/here-doc-double.expect
new file mode 100644
index 0000000000..20dba4b452
--- /dev/null
+++ b/t/chainlint/here-doc-double.expect
@@ -0,0 +1,2 @@
+8 echo "actual test commands" ?!AMP?!
+9 echo "that should be checked"
diff --git a/t/chainlint/here-doc-double.test b/t/chainlint/here-doc-double.test
new file mode 100644
index 0000000000..777389f0d9
--- /dev/null
+++ b/t/chainlint/here-doc-double.test
@@ -0,0 +1,10 @@
+# This is obviously a ridiculous thing to do, but we should be able
+# to handle two here-docs on the same line, and attribute them
+# correctly.
+test_expect_success "$(cat <<END_OF_PREREQS)" 'here-doc-double' - <<\EOT
+SOME
+PREREQS
+END_OF_PREREQS
+ echo "actual test commands"
+ echo "that should be checked"
+EOT
diff --git a/t/chainlint/here-doc-indent-operator.expect b/t/chainlint/here-doc-indent-operator.expect
index f92a7ce999..277a11202d 100644
--- a/t/chainlint/here-doc-indent-operator.expect
+++ b/t/chainlint/here-doc-indent-operator.expect
@@ -1,11 +1,11 @@
-cat >expect <<- EOF &&
-header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
-num_commits: $1
-chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
-EOF
-
-cat >expect << -EOF ?!AMP?!
-this is not indented
--EOF
-
-cleanup
+2 cat >expect <<- EOF &&
+3 header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
+4 num_commits: $1
+5 chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
+6 EOF
+7
+8 cat >expect << -EOF ?!AMP?!
+9 this is not indented
+10 -EOF
+11
+12 cleanup
diff --git a/t/chainlint/here-doc-indent-operator.test b/t/chainlint/here-doc-indent-operator.test
index c8a6f18eb4..a2656f47c1 100644
--- a/t/chainlint/here-doc-indent-operator.test
+++ b/t/chainlint/here-doc-indent-operator.test
@@ -1,3 +1,4 @@
+test_expect_success 'here-doc-indent-operator' '
# LINT: whitespace between operator "<<-" and tag legal
cat >expect <<- EOF &&
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
@@ -11,3 +12,4 @@ this is not indented
-EOF
cleanup
+'
diff --git a/t/chainlint/here-doc-multi-line-command-subst.expect b/t/chainlint/here-doc-multi-line-command-subst.expect
index b7364c82c8..41b55f6437 100644
--- a/t/chainlint/here-doc-multi-line-command-subst.expect
+++ b/t/chainlint/here-doc-multi-line-command-subst.expect
@@ -1,8 +1,8 @@
-(
- x=$(bobble <<-\END &&
- fossil
- vegetable
- END
- wiffle) ?!AMP?!
- echo $x
-)
+2 (
+3 x=$(bobble <<-\END &&
+4 fossil
+5 vegetable
+6 END
+7 wiffle) ?!AMP?!
+8 echo $x
+9 )
diff --git a/t/chainlint/here-doc-multi-line-command-subst.test b/t/chainlint/here-doc-multi-line-command-subst.test
index 899bc5de8b..8710a8c483 100644
--- a/t/chainlint/here-doc-multi-line-command-subst.test
+++ b/t/chainlint/here-doc-multi-line-command-subst.test
@@ -1,3 +1,4 @@
+test_expect_success 'here-doc-multi-line-command-subst' '
(
# LINT: line contains here-doc and opens multi-line $(...)
x=$(bobble <<-\END &&
@@ -7,3 +8,4 @@
wiffle)
echo $x
)
+'
diff --git a/t/chainlint/here-doc-multi-line-string.expect b/t/chainlint/here-doc-multi-line-string.expect
index 6c13bdcbfb..c71828589e 100644
--- a/t/chainlint/here-doc-multi-line-string.expect
+++ b/t/chainlint/here-doc-multi-line-string.expect
@@ -1,7 +1,7 @@
-(
- cat <<-\TXT && echo "multi-line
- string" ?!AMP?!
- fizzle
- TXT
- bap
-)
+2 (
+3 cat <<-\TXT && echo "multi-line
+4 string" ?!AMP?!
+5 fizzle
+6 TXT
+7 bap
+8 )
diff --git a/t/chainlint/here-doc-multi-line-string.test b/t/chainlint/here-doc-multi-line-string.test
index a53edbcc8d..2f496002fd 100644
--- a/t/chainlint/here-doc-multi-line-string.test
+++ b/t/chainlint/here-doc-multi-line-string.test
@@ -1,3 +1,4 @@
+test_expect_success 'here-doc-multi-line-string' '
(
# LINT: line contains here-doc and opens multi-line string
cat <<-\TXT && echo "multi-line
@@ -6,3 +7,4 @@
TXT
bap
)
+'
diff --git a/t/chainlint/here-doc.expect b/t/chainlint/here-doc.expect
index 91b961242a..2c382dd8eb 100644
--- a/t/chainlint/here-doc.expect
+++ b/t/chainlint/here-doc.expect
@@ -1,25 +1,25 @@
-boodle wobba \
- gorgo snoot \
- wafta snurb <<EOF &&
-quoth the raven,
-nevermore...
-EOF
-
-cat <<-Arbitrary_Tag_42 >foo &&
-snoz
-boz
-woz
-Arbitrary_Tag_42
-
-cat <<"zump" >boo &&
-snoz
-boz
-woz
-zump
-
-horticulture <<\EOF
-gomez
-morticia
-wednesday
-pugsly
-EOF
+2 boodle wobba \
+3 gorgo snoot \
+4 wafta snurb <<EOF &&
+5 quoth the raven,
+6 nevermore...
+7 EOF
+8
+9 cat <<-Arbitrary_Tag_42 >foo &&
+10 snoz
+11 boz
+12 woz
+13 Arbitrary_Tag_42
+14
+15 cat <<"zump" >boo &&
+16 snoz
+17 boz
+18 woz
+19 zump
+20
+21 horticulture <<\EOF
+22 gomez
+23 morticia
+24 wednesday
+25 pugsly
+26 EOF
diff --git a/t/chainlint/here-doc.test b/t/chainlint/here-doc.test
index 3f5f92cad3..c91b695319 100644
--- a/t/chainlint/here-doc.test
+++ b/t/chainlint/here-doc.test
@@ -1,3 +1,4 @@
+test_expect_success 'here-doc' '
# LINT: stitch together incomplete \-ending lines
# LINT: swallow here-doc to avoid false positives in content
boodle wobba \
@@ -28,3 +29,4 @@ morticia
wednesday
pugsly
EOF
+'
diff --git a/t/chainlint/if-condition-split.expect b/t/chainlint/if-condition-split.expect
index ee745ef8d7..9daf3d294a 100644
--- a/t/chainlint/if-condition-split.expect
+++ b/t/chainlint/if-condition-split.expect
@@ -1,7 +1,7 @@
-if bob &&
- marcia ||
- kevin
-then
- echo "nomads" ?!AMP?!
- echo "for sure"
-fi
+2 if bob &&
+3 marcia ||
+4 kevin
+5 then
+6 echo "nomads" ?!AMP?!
+7 echo "for sure"
+8 fi
diff --git a/t/chainlint/if-condition-split.test b/t/chainlint/if-condition-split.test
index 240daa9fd5..9a3b3ed04a 100644
--- a/t/chainlint/if-condition-split.test
+++ b/t/chainlint/if-condition-split.test
@@ -1,3 +1,4 @@
+test_expect_success 'if-condition-split' '
# LINT: "if" condition split across multiple lines at "&&" or "||"
if bob &&
marcia ||
@@ -6,3 +7,4 @@ then
echo "nomads"
echo "for sure"
fi
+'
diff --git a/t/chainlint/if-in-loop.expect b/t/chainlint/if-in-loop.expect
index d6514ae749..ff8c60dbdb 100644
--- a/t/chainlint/if-in-loop.expect
+++ b/t/chainlint/if-in-loop.expect
@@ -1,12 +1,12 @@
-(
- for i in a b c
- do
- if false
- then
- echo "err"
- exit 1
- fi ?!AMP?!
- foo
- done ?!AMP?!
- bar
-)
+2 (
+3 for i in a b c
+4 do
+5 if false
+6 then
+7 echo "err"
+8 exit 1
+9 fi ?!AMP?!
+10 foo
+11 done ?!AMP?!
+12 bar
+13 )
diff --git a/t/chainlint/if-in-loop.test b/t/chainlint/if-in-loop.test
index 90c23976fe..5be9d1cfa5 100644
--- a/t/chainlint/if-in-loop.test
+++ b/t/chainlint/if-in-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'if-in-loop' '
(
for i in a b c
do
@@ -13,3 +14,4 @@
done
bar
)
+'
diff --git a/t/chainlint/if-then-else.expect b/t/chainlint/if-then-else.expect
index cbaaf857d4..965d7e41a2 100644
--- a/t/chainlint/if-then-else.expect
+++ b/t/chainlint/if-then-else.expect
@@ -1,22 +1,22 @@
-(
- if test -n ""
- then
- echo very ?!AMP?!
- echo empty
- elif test -z ""
- then
- echo foo
- else
- echo foo &&
- cat <<-\EOF
- bar
- EOF
- fi ?!AMP?!
- echo poodle
-) &&
-(
- if test -n ""; then
- echo very &&
- echo empty
- fi
-)
+2 (
+3 if test -n ""
+4 then
+5 echo very ?!AMP?!
+6 echo empty
+7 elif test -z ""
+8 then
+9 echo foo
+10 else
+11 echo foo &&
+12 cat <<-\EOF
+13 bar
+14 EOF
+15 fi ?!AMP?!
+16 echo poodle
+17 ) &&
+18 (
+19 if test -n ""; then
+20 echo very &&
+21 echo empty
+22 fi
+23 )
diff --git a/t/chainlint/if-then-else.test b/t/chainlint/if-then-else.test
index 2055336c2b..6582a7f440 100644
--- a/t/chainlint/if-then-else.test
+++ b/t/chainlint/if-then-else.test
@@ -1,3 +1,4 @@
+test_expect_success 'if-then-else' '
(
# LINT: "if", "then", "elif", "else", "fi" do not need "&&"
if test -n ""
@@ -27,3 +28,4 @@
echo empty
fi
)
+'
diff --git a/t/chainlint/incomplete-line.expect b/t/chainlint/incomplete-line.expect
index 134d3a14f5..b15e00b901 100644
--- a/t/chainlint/incomplete-line.expect
+++ b/t/chainlint/incomplete-line.expect
@@ -1,10 +1,10 @@
-line 1 \
-line 2 \
-line 3 \
-line 4 &&
-(
- line 5 \
- line 6 \
- line 7 \
- line 8
-)
+2 line 1 \
+3 line 2 \
+4 line 3 \
+5 line 4 &&
+6 (
+7 line 5 \
+8 line 6 \
+9 line 7 \
+10 line 8
+11 )
diff --git a/t/chainlint/incomplete-line.test b/t/chainlint/incomplete-line.test
index d856658083..74a93021eb 100644
--- a/t/chainlint/incomplete-line.test
+++ b/t/chainlint/incomplete-line.test
@@ -1,3 +1,4 @@
+test_expect_success 'incomplete-line' '
# LINT: stitch together all incomplete \-ending lines
line 1 \
line 2 \
@@ -10,3 +11,4 @@ line 4 &&
line 7 \
line 8
)
+'
diff --git a/t/chainlint/inline-comment.expect b/t/chainlint/inline-comment.expect
index 6bad218530..0285c0b22c 100644
--- a/t/chainlint/inline-comment.expect
+++ b/t/chainlint/inline-comment.expect
@@ -1,8 +1,8 @@
-(
- foobar && # comment 1
- barfoo ?!AMP?! # wrong position for &&
- flibble "not a # comment"
-) &&
-
-(cd foo &&
- flibble "not a # comment")
+2 (
+3 foobar && # comment 1
+4 barfoo ?!AMP?! # wrong position for &&
+5 flibble "not a # comment"
+6 ) &&
+7
+8 (cd foo &&
+9 flibble "not a # comment")
diff --git a/t/chainlint/inline-comment.test b/t/chainlint/inline-comment.test
index 8f26856e77..4fbbf1058a 100644
--- a/t/chainlint/inline-comment.test
+++ b/t/chainlint/inline-comment.test
@@ -1,3 +1,4 @@
+test_expect_success 'inline-comment' '
(
# LINT: swallow inline comment (leaving command intact)
foobar && # comment 1
@@ -10,3 +11,4 @@
# LINT: "#" in string in cuddled subshell not misinterpreted as comment
(cd foo &&
flibble "not a # comment")
+'
diff --git a/t/chainlint/loop-detect-failure.expect b/t/chainlint/loop-detect-failure.expect
index a66025c39d..40c06f0d53 100644
--- a/t/chainlint/loop-detect-failure.expect
+++ b/t/chainlint/loop-detect-failure.expect
@@ -1,15 +1,15 @@
-git init r1 &&
-for n in 1 2 3 4 5
-do
- echo "This is file: $n" > r1/file.$n &&
- git -C r1 add file.$n &&
- git -C r1 commit -m "$n" || return 1
-done &&
-
-git init r2 &&
-for n in 1000 10000
-do
- printf "%"$n"s" X > r2/large.$n &&
- git -C r2 add large.$n &&
- git -C r2 commit -m "$n" ?!LOOP?!
-done
+2 git init r1 &&
+3 for n in 1 2 3 4 5
+4 do
+5 echo "This is file: $n" > r1/file.$n &&
+6 git -C r1 add file.$n &&
+7 git -C r1 commit -m "$n" || return 1
+8 done &&
+9
+10 git init r2 &&
+11 for n in 1000 10000
+12 do
+13 printf "%"$n"s" X > r2/large.$n &&
+14 git -C r2 add large.$n &&
+15 git -C r2 commit -m "$n" ?!LOOP?!
+16 done
diff --git a/t/chainlint/loop-detect-failure.test b/t/chainlint/loop-detect-failure.test
index b9791cc802..44673aa394 100644
--- a/t/chainlint/loop-detect-failure.test
+++ b/t/chainlint/loop-detect-failure.test
@@ -1,3 +1,4 @@
+test_expect_success 'loop-detect-failure' '
git init r1 &&
# LINT: loop handles failure explicitly with "|| return 1"
for n in 1 2 3 4 5
@@ -15,3 +16,4 @@ do
git -C r2 add large.$n &&
git -C r2 commit -m "$n"
done
+'
diff --git a/t/chainlint/loop-detect-status.expect b/t/chainlint/loop-detect-status.expect
index 7ce3a34806..0f180b08de 100644
--- a/t/chainlint/loop-detect-status.expect
+++ b/t/chainlint/loop-detect-status.expect
@@ -1,18 +1,18 @@
-(while test $i -le $blobcount
- do
- printf "Generating blob $i/$blobcount\r" >&2 &&
- printf "blob\nmark :$i\ndata $blobsize\n" &&
- #test-tool genrandom $i $blobsize &&
- printf "%-${blobsize}s" $i &&
- echo "M 100644 :$i $i" >> commit &&
- i=$(($i+1)) ||
- echo $? > exit-status
- done &&
- echo "commit refs/heads/main" &&
- echo "author A U Thor <author@email.com> 123456789 +0000" &&
- echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
- echo "data 5" &&
- echo ">2gb" &&
- cat commit) |
-git fast-import --big-file-threshold=2 &&
-test ! -f exit-status
+2 (while test $i -le $blobcount
+3 do
+4 printf "Generating blob $i/$blobcount\r" >&2 &&
+5 printf "blob\nmark :$i\ndata $blobsize\n" &&
+6 #test-tool genrandom $i $blobsize &&
+7 printf "%-${blobsize}s" $i &&
+8 echo "M 100644 :$i $i" >> commit &&
+9 i=$(($i+1)) ||
+10 echo $? > exit-status
+11 done &&
+12 echo "commit refs/heads/main" &&
+13 echo "author A U Thor <author@email.com> 123456789 +0000" &&
+14 echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
+15 echo "data 5" &&
+16 echo ">2gb" &&
+17 cat commit) |
+18 git fast-import --big-file-threshold=2 &&
+19 test ! -f exit-status
diff --git a/t/chainlint/loop-detect-status.test b/t/chainlint/loop-detect-status.test
index 1c6c23cfc9..8b639be073 100644
--- a/t/chainlint/loop-detect-status.test
+++ b/t/chainlint/loop-detect-status.test
@@ -1,3 +1,4 @@
+test_expect_success 'loop-detect-status' '
# LINT: "$?" handled explicitly within loop body
(while test $i -le $blobcount
do
@@ -17,3 +18,4 @@
cat commit) |
git fast-import --big-file-threshold=2 &&
test ! -f exit-status
+'
diff --git a/t/chainlint/loop-in-if.expect b/t/chainlint/loop-in-if.expect
index 6c5d6e5b24..4e8c67c914 100644
--- a/t/chainlint/loop-in-if.expect
+++ b/t/chainlint/loop-in-if.expect
@@ -1,12 +1,12 @@
-(
- if true
- then
- while true
- do
- echo "pop" ?!AMP?!
- echo "glup" ?!LOOP?!
- done ?!AMP?!
- foo
- fi ?!AMP?!
- bar
-)
+2 (
+3 if true
+4 then
+5 while true
+6 do
+7 echo "pop" ?!AMP?!
+8 echo "glup" ?!LOOP?!
+9 done ?!AMP?!
+10 foo
+11 fi ?!AMP?!
+12 bar
+13 )
diff --git a/t/chainlint/loop-in-if.test b/t/chainlint/loop-in-if.test
index dfcc3f98fb..b0d0d393cf 100644
--- a/t/chainlint/loop-in-if.test
+++ b/t/chainlint/loop-in-if.test
@@ -1,3 +1,4 @@
+test_expect_success 'loop-in-if' '
(
if true
then
@@ -13,3 +14,4 @@
fi
bar
)
+'
diff --git a/t/chainlint/loop-upstream-pipe.expect b/t/chainlint/loop-upstream-pipe.expect
index 0b82ecc4b9..bef82479ca 100644
--- a/t/chainlint/loop-upstream-pipe.expect
+++ b/t/chainlint/loop-upstream-pipe.expect
@@ -1,10 +1,10 @@
-(
- git rev-list --objects --no-object-names base..loose |
- while read oid
- do
- path="$objdir/$(test_oid_to_path "$oid")" &&
- printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" ||
- echo "object list generation failed for $oid"
- done |
- sort -k1
-) >expect &&
+2 (
+3 git rev-list --objects --no-object-names base..loose |
+4 while read oid
+5 do
+6 path="$objdir/$(test_oid_to_path "$oid")" &&
+7 printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" ||
+8 echo "object list generation failed for $oid"
+9 done |
+10 sort -k1
+11 ) >expect &&
diff --git a/t/chainlint/loop-upstream-pipe.test b/t/chainlint/loop-upstream-pipe.test
index efb77da897..8415a4db27 100644
--- a/t/chainlint/loop-upstream-pipe.test
+++ b/t/chainlint/loop-upstream-pipe.test
@@ -1,3 +1,4 @@
+test_expect_success 'loop-upstream-pipe' '
(
git rev-list --objects --no-object-names base..loose |
while read oid
@@ -9,3 +10,4 @@
done |
sort -k1
) >expect &&
+'
diff --git a/t/chainlint/multi-line-nested-command-substitution.expect b/t/chainlint/multi-line-nested-command-substitution.expect
index 300058341b..ad27e43e05 100644
--- a/t/chainlint/multi-line-nested-command-substitution.expect
+++ b/t/chainlint/multi-line-nested-command-substitution.expect
@@ -1,18 +1,18 @@
-(
- foo &&
- x=$(
- echo bar |
- cat
- ) &&
- echo ok
-) |
-sort &&
-(
- bar &&
- x=$(echo bar |
- cat
- ) &&
- y=$(echo baz |
- fip) &&
- echo fail
-)
+2 (
+3 foo &&
+4 x=$(
+5 echo bar |
+6 cat
+7 ) &&
+8 echo ok
+9 ) |
+10 sort &&
+11 (
+12 bar &&
+13 x=$(echo bar |
+14 cat
+15 ) &&
+16 y=$(echo baz |
+17 fip) &&
+18 echo fail
+19 )
diff --git a/t/chainlint/multi-line-nested-command-substitution.test b/t/chainlint/multi-line-nested-command-substitution.test
index 300058341b..e811c63f2b 100644
--- a/t/chainlint/multi-line-nested-command-substitution.test
+++ b/t/chainlint/multi-line-nested-command-substitution.test
@@ -1,3 +1,4 @@
+test_expect_success 'multi-line-nested-command-substitution' '
(
foo &&
x=$(
@@ -16,3 +17,4 @@ sort &&
fip) &&
echo fail
)
+'
diff --git a/t/chainlint/multi-line-string.expect b/t/chainlint/multi-line-string.expect
index 27ff95218e..62c54e3a5e 100644
--- a/t/chainlint/multi-line-string.expect
+++ b/t/chainlint/multi-line-string.expect
@@ -1,14 +1,14 @@
-(
- x="line 1
- line 2
- line 3" &&
- y="line 1
- line2" ?!AMP?!
- foobar
-) &&
-(
- echo "xyz" "abc
- def
- ghi" &&
- barfoo
-)
+2 (
+3 x="line 1
+4 line 2
+5 line 3" &&
+6 y="line 1
+7 line2" ?!AMP?!
+8 foobar
+9 ) &&
+10 (
+11 echo "xyz" "abc
+12 def
+13 ghi" &&
+14 barfoo
+15 )
diff --git a/t/chainlint/multi-line-string.test b/t/chainlint/multi-line-string.test
index 4a0af2107d..7b5048d2ea 100644
--- a/t/chainlint/multi-line-string.test
+++ b/t/chainlint/multi-line-string.test
@@ -1,3 +1,4 @@
+test_expect_success 'multi-line-string' '
(
x="line 1
line 2
@@ -13,3 +14,4 @@
ghi" &&
barfoo
)
+'
diff --git a/t/chainlint/negated-one-liner.expect b/t/chainlint/negated-one-liner.expect
index ad4c2d949e..a6ce52a1da 100644
--- a/t/chainlint/negated-one-liner.expect
+++ b/t/chainlint/negated-one-liner.expect
@@ -1,5 +1,5 @@
-! (foo && bar) &&
-! (foo && bar) >baz &&
-
-! (foo; ?!AMP?! bar) &&
-! (foo; ?!AMP?! bar) >baz
+2 ! (foo && bar) &&
+3 ! (foo && bar) >baz &&
+4
+5 ! (foo; ?!AMP?! bar) &&
+6 ! (foo; ?!AMP?! bar) >baz
diff --git a/t/chainlint/negated-one-liner.test b/t/chainlint/negated-one-liner.test
index c9598e9153..30f4cc5a9b 100644
--- a/t/chainlint/negated-one-liner.test
+++ b/t/chainlint/negated-one-liner.test
@@ -1,3 +1,4 @@
+test_expect_success 'negated-one-liner' '
# LINT: top-level one-liner subshell
! (foo && bar) &&
! (foo && bar) >baz &&
@@ -5,3 +6,4 @@
# LINT: top-level one-liner subshell missing internal "&&"
! (foo; bar) &&
! (foo; bar) >baz
+'
diff --git a/t/chainlint/nested-cuddled-subshell.expect b/t/chainlint/nested-cuddled-subshell.expect
index 3836049cc4..0191c9c294 100644
--- a/t/chainlint/nested-cuddled-subshell.expect
+++ b/t/chainlint/nested-cuddled-subshell.expect
@@ -1,25 +1,25 @@
-(
- (cd foo &&
- bar
- ) &&
-
- (cd foo &&
- bar
- ) ?!AMP?!
-
- (
- cd foo &&
- bar) &&
-
- (
- cd foo &&
- bar) ?!AMP?!
-
- (cd foo &&
- bar) &&
-
- (cd foo &&
- bar) ?!AMP?!
-
- foobar
-)
+2 (
+3 (cd foo &&
+4 bar
+5 ) &&
+6
+7 (cd foo &&
+8 bar
+9 ) ?!AMP?!
+10
+11 (
+12 cd foo &&
+13 bar) &&
+14
+15 (
+16 cd foo &&
+17 bar) ?!AMP?!
+18
+19 (cd foo &&
+20 bar) &&
+21
+22 (cd foo &&
+23 bar) ?!AMP?!
+24
+25 foobar
+26 )
diff --git a/t/chainlint/nested-cuddled-subshell.test b/t/chainlint/nested-cuddled-subshell.test
index 8fd656c7b5..31e92d3be4 100644
--- a/t/chainlint/nested-cuddled-subshell.test
+++ b/t/chainlint/nested-cuddled-subshell.test
@@ -1,3 +1,4 @@
+test_expect_success 'nested-cuddled-subshell' '
(
# LINT: opening "(" cuddled with first nested subshell statement
(cd foo &&
@@ -29,3 +30,4 @@
foobar
)
+'
diff --git a/t/chainlint/nested-here-doc.expect b/t/chainlint/nested-here-doc.expect
index 29b3832a98..70d9b68dc9 100644
--- a/t/chainlint/nested-here-doc.expect
+++ b/t/chainlint/nested-here-doc.expect
@@ -1,30 +1,30 @@
-cat <<ARBITRARY >foop &&
-naddle
-fub <<EOF
- nozzle
- noodle
-EOF
-formp
-ARBITRARY
-
-(
- cat <<-\INPUT_END &&
- fish are mice
- but geese go slow
- data <<EOF
- perl is lerp
- and nothing else
- EOF
- toink
- INPUT_END
-
- cat <<-\EOT ?!AMP?!
- text goes here
- data <<EOF
- data goes here
- EOF
- more test here
- EOT
-
- foobar
-)
+2 cat <<ARBITRARY >foop &&
+3 naddle
+4 fub <<EOF
+5 nozzle
+6 noodle
+7 EOF
+8 formp
+9 ARBITRARY
+10
+11 (
+12 cat <<-\INPUT_END &&
+13 fish are mice
+14 but geese go slow
+15 data <<EOF
+16 perl is lerp
+17 and nothing else
+18 EOF
+19 toink
+20 INPUT_END
+21
+22 cat <<-\EOT ?!AMP?!
+23 text goes here
+24 data <<EOF
+25 data goes here
+26 EOF
+27 more test here
+28 EOT
+29
+30 foobar
+31 )
diff --git a/t/chainlint/nested-here-doc.test b/t/chainlint/nested-here-doc.test
index f35404bf0f..9505c47a34 100644
--- a/t/chainlint/nested-here-doc.test
+++ b/t/chainlint/nested-here-doc.test
@@ -1,3 +1,4 @@
+test_expect_success 'nested-here-doc' '
# LINT: inner "EOF" not misintrepreted as closing ARBITRARY here-doc
cat <<ARBITRARY >foop &&
naddle
@@ -31,3 +32,4 @@ ARBITRARY
foobar
)
+'
diff --git a/t/chainlint/nested-loop-detect-failure.expect b/t/chainlint/nested-loop-detect-failure.expect
index 3461df40e5..c13c4d2f90 100644
--- a/t/chainlint/nested-loop-detect-failure.expect
+++ b/t/chainlint/nested-loop-detect-failure.expect
@@ -1,31 +1,31 @@
-for i in 0 1 2 3 4 5 6 7 8 9;
-do
- for j in 0 1 2 3 4 5 6 7 8 9;
- do
- echo "$i$j" >"path$i$j" ?!LOOP?!
- done ?!LOOP?!
-done &&
-
-for i in 0 1 2 3 4 5 6 7 8 9;
-do
- for j in 0 1 2 3 4 5 6 7 8 9;
- do
- echo "$i$j" >"path$i$j" || return 1
- done
-done &&
-
-for i in 0 1 2 3 4 5 6 7 8 9;
-do
- for j in 0 1 2 3 4 5 6 7 8 9;
- do
- echo "$i$j" >"path$i$j" ?!LOOP?!
- done || return 1
-done &&
-
-for i in 0 1 2 3 4 5 6 7 8 9;
-do
- for j in 0 1 2 3 4 5 6 7 8 9;
- do
- echo "$i$j" >"path$i$j" || return 1
- done || return 1
-done
+2 for i in 0 1 2 3 4 5 6 7 8 9;
+3 do
+4 for j in 0 1 2 3 4 5 6 7 8 9;
+5 do
+6 echo "$i$j" >"path$i$j" ?!LOOP?!
+7 done ?!LOOP?!
+8 done &&
+9
+10 for i in 0 1 2 3 4 5 6 7 8 9;
+11 do
+12 for j in 0 1 2 3 4 5 6 7 8 9;
+13 do
+14 echo "$i$j" >"path$i$j" || return 1
+15 done
+16 done &&
+17
+18 for i in 0 1 2 3 4 5 6 7 8 9;
+19 do
+20 for j in 0 1 2 3 4 5 6 7 8 9;
+21 do
+22 echo "$i$j" >"path$i$j" ?!LOOP?!
+23 done || return 1
+24 done &&
+25
+26 for i in 0 1 2 3 4 5 6 7 8 9;
+27 do
+28 for j in 0 1 2 3 4 5 6 7 8 9;
+29 do
+30 echo "$i$j" >"path$i$j" || return 1
+31 done || return 1
+32 done
diff --git a/t/chainlint/nested-loop-detect-failure.test b/t/chainlint/nested-loop-detect-failure.test
index e6f0c1acfb..3d4b657412 100644
--- a/t/chainlint/nested-loop-detect-failure.test
+++ b/t/chainlint/nested-loop-detect-failure.test
@@ -1,3 +1,4 @@
+test_expect_success 'nested-loop-detect-failure' '
# LINT: neither loop handles failure explicitly with "|| return 1"
for i in 0 1 2 3 4 5 6 7 8 9;
do
@@ -33,3 +34,4 @@ do
echo "$i$j" >"path$i$j" || return 1
done || return 1
done
+'
diff --git a/t/chainlint/nested-subshell-comment.expect b/t/chainlint/nested-subshell-comment.expect
index 9138cf386d..f89a8d03a8 100644
--- a/t/chainlint/nested-subshell-comment.expect
+++ b/t/chainlint/nested-subshell-comment.expect
@@ -1,11 +1,11 @@
-(
- foo &&
- (
- bar &&
- # bottles wobble while fiddles gobble
- # minor numbers of cows (or do they?)
- baz &&
- snaff
- ) ?!AMP?!
- fuzzy
-)
+2 (
+3 foo &&
+4 (
+5 bar &&
+6 # bottles wobble while fiddles gobble
+7 # minor numbers of cows (or do they?)
+8 baz &&
+9 snaff
+10 ) ?!AMP?!
+11 fuzzy
+12 )
diff --git a/t/chainlint/nested-subshell-comment.test b/t/chainlint/nested-subshell-comment.test
index 0215cdb192..b430580ce0 100644
--- a/t/chainlint/nested-subshell-comment.test
+++ b/t/chainlint/nested-subshell-comment.test
@@ -1,3 +1,4 @@
+test_expect_success 'nested-subshell-comment' '
(
foo &&
(
@@ -11,3 +12,4 @@
)
fuzzy
)
+'
diff --git a/t/chainlint/nested-subshell.expect b/t/chainlint/nested-subshell.expect
index 73ff28546a..811e8a7912 100644
--- a/t/chainlint/nested-subshell.expect
+++ b/t/chainlint/nested-subshell.expect
@@ -1,13 +1,13 @@
-(
- cd foo &&
- (
- echo a &&
- echo b
- ) >file &&
-
- cd foo &&
- (
- echo a ?!AMP?!
- echo b
- ) >file
-)
+2 (
+3 cd foo &&
+4 (
+5 echo a &&
+6 echo b
+7 ) >file &&
+8
+9 cd foo &&
+10 (
+11 echo a ?!AMP?!
+12 echo b
+13 ) >file
+14 )
diff --git a/t/chainlint/nested-subshell.test b/t/chainlint/nested-subshell.test
index 440ee9992d..c31da34b73 100644
--- a/t/chainlint/nested-subshell.test
+++ b/t/chainlint/nested-subshell.test
@@ -1,3 +1,4 @@
+test_expect_success 'nested-subshell' '
(
cd foo &&
(
@@ -11,3 +12,4 @@
echo b
) >file
)
+'
diff --git a/t/chainlint/not-heredoc.expect b/t/chainlint/not-heredoc.expect
index 2e9bb135fe..611b7b75cb 100644
--- a/t/chainlint/not-heredoc.expect
+++ b/t/chainlint/not-heredoc.expect
@@ -1,14 +1,14 @@
-echo "<<<<<<< ours" &&
-echo ourside &&
-echo "=======" &&
-echo theirside &&
-echo ">>>>>>> theirs" &&
-
-(
- echo "<<<<<<< ours" &&
- echo ourside &&
- echo "=======" &&
- echo theirside &&
- echo ">>>>>>> theirs" ?!AMP?!
- poodle
-) >merged
+2 echo "<<<<<<< ours" &&
+3 echo ourside &&
+4 echo "=======" &&
+5 echo theirside &&
+6 echo ">>>>>>> theirs" &&
+7
+8 (
+9 echo "<<<<<<< ours" &&
+10 echo ourside &&
+11 echo "=======" &&
+12 echo theirside &&
+13 echo ">>>>>>> theirs" ?!AMP?!
+14 poodle
+15 ) >merged
diff --git a/t/chainlint/not-heredoc.test b/t/chainlint/not-heredoc.test
index 9aa57346cd..09711e45e0 100644
--- a/t/chainlint/not-heredoc.test
+++ b/t/chainlint/not-heredoc.test
@@ -1,3 +1,4 @@
+test_expect_success 'not-heredoc' '
# LINT: "<< ours" inside string is not here-doc
echo "<<<<<<< ours" &&
echo ourside &&
@@ -14,3 +15,4 @@ echo ">>>>>>> theirs" &&
echo ">>>>>>> theirs"
poodle
) >merged
+'
diff --git a/t/chainlint/one-liner-for-loop.expect b/t/chainlint/one-liner-for-loop.expect
index 51a3dc7c54..49dcf065ef 100644
--- a/t/chainlint/one-liner-for-loop.expect
+++ b/t/chainlint/one-liner-for-loop.expect
@@ -1,9 +1,9 @@
-git init dir-rename-and-content &&
-(
- cd dir-rename-and-content &&
- test_write_lines 1 2 3 4 5 >foo &&
- mkdir olddir &&
- for i in a b c; do echo $i >olddir/$i; ?!LOOP?! done ?!AMP?!
- git add foo olddir &&
- git commit -m "original" &&
-)
+2 git init dir-rename-and-content &&
+3 (
+4 cd dir-rename-and-content &&
+5 test_write_lines 1 2 3 4 5 >foo &&
+6 mkdir olddir &&
+7 for i in a b c; do echo $i >olddir/$i; ?!LOOP?! done ?!AMP?!
+8 git add foo olddir &&
+9 git commit -m "original" &&
+10 )
diff --git a/t/chainlint/one-liner-for-loop.test b/t/chainlint/one-liner-for-loop.test
index 4bd8c066c7..00afd7ef76 100644
--- a/t/chainlint/one-liner-for-loop.test
+++ b/t/chainlint/one-liner-for-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'one-liner-for-loop' '
git init dir-rename-and-content &&
(
cd dir-rename-and-content &&
@@ -8,3 +9,4 @@ git init dir-rename-and-content &&
git add foo olddir &&
git commit -m "original" &&
)
+'
diff --git a/t/chainlint/one-liner.expect b/t/chainlint/one-liner.expect
index 57a7a444c1..9861811283 100644
--- a/t/chainlint/one-liner.expect
+++ b/t/chainlint/one-liner.expect
@@ -1,9 +1,9 @@
-(foo && bar) &&
-(foo && bar) |
-(foo && bar) >baz &&
-
-(foo; ?!AMP?! bar) &&
-(foo; ?!AMP?! bar) |
-(foo; ?!AMP?! bar) >baz &&
-
-(foo "bar; baz")
+2 (foo && bar) &&
+3 (foo && bar) |
+4 (foo && bar) >baz &&
+5
+6 (foo; ?!AMP?! bar) &&
+7 (foo; ?!AMP?! bar) |
+8 (foo; ?!AMP?! bar) >baz &&
+9
+10 (foo "bar; baz")
diff --git a/t/chainlint/one-liner.test b/t/chainlint/one-liner.test
index be9858fa29..6e42ee1b5e 100644
--- a/t/chainlint/one-liner.test
+++ b/t/chainlint/one-liner.test
@@ -1,3 +1,4 @@
+test_expect_success 'one-liner' '
# LINT: top-level one-liner subshell
(foo && bar) &&
(foo && bar) |
@@ -10,3 +11,4 @@
# LINT: ";" in string not misinterpreted as broken &&-chain
(foo "bar; baz")
+'
diff --git a/t/chainlint/p4-filespec.expect b/t/chainlint/p4-filespec.expect
index 1290fd1ff2..cff3e4e3d1 100644
--- a/t/chainlint/p4-filespec.expect
+++ b/t/chainlint/p4-filespec.expect
@@ -1,4 +1,4 @@
-(
- p4 print -1 //depot/fiddle#42 >file &&
- foobar
-)
+2 (
+3 p4 print -1 //depot/fiddle#42 >file &&
+4 foobar
+5 )
diff --git a/t/chainlint/p4-filespec.test b/t/chainlint/p4-filespec.test
index 4fd2d6e2b8..8ba6b911dc 100644
--- a/t/chainlint/p4-filespec.test
+++ b/t/chainlint/p4-filespec.test
@@ -1,5 +1,7 @@
+test_expect_success 'p4-filespec' '
(
# LINT: Perforce revspec in filespec not misinterpreted as in-line comment
p4 print -1 //depot/fiddle#42 >file &&
foobar
)
+'
diff --git a/t/chainlint/pipe.expect b/t/chainlint/pipe.expect
index 811971b1a3..1bbe5a2ce1 100644
--- a/t/chainlint/pipe.expect
+++ b/t/chainlint/pipe.expect
@@ -1,10 +1,10 @@
-(
- foo |
- bar |
- baz &&
-
- fish |
- cow ?!AMP?!
-
- sunder
-)
+2 (
+3 foo |
+4 bar |
+5 baz &&
+6
+7 fish |
+8 cow ?!AMP?!
+9
+10 sunder
+11 )
diff --git a/t/chainlint/pipe.test b/t/chainlint/pipe.test
index dd82534c66..1af81c243b 100644
--- a/t/chainlint/pipe.test
+++ b/t/chainlint/pipe.test
@@ -1,3 +1,4 @@
+test_expect_success 'pipe' '
(
# LINT: no "&&" needed on line ending with "|"
foo |
@@ -10,3 +11,4 @@
sunder
)
+'
diff --git a/t/chainlint/return-loop.expect b/t/chainlint/return-loop.expect
index cfc0549bef..da8f9abea3 100644
--- a/t/chainlint/return-loop.expect
+++ b/t/chainlint/return-loop.expect
@@ -1,5 +1,5 @@
-while test $i -lt $((num - 5))
-do
- git notes add -m "notes for commit$i" HEAD~$i || return 1
- i=$((i + 1))
-done
+2 while test $i -lt $((num - 5))
+3 do
+4 git notes add -m "notes for commit$i" HEAD~$i || return 1
+5 i=$((i + 1))
+6 done
diff --git a/t/chainlint/return-loop.test b/t/chainlint/return-loop.test
index f90b171300..ea76c3593a 100644
--- a/t/chainlint/return-loop.test
+++ b/t/chainlint/return-loop.test
@@ -1,6 +1,8 @@
+test_expect_success 'return-loop' '
while test $i -lt $((num - 5))
do
# LINT: "|| return {n}" valid loop escape outside subshell; no "&&" needed
git notes add -m "notes for commit$i" HEAD~$i || return 1
i=$((i + 1))
done
+'
diff --git a/t/chainlint/semicolon.expect b/t/chainlint/semicolon.expect
index 3aa2259f36..866438310c 100644
--- a/t/chainlint/semicolon.expect
+++ b/t/chainlint/semicolon.expect
@@ -1,19 +1,19 @@
-(
- cat foo ; ?!AMP?! echo bar ?!AMP?!
- cat foo ; ?!AMP?! echo bar
-) &&
-(
- cat foo ; ?!AMP?! echo bar &&
- cat foo ; ?!AMP?! echo bar
-) &&
-(
- echo "foo; bar" &&
- cat foo; ?!AMP?! echo bar
-) &&
-(
- foo;
-) &&
-(cd foo &&
- for i in a b c; do
- echo; ?!LOOP?!
- done)
+2 (
+3 cat foo ; ?!AMP?! echo bar ?!AMP?!
+4 cat foo ; ?!AMP?! echo bar
+5 ) &&
+6 (
+7 cat foo ; ?!AMP?! echo bar &&
+8 cat foo ; ?!AMP?! echo bar
+9 ) &&
+10 (
+11 echo "foo; bar" &&
+12 cat foo; ?!AMP?! echo bar
+13 ) &&
+14 (
+15 foo;
+16 ) &&
+17 (cd foo &&
+18 for i in a b c; do
+19 echo; ?!LOOP?!
+20 done)
diff --git a/t/chainlint/semicolon.test b/t/chainlint/semicolon.test
index 67e1192c50..fc0ba1b539 100644
--- a/t/chainlint/semicolon.test
+++ b/t/chainlint/semicolon.test
@@ -1,3 +1,4 @@
+test_expect_success 'semicolon' '
(
# LINT: missing internal "&&" and ending "&&"
cat foo ; echo bar
@@ -23,3 +24,4 @@
# LINT: semicolon unnecessary but legitimate
echo;
done)
+'
diff --git a/t/chainlint/sqstring-in-sqstring.expect b/t/chainlint/sqstring-in-sqstring.expect
index cf0b591cf7..ba5d3c3a6d 100644
--- a/t/chainlint/sqstring-in-sqstring.expect
+++ b/t/chainlint/sqstring-in-sqstring.expect
@@ -1,4 +1,4 @@
-perl -e '
- defined($_ = -s $_) or die for @ARGV;
- exit 1 if $ARGV[0] <= $ARGV[1];
-' test-2-$packname_2.pack test-3-$packname_3.pack
+2 perl -e '
+3 defined($_ = -s $_) or die for @ARGV;
+4 exit 1 if $ARGV[0] <= $ARGV[1];
+5 ' test-2-$packname_2.pack test-3-$packname_3.pack
diff --git a/t/chainlint/sqstring-in-sqstring.test b/t/chainlint/sqstring-in-sqstring.test
index 77a425e0c7..24169724a5 100644
--- a/t/chainlint/sqstring-in-sqstring.test
+++ b/t/chainlint/sqstring-in-sqstring.test
@@ -1,5 +1,7 @@
+test_expect_success 'sqstring-in-sqstring' '
# LINT: SQ-string Perl code fragment within SQ-string
perl -e '\''
defined($_ = -s $_) or die for @ARGV;
exit 1 if $ARGV[0] <= $ARGV[1];
'\'' test-2-$packname_2.pack test-3-$packname_3.pack
+'
diff --git a/t/chainlint/subshell-here-doc.expect b/t/chainlint/subshell-here-doc.expect
index 75d6f607e2..5647500c82 100644
--- a/t/chainlint/subshell-here-doc.expect
+++ b/t/chainlint/subshell-here-doc.expect
@@ -1,30 +1,30 @@
-(
- echo wobba \
- gorgo snoot \
- wafta snurb <<-EOF &&
- quoth the raven,
- nevermore...
- EOF
-
- cat <<EOF >bip ?!AMP?!
- fish fly high
-EOF
-
- echo <<-\EOF >bop
- gomez
- morticia
- wednesday
- pugsly
- EOF
-) &&
-(
- cat <<-\ARBITRARY >bup &&
- glink
- FIZZ
- ARBITRARY
- cat <<-"ARBITRARY3" >bup3 &&
- glink
- FIZZ
- ARBITRARY3
- meep
-)
+2 (
+3 echo wobba \
+4 gorgo snoot \
+5 wafta snurb <<-EOF &&
+6 quoth the raven,
+7 nevermore...
+8 EOF
+9
+10 cat <<EOF >bip ?!AMP?!
+11 fish fly high
+12 EOF
+13
+14 echo <<-\EOF >bop
+15 gomez
+16 morticia
+17 wednesday
+18 pugsly
+19 EOF
+20 ) &&
+21 (
+22 cat <<-\ARBITRARY >bup &&
+23 glink
+24 FIZZ
+25 ARBITRARY
+26 cat <<-"ARBITRARY3" >bup3 &&
+27 glink
+28 FIZZ
+29 ARBITRARY3
+30 meep
+31 )
diff --git a/t/chainlint/subshell-here-doc.test b/t/chainlint/subshell-here-doc.test
index d40eb65583..4a38f47f01 100644
--- a/t/chainlint/subshell-here-doc.test
+++ b/t/chainlint/subshell-here-doc.test
@@ -1,3 +1,4 @@
+test_expect_success 'subshell-here-doc' '
(
# LINT: stitch together incomplete \-ending lines
# LINT: swallow here-doc to avoid false positives in content
@@ -33,3 +34,4 @@ EOF
ARBITRARY3
meep
)
+'
diff --git a/t/chainlint/subshell-one-liner.expect b/t/chainlint/subshell-one-liner.expect
index 8f694990e8..214316c6a0 100644
--- a/t/chainlint/subshell-one-liner.expect
+++ b/t/chainlint/subshell-one-liner.expect
@@ -1,19 +1,19 @@
-(
- (foo && bar) &&
- (foo && bar) |
- (foo && bar) >baz &&
-
- (foo; ?!AMP?! bar) &&
- (foo; ?!AMP?! bar) |
- (foo; ?!AMP?! bar) >baz &&
-
- (foo || exit 1) &&
- (foo || exit 1) |
- (foo || exit 1) >baz &&
-
- (foo && bar) ?!AMP?!
-
- (foo && bar; ?!AMP?! baz) ?!AMP?!
-
- foobar
-)
+2 (
+3 (foo && bar) &&
+4 (foo && bar) |
+5 (foo && bar) >baz &&
+6
+7 (foo; ?!AMP?! bar) &&
+8 (foo; ?!AMP?! bar) |
+9 (foo; ?!AMP?! bar) >baz &&
+10
+11 (foo || exit 1) &&
+12 (foo || exit 1) |
+13 (foo || exit 1) >baz &&
+14
+15 (foo && bar) ?!AMP?!
+16
+17 (foo && bar; ?!AMP?! baz) ?!AMP?!
+18
+19 foobar
+20 )
diff --git a/t/chainlint/subshell-one-liner.test b/t/chainlint/subshell-one-liner.test
index 37fa643c20..dac536afcc 100644
--- a/t/chainlint/subshell-one-liner.test
+++ b/t/chainlint/subshell-one-liner.test
@@ -1,3 +1,4 @@
+test_expect_success 'subshell-one-liner' '
(
# LINT: nested one-liner subshell
(foo && bar) &&
@@ -22,3 +23,4 @@
foobar
)
+'
diff --git a/t/chainlint/t7900-subtree.expect b/t/chainlint/t7900-subtree.expect
index 02f3129232..9e60338bcf 100644
--- a/t/chainlint/t7900-subtree.expect
+++ b/t/chainlint/t7900-subtree.expect
@@ -1,22 +1,22 @@
-(
- chks="sub1
-sub2
-sub3
-sub4" &&
- chks_sub=$(cat <<TXT | sed "s,^,sub dir/,"
-$chks
-TXT
-) &&
- chkms="main-sub1
-main-sub2
-main-sub3
-main-sub4" &&
- chkms_sub=$(cat <<TXT | sed "s,^,sub dir/,"
-$chkms
-TXT
-) &&
-
- subfiles=$(git ls-files) &&
- check_equal "$subfiles" "$chkms
-$chks"
-)
+2 (
+3 chks="sub1
+4 sub2
+5 sub3
+6 sub4" &&
+7 chks_sub=$(cat <<TXT | sed "s,^,sub dir/,"
+8 $chks
+9 TXT
+10 ) &&
+11 chkms="main-sub1
+12 main-sub2
+13 main-sub3
+14 main-sub4" &&
+15 chkms_sub=$(cat <<TXT | sed "s,^,sub dir/,"
+16 $chkms
+17 TXT
+18 ) &&
+19
+20 subfiles=$(git ls-files) &&
+21 check_equal "$subfiles" "$chkms
+22 $chks"
+23 )
diff --git a/t/chainlint/t7900-subtree.test b/t/chainlint/t7900-subtree.test
index 02f3129232..1f4f03300f 100644
--- a/t/chainlint/t7900-subtree.test
+++ b/t/chainlint/t7900-subtree.test
@@ -1,3 +1,4 @@
+test_expect_success 't7900-subtree' '
(
chks="sub1
sub2
@@ -20,3 +21,4 @@ TXT
check_equal "$subfiles" "$chkms
$chks"
)
+'
diff --git a/t/chainlint/token-pasting.expect b/t/chainlint/token-pasting.expect
index 6a387917a7..64f3235d26 100644
--- a/t/chainlint/token-pasting.expect
+++ b/t/chainlint/token-pasting.expect
@@ -1,27 +1,27 @@
-git config filter.rot13.smudge ./rot13.sh &&
-git config filter.rot13.clean ./rot13.sh &&
-
-{
- echo "*.t filter=rot13" ?!AMP?!
- echo "*.i ident"
-} >.gitattributes &&
-
-{
- echo a b c d e f g h i j k l m ?!AMP?!
- echo n o p q r s t u v w x y z ?!AMP?!
- echo '$Id$'
-} >test &&
-cat test >test.t &&
-cat test >test.o &&
-cat test >test.i &&
-git add test test.t test.i &&
-rm -f test test.t test.i &&
-git checkout -- test test.t test.i &&
-
-echo "content-test2" >test2.o &&
-echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?!
-
-downstream_url_for_sed=$(
- printf "%sn" "$downstream_url" |
- sed -e 's/\/\\/g' -e 's/[[/.*^$]/\&/g'
-)
+2 git config filter.rot13.smudge ./rot13.sh &&
+3 git config filter.rot13.clean ./rot13.sh &&
+4
+5 {
+6 echo "*.t filter=rot13" ?!AMP?!
+7 echo "*.i ident"
+8 } >.gitattributes &&
+9
+10 {
+11 echo a b c d e f g h i j k l m ?!AMP?!
+12 echo n o p q r s t u v w x y z ?!AMP?!
+13 echo '$Id$'
+14 } >test &&
+15 cat test >test.t &&
+16 cat test >test.o &&
+17 cat test >test.i &&
+18 git add test test.t test.i &&
+19 rm -f test test.t test.i &&
+20 git checkout -- test test.t test.i &&
+21
+22 echo "content-test2" >test2.o &&
+23 echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?!
+24
+25 downstream_url_for_sed=$(
+26 printf "%sn" "$downstream_url" |
+27 sed -e 's/\/\\/g' -e 's/[[/.*^$]/\&/g'
+28 )
diff --git a/t/chainlint/token-pasting.test b/t/chainlint/token-pasting.test
index b4610ce815..590914b733 100644
--- a/t/chainlint/token-pasting.test
+++ b/t/chainlint/token-pasting.test
@@ -1,3 +1,4 @@
+test_expect_success 'token-pasting' '
# LINT: single token; composite of multiple strings
git config filter.rot13.smudge ./rot13.sh &&
git config filter.rot13.clean ./rot13.sh &&
@@ -30,3 +31,4 @@ downstream_url_for_sed=$(
# LINT: exit/enter string context; "&" inside string not command terminator
sed -e '\''s/\\/\\\\/g'\'' -e '\''s/[[/.*^$]/\\&/g'\''
)
+'
diff --git a/t/chainlint/unclosed-here-doc-indent.expect b/t/chainlint/unclosed-here-doc-indent.expect
index 7c30a1a024..f78e23cb63 100644
--- a/t/chainlint/unclosed-here-doc-indent.expect
+++ b/t/chainlint/unclosed-here-doc-indent.expect
@@ -1,4 +1,4 @@
-command_which_is_run &&
-cat >expect <<-\EOF ?!UNCLOSED-HEREDOC?! &&
-we forget to end the here-doc
-command_which_is_gobbled
+2 command_which_is_run &&
+3 cat >expect <<-\EOF ?!UNCLOSED-HEREDOC?! &&
+4 we forget to end the here-doc
+5 command_which_is_gobbled
diff --git a/t/chainlint/unclosed-here-doc-indent.test b/t/chainlint/unclosed-here-doc-indent.test
index 5c841a9dfd..7ac9d0f7d7 100644
--- a/t/chainlint/unclosed-here-doc-indent.test
+++ b/t/chainlint/unclosed-here-doc-indent.test
@@ -1,4 +1,6 @@
+test_expect_success 'unclosed-here-doc-indent' '
command_which_is_run &&
cat >expect <<-\EOF &&
we forget to end the here-doc
command_which_is_gobbled
+'
diff --git a/t/chainlint/unclosed-here-doc.expect b/t/chainlint/unclosed-here-doc.expect
index d65e50f78d..51304672cf 100644
--- a/t/chainlint/unclosed-here-doc.expect
+++ b/t/chainlint/unclosed-here-doc.expect
@@ -1,7 +1,7 @@
-command_which_is_run &&
-cat >expect <<\EOF ?!UNCLOSED-HEREDOC?! &&
- we try to end the here-doc below,
- but the indentation throws us off
- since the operator is not "<<-".
- EOF
-command_which_is_gobbled
+2 command_which_is_run &&
+3 cat >expect <<\EOF ?!UNCLOSED-HEREDOC?! &&
+4 we try to end the here-doc below,
+5 but the indentation throws us off
+6 since the operator is not "<<-".
+7 EOF
+8 command_which_is_gobbled
diff --git a/t/chainlint/unclosed-here-doc.test b/t/chainlint/unclosed-here-doc.test
index 69d3786c34..68e78f06f3 100644
--- a/t/chainlint/unclosed-here-doc.test
+++ b/t/chainlint/unclosed-here-doc.test
@@ -1,3 +1,4 @@
+test_expect_success 'unclosed-here-doc' '
command_which_is_run &&
cat >expect <<\EOF &&
we try to end the here-doc below,
@@ -5,3 +6,4 @@ cat >expect <<\EOF &&
since the operator is not "<<-".
EOF
command_which_is_gobbled
+'
diff --git a/t/chainlint/while-loop.expect b/t/chainlint/while-loop.expect
index 06c1567f48..5ffabd5a93 100644
--- a/t/chainlint/while-loop.expect
+++ b/t/chainlint/while-loop.expect
@@ -1,14 +1,14 @@
-(
- while true
- do
- echo foo ?!AMP?!
- cat <<-\EOF ?!LOOP?!
- bar
- EOF
- done ?!AMP?!
-
- while true; do
- echo foo &&
- cat bar ?!LOOP?!
- done
-)
+2 (
+3 while true
+4 do
+5 echo foo ?!AMP?!
+6 cat <<-\EOF ?!LOOP?!
+7 bar
+8 EOF
+9 done ?!AMP?!
+10
+11 while true; do
+12 echo foo &&
+13 cat bar ?!LOOP?!
+14 done
+15 )
diff --git a/t/chainlint/while-loop.test b/t/chainlint/while-loop.test
index d09fb016e4..33a201906a 100644
--- a/t/chainlint/while-loop.test
+++ b/t/chainlint/while-loop.test
@@ -1,3 +1,4 @@
+test_expect_success 'while-loop' '
(
# LINT: "while", "do", "done" do not need "&&"
while true
@@ -17,3 +18,4 @@
cat bar
done
)
+'
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index b2b28c2ced..6ee7700eb4 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -49,8 +49,8 @@ while (<>) {
/\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
/\blocal\s+[A-Za-z0-9_]*=\$([A-Za-z0-9_{]|[(][^(])/ and
err q(quote "$val" in 'local var=$val');
- /^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
- err '"FOO=bar shell_func" assignment extends beyond "shell_func"';
+ /\b([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and !/test_env.+=/ and exists($func{$4}) and
+ err '"FOO=bar shell_func" is not portable (use test_env FOO=bar shell_func)';
$line = '';
# this resets our $. for each file
close ARGV if eof;
diff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c
index f7f9b62002..97541daf71 100644
--- a/t/helper/test-bloom.c
+++ b/t/helper/test-bloom.c
@@ -51,6 +51,7 @@ static void get_bloom_filter_for_commit(const struct object_id *commit_oid)
static const char *bloom_usage = "\n"
" test-tool bloom get_murmur3 <string>\n"
+" test-tool bloom get_murmur3_seven_highbit\n"
" test-tool bloom generate_filter <string> [<string>...]\n"
" test-tool bloom get_filter_for_commit <commit-hex>\n";
@@ -65,7 +66,13 @@ int cmd__bloom(int argc, const char **argv)
uint32_t hashed;
if (argc < 3)
usage(bloom_usage);
- hashed = murmur3_seeded(0, argv[2], strlen(argv[2]));
+ hashed = murmur3_seeded_v2(0, argv[2], strlen(argv[2]));
+ printf("Murmur3 Hash with seed=0:0x%08x\n", hashed);
+ }
+
+ if (!strcmp(argv[1], "get_murmur3_seven_highbit")) {
+ uint32_t hashed;
+ hashed = murmur3_seeded_v2(0, "\x99\xaa\xbb\xcc\xdd\xee\xff", 7);
printf("Murmur3 Hash with seed=0:0x%08x\n", hashed);
}
diff --git a/t/helper/test-json-writer.c b/t/helper/test-json-writer.c
index ed52eb76bf..a288069b04 100644
--- a/t/helper/test-json-writer.c
+++ b/t/helper/test-json-writer.c
@@ -415,6 +415,7 @@ static void get_i(struct line *line, intmax_t *s_in)
get_s(line, &s);
+ errno = 0;
*s_in = strtol(s, &endptr, 10);
if (*endptr || errno == ERANGE)
die("line[%d]: invalid integer value", line->nr);
@@ -427,6 +428,7 @@ static void get_d(struct line *line, double *s_in)
get_s(line, &s);
+ errno = 0;
*s_in = strtod(s, &endptr);
if (*endptr || errno == ERANGE)
die("line[%d]: invalid float value", line->nr);
diff --git a/t/helper/test-oidmap.c b/t/helper/test-oidmap.c
deleted file mode 100644
index c03cfa5ecf..0000000000
--- a/t/helper/test-oidmap.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#define USE_THE_REPOSITORY_VARIABLE
-
-#include "test-tool.h"
-#include "hex.h"
-#include "object-name.h"
-#include "oidmap.h"
-#include "repository.h"
-#include "setup.h"
-#include "strbuf.h"
-#include "string-list.h"
-
-/* key is an oid and value is a name (could be a refname for example) */
-struct test_entry {
- struct oidmap_entry entry;
- char name[FLEX_ARRAY];
-};
-
-#define DELIM " \t\r\n"
-
-/*
- * Read stdin line by line and print result of commands to stdout:
- *
- * hash oidkey -> sha1hash(oidkey)
- * put oidkey namevalue -> NULL / old namevalue
- * get oidkey -> NULL / namevalue
- * remove oidkey -> NULL / old namevalue
- * iterate -> oidkey1 namevalue1\noidkey2 namevalue2\n...
- *
- */
-int cmd__oidmap(int argc UNUSED, const char **argv UNUSED)
-{
- struct string_list parts = STRING_LIST_INIT_NODUP;
- struct strbuf line = STRBUF_INIT;
- struct oidmap map = OIDMAP_INIT;
-
- setup_git_directory();
-
- /* init oidmap */
- oidmap_init(&map, 0);
-
- /* process commands from stdin */
- while (strbuf_getline(&line, stdin) != EOF) {
- char *cmd, *p1, *p2;
- struct test_entry *entry;
- struct object_id oid;
-
- /* break line into command and up to two parameters */
- string_list_setlen(&parts, 0);
- string_list_split_in_place(&parts, line.buf, DELIM, 2);
- string_list_remove_empty_items(&parts, 0);
-
- /* ignore empty lines */
- if (!parts.nr)
- continue;
- if (!*parts.items[0].string || *parts.items[0].string == '#')
- continue;
-
- cmd = parts.items[0].string;
- p1 = parts.nr >= 1 ? parts.items[1].string : NULL;
- p2 = parts.nr >= 2 ? parts.items[2].string : NULL;
-
- if (!strcmp("put", cmd) && p1 && p2) {
-
- if (repo_get_oid(the_repository, p1, &oid)) {
- printf("Unknown oid: %s\n", p1);
- continue;
- }
-
- /* create entry with oid_key = p1, name_value = p2 */
- FLEX_ALLOC_STR(entry, name, p2);
- oidcpy(&entry->entry.oid, &oid);
-
- /* add / replace entry */
- entry = oidmap_put(&map, entry);
-
- /* print and free replaced entry, if any */
- puts(entry ? entry->name : "NULL");
- free(entry);
-
- } else if (!strcmp("get", cmd) && p1) {
-
- if (repo_get_oid(the_repository, p1, &oid)) {
- printf("Unknown oid: %s\n", p1);
- continue;
- }
-
- /* lookup entry in oidmap */
- entry = oidmap_get(&map, &oid);
-
- /* print result */
- puts(entry ? entry->name : "NULL");
-
- } else if (!strcmp("remove", cmd) && p1) {
-
- if (repo_get_oid(the_repository, p1, &oid)) {
- printf("Unknown oid: %s\n", p1);
- continue;
- }
-
- /* remove entry from oidmap */
- entry = oidmap_remove(&map, &oid);
-
- /* print result and free entry*/
- puts(entry ? entry->name : "NULL");
- free(entry);
-
- } else if (!strcmp("iterate", cmd)) {
-
- struct oidmap_iter iter;
- oidmap_iter_init(&map, &iter);
- while ((entry = oidmap_iter_next(&iter)))
- printf("%s %s\n", oid_to_hex(&entry->entry.oid), entry->name);
-
- } else {
-
- printf("Unknown command %s\n", cmd);
-
- }
- }
-
- string_list_clear(&parts, 0);
- strbuf_release(&line);
- oidmap_free(&map, 1);
- return 0;
-}
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index ded8116cc5..5250913d99 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -207,6 +207,7 @@ int cmd__parse_options(int argc, const char **argv)
expect.strdup_strings = 1;
string_list_clear(&expect, 0);
string_list_clear(&list, 0);
+ free(file);
return ret;
}
diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c
index d9e980d04c..9018c9f541 100644
--- a/t/helper/test-read-graph.c
+++ b/t/helper/test-read-graph.c
@@ -7,20 +7,8 @@
#include "bloom.h"
#include "setup.h"
-int cmd__read_graph(int argc UNUSED, const char **argv UNUSED)
+static void dump_graph_info(struct commit_graph *graph)
{
- struct commit_graph *graph = NULL;
- struct object_directory *odb;
-
- setup_git_directory();
- odb = the_repository->objects->odb;
-
- prepare_repo_settings(the_repository);
-
- graph = read_commit_graph_one(the_repository, odb);
- if (!graph)
- return 1;
-
printf("header: %08x %d %d %d %d\n",
ntohl(*(uint32_t*)graph->data),
*(unsigned char*)(graph->data + 4),
@@ -59,8 +47,57 @@ int cmd__read_graph(int argc UNUSED, const char **argv UNUSED)
if (graph->topo_levels)
printf(" topo_levels");
printf("\n");
+}
+
+static void dump_graph_bloom_filters(struct commit_graph *graph)
+{
+ uint32_t i;
+
+ for (i = 0; i < graph->num_commits + graph->num_commits_in_base; i++) {
+ struct bloom_filter filter = { 0 };
+ size_t j;
+
+ if (load_bloom_filter_from_graph(graph, &filter, i) < 0) {
+ fprintf(stderr, "missing Bloom filter for graph "
+ "position %"PRIu32"\n", i);
+ continue;
+ }
+
+ for (j = 0; j < filter.len; j++)
+ printf("%02x", filter.data[j]);
+ if (filter.len)
+ printf("\n");
+ }
+}
+
+int cmd__read_graph(int argc, const char **argv)
+{
+ struct commit_graph *graph = NULL;
+ struct object_directory *odb;
+ int ret = 0;
+
+ setup_git_directory();
+ odb = the_repository->objects->odb;
+
+ prepare_repo_settings(the_repository);
+
+ graph = read_commit_graph_one(the_repository, odb);
+ if (!graph) {
+ ret = 1;
+ goto done;
+ }
+
+ if (argc <= 1)
+ dump_graph_info(graph);
+ else if (!strcmp(argv[1], "bloom-filters"))
+ dump_graph_bloom_filters(graph);
+ else {
+ fprintf(stderr, "unknown sub-command: '%s'\n", argv[1]);
+ ret = 1;
+ }
+done:
UNLEAK(graph);
- return 0;
+ return ret;
}
diff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c
index 9160bc5da6..623cf3f0f5 100644
--- a/t/helper/test-reftable.c
+++ b/t/helper/test-reftable.c
@@ -5,12 +5,8 @@
int cmd__reftable(int argc, const char **argv)
{
/* test from simple to complex. */
- record_test_main(argc, argv);
block_test_main(argc, argv);
- tree_test_main(argc, argv);
- pq_test_main(argc, argv);
readwrite_test_main(argc, argv);
- merged_test_main(argc, argv);
stack_test_main(argc, argv);
return 0;
}
diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c
index c6a074df3d..63c37de33d 100644
--- a/t/helper/test-repository.c
+++ b/t/helper/test-repository.c
@@ -19,7 +19,7 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
setup_git_env(gitdir);
- memset(the_repository, 0, sizeof(*the_repository));
+ repo_clear(the_repository);
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
@@ -49,7 +49,7 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
setup_git_env(gitdir);
- memset(the_repository, 0, sizeof(*the_repository));
+ repo_clear(the_repository);
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 93436a82ae..da3e69128a 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -44,7 +44,6 @@ static struct test_cmd cmds[] = {
{ "mergesort", cmd__mergesort },
{ "mktemp", cmd__mktemp },
{ "oid-array", cmd__oid_array },
- { "oidmap", cmd__oidmap },
{ "online-cpus", cmd__online_cpus },
{ "pack-mtimes", cmd__pack_mtimes },
{ "parse-options", cmd__parse_options },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index d9033d14e1..642a34578c 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -37,7 +37,6 @@ int cmd__lazy_init_name_hash(int argc, const char **argv);
int cmd__match_trees(int argc, const char **argv);
int cmd__mergesort(int argc, const char **argv);
int cmd__mktemp(int argc, const char **argv);
-int cmd__oidmap(int argc, const char **argv);
int cmd__online_cpus(int argc, const char **argv);
int cmd__pack_mtimes(int argc, const char **argv);
int cmd__parse_options(int argc, const char **argv);
diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c
index cd955ec63e..c588c273ce 100644
--- a/t/helper/test-trace2.c
+++ b/t/helper/test-trace2.c
@@ -26,6 +26,7 @@ static int get_i(int *p_value, const char *data)
if (!data || !*data)
return MyError;
+ errno = 0;
*p_value = strtol(data, &endptr, 10);
if (*endptr || errno == ERANGE)
return MyError;
diff --git a/t/lib-bundle-uri-protocol.sh b/t/lib-bundle-uri-protocol.sh
index a4a1af8d02..de09b6b02e 100644
--- a/t/lib-bundle-uri-protocol.sh
+++ b/t/lib-bundle-uri-protocol.sh
@@ -18,7 +18,7 @@ git)
start_git_daemon --export-all --enable=receive-pack
BUNDLE_URI_PARENT="$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent"
BUNDLE_URI_REPO_URI="$GIT_DAEMON_URL/parent"
- BUNDLE_URI_BUNDLE_URI="https://example.com/fake.bdl"
+ BUNDLE_URI_BUNDLE_URI="$BUNDLE_URI_REPO_URI/fake.bdl"
test_set_prereq BUNDLE_URI_GIT
;;
http)
@@ -26,7 +26,7 @@ http)
start_httpd
BUNDLE_URI_PARENT="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"
BUNDLE_URI_REPO_URI="$HTTPD_URL/smart/http_parent"
- BUNDLE_URI_BUNDLE_URI="https://example.com/fake.bdl"
+ BUNDLE_URI_BUNDLE_URI="$BUNDLE_URI_REPO_URL/fake.bdl"
test_set_prereq BUNDLE_URI_HTTP
;;
*)
diff --git a/t/socks4-proxy.pl b/t/socks4-proxy.pl
new file mode 100644
index 0000000000..4c3a35c008
--- /dev/null
+++ b/t/socks4-proxy.pl
@@ -0,0 +1,48 @@
+use strict;
+use IO::Select;
+use IO::Socket::UNIX;
+use IO::Socket::INET;
+
+my $path = shift;
+
+unlink($path);
+my $server = IO::Socket::UNIX->new(Listen => 1, Local => $path)
+ or die "unable to listen on $path: $!";
+
+$| = 1;
+print "ready\n";
+
+while (my $client = $server->accept()) {
+ sysread $client, my $buf, 8;
+ my ($version, $cmd, $port, $ip) = unpack 'CCnN', $buf;
+ next unless $version == 4; # socks4
+ next unless $cmd == 1; # TCP stream connection
+
+ # skip NUL-terminated id
+ while (sysread $client, my $char, 1) {
+ last unless ord($char);
+ }
+
+ # version(0), reply(5a == granted), port (ignored), ip (ignored)
+ syswrite $client, "\x00\x5a\x00\x00\x00\x00\x00\x00";
+
+ my $remote = IO::Socket::INET->new(PeerHost => $ip, PeerPort => $port)
+ or die "unable to connect to $ip/$port: $!";
+
+ my $io = IO::Select->new($client, $remote);
+ while ($io->count) {
+ for my $fh ($io->can_read(0)) {
+ for my $pair ([$client, $remote], [$remote, $client]) {
+ my ($from, $to) = @$pair;
+ next unless $fh == $from;
+
+ my $r = sysread $from, my $buf, 1024;
+ if (!defined $r || $r <= 0) {
+ $io->remove($from);
+ next;
+ }
+ syswrite $to, $buf;
+ }
+ }
+ }
+}
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 3031256d14..fd373e1b39 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -8,6 +8,11 @@ TEST_PASSES_SANITIZE_LEAK=true
# arbitrary reference time: 2009-08-30 19:20:00
GIT_TEST_DATE_NOW=1251660000; export GIT_TEST_DATE_NOW
+if test_have_prereq TIME_IS_64BIT,TIME_T_IS_64BIT
+then
+ test_set_prereq HAVE_64BIT_TIME
+fi
+
check_relative() {
t=$(($GIT_TEST_DATE_NOW - $1))
echo "$t -> $2" >expect
@@ -80,14 +85,15 @@ check_show raw "$TIME" '1466000000 -0200'
# arbitrary time absurdly far in the future
FUTURE="5758122296 -0400"
-check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" TIME_IS_64BIT,TIME_T_IS_64BIT
-check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" TIME_IS_64BIT,TIME_T_IS_64BIT
+check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" HAVE_64BIT_TIME
+check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" HAVE_64BIT_TIME
-check_parse() {
+REQUIRE_64BIT_TIME=
+check_parse () {
echo "$1 -> $2" >expect
- test_expect_${4:-success} "parse date ($1${3:+ TZ=$3})" "
- TZ=${3:-$TZ} test-tool date parse '$1' >actual &&
- test_cmp expect actual
+ test_expect_success $REQUIRE_64BIT_TIME "parse date ($1${3:+ TZ=$3}) -> $2" "
+ TZ=${3:-$TZ} test-tool date parse '$1' >actual &&
+ test_cmp expect actual
"
}
@@ -117,6 +123,39 @@ check_parse '2008-02-14 20:30:45 -05:00' '2008-02-14 20:30:45 -0500'
check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5
check_parse 'Thu, 7 Apr 2005 15:14:13 -0700' '2005-04-07 15:14:13 -0700'
+check_parse '1970-01-01 00:00:00' '1970-01-01 00:00:00 +0000'
+check_parse '1970-01-01 00:00:00 +00' '1970-01-01 00:00:00 +0000'
+check_parse '1970-01-01 00:00:00 Z' '1970-01-01 00:00:00 +0000'
+check_parse '1970-01-01 00:00:00 -01' '1970-01-01 00:00:00 -0100'
+check_parse '1970-01-01 00:00:00 +01' bad
+check_parse '1970-01-01 00:00:00 +11' bad
+check_parse '1970-01-01 00:59:59 +01' bad
+check_parse '1970-01-01 01:00:00 +01' '1970-01-01 01:00:00 +0100'
+check_parse '1970-01-01 01:00:00 +11' bad
+check_parse '1970-01-02 00:00:00 +11' '1970-01-02 00:00:00 +1100'
+check_parse '1969-12-31 23:59:59' bad
+check_parse '1969-12-31 23:59:59 +00' bad
+check_parse '1969-12-31 23:59:59 Z' bad
+check_parse '1969-12-31 23:59:59 +11' bad
+check_parse '1969-12-31 23:59:59 -11' bad
+
+REQUIRE_64BIT_TIME=HAVE_64BIT_TIME
+check_parse '2099-12-31 23:59:59' '2099-12-31 23:59:59 +0000'
+check_parse '2099-12-31 23:59:59 +00' '2099-12-31 23:59:59 +0000'
+check_parse '2099-12-31 23:59:59 Z' '2099-12-31 23:59:59 +0000'
+check_parse '2099-12-31 23:59:59 +01' '2099-12-31 23:59:59 +0100'
+check_parse '2099-12-31 23:59:59 -01' bad
+check_parse '2099-12-31 23:59:59 -11' bad
+check_parse '2099-12-31 23:00:00 -01' bad
+check_parse '2099-12-31 22:59:59 -01' '2099-12-31 22:59:59 -0100'
+check_parse '2100-00-00 00:00:00' bad
+check_parse '2099-12-30 00:00:00 -11' '2099-12-30 00:00:00 -1100'
+check_parse '2100-00-00 00:00:00 +00' bad
+check_parse '2100-00-00 00:00:00 Z' bad
+check_parse '2100-00-00 00:00:00 -11' bad
+check_parse '2100-00-00 00:00:00 +11' bad
+REQUIRE_64BIT_TIME=
+
check_approxidate() {
echo "$1 -> $2 +0000" >expect
test_expect_${3:-success} "parse approxidate ($1)" "
diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh
index ff4fd9348c..9fc5882387 100755
--- a/t/t0007-git-var.sh
+++ b/t/t0007-git-var.sh
@@ -157,7 +157,7 @@ test_expect_success POSIXPERM 'GIT_SHELL_PATH points to a valid executable' '
test_expect_success MINGW 'GIT_SHELL_PATH points to a suitable shell' '
shellpath=$(git var GIT_SHELL_PATH) &&
case "$shellpath" in
- *sh) ;;
+ [A-Z]:/*/sh.exe) test -f "$shellpath";;
*) return 1;;
esac
'
diff --git a/t/t0016-oidmap.sh b/t/t0016-oidmap.sh
deleted file mode 100755
index 0faef1f4f1..0000000000
--- a/t/t0016-oidmap.sh
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/sh
-
-test_description='test oidmap'
-
-TEST_PASSES_SANITIZE_LEAK=true
-. ./test-lib.sh
-
-# This purposefully is very similar to t0011-hashmap.sh
-
-test_oidmap () {
- echo "$1" | test-tool oidmap $3 >actual &&
- echo "$2" >expect &&
- test_cmp expect actual
-}
-
-
-test_expect_success 'setup' '
-
- test_commit one &&
- test_commit two &&
- test_commit three &&
- test_commit four
-
-'
-
-test_expect_success 'put' '
-
-test_oidmap "put one 1
-put two 2
-put invalidOid 4
-put three 3" "NULL
-NULL
-Unknown oid: invalidOid
-NULL"
-
-'
-
-test_expect_success 'replace' '
-
-test_oidmap "put one 1
-put two 2
-put three 3
-put invalidOid 4
-put two deux
-put one un" "NULL
-NULL
-NULL
-Unknown oid: invalidOid
-2
-1"
-
-'
-
-test_expect_success 'get' '
-
-test_oidmap "put one 1
-put two 2
-put three 3
-get two
-get four
-get invalidOid
-get one" "NULL
-NULL
-NULL
-2
-NULL
-Unknown oid: invalidOid
-1"
-
-'
-
-test_expect_success 'remove' '
-
-test_oidmap "put one 1
-put two 2
-put three 3
-remove one
-remove two
-remove invalidOid
-remove four" "NULL
-NULL
-NULL
-1
-2
-Unknown oid: invalidOid
-NULL"
-
-'
-
-test_expect_success 'iterate' '
- test-tool oidmap >actual.raw <<-\EOF &&
- put one 1
- put two 2
- put three 3
- iterate
- EOF
-
- # sort "expect" too so we do not rely on the order of particular oids
- sort >expect <<-EOF &&
- NULL
- NULL
- NULL
- $(git rev-parse one) 1
- $(git rev-parse two) 2
- $(git rev-parse three) 3
- EOF
-
- sort <actual.raw >actual &&
- test_cmp expect actual
-'
-
-test_done
diff --git a/t/t0018-advice.sh b/t/t0018-advice.sh
index 29306b367c..fac52322a7 100755
--- a/t/t0018-advice.sh
+++ b/t/t0018-advice.sh
@@ -96,7 +96,6 @@ test_expect_success 'advice should be printed when GIT_ADVICE is set to true' '
>README &&
GIT_ADVICE=true git status
) >actual &&
- cat actual > /tmp/actual &&
test_cmp expect actual
'
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index 0b4997022b..eeb2714d9d 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -5,6 +5,7 @@ test_description='blob conversion via gitattributes'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh
index 5fe61f1291..e97a84764f 100755
--- a/t/t0033-safe-directory.sh
+++ b/t/t0033-safe-directory.sh
@@ -119,4 +119,182 @@ test_expect_success 'local clone of unowned repo accepted in safe directory' '
test_path_is_dir target
'
+test_expect_success SYMLINKS 'checked paths are normalized' '
+ test_when_finished "rm -rf repository; rm -f repo" &&
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global --unset-all safe.directory
+ ) &&
+ git init repository &&
+ ln -s repository repo &&
+ (
+ cd repository &&
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ test_commit sample
+ ) &&
+
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global safe.directory "$(pwd)/repository"
+ ) &&
+ git -C repository for-each-ref &&
+ git -C repository/ for-each-ref &&
+ git -C repo for-each-ref &&
+ git -C repo/ for-each-ref &&
+ test_must_fail git -C repository/.git for-each-ref &&
+ test_must_fail git -C repository/.git/ for-each-ref &&
+ test_must_fail git -C repo/.git for-each-ref &&
+ test_must_fail git -C repo/.git/ for-each-ref
+'
+
+test_expect_success SYMLINKS 'checked leading paths are normalized' '
+ test_when_finished "rm -rf repository; rm -f repo" &&
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global --unset-all safe.directory
+ ) &&
+ mkdir -p repository &&
+ git init repository/s &&
+ ln -s repository repo &&
+ (
+ cd repository/s &&
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ test_commit sample
+ ) &&
+
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global safe.directory "$(pwd)/repository/*"
+ ) &&
+ git -C repository/s for-each-ref &&
+ git -C repository/s/ for-each-ref &&
+ git -C repo/s for-each-ref &&
+ git -C repo/s/ for-each-ref &&
+ git -C repository/s/.git for-each-ref &&
+ git -C repository/s/.git/ for-each-ref &&
+ git -C repo/s/.git for-each-ref &&
+ git -C repo/s/.git/ for-each-ref
+'
+
+test_expect_success SYMLINKS 'configured paths are normalized' '
+ test_when_finished "rm -rf repository; rm -f repo" &&
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global --unset-all safe.directory
+ ) &&
+ git init repository &&
+ ln -s repository repo &&
+ (
+ cd repository &&
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ test_commit sample
+ ) &&
+
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global safe.directory "$(pwd)/repo"
+ ) &&
+ git -C repository for-each-ref &&
+ git -C repository/ for-each-ref &&
+ git -C repo for-each-ref &&
+ git -C repo/ for-each-ref &&
+ test_must_fail git -C repository/.git for-each-ref &&
+ test_must_fail git -C repository/.git/ for-each-ref &&
+ test_must_fail git -C repo/.git for-each-ref &&
+ test_must_fail git -C repo/.git/ for-each-ref
+'
+
+test_expect_success SYMLINKS 'configured leading paths are normalized' '
+ test_when_finished "rm -rf repository; rm -f repo" &&
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global --unset-all safe.directory
+ ) &&
+ mkdir -p repository &&
+ git init repository/s &&
+ ln -s repository repo &&
+ (
+ cd repository/s &&
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ test_commit sample
+ ) &&
+
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global safe.directory "$(pwd)/repo/*"
+ ) &&
+ git -C repository/s for-each-ref &&
+ git -C repository/s/ for-each-ref &&
+ git -C repository/s/.git for-each-ref &&
+ git -C repository/s/.git/ for-each-ref &&
+ git -C repo/s for-each-ref &&
+ git -C repo/s/ for-each-ref &&
+ git -C repo/s/.git for-each-ref &&
+ git -C repo/s/.git/ for-each-ref
+'
+
+test_expect_success 'safe.directory set to a dot' '
+ test_when_finished "rm -rf repository" &&
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global --unset-all safe.directory
+ ) &&
+ mkdir -p repository/subdir &&
+ git init repository &&
+ (
+ cd repository &&
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ test_commit sample
+ ) &&
+
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global safe.directory "."
+ ) &&
+ git -C repository for-each-ref &&
+ git -C repository/ for-each-ref &&
+ git -C repository/.git for-each-ref &&
+ git -C repository/.git/ for-each-ref &&
+
+ # What is allowed is repository/subdir but the repository
+ # path is repository.
+ test_must_fail git -C repository/subdir for-each-ref &&
+
+ # Likewise, repository .git/refs is allowed with "." but
+ # repository/.git that is accessed is not allowed.
+ test_must_fail git -C repository/.git/refs for-each-ref
+'
+
+test_expect_success 'safe.directory set to asterisk' '
+ test_when_finished "rm -rf repository" &&
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global --unset-all safe.directory
+ ) &&
+ mkdir -p repository/subdir &&
+ git init repository &&
+ (
+ cd repository &&
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ test_commit sample
+ ) &&
+
+ (
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config --global safe.directory "*"
+ ) &&
+ # these are trivial
+ git -C repository for-each-ref &&
+ git -C repository/ for-each-ref &&
+ git -C repository/.git for-each-ref &&
+ git -C repository/.git/ for-each-ref &&
+
+ # With "*", everything is allowed, and the repository is
+ # discovered, which is different behaviour from "." above.
+ git -C repository/subdir for-each-ref &&
+
+ # Likewise.
+ git -C repository/.git/refs for-each-ref
+'
+
test_done
diff --git a/t/t0095-bloom.sh b/t/t0095-bloom.sh
index b567383eb8..c8d84ab606 100755
--- a/t/t0095-bloom.sh
+++ b/t/t0095-bloom.sh
@@ -29,6 +29,14 @@ test_expect_success 'compute unseeded murmur3 hash for test string 2' '
test_cmp expect actual
'
+test_expect_success 'compute unseeded murmur3 hash for test string 3' '
+ cat >expect <<-\EOF &&
+ Murmur3 Hash with seed=0:0xa183ccfd
+ EOF
+ test-tool bloom get_murmur3_seven_highbit >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'compute bloom key for empty string' '
cat >expect <<-\EOF &&
Hashes:0x5615800c|0x5b966560|0x61174ab4|0x66983008|0x6c19155c|0x7199fab0|0x771ae004|
diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
index c10e35905e..5d5b64205f 100755
--- a/t/t0301-credential-cache.sh
+++ b/t/t0301-credential-cache.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='credential-cache tests'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-credential.sh
diff --git a/t/t0302-credential-store.sh b/t/t0302-credential-store.sh
index 716bf1af9f..f83db659e2 100755
--- a/t/t0302-credential-store.sh
+++ b/t/t0302-credential-store.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='credential-store tests'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-credential.sh
diff --git a/t/t0303-credential-external.sh b/t/t0303-credential-external.sh
index 72ae405c3e..8aadbe86c4 100755
--- a/t/t0303-credential-external.sh
+++ b/t/t0303-credential-external.sh
@@ -29,6 +29,7 @@ you can set GIT_TEST_CREDENTIAL_HELPER_SETUP to a sequence of shell
commands.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-credential.sh
diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh
index b2a771ff2b..20df336cc3 100755
--- a/t/t0600-reffiles-backend.sh
+++ b/t/t0600-reffiles-backend.sh
@@ -91,82 +91,82 @@ test_expect_success 'empty directory should not fool 1-arg delete' '
git update-ref --stdin
'
-test_expect_success 'non-empty directory blocks create' '
+test_expect_success 'non-empty directory blocks create' - <<\EOT
prefix=refs/ne-create &&
mkdir -p .git/$prefix/foo/bar &&
: >.git/$prefix/foo/bar/baz.lock &&
test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ
+ fatal: cannot lock ref '$prefix/foo': there is a non-empty directory '.git/$prefix/foo' blocking reference '$prefix/foo'
EOF
printf "%s\n" "update $prefix/foo $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
+ fatal: cannot lock ref '$prefix/foo': unable to resolve reference '$prefix/foo'
EOF
printf "%s\n" "update $prefix/foo $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'broken reference blocks create' '
+test_expect_success 'broken reference blocks create' - <<\EOT
prefix=refs/broken-create &&
mkdir -p .git/$prefix &&
echo "gobbledigook" >.git/$prefix/foo &&
test_when_finished "rm -f .git/$prefix/foo" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
+ fatal: cannot lock ref '$prefix/foo': unable to resolve reference '$prefix/foo': reference broken
EOF
printf "%s\n" "update $prefix/foo $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
+ fatal: cannot lock ref '$prefix/foo': unable to resolve reference '$prefix/foo': reference broken
EOF
printf "%s\n" "update $prefix/foo $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'non-empty directory blocks indirect create' '
+test_expect_success 'non-empty directory blocks indirect create' - <<\EOT
prefix=refs/ne-indirect-create &&
git symbolic-ref $prefix/symref $prefix/foo &&
mkdir -p .git/$prefix/foo/bar &&
: >.git/$prefix/foo/bar/baz.lock &&
test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ
+ fatal: cannot lock ref '$prefix/symref': there is a non-empty directory '.git/$prefix/foo' blocking reference '$prefix/foo'
EOF
printf "%s\n" "update $prefix/symref $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
+ fatal: cannot lock ref '$prefix/symref': unable to resolve reference '$prefix/foo'
EOF
printf "%s\n" "update $prefix/symref $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'broken reference blocks indirect create' '
+test_expect_success 'broken reference blocks indirect create' - <<\EOT
prefix=refs/broken-indirect-create &&
git symbolic-ref $prefix/symref $prefix/foo &&
echo "gobbledigook" >.git/$prefix/foo &&
test_when_finished "rm -f .git/$prefix/foo" &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
+ fatal: cannot lock ref '$prefix/symref': unable to resolve reference '$prefix/foo': reference broken
EOF
printf "%s\n" "update $prefix/symref $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken
+ fatal: cannot lock ref '$prefix/symref': unable to resolve reference '$prefix/foo': reference broken
EOF
printf "%s\n" "update $prefix/symref $D $C" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
test_expect_success 'no bogus intermediate values during delete' '
prefix=refs/slow-transaction &&
@@ -224,7 +224,7 @@ test_expect_success 'no bogus intermediate values during delete' '
test_must_fail git rev-parse --verify --quiet $prefix/foo
'
-test_expect_success 'delete fails cleanly if packed-refs file is locked' '
+test_expect_success 'delete fails cleanly if packed-refs file is locked' - <<\EOT
prefix=refs/locked-packed-refs &&
# Set up a reference with differing loose and packed versions:
git update-ref $prefix/foo $C &&
@@ -236,9 +236,9 @@ test_expect_success 'delete fails cleanly if packed-refs file is locked' '
test_when_finished "rm -f .git/packed-refs.lock" &&
test_must_fail git update-ref -d $prefix/foo >out 2>err &&
git for-each-ref $prefix >actual &&
- test_grep "Unable to create $SQ.*packed-refs.lock$SQ: " err &&
+ test_grep "Unable to create '.*packed-refs.lock': " err &&
test_cmp unchanged actual
-'
+EOT
test_expect_success 'delete fails cleanly if packed-refs.new write fails' '
# Setup and expectations are similar to the test above.
diff --git a/t/t0612-reftable-jgit-compatibility.sh b/t/t0612-reftable-jgit-compatibility.sh
index d0d7e80b49..84922153ab 100755
--- a/t/t0612-reftable-jgit-compatibility.sh
+++ b/t/t0612-reftable-jgit-compatibility.sh
@@ -11,6 +11,7 @@ export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_SPLIT_INDEX=0
export GIT_TEST_SPLIT_INDEX
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
if ! test_have_prereq JGIT
diff --git a/t/t0613-reftable-write-options.sh b/t/t0613-reftable-write-options.sh
index e2708e11d5..b1c6c97524 100755
--- a/t/t0613-reftable-write-options.sh
+++ b/t/t0613-reftable-write-options.sh
@@ -16,6 +16,7 @@ export GIT_TEST_DEFAULT_HASH
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'default write options' '
diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh
index 11bf10424f..2b9720b0fe 100755
--- a/t/t1004-read-tree-m-u-wf.sh
+++ b/t/t1004-read-tree-m-u-wf.sh
@@ -5,6 +5,7 @@ test_description='read-tree -m -u checks working tree files'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-read-tree.sh
diff --git a/t/t1015-read-index-unmerged.sh b/t/t1015-read-index-unmerged.sh
index 55d22da32c..da737a32a2 100755
--- a/t/t1015-read-index-unmerged.sh
+++ b/t/t1015-read-index-unmerged.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='Test various callers of read_index_unmerged'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup modify/delete + directory/file conflict' '
diff --git a/t/t1021-rerere-in-workdir.sh b/t/t1021-rerere-in-workdir.sh
index 0b892894eb..69bf9476cb 100755
--- a/t/t1021-rerere-in-workdir.sh
+++ b/t/t1021-rerere-in-workdir.sh
@@ -4,6 +4,7 @@ test_description='rerere run in a workdir'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success SYMLINKS setup '
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 2f1ae5fd3b..a2c0e1b4dc 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -159,7 +159,10 @@ init_repos () {
git -C sparse-checkout sparse-checkout set deep &&
git -C sparse-index sparse-checkout init --cone --sparse-index &&
test_cmp_config -C sparse-index true index.sparse &&
- git -C sparse-index sparse-checkout set deep
+ git -C sparse-index sparse-checkout set deep &&
+
+ # Disable this message to keep stderr the same.
+ git -C sparse-index config advice.sparseIndexExpanded false
}
init_repos_as_submodules () {
@@ -2331,4 +2334,15 @@ test_expect_success 'sparse-index is not expanded: check-attr' '
ensure_not_expanded check-attr -a --cached -- folder1/a
'
+test_expect_success 'advice.sparseIndexExpanded' '
+ init_repos &&
+
+ git -C sparse-index config --unset advice.sparseIndexExpanded &&
+ git -C sparse-index sparse-checkout set deep/deeper1 &&
+ mkdir -p sparse-index/deep/deeper2/deepest &&
+ touch sparse-index/deep/deeper2/deepest/bogus &&
+ git -C sparse-index status 2>err &&
+ grep "The sparse index is expanding to a full index" err
+'
+
test_done
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 9de2d95f06..f13277c8f3 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -2704,6 +2704,15 @@ test_expect_success '--get and --get-all with --fixed-value' '
test_must_fail git config --file=config --get-regexp --fixed-value fixed+ non-existent
'
+test_expect_success '--fixed-value with value-less configuration' '
+ test_when_finished rm -f config &&
+ cat >config <<-\EOF &&
+ [section]
+ key
+ EOF
+ git config --file=config --fixed-value section.key value pattern
+'
+
test_expect_success 'includeIf.hasconfig:remote.*.url' '
git init hasremoteurlTest &&
test_when_finished "rm -rf hasremoteurlTest" &&
diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index 67ebd81a4c..df90112618 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -100,13 +100,13 @@ df_test() {
printf "%s\n" "delete $delname" "create $addname $D"
fi >commands &&
test_must_fail git update-ref --stdin <commands 2>output.err &&
- grep -E "fatal:( cannot lock ref $SQ$addname$SQ:)? $SQ$delref$SQ exists; cannot create $SQ$addref$SQ" output.err &&
+ grep -E "fatal:( cannot lock ref '$addname':)? '$delref' exists; cannot create '$addref'" output.err &&
printf "%s\n" "$C $delref" >expected-refs &&
git for-each-ref --format="%(objectname) %(refname)" $prefix/r >actual-refs &&
test_cmp expected-refs actual-refs
}
-test_expect_success 'setup' '
+test_expect_success 'setup' - <<\EOT
git commit --allow-empty -m Initial &&
C=$(git rev-parse HEAD) &&
@@ -114,283 +114,283 @@ test_expect_success 'setup' '
D=$(git rev-parse HEAD) &&
git commit --allow-empty -m Third &&
E=$(git rev-parse HEAD)
-'
+EOT
-test_expect_success 'existing loose ref is a simple prefix of new' '
+test_expect_success 'existing loose ref is a simple prefix of new' - <<\EOT
prefix=refs/1l &&
test_update_rejected "a c e" false "b c/x d" \
- "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
+ "'$prefix/c' exists; cannot create '$prefix/c/x'"
-'
+EOT
-test_expect_success 'existing packed ref is a simple prefix of new' '
+test_expect_success 'existing packed ref is a simple prefix of new' - <<\EOT
prefix=refs/1p &&
test_update_rejected "a c e" true "b c/x d" \
- "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
+ "'$prefix/c' exists; cannot create '$prefix/c/x'"
-'
+EOT
-test_expect_success 'existing loose ref is a deeper prefix of new' '
+test_expect_success 'existing loose ref is a deeper prefix of new' - <<\EOT
prefix=refs/2l &&
test_update_rejected "a c e" false "b c/x/y d" \
- "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
+ "'$prefix/c' exists; cannot create '$prefix/c/x/y'"
-'
+EOT
-test_expect_success 'existing packed ref is a deeper prefix of new' '
+test_expect_success 'existing packed ref is a deeper prefix of new' - <<\EOT
prefix=refs/2p &&
test_update_rejected "a c e" true "b c/x/y d" \
- "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
+ "'$prefix/c' exists; cannot create '$prefix/c/x/y'"
-'
+EOT
-test_expect_success 'new ref is a simple prefix of existing loose' '
+test_expect_success 'new ref is a simple prefix of existing loose' - <<\EOT
prefix=refs/3l &&
test_update_rejected "a c/x e" false "b c d" \
- "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
+ "'$prefix/c/x' exists; cannot create '$prefix/c'"
-'
+EOT
-test_expect_success 'new ref is a simple prefix of existing packed' '
+test_expect_success 'new ref is a simple prefix of existing packed' - <<\EOT
prefix=refs/3p &&
test_update_rejected "a c/x e" true "b c d" \
- "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
+ "'$prefix/c/x' exists; cannot create '$prefix/c'"
-'
+EOT
-test_expect_success 'new ref is a deeper prefix of existing loose' '
+test_expect_success 'new ref is a deeper prefix of existing loose' - <<\EOT
prefix=refs/4l &&
test_update_rejected "a c/x/y e" false "b c d" \
- "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
+ "'$prefix/c/x/y' exists; cannot create '$prefix/c'"
-'
+EOT
-test_expect_success 'new ref is a deeper prefix of existing packed' '
+test_expect_success 'new ref is a deeper prefix of existing packed' - <<\EOT
prefix=refs/4p &&
test_update_rejected "a c/x/y e" true "b c d" \
- "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
+ "'$prefix/c/x/y' exists; cannot create '$prefix/c'"
-'
+EOT
-test_expect_success 'one new ref is a simple prefix of another' '
+test_expect_success 'one new ref is a simple prefix of another' - <<\EOT
prefix=refs/5 &&
test_update_rejected "a e" false "b c c/x d" \
- "cannot process $SQ$prefix/c$SQ and $SQ$prefix/c/x$SQ at the same time"
+ "cannot process '$prefix/c' and '$prefix/c/x' at the same time"
-'
+EOT
-test_expect_success 'D/F conflict prevents add long + delete short' '
+test_expect_success 'D/F conflict prevents add long + delete short' - <<\EOT
df_test refs/df-al-ds --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents add short + delete long' '
+test_expect_success 'D/F conflict prevents add short + delete long' - <<\EOT
df_test refs/df-as-dl --add-del foo foo/bar
-'
+EOT
-test_expect_success 'D/F conflict prevents delete long + add short' '
+test_expect_success 'D/F conflict prevents delete long + add short' - <<\EOT
df_test refs/df-dl-as --del-add foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents delete short + add long' '
+test_expect_success 'D/F conflict prevents delete short + add long' - <<\EOT
df_test refs/df-ds-al --del-add foo foo/bar
-'
+EOT
-test_expect_success 'D/F conflict prevents add long + delete short packed' '
+test_expect_success 'D/F conflict prevents add long + delete short packed' - <<\EOT
df_test refs/df-al-dsp --pack --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents add short + delete long packed' '
+test_expect_success 'D/F conflict prevents add short + delete long packed' - <<\EOT
df_test refs/df-as-dlp --pack --add-del foo foo/bar
-'
+EOT
-test_expect_success 'D/F conflict prevents delete long packed + add short' '
+test_expect_success 'D/F conflict prevents delete long packed + add short' - <<\EOT
df_test refs/df-dlp-as --pack --del-add foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents delete short packed + add long' '
+test_expect_success 'D/F conflict prevents delete short packed + add long' - <<\EOT
df_test refs/df-dsp-al --pack --del-add foo foo/bar
-'
+EOT
# Try some combinations involving symbolic refs...
-test_expect_success 'D/F conflict prevents indirect add long + delete short' '
+test_expect_success 'D/F conflict prevents indirect add long + delete short' - <<\EOT
df_test refs/df-ial-ds --sym-add --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents indirect add long + indirect delete short' '
+test_expect_success 'D/F conflict prevents indirect add long + indirect delete short' - <<\EOT
df_test refs/df-ial-ids --sym-add --sym-del --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents indirect add short + indirect delete long' '
+test_expect_success 'D/F conflict prevents indirect add short + indirect delete long' - <<\EOT
df_test refs/df-ias-idl --sym-add --sym-del --add-del foo foo/bar
-'
+EOT
-test_expect_success 'D/F conflict prevents indirect delete long + indirect add short' '
+test_expect_success 'D/F conflict prevents indirect delete long + indirect add short' - <<\EOT
df_test refs/df-idl-ias --sym-add --sym-del --del-add foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents indirect add long + delete short packed' '
+test_expect_success 'D/F conflict prevents indirect add long + delete short packed' - <<\EOT
df_test refs/df-ial-dsp --sym-add --pack --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents indirect add long + indirect delete short packed' '
+test_expect_success 'D/F conflict prevents indirect add long + indirect delete short packed' - <<\EOT
df_test refs/df-ial-idsp --sym-add --sym-del --pack --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents add long + indirect delete short packed' '
+test_expect_success 'D/F conflict prevents add long + indirect delete short packed' - <<\EOT
df_test refs/df-al-idsp --sym-del --pack --add-del foo/bar foo
-'
+EOT
-test_expect_success 'D/F conflict prevents indirect delete long packed + indirect add short' '
+test_expect_success 'D/F conflict prevents indirect delete long packed + indirect add short' - <<\EOT
df_test refs/df-idlp-ias --sym-add --sym-del --pack --del-add foo/bar foo
-'
+EOT
# Test various errors when reading the old values of references...
-test_expect_success 'missing old value blocks update' '
+test_expect_success 'missing old value blocks update' - <<\EOT
prefix=refs/missing-update &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
+ fatal: cannot lock ref '$prefix/foo': unable to resolve reference '$prefix/foo'
EOF
printf "%s\n" "update $prefix/foo $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'incorrect old value blocks update' '
+test_expect_success 'incorrect old value blocks update' - <<\EOT
prefix=refs/incorrect-update &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
+ fatal: cannot lock ref '$prefix/foo': is at $C but expected $D
EOF
printf "%s\n" "update $prefix/foo $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'existing old value blocks create' '
+test_expect_success 'existing old value blocks create' - <<\EOT
prefix=refs/existing-create &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: reference already exists
+ fatal: cannot lock ref '$prefix/foo': reference already exists
EOF
printf "%s\n" "create $prefix/foo $E" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'incorrect old value blocks delete' '
+test_expect_success 'incorrect old value blocks delete' - <<\EOT
prefix=refs/incorrect-delete &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
+ fatal: cannot lock ref '$prefix/foo': is at $C but expected $D
EOF
printf "%s\n" "delete $prefix/foo $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'missing old value blocks indirect update' '
+test_expect_success 'missing old value blocks indirect update' - <<\EOT
prefix=refs/missing-indirect-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
+ fatal: cannot lock ref '$prefix/symref': unable to resolve reference '$prefix/foo'
EOF
printf "%s\n" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'incorrect old value blocks indirect update' '
+test_expect_success 'incorrect old value blocks indirect update' - <<\EOT
prefix=refs/incorrect-indirect-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
+ fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
EOF
printf "%s\n" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'existing old value blocks indirect create' '
+test_expect_success 'existing old value blocks indirect create' - <<\EOT
prefix=refs/existing-indirect-create &&
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
+ fatal: cannot lock ref '$prefix/symref': reference already exists
EOF
printf "%s\n" "create $prefix/symref $E" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'incorrect old value blocks indirect delete' '
+test_expect_success 'incorrect old value blocks indirect delete' - <<\EOT
prefix=refs/incorrect-indirect-delete &&
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
+ fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
EOF
printf "%s\n" "delete $prefix/symref $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'missing old value blocks indirect no-deref update' '
+test_expect_success 'missing old value blocks indirect no-deref update' - <<\EOT
prefix=refs/missing-noderef-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: reference is missing but expected $D
+ fatal: cannot lock ref '$prefix/symref': reference is missing but expected $D
EOF
printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'incorrect old value blocks indirect no-deref update' '
+test_expect_success 'incorrect old value blocks indirect no-deref update' - <<\EOT
prefix=refs/incorrect-noderef-update &&
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
+ fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
EOF
printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'existing old value blocks indirect no-deref create' '
+test_expect_success 'existing old value blocks indirect no-deref create' - <<\EOT
prefix=refs/existing-noderef-create &&
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
+ fatal: cannot lock ref '$prefix/symref': reference already exists
EOF
printf "%s\n" "option no-deref" "create $prefix/symref $E" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
-test_expect_success 'incorrect old value blocks indirect no-deref delete' '
+test_expect_success 'incorrect old value blocks indirect no-deref delete' - <<\EOT
prefix=refs/incorrect-noderef-delete &&
git symbolic-ref $prefix/symref $prefix/foo &&
git update-ref $prefix/foo $C &&
cat >expected <<-EOF &&
- fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
+ fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
EOF
printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
test_must_fail git update-ref --stdin 2>output.err &&
test_cmp expected output.err
-'
+EOT
test_done
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 5bf883f1e3..246a3f46ab 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -146,6 +146,14 @@ test_expect_success rewind '
test_line_count = 5 output
'
+test_expect_success 'reflog expire should not barf on an annotated tag' '
+ test_when_finished "git tag -d v0.tag || :" &&
+ git -c core.logAllRefUpdates=always \
+ tag -a -m "tag name" v0.tag main &&
+ git reflog expire --dry-run refs/tags/v0.tag 2>err &&
+ test_grep ! "error: [Oo]bject .* not a commit" err
+'
+
test_expect_success 'corrupt and check' '
corrupt $F &&
diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh
index b754b9fd74..5eaa6428c4 100755
--- a/t/t1502-rev-parse-parseopt.sh
+++ b/t/t1502-rev-parse-parseopt.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='test git rev-parse --parseopt'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check_invalid_long_option () {
diff --git a/t/t1511-rev-parse-caret.sh b/t/t1511-rev-parse-caret.sh
index 6ecfed86bc..e7e78a4028 100755
--- a/t/t1511-rev-parse-caret.sh
+++ b/t/t1511-rev-parse-caret.sh
@@ -5,6 +5,7 @@ test_description='tests for ref^{stuff}'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh
index 70f1e0a998..f9d68ce74e 100755
--- a/t/t1512-rev-parse-disambiguation.sh
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -23,6 +23,7 @@ one tagged as v1.0.0. They all have one regular file each.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_cmp_failed_rev_parse () {
diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh
index be3fcdde07..b3f6bc97b5 100755
--- a/t/t2030-unresolve-info.sh
+++ b/t/t2030-unresolve-info.sh
@@ -5,6 +5,7 @@ test_description='undoing resolution'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check_resolve_undo () {
diff --git a/t/t2080-parallel-checkout-basics.sh b/t/t2080-parallel-checkout-basics.sh
index 5ffe1a41e2..59e5570cb2 100755
--- a/t/t2080-parallel-checkout-basics.sh
+++ b/t/t2080-parallel-checkout-basics.sh
@@ -8,6 +8,7 @@ working tree.
'
TEST_NO_CREATE_REPO=1
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY/lib-parallel-checkout.sh"
diff --git a/t/t2082-parallel-checkout-attributes.sh b/t/t2082-parallel-checkout-attributes.sh
index f3511cd43a..aec55496eb 100755
--- a/t/t2082-parallel-checkout-attributes.sh
+++ b/t/t2082-parallel-checkout-attributes.sh
@@ -10,6 +10,7 @@ properly (without access to the index or attribute stack).
'
TEST_NO_CREATE_REPO=1
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY/lib-parallel-checkout.sh"
. "$TEST_DIRECTORY/lib-encoding.sh"
diff --git a/t/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh
index cc72ead79f..f0eab13f96 100755
--- a/t/t2107-update-index-basic.sh
+++ b/t/t2107-update-index-basic.sh
@@ -5,6 +5,7 @@ test_description='basic update-index tests
Tests for command-line parsing and basic operation.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'update-index --nonsense fails' '
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index ba320dc417..cfc4aeb179 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -6,6 +6,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_CREATE_REPO_NO_TEMPLATE=1
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh
index 5c0bf4d21f..714feb83be 100755
--- a/t/t2500-untracked-overwriting.sh
+++ b/t/t2500-untracked-overwriting.sh
@@ -2,6 +2,7 @@
test_description='Test handling of overwriting untracked files'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_setup_reset () {
diff --git a/t/t2501-cwd-empty.sh b/t/t2501-cwd-empty.sh
index f6d8d7d03d..8af4e8cfe3 100755
--- a/t/t2501-cwd-empty.sh
+++ b/t/t2501-cwd-empty.sh
@@ -2,6 +2,7 @@
test_description='Test handling of the current working directory becoming empty'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 800fc33165..6e587d27d7 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -2,6 +2,7 @@
test_description='branch --contains <commit>, --no-contains <commit> --merged, and --no-merged'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh
index a1139f79e2..3b6dad0c46 100755
--- a/t/t3202-show-branch.sh
+++ b/t/t3202-show-branch.sh
@@ -2,6 +2,7 @@
test_description='test show-branch'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'error descriptions on empty repository' '
diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index a767c3520e..86010931ab 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -5,6 +5,7 @@ test_description='range-diff tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Note that because of the range-diff's heuristics, test_commit does more
@@ -533,9 +534,9 @@ test_expect_success 'dual-coloring' '
for prev in topic main..topic
do
test_expect_success "format-patch --range-diff=$prev" '
+ test_when_finished "rm -f 000?-*" &&
git format-patch --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
test_line_count = 5 actual &&
test_grep "^Range-diff:$" 0000-* &&
grep "= 1: .* s/5/A" 0000-* &&
@@ -560,32 +561,32 @@ test_expect_success "explicit --no-cover-letter defeats implied --cover-letter"
'
test_expect_success 'format-patch --range-diff as commentary' '
+ test_when_finished "rm -f 0001-*" &&
git format-patch --range-diff=HEAD~1 HEAD~1 >actual &&
- test_when_finished "rm 0001-*" &&
test_line_count = 1 actual &&
test_grep "^Range-diff:$" 0001-* &&
grep "> 1: .* new message" 0001-*
'
test_expect_success 'format-patch --range-diff reroll-count with a non-integer' '
+ test_when_finished "rm -f v2.9-0001-*" &&
git format-patch --range-diff=HEAD~1 -v2.9 HEAD~1 >actual &&
- test_when_finished "rm v2.9-0001-*" &&
test_line_count = 1 actual &&
test_grep "^Range-diff:$" v2.9-0001-* &&
grep "> 1: .* new message" v2.9-0001-*
'
test_expect_success 'format-patch --range-diff reroll-count with a integer' '
+ test_when_finished "rm -f v2-0001-*" &&
git format-patch --range-diff=HEAD~1 -v2 HEAD~1 >actual &&
- test_when_finished "rm v2-0001-*" &&
test_line_count = 1 actual &&
test_grep "^Range-diff ..* v1:$" v2-0001-* &&
grep "> 1: .* new message" v2-0001-*
'
test_expect_success 'format-patch --range-diff with v0' '
+ test_when_finished "rm -f v0-0001-*" &&
git format-patch --range-diff=HEAD~1 -v0 HEAD~1 >actual &&
- test_when_finished "rm v0-0001-*" &&
test_line_count = 1 actual &&
test_grep "^Range-diff:$" v0-0001-* &&
grep "> 1: .* new message" v0-0001-*
@@ -606,9 +607,9 @@ test_expect_success 'basic with modified format.pretty without "commit "' '
'
test_expect_success 'range-diff compares notes by default' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
git range-diff --no-color main..topic main..unmodified \
>actual &&
sed s/Z/\ /g >expect <<-EOF &&
@@ -630,9 +631,9 @@ test_expect_success 'range-diff compares notes by default' '
'
test_expect_success 'range-diff with --no-notes' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
git range-diff --no-color --no-notes main..topic main..unmodified \
>actual &&
cat >expect <<-EOF &&
@@ -645,12 +646,12 @@ test_expect_success 'range-diff with --no-notes' '
'
test_expect_success 'range-diff with multiple --notes' '
+ test_when_finished "git notes --ref=note1 remove topic unmodified || :" &&
git notes --ref=note1 add -m "topic note1" topic &&
git notes --ref=note1 add -m "unmodified note1" unmodified &&
- test_when_finished git notes --ref=note1 remove topic unmodified &&
+ test_when_finished "git notes --ref=note2 remove topic unmodified || :" &&
git notes --ref=note2 add -m "topic note2" topic &&
git notes --ref=note2 add -m "unmodified note2" unmodified &&
- test_when_finished git notes --ref=note2 remove topic unmodified &&
git range-diff --no-color --notes=note1 --notes=note2 main..topic main..unmodified \
>actual &&
sed s/Z/\ /g >expect <<-EOF &&
@@ -678,12 +679,12 @@ test_expect_success 'range-diff with multiple --notes' '
# `range-diff` should act like `log` with regards to notes
test_expect_success 'range-diff with --notes=custom does not show default notes' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
+ test_when_finished "git notes --ref=custom remove topic unmodified || :" &&
git notes --ref=custom add -m "topic note" topic &&
git notes --ref=custom add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
- test_when_finished git notes --ref=custom remove topic unmodified &&
git range-diff --notes=custom main..topic main..unmodified \
>actual &&
! grep "## Notes ##" actual &&
@@ -691,12 +692,12 @@ test_expect_success 'range-diff with --notes=custom does not show default notes'
'
test_expect_success 'format-patch --range-diff does not compare notes by default' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
+ test_when_finished "rm -f 000?-*" &&
git format-patch --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
test_line_count = 5 actual &&
test_grep "^Range-diff:$" 0000-* &&
grep "= 1: .* s/5/A" 0000-* &&
@@ -708,26 +709,26 @@ test_expect_success 'format-patch --range-diff does not compare notes by default
'
test_expect_success 'format-patch --notes=custom --range-diff only compares custom notes' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
- git notes --ref=custom add -m "topic note (custom)" topic &&
git notes add -m "unmodified note" unmodified &&
+ test_when_finished "git notes --ref=custom remove topic unmodified || :" &&
+ git notes --ref=custom add -m "topic note (custom)" topic &&
git notes --ref=custom add -m "unmodified note (custom)" unmodified &&
- test_when_finished git notes remove topic unmodified &&
- test_when_finished git notes --ref=custom remove topic unmodified &&
+ test_when_finished "rm -f 000?-*" &&
git format-patch --notes=custom --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
grep "## Notes (custom) ##" 0000-* &&
! grep "## Notes ##" 0000-*
'
test_expect_success 'format-patch --range-diff with --no-notes' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
+ test_when_finished "rm -f 000?-*" &&
git format-patch --no-notes --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
test_line_count = 5 actual &&
test_grep "^Range-diff:$" 0000-* &&
grep "= 1: .* s/5/A" 0000-* &&
@@ -739,12 +740,12 @@ test_expect_success 'format-patch --range-diff with --no-notes' '
'
test_expect_success 'format-patch --range-diff with --notes' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
+ test_when_finished "rm -f 000?-*" &&
git format-patch --notes --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
test_line_count = 5 actual &&
test_grep "^Range-diff:$" 0000-* &&
grep "= 1: .* s/5/A" 0000-* &&
@@ -767,13 +768,13 @@ test_expect_success 'format-patch --range-diff with --notes' '
'
test_expect_success 'format-patch --range-diff with format.notes config' '
+ test_when_finished "git notes remove topic unmodified || :" &&
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
- test_when_finished git notes remove topic unmodified &&
test_config format.notes true &&
+ test_when_finished "rm -f 000?-*" &&
git format-patch --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
test_line_count = 5 actual &&
test_grep "^Range-diff:$" 0000-* &&
grep "= 1: .* s/5/A" 0000-* &&
@@ -796,15 +797,15 @@ test_expect_success 'format-patch --range-diff with format.notes config' '
'
test_expect_success 'format-patch --range-diff with multiple notes' '
+ test_when_finished "git notes --ref=note1 remove topic unmodified || :" &&
git notes --ref=note1 add -m "topic note1" topic &&
git notes --ref=note1 add -m "unmodified note1" unmodified &&
- test_when_finished git notes --ref=note1 remove topic unmodified &&
+ test_when_finished "git notes --ref=note2 remove topic unmodified || :" &&
git notes --ref=note2 add -m "topic note2" topic &&
git notes --ref=note2 add -m "unmodified note2" unmodified &&
- test_when_finished git notes --ref=note2 remove topic unmodified &&
+ test_when_finished "rm -f 000?-*" &&
git format-patch --notes=note1 --notes=note2 --cover-letter --range-diff=$prev \
main..unmodified >actual &&
- test_when_finished "rm 000?-*" &&
test_line_count = 5 actual &&
test_grep "^Range-diff:$" 0000-* &&
grep "= 1: .* s/5/A" 0000-* &&
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index cf23c06c09..99137fb235 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -5,6 +5,7 @@
test_description='Test commit notes'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
write_script fake_editor <<\EOF
@@ -1556,4 +1557,14 @@ test_expect_success 'empty notes are displayed by git log' '
test_cmp expect actual
'
+test_expect_success 'empty notes do not invoke the editor' '
+ test_commit 18th &&
+ GIT_EDITOR="false" git notes add -C "$empty_blob" --allow-empty &&
+ git notes remove HEAD &&
+ GIT_EDITOR="false" git notes add -m "" --allow-empty &&
+ git notes remove HEAD &&
+ GIT_EDITOR="false" git notes add -F /dev/null --allow-empty &&
+ git notes remove HEAD
+'
+
test_done
diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
index 8f4102ff9e..b6e9f643e3 100755
--- a/t/t3306-notes-prune.sh
+++ b/t/t3306-notes-prune.sh
@@ -2,6 +2,7 @@
test_description='Test git notes prune'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup: create a few commits with notes' '
diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh
index 202702be1a..e1d05ff6bc 100755
--- a/t/t3308-notes-merge.sh
+++ b/t/t3308-notes-merge.sh
@@ -5,6 +5,7 @@
test_description='Test merging of notes trees'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3309-notes-merge-auto-resolve.sh b/t/t3309-notes-merge-auto-resolve.sh
index 9bd5dbf341..f55277f499 100755
--- a/t/t3309-notes-merge-auto-resolve.sh
+++ b/t/t3309-notes-merge-auto-resolve.sh
@@ -5,6 +5,7 @@
test_description='Test notes merging with auto-resolving strategies'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Set up a notes merge scenario with all kinds of potential conflicts
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index e1c8c5f701..ae34bfad60 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -11,6 +11,7 @@ among other things.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_AUTHOR_NAME=author@name
diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh
index f18bae9450..328c1d3a3f 100755
--- a/t/t3401-rebase-and-am-rename.sh
+++ b/t/t3401-rebase-and-am-rename.sh
@@ -2,6 +2,7 @@
test_description='git rebase + directory rename tests'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh
index a1911c4a9d..4f1d6e8ea6 100755
--- a/t/t3403-rebase-skip.sh
+++ b/t/t3403-rebase-skip.sh
@@ -8,6 +8,7 @@ test_description='git rebase --merge --skip tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index a1d7fa7f7c..82108b67e6 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -5,6 +5,7 @@ test_description='messages from rebase operation'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh
index 9f49c4228b..2c3f38d45a 100755
--- a/t/t3407-rebase-abort.sh
+++ b/t/t3407-rebase-abort.sh
@@ -5,6 +5,7 @@ test_description='git rebase --abort tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh
index 96f2cf22fa..22ee3a2045 100755
--- a/t/t3417-rebase-whitespace-fix.sh
+++ b/t/t3417-rebase-whitespace-fix.sh
@@ -5,6 +5,7 @@ test_description='git rebase --whitespace=fix
This test runs git rebase --whitespace=fix and make sure that it works.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# prepare initial revision of "file" with a blank line at the end
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 127216f722..c0d29c2154 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -5,6 +5,7 @@ test_description='git rebase --continue tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index 1a820f1481..63e400b89f 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -7,6 +7,7 @@ test_description='git rebase --autostash tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh
index 62d86d557d..737af80bb3 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='basic rebase topology tests'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh
index 1ee6b00fd5..515c949ae3 100755
--- a/t/t3424-rebase-empty.sh
+++ b/t/t3424-rebase-empty.sh
@@ -2,6 +2,7 @@
test_description='git rebase of commits that start or become empty'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup test repository' '
diff --git a/t/t3428-rebase-signoff.sh b/t/t3428-rebase-signoff.sh
index 6f57aed9fa..365436ebfc 100755
--- a/t/t3428-rebase-signoff.sh
+++ b/t/t3428-rebase-signoff.sh
@@ -5,6 +5,7 @@ test_description='git rebase --signoff
This test runs git rebase --signoff and make sure that it works.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 59b5d6b6f2..2aa8593f77 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -21,6 +21,7 @@ Initial setup:
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
. "$TEST_DIRECTORY"/lib-log-graph.sh
@@ -391,8 +392,7 @@ test_expect_success 'refuse to merge ancestors of HEAD' '
test_expect_success 'root commits' '
git checkout --orphan unrelated &&
- (GIT_AUTHOR_NAME="Parsnip" GIT_AUTHOR_EMAIL="root@example.com" \
- test_commit second-root) &&
+ test_commit --author "Parsnip <root@example.com>" second-root &&
test_commit third-root &&
cat >script-from-scratch <<-\EOF &&
pick third-root
diff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh
index a4e482d2cd..26a48d6b10 100755
--- a/t/t3434-rebase-i18n.sh
+++ b/t/t3434-rebase-i18n.sh
@@ -17,6 +17,7 @@ Initial setup:
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
compare_msg () {
diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh
index 78c3eac54b..61ca87512d 100755
--- a/t/t3500-cherry.sh
+++ b/t/t3500-cherry.sh
@@ -11,6 +11,7 @@ checks that git cherry only returns the second patch in the local branch
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_AUTHOR_EMAIL=bogus_email_address
diff --git a/t/t3504-cherry-pick-rerere.sh b/t/t3504-cherry-pick-rerere.sh
index 4581ae98b8..597c98e9c5 100755
--- a/t/t3504-cherry-pick-rerere.sh
+++ b/t/t3504-cherry-pick-rerere.sh
@@ -5,6 +5,7 @@ test_description='cherry-pick should rerere for conflicts'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3505-cherry-pick-empty.sh b/t/t3505-cherry-pick-empty.sh
index 9748443530..ead3fb4680 100755
--- a/t/t3505-cherry-pick-empty.sh
+++ b/t/t3505-cherry-pick-empty.sh
@@ -5,6 +5,7 @@ test_description='test cherry-picking an empty commit'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index 2d53ce754c..afa7727a4a 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -5,6 +5,7 @@ test_description='test cherry-picking many commits'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check_head_differs_from() {
diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh
index f4159246e1..171cc6d76b 100755
--- a/t/t3509-cherry-pick-merge-df.sh
+++ b/t/t3509-cherry-pick-merge-df.sh
@@ -4,6 +4,7 @@ test_description='Test cherry-pick with directory/file conflicts'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'Initialize repository' '
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index 389670262e..12bd3db4cb 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -5,6 +5,7 @@ test_description='basic git replay tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_AUTHOR_NAME=author@name
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 5d78868ac1..718438ffc7 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -575,6 +575,54 @@ test_expect_success 'navigate to hunk via regex / pattern' '
test_cmp expect actual.trimmed
'
+test_expect_success 'print again the hunk' '
+ test_when_finished "git reset" &&
+ tr _ " " >expect <<-EOF &&
+ +15
+ 20
+ (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? @@ -1,2 +1,3 @@
+ 10
+ +15
+ 20
+ (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_
+ EOF
+ test_write_lines s y g 1 p | git add -p >actual &&
+ tail -n 7 <actual >actual.trimmed &&
+ test_cmp expect actual.trimmed
+'
+
+test_expect_success TTY 'print again the hunk (PAGER)' '
+ test_when_finished "git reset" &&
+ cat >expect <<-EOF &&
+ <GREEN>+<RESET><GREEN>15<RESET>
+ 20<RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+ PAGER 10<RESET>
+ PAGER <GREEN>+<RESET><GREEN>15<RESET>
+ PAGER 20<RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET>
+ EOF
+ test_write_lines s y g 1 P |
+ (
+ GIT_PAGER="sed s/^/PAGER\ /" &&
+ export GIT_PAGER &&
+ test_terminal git add -p >actual
+ ) &&
+ tail -n 7 <actual | test_decode_color >actual.trimmed &&
+ test_cmp expect actual.trimmed
+'
+
+test_expect_success TTY 'P handles SIGPIPE when writing to pager' '
+ test_when_finished "rm -f huge_file; git reset" &&
+ printf "\n%2500000s" Y >huge_file &&
+ git add -N huge_file &&
+ test_write_lines P q | (
+ GIT_PAGER="head -n 1" &&
+ export GIT_PAGER &&
+ test_terminal git add -p
+ )
+'
+
test_expect_success 'split hunk "add -p (edit)"' '
# Split, say Edit and do nothing. Then:
#
@@ -1164,4 +1212,23 @@ test_expect_success 'reset -p with unmerged files' '
test_must_be_empty staged
'
+test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' '
+ test_config diff.suppressBlankEmpty true &&
+ write_script fake-editor.sh <<-\EOF &&
+ tr F G <"$1" >"$1.tmp" &&
+ mv "$1.tmp" "$1"
+ EOF
+
+ test_write_lines a b "" c d "" e f "" >file &&
+ git add file &&
+ test_write_lines A b "" c D "" e F "" >file &&
+ (
+ test_set_editor "$(pwd)/fake-editor.sh" &&
+ test_write_lines s n y e q | git add -p file
+ ) &&
+ git cat-file blob :file >actual &&
+ test_write_lines a b "" c D "" e G "" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index a7f71f8126..e4c0937f61 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -8,6 +8,7 @@ test_description='Test git stash'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-unique-files.sh
diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh
index 368fc2a6cc..aa5019fd6c 100755
--- a/t/t3904-stash-patch.sh
+++ b/t/t3904-stash-patch.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='stash -p'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-patch-mode.sh
test_expect_success 'setup' '
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index 1289ae3e07..a1733f45c3 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -5,6 +5,7 @@
test_description='Test git stash --include-untracked'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'stash save --include-untracked some dirty working directory' '
diff --git a/t/t3907-stash-show-config.sh b/t/t3907-stash-show-config.sh
index 10914bba7b..7a2eb98b86 100755
--- a/t/t3907-stash-show-config.sh
+++ b/t/t3907-stash-show-config.sh
@@ -2,6 +2,7 @@
test_description='Test git stash show configuration.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 74586f3813..4dcd7e9925 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -70,7 +70,7 @@ test_language_driver () {
word_diff --color-words
'
test_expect_success "diff driver '$lang' in Islandic" '
- LANG=is_IS.UTF-8 LANGUAGE=is LC_ALL="$is_IS_locale" \
+ test_env LANG=is_IS.UTF-8 LANGUAGE=is LC_ALL="$is_IS_locale" \
word_diff --color-words
'
}
diff --git a/t/t4061-diff-indent.sh b/t/t4061-diff-indent.sh
index 7750b87ca1..2942e5d9b9 100755
--- a/t/t4061-diff-indent.sh
+++ b/t/t4061-diff-indent.sh
@@ -6,6 +6,7 @@ test_description='Test diff indent heuristic.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-diff.sh
diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh
index 4eb8444029..d9a1084b5e 100755
--- a/t/t4129-apply-samemode.sh
+++ b/t/t4129-apply-samemode.sh
@@ -130,4 +130,66 @@ test_expect_success 'git apply respects core.fileMode' '
test_grep ! "has type 100644, expected 100755" err
'
+test_expect_success POSIXPERM 'patch mode for new file is canonicalized' '
+ cat >patch <<-\EOF &&
+ diff --git a/non-canon b/non-canon
+ new file mode 100660
+ --- /dev/null
+ +++ b/non-canon
+ +content
+ EOF
+ test_when_finished "git reset --hard" &&
+ (
+ umask 0 &&
+ git apply --index patch 2>err
+ ) &&
+ test_must_be_empty err &&
+ git ls-files -s -- non-canon >staged &&
+ test_grep "^100644" staged &&
+ ls -l non-canon >worktree &&
+ test_grep "^-rw-rw-rw" worktree
+'
+
+test_expect_success POSIXPERM 'patch mode for deleted file is canonicalized' '
+ test_when_finished "git reset --hard" &&
+ echo content >non-canon &&
+ git add non-canon &&
+ chmod 666 non-canon &&
+
+ cat >patch <<-\EOF &&
+ diff --git a/non-canon b/non-canon
+ deleted file mode 100660
+ --- a/non-canon
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -content
+ EOF
+ git apply --index patch 2>err &&
+ test_must_be_empty err &&
+ git ls-files -- non-canon >staged &&
+ test_must_be_empty staged &&
+ test_path_is_missing non-canon
+'
+
+test_expect_success POSIXPERM 'patch mode for mode change is canonicalized' '
+ test_when_finished "git reset --hard" &&
+ echo content >non-canon &&
+ git add non-canon &&
+
+ cat >patch <<-\EOF &&
+ diff --git a/non-canon b/non-canon
+ old mode 100660
+ new mode 100770
+ EOF
+ (
+ umask 0 &&
+ git apply --index patch 2>err
+ ) &&
+ test_must_be_empty err &&
+ git ls-files -s -- non-canon >staged &&
+ test_grep "^100755" staged &&
+ ls -l non-canon >worktree &&
+ test_grep "^-rwxrwxrwx" worktree
+'
+
test_done
diff --git a/t/t4131-apply-fake-ancestor.sh b/t/t4131-apply-fake-ancestor.sh
index b1361ce546..40c92115a6 100755
--- a/t/t4131-apply-fake-ancestor.sh
+++ b/t/t4131-apply-fake-ancestor.sh
@@ -5,6 +5,7 @@
test_description='git apply --build-fake-ancestor handling.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh
index edb38da701..1825a89d6a 100755
--- a/t/t4151-am-abort.sh
+++ b/t/t4151-am-abort.sh
@@ -2,6 +2,7 @@
test_description='am --abort'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh
index a32cec42aa..dd6ad8f7a8 100755
--- a/t/t4153-am-resume-override-opts.sh
+++ b/t/t4153-am-resume-override-opts.sh
@@ -2,6 +2,7 @@
test_description='git-am command-line options override saved options'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
format_patch () {
@@ -98,7 +99,7 @@ test_expect_success '--reject overrides --no-reject' '
test_path_is_dir .git/rebase-apply &&
test_path_is_missing file.rej &&
- test_must_fail git am --retry --reject </dev/zero &&
+ test_must_fail git am --retry --reject &&
test_path_is_dir .git/rebase-apply &&
test_path_is_file file.rej
'
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index b0a3e84984..213b36fb96 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -25,6 +25,7 @@ test_description='git rerere
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index f698d0c9ad..c20c885724 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -9,6 +9,7 @@ test_description='git shortlog
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 8a88dd7900..79e5f42760 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -5,6 +5,7 @@ test_description='.mailmap configurations'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup commits and contacts file' '
diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh
index 605faea0c7..dc8ddb10af 100755
--- a/t/t4204-patch-id.sh
+++ b/t/t4204-patch-id.sh
@@ -114,6 +114,46 @@ test_expect_success 'patch-id supports git-format-patch output' '
test "$2" = $(git rev-parse HEAD)
'
+test_expect_success 'patch-id computes the same for various formats' '
+ # This test happens to consider "git log -p -1" output
+ # the canonical input format, so use it as the norm.
+ git log -1 -p same >log-p.output &&
+ git patch-id <log-p.output >expect &&
+
+ # format-patch begins with "From <commit object name>"
+ git format-patch -1 --stdout same >format-patch.output &&
+ git patch-id <format-patch.output >actual &&
+ test_cmp actual expect &&
+
+ # "diff-tree --stdin -p" begins with "<commit object name>"
+ same=$(git rev-parse same) &&
+ echo $same | git diff-tree --stdin -p >diff-tree.output &&
+ git patch-id <diff-tree.output >actual &&
+ test_cmp actual expect &&
+
+ # "diff-tree --stdin -v -p" begins with "commit <commit object name>"
+ echo $same | git diff-tree --stdin -p -v >diff-tree-v.output &&
+ git patch-id <diff-tree-v.output >actual &&
+ test_cmp actual expect
+'
+
+hash=$(git rev-parse same:)
+for cruft in "$hash" "commit $hash is bad" "From $hash status"
+do
+ test_expect_success "patch-id with <$cruft> in log message" '
+ git format-patch -1 --stdout same >patch-0 &&
+ git patch-id <patch-0 >expect &&
+
+ {
+ sed -e "/^$/q" patch-0 &&
+ printf "random message\n%s\n\n" "$cruft" &&
+ sed -e "1,/^$/d" patch-0
+ } >patch-cruft &&
+ git patch-id <patch-cruft >actual &&
+ test_cmp actual expect
+ '
+done
+
test_expect_success 'whitespace is irrelevant in footer' '
get_patch_id main &&
git checkout same &&
diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh
index 806b2809d4..2a46eb6bed 100755
--- a/t/t4208-log-magic-pathspec.sh
+++ b/t/t4208-log-magic-pathspec.sh
@@ -5,6 +5,7 @@ test_description='magic pathspec tests using git-log'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh
index 2ba0324a69..3f163dc396 100755
--- a/t/t4216-log-bloom.sh
+++ b/t/t4216-log-bloom.sh
@@ -82,7 +82,23 @@ test_bloom_filters_used () {
test_bloom_filters_not_used () {
log_args=$1
setup "$log_args" &&
- ! grep -q "statistics:{\"filter_not_present\":" "$TRASH_DIRECTORY/trace.perf" &&
+
+ if grep -q "statistics:{\"filter_not_present\":" "$TRASH_DIRECTORY/trace.perf"
+ then
+ # if the Bloom filter system is initialized, ensure that no
+ # filters were used
+ data="statistics:{"
+ # unusable filters (e.g., those computed with a
+ # different value of commitGraph.changedPathsVersion)
+ # are counted in the filter_not_present bucket, so any
+ # value is OK there.
+ data="$data\"filter_not_present\":[0-9][0-9]*,"
+ data="$data\"maybe\":0,"
+ data="$data\"definitely_not\":0,"
+ data="$data\"false_positive\":0}"
+
+ grep -q "$data" "$TRASH_DIRECTORY/trace.perf"
+ fi &&
test_cmp log_wo_bloom log_w_bloom
}
@@ -163,7 +179,7 @@ test_expect_success 'setup - add commit-graph to the chain with Bloom filters' '
test_bloom_filters_used_when_some_filters_are_missing () {
log_args=$1
- bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"maybe\":6,\"definitely_not\":9"
+ bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"maybe\":6,\"definitely_not\":10"
setup "$log_args" &&
grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" &&
test_cmp log_wo_bloom log_w_bloom
@@ -206,6 +222,10 @@ test_filter_trunc_large () {
grep "\"key\":\"filter-trunc-large\",\"value\":\"$1\"" $2
}
+test_filter_upgraded () {
+ grep "\"key\":\"filter-upgraded\",\"value\":\"$1\"" $2
+}
+
test_expect_success 'correctly report changes over limit' '
git init limits &&
(
@@ -405,8 +425,307 @@ test_expect_success 'Bloom generation backfills empty commits' '
)
'
+graph=.git/objects/info/commit-graph
+graphdir=.git/objects/info/commit-graphs
+chain=$graphdir/commit-graph-chain
+
+test_expect_success 'setup for mixed Bloom setting tests' '
+ repo=mixed-bloom-settings &&
+
+ git init $repo &&
+ for i in one two three
+ do
+ test_commit -C $repo $i file || return 1
+ done
+'
+
+test_expect_success 'ensure Bloom filters with incompatible settings are ignored' '
+ # Compute Bloom filters with "unusual" settings.
+ git -C $repo rev-parse one >in &&
+ GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=3 git -C $repo commit-graph write \
+ --stdin-commits --changed-paths --split <in &&
+ layer=$(head -n 1 $repo/$chain) &&
+
+ # A commit-graph layer without Bloom filters "hides" the layers
+ # below ...
+ git -C $repo rev-parse two >in &&
+ git -C $repo commit-graph write --stdin-commits --no-changed-paths \
+ --split=no-merge <in &&
+
+ # Another commit-graph layer that has Bloom filters, but with
+ # standard settings, and is thus incompatible with the base
+ # layer written above.
+ git -C $repo rev-parse HEAD >in &&
+ git -C $repo commit-graph write --stdin-commits --changed-paths \
+ --split=no-merge <in &&
+
+ test_line_count = 3 $repo/$chain &&
+
+ # Ensure that incompatible Bloom filters are ignored.
+ git -C $repo -c core.commitGraph=false log --oneline --no-decorate -- file \
+ >expect 2>err &&
+ git -C $repo log --oneline --no-decorate -- file >actual 2>err &&
+ test_cmp expect actual &&
+ grep "disabling Bloom filters for commit-graph layer .$layer." err
+'
+
+test_expect_success 'merge graph layers with incompatible Bloom settings' '
+ # Ensure that incompatible Bloom filters are ignored when
+ # merging existing layers.
+ >trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git -C $repo commit-graph write --reachable --changed-paths 2>err &&
+ grep "disabling Bloom filters for commit-graph layer .$layer." err &&
+ grep "{\"hash_version\":1,\"num_hashes\":7,\"bits_per_entry\":10,\"max_changed_paths\":512" trace2.txt &&
+
+ test_path_is_file $repo/$graph &&
+ test_dir_is_empty $repo/$graphdir &&
+
+ git -C $repo -c core.commitGraph=false log --oneline --no-decorate -- \
+ file >expect &&
+ trace_out="$(pwd)/trace.perf" &&
+ GIT_TRACE2_PERF="$trace_out" \
+ git -C $repo log --oneline --no-decorate -- file >actual 2>err &&
+
+ test_cmp expect actual &&
+ grep "statistics:{\"filter_not_present\":0," trace.perf &&
+ test_must_be_empty err
+'
+
+# chosen to be the same under all Unicode normalization forms
+CENT=$(printf "\302\242")
+
+test_expect_success 'ensure Bloom filter with incompatible versions are ignored' '
+ rm "$repo/$graph" &&
+
+ git -C $repo log --oneline --no-decorate -- $CENT >expect &&
+
+ # Compute v1 Bloom filters for commits at the bottom.
+ git -C $repo rev-parse HEAD^ >in &&
+ git -C $repo commit-graph write --stdin-commits --changed-paths \
+ --split <in &&
+
+ # Compute v2 Bloomfilters for the rest of the commits at the top.
+ git -C $repo rev-parse HEAD >in &&
+ git -C $repo -c commitGraph.changedPathsVersion=2 commit-graph write \
+ --stdin-commits --changed-paths --split=no-merge <in &&
+
+ test_line_count = 2 $repo/$chain &&
+
+ git -C $repo log --oneline --no-decorate -- $CENT >actual 2>err &&
+ test_cmp expect actual &&
+
+ layer="$(head -n 1 $repo/$chain)" &&
+ cat >expect.err <<-EOF &&
+ warning: disabling Bloom filters for commit-graph layer $SQ$layer$SQ due to incompatible settings
+ EOF
+ test_cmp expect.err err &&
+
+ # Merge the two layers with incompatible bloom filter versions,
+ # ensuring that the v2 filters are used.
+ >trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git -C $repo -c commitGraph.changedPathsVersion=2 commit-graph write --reachable --changed-paths 2>err &&
+ grep "disabling Bloom filters for commit-graph layer .$layer." err &&
+ grep "{\"hash_version\":2,\"num_hashes\":7,\"bits_per_entry\":10,\"max_changed_paths\":512" trace2.txt
+'
+
+get_first_changed_path_filter () {
+ test-tool read-graph bloom-filters >filters.dat &&
+ head -n 1 filters.dat
+}
+
+test_expect_success 'set up repo with high bit path, version 1 changed-path' '
+ git init highbit1 &&
+ test_commit -C highbit1 c1 "$CENT" &&
+ git -C highbit1 commit-graph write --reachable --changed-paths
+'
+
+test_expect_success 'setup check value of version 1 changed-path' '
+ (
+ cd highbit1 &&
+ echo "52a9" >expect &&
+ get_first_changed_path_filter >actual
+ )
+'
+
+# expect will not match actual if char is unsigned by default. Write the test
+# in this way, so that a user running this test script can still see if the two
+# files match. (It will appear as an ordinary success if they match, and a skip
+# if not.)
+if test_cmp highbit1/expect highbit1/actual
+then
+ test_set_prereq SIGNED_CHAR_BY_DEFAULT
+fi
+test_expect_success SIGNED_CHAR_BY_DEFAULT 'check value of version 1 changed-path' '
+ # Only the prereq matters for this test.
+ true
+'
+
+test_expect_success 'setup make another commit' '
+ # "git log" does not use Bloom filters for root commits - see how, in
+ # revision.c, rev_compare_tree() (the only code path that eventually calls
+ # get_bloom_filter()) is only called by try_to_simplify_commit() when the commit
+ # has one parent. Therefore, make another commit so that we perform the tests on
+ # a non-root commit.
+ test_commit -C highbit1 anotherc1 "another$CENT"
+'
+
+test_expect_success 'version 1 changed-path used when version 1 requested' '
+ (
+ cd highbit1 &&
+ test_bloom_filters_used "-- another$CENT"
+ )
+'
+
+test_expect_success 'version 1 changed-path not used when version 2 requested' '
+ (
+ cd highbit1 &&
+ git config --add commitGraph.changedPathsVersion 2 &&
+ test_bloom_filters_not_used "-- another$CENT"
+ )
+'
+
+test_expect_success 'version 1 changed-path used when autodetect requested' '
+ (
+ cd highbit1 &&
+ git config --add commitGraph.changedPathsVersion -1 &&
+ test_bloom_filters_used "-- another$CENT"
+ )
+'
+
+test_expect_success 'when writing another commit graph, preserve existing version 1 of changed-path' '
+ test_commit -C highbit1 c1double "$CENT$CENT" &&
+ git -C highbit1 commit-graph write --reachable --changed-paths &&
+ (
+ cd highbit1 &&
+ git config --add commitGraph.changedPathsVersion -1 &&
+ echo "options: bloom(1,10,7) read_generation_data" >expect &&
+ test-tool read-graph >full &&
+ grep options full >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'set up repo with high bit path, version 2 changed-path' '
+ git init highbit2 &&
+ git -C highbit2 config --add commitGraph.changedPathsVersion 2 &&
+ test_commit -C highbit2 c2 "$CENT" &&
+ git -C highbit2 commit-graph write --reachable --changed-paths
+'
+
+test_expect_success 'check value of version 2 changed-path' '
+ (
+ cd highbit2 &&
+ echo "c01f" >expect &&
+ get_first_changed_path_filter >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'setup make another commit' '
+ # "git log" does not use Bloom filters for root commits - see how, in
+ # revision.c, rev_compare_tree() (the only code path that eventually calls
+ # get_bloom_filter()) is only called by try_to_simplify_commit() when the commit
+ # has one parent. Therefore, make another commit so that we perform the tests on
+ # a non-root commit.
+ test_commit -C highbit2 anotherc2 "another$CENT"
+'
+
+test_expect_success 'version 2 changed-path used when version 2 requested' '
+ (
+ cd highbit2 &&
+ test_bloom_filters_used "-- another$CENT"
+ )
+'
+
+test_expect_success 'version 2 changed-path not used when version 1 requested' '
+ (
+ cd highbit2 &&
+ git config --add commitGraph.changedPathsVersion 1 &&
+ test_bloom_filters_not_used "-- another$CENT"
+ )
+'
+
+test_expect_success 'version 2 changed-path used when autodetect requested' '
+ (
+ cd highbit2 &&
+ git config --add commitGraph.changedPathsVersion -1 &&
+ test_bloom_filters_used "-- another$CENT"
+ )
+'
+
+test_expect_success 'when writing another commit graph, preserve existing version 2 of changed-path' '
+ test_commit -C highbit2 c2double "$CENT$CENT" &&
+ git -C highbit2 commit-graph write --reachable --changed-paths &&
+ (
+ cd highbit2 &&
+ git config --add commitGraph.changedPathsVersion -1 &&
+ echo "options: bloom(2,10,7) read_generation_data" >expect &&
+ test-tool read-graph >full &&
+ grep options full >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'when writing commit graph, do not reuse changed-path of another version' '
+ git init doublewrite &&
+ test_commit -C doublewrite c "$CENT" &&
+
+ git -C doublewrite config --add commitGraph.changedPathsVersion 1 &&
+ >trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git -C doublewrite commit-graph write --reachable --changed-paths &&
+ test_filter_computed 1 trace2.txt &&
+ test_filter_upgraded 0 trace2.txt &&
+
+ git -C doublewrite commit-graph write --reachable --changed-paths &&
+ for v in -2 3
+ do
+ git -C doublewrite config --add commitGraph.changedPathsVersion $v &&
+ git -C doublewrite commit-graph write --reachable --changed-paths 2>err &&
+ cat >expect <<-EOF &&
+ warning: attempting to write a commit-graph, but ${SQ}commitGraph.changedPathsVersion${SQ} ($v) is not supported
+ EOF
+ test_cmp expect err || return 1
+ done &&
+
+ git -C doublewrite config --add commitGraph.changedPathsVersion 2 &&
+ >trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git -C doublewrite commit-graph write --reachable --changed-paths &&
+ test_filter_computed 1 trace2.txt &&
+ test_filter_upgraded 0 trace2.txt &&
+
+ (
+ cd doublewrite &&
+ echo "c01f" >expect &&
+ get_first_changed_path_filter >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'when writing commit graph, reuse changed-path of another version where possible' '
+ git init upgrade &&
+
+ test_commit -C upgrade base no-high-bits &&
+
+ git -C upgrade config --add commitGraph.changedPathsVersion 1 &&
+ >trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git -C upgrade commit-graph write --reachable --changed-paths &&
+ test_filter_computed 1 trace2.txt &&
+ test_filter_upgraded 0 trace2.txt &&
+
+ git -C upgrade config --add commitGraph.changedPathsVersion 2 &&
+ >trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git -C upgrade commit-graph write --reachable --changed-paths &&
+ test_filter_computed 0 trace2.txt &&
+ test_filter_upgraded 1 trace2.txt
+'
+
corrupt_graph () {
- graph=.git/objects/info/commit-graph &&
test_when_finished "rm -rf $graph" &&
git commit-graph write --reachable --changed-paths &&
corrupt_chunk_file $graph "$@"
diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh
index 0ee69d2a0c..2bcdd9f34f 100755
--- a/t/t4253-am-keep-cr-dos.sh
+++ b/t/t4253-am-keep-cr-dos.sh
@@ -9,6 +9,7 @@ test_description='git-am mbox with dos line ending.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Three patches which will be added as files with dos line ending.
diff --git a/t/t4255-am-submodule.sh b/t/t4255-am-submodule.sh
index a7ba08f728..04f3ccfc41 100755
--- a/t/t4255-am-submodule.sh
+++ b/t/t4255-am-submodule.sh
@@ -2,6 +2,7 @@
test_description='git am handling submodules'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-submodule-update.sh
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index cb67bac1c4..86bee33160 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -5,6 +5,7 @@ test_description='Test workflows involving pull request.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
if ! test_have_prereq PERL
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 61e2be2903..4ad023c846 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -3,9 +3,9 @@
# Copyright (c) 2005 Junio C Hamano
#
-test_description='git pack-object
+test_description='git pack-object'
-'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t5305-include-tag.sh b/t/t5305-include-tag.sh
index 44bd9ef45f..dc8fe55c82 100755
--- a/t/t5305-include-tag.sh
+++ b/t/t5305-include-tag.sh
@@ -4,6 +4,7 @@ test_description='git pack-object --include-tag'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
TRASH=$(pwd)
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index a2b4442660..2916c07e3c 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='commit graph'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-chunk.sh
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 10d2a6bf92..ace5ac3b61 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -1027,6 +1027,61 @@ test_expect_success 'repack --batch-size=<large> repacks everything' '
)
'
+test_expect_success 'repack/expire loop' '
+ git init repack-expire &&
+ test_when_finished "rm -fr repack-expire" &&
+ (
+ cd repack-expire &&
+
+ test_commit_bulk 5 &&
+
+ # Create three overlapping pack-files
+ git rev-list --objects HEAD~3 >in-1 &&
+ git rev-list --objects HEAD~4..HEAD~2 >in-2 &&
+ git rev-list --objects HEAD~3..HEAD >in-3 &&
+
+ # Create disconnected blobs
+ obj1=$(git hash-object -w in-1) &&
+ obj2=$(git hash-object -w in-2) &&
+ obj3=$(git hash-object -w in-3) &&
+
+ echo $obj2 >>in-2 &&
+ echo $obj3 >>in-3 &&
+
+ for i in $(test_seq 3)
+ do
+ git pack-objects .git/objects/pack/test-$i <in-$i \
+ || return 1
+ done &&
+
+ rm -fr .git/objects/pack/pack-* &&
+ git multi-pack-index write &&
+
+ for i in $(test_seq 3)
+ do
+ for file in $(ls .git/objects/pack/test-$i*)
+ do
+ test-tool chmtime =+$((3600*$i-25000)) $file || return 1
+ done || return 1
+ done &&
+
+ pack1=$(ls .git/objects/pack/test-1-*.pack) &&
+ pack2=$(ls .git/objects/pack/test-2-*.pack) &&
+ pack3=$(ls .git/objects/pack/test-3-*.pack) &&
+
+ # Prevent test-1 from being rewritten.
+ touch "${pack1%.pack}.keep" &&
+
+ # This repack-expire loop should repack all non-kept packs
+ # into a new pack and then delete the old packs.
+ git multi-pack-index repack &&
+ git multi-pack-index expire &&
+
+ test_path_is_missing $pack3 &&
+ test_path_is_missing $pack2
+ )
+'
+
test_expect_success 'load reverse index when missing .idx, .pack' '
git init repo &&
test_when_finished "rm -fr repo" &&
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index ad7f8c6f00..e99e728236 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -7,6 +7,7 @@ test_description='Test the post-rewrite hook.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 42e77eb5a9..d64b40e408 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -5,6 +5,7 @@ test_description='git ls-remote'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
generate_references () {
@@ -402,4 +403,17 @@ test_expect_success 'v0 clients can handle multiple symrefs' '
test_cmp expect actual
'
+test_expect_success 'helper with refspec capability fails gracefully' '
+ mkdir test-bin &&
+ write_script test-bin/git-remote-foo <<-EOF &&
+ echo import
+ echo refspec ${SQ}*:*${SQ}
+ EOF
+ (
+ PATH="$PWD/test-bin:$PATH" &&
+ export PATH &&
+ test_must_fail nongit git ls-remote foo::bar
+ )
+'
+
test_done
diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh
index 25772c85c5..579872c258 100755
--- a/t/t5514-fetch-multiple.sh
+++ b/t/t5514-fetch-multiple.sh
@@ -5,6 +5,7 @@ test_description='fetch --all works correctly'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
setup_repository () {
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 2e7c0e1648..9d693eb57f 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -230,6 +230,16 @@ test_expect_success 'push with negotiation proceeds anyway even if negotiation f
test_grep "push negotiation failed" err
'
+test_expect_success 'push deletion with negotiation' '
+ mk_empty testrepo &&
+ git push testrepo $the_first_commit:refs/heads/master &&
+ git -c push.negotiate=1 push testrepo \
+ :master $the_first_commit:refs/heads/next 2>errors-2 &&
+ test_grep ! "negotiate-only needs one or " errors-2 &&
+ git -c push.negotiate=1 push testrepo :next 2>errors-1 &&
+ test_grep ! "negotiate-only needs one or " errors-1
+'
+
test_expect_success 'push with negotiation does not attempt to fetch submodules' '
mk_empty submodule_upstream &&
test_commit -C submodule_upstream submodule_commit &&
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 47534f1062..1098cbd0a1 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -5,6 +5,7 @@ test_description='pulling into void'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
modify () {
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index 14f7eced9a..bc2bada34c 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -4,6 +4,7 @@ test_description='check various push.default settings'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup bare remotes' '
diff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh
index 0247137cb3..17d7257892 100755
--- a/t/t5529-push-errors.sh
+++ b/t/t5529-push-errors.sh
@@ -2,6 +2,9 @@
test_description='detect some push errors early (before contacting remote)'
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
@@ -38,6 +41,20 @@ test_expect_success 'detect missing sha1 expressions early' '
test_cmp expect rp-ran
'
+# We use an existing local_ref, since it follows a different flow in
+# 'builtin/push.c:set_refspecs()' and we want to test that regression.
+test_expect_success 'detect empty remote with existing local ref' '
+ test_must_fail git push "" main 2> stderr &&
+ grep "fatal: bad repository ${SQ}${SQ}" stderr
+'
+
+# While similar to the previous test, here we want to ensure that
+# even targeted refspecs are handled.
+test_expect_success 'detect empty remote with targeted refspec' '
+ test_must_fail git push "" HEAD:refs/heads/main 2> stderr &&
+ grep "fatal: bad repository ${SQ}${SQ}" stderr
+'
+
test_expect_success 'detect ambiguous refs early' '
git branch foo &&
git tag foo &&
diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh
index e8f6d233ff..7122af7fdb 100755
--- a/t/t5535-fetch-push-symref.sh
+++ b/t/t5535-fetch-push-symref.sh
@@ -2,6 +2,7 @@
test_description='avoiding conflicting update through symref aliasing'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index 04b47ad84a..479d103469 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -5,6 +5,7 @@ test_description='pushing to a repository using the atomic push option'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
mk_repo_pair () {
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index a623a1058c..7b5ab0eae1 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -643,7 +643,6 @@ test_expect_success 'clone empty SHA-256 repository with protocol v0' '
test_expect_success 'passing hostname resolution information works' '
BOGUS_HOST=gitbogusexamplehost.invalid &&
BOGUS_HTTPD_URL=$HTTPD_PROTO://$BOGUS_HOST:$LIB_HTTPD_PORT &&
- test_must_fail git ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null &&
git -c "http.curloptResolve=$BOGUS_HOST:$LIB_HTTPD_PORT:127.0.0.1" ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null
'
diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh
index 48050162c2..70e3376d31 100755
--- a/t/t5553-set-upstream.sh
+++ b/t/t5553-set-upstream.sh
@@ -73,10 +73,10 @@ test_expect_success 'fetch --set-upstream main:other does not set the branch oth
check_config_missing other2
'
-test_expect_success 'fetch --set-upstream http://nosuchdomain.example.com fails with invalid url' '
+test_expect_success 'fetch --set-upstream ./does-not-exist fails with invalid url' '
# main explicitly not cleared, we check that it is not touched from previous value
clear_config other other2 &&
- test_must_fail git fetch --set-upstream http://nosuchdomain.example.com &&
+ test_must_fail git fetch --set-upstream ./does-not-exist &&
check_config main upstream refs/heads/other &&
check_config_missing other &&
check_config_missing other2
@@ -143,10 +143,10 @@ test_expect_success 'pull --set-upstream upstream tag does not set the tag' '
check_config_missing three
'
-test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails with invalid url' '
+test_expect_success 'pull --set-upstream ./does-not-exist fails with invalid url' '
# main explicitly not cleared, we check that it is not touched from previous value
clear_config other other2 three &&
- test_must_fail git pull --set-upstream http://nosuchdomain.example.com &&
+ test_must_fail git pull --set-upstream ./does-not-exist &&
check_config main upstream refs/heads/other &&
check_config_missing other &&
check_config_missing other2 &&
diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh
index 1ca5f745e7..cd05321e17 100755
--- a/t/t5558-clone-bundle-uri.sh
+++ b/t/t5558-clone-bundle-uri.sh
@@ -3,6 +3,7 @@
test_description='test fetching bundles with --bundle-uri'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-bundle.sh
test_expect_success 'fail to clone from non-existent file' '
test_when_finished rm -rf test &&
@@ -19,10 +20,39 @@ test_expect_success 'fail to clone from non-bundle file' '
test_expect_success 'create bundle' '
git init clone-from &&
- git -C clone-from checkout -b topic &&
- test_commit -C clone-from A &&
- test_commit -C clone-from B &&
- git -C clone-from bundle create B.bundle topic
+ (
+ cd clone-from &&
+ git checkout -b topic &&
+
+ test_commit A &&
+ git bundle create A.bundle topic &&
+
+ test_commit B &&
+ git bundle create B.bundle topic &&
+
+ # Create a bundle with reference pointing to non-existent object.
+ commit_a=$(git rev-parse A) &&
+ commit_b=$(git rev-parse B) &&
+ sed -e "/^$/q" -e "s/$commit_a /$commit_b /" \
+ <A.bundle >bad-header.bundle &&
+ convert_bundle_to_pack \
+ <A.bundle >>bad-header.bundle &&
+
+ tree_b=$(git rev-parse B^{tree}) &&
+ cat >data <<-EOF &&
+ tree $tree_b
+ parent $commit_b
+ author A U Thor
+ committer A U Thor
+
+ commit: this is a commit with bad emails
+
+ EOF
+ bad_commit=$(git hash-object --literally -t commit -w --stdin <data) &&
+ git branch bad $bad_commit &&
+ git bundle create bad-object.bundle bad &&
+ git update-ref -d refs/heads/bad
+ )
'
test_expect_success 'clone with path bundle' '
@@ -33,6 +63,33 @@ test_expect_success 'clone with path bundle' '
test_cmp expect actual
'
+test_expect_success 'clone with bundle that has bad header' '
+ # Write bundle ref fails, but clone can still proceed.
+ git clone --bundle-uri="clone-from/bad-header.bundle" \
+ clone-from clone-bad-header 2>err &&
+ commit_b=$(git -C clone-from rev-parse B) &&
+ test_grep "trying to write ref '\''refs/bundles/topic'\'' with nonexistent object $commit_b" err &&
+ git -C clone-bad-header for-each-ref --format="%(refname)" >refs &&
+ test_grep ! "refs/bundles/" refs
+'
+
+test_expect_success 'clone with bundle that has bad object' '
+ # Unbundle succeeds if no fsckObjects configured.
+ git clone --bundle-uri="clone-from/bad-object.bundle" \
+ clone-from clone-bad-object-no-fsck &&
+ git -C clone-bad-object-no-fsck for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ test_write_lines refs/bundles/bad >expect &&
+ test_cmp expect actual &&
+
+ # Unbundle fails with fsckObjects set true, but clone can still proceed.
+ git -c fetch.fsckObjects=true clone --bundle-uri="clone-from/bad-object.bundle" \
+ clone-from clone-bad-object-fsck 2>err &&
+ test_grep "missingEmail" err &&
+ git -C clone-bad-object-fsck for-each-ref --format="%(refname)" >refs &&
+ test_grep ! "refs/bundles/" refs
+'
+
test_expect_success 'clone with path bundle and non-default hash' '
test_when_finished "rm -rf clone-path-non-default-hash" &&
GIT_DEFAULT_HASH=sha256 git clone --bundle-uri="clone-from/B.bundle" \
@@ -259,6 +316,128 @@ test_expect_success 'clone bundle list (file, any mode, all failures)' '
! grep "refs/bundles/" refs
'
+test_expect_success 'negotiation: bundle with part of wanted commits' '
+ test_when_finished "rm -f trace*.txt" &&
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --bundle-uri="clone-from/A.bundle" \
+ clone-from nego-bundle-part &&
+ git -C nego-bundle-part for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ test_write_lines refs/bundles/topic >expect &&
+ test_cmp expect actual &&
+ # Ensure that refs/bundles/topic are sent as "have".
+ tip=$(git -C clone-from rev-parse A) &&
+ test_grep "clone> have $tip" trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle with all wanted commits' '
+ test_when_finished "rm -f trace*.txt" &&
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --single-branch --branch=topic --no-tags \
+ --bundle-uri="clone-from/B.bundle" \
+ clone-from nego-bundle-all &&
+ git -C nego-bundle-all for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ test_write_lines refs/bundles/topic >expect &&
+ test_cmp expect actual &&
+ # We already have all needed commits so no "want" needed.
+ test_grep ! "clone> want " trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle list (no heuristic)' '
+ test_when_finished "rm -f trace*.txt" &&
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+ EOF
+
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from nego-bundle-list-no-heuristic &&
+
+ git -C nego-bundle-list-no-heuristic for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ EOF
+ test_cmp expect actual &&
+ tip=$(git -C nego-bundle-list-no-heuristic rev-parse refs/bundles/left) &&
+ test_grep "clone> have $tip" trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle list (creationToken)' '
+ test_when_finished "rm -f trace*.txt" &&
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ heuristic = creationToken
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+ creationToken = 1
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+ creationToken = 2
+ EOF
+
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from nego-bundle-list-heuristic &&
+
+ git -C nego-bundle-list-heuristic for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ EOF
+ test_cmp expect actual &&
+ tip=$(git -C nego-bundle-list-heuristic rev-parse refs/bundles/left) &&
+ test_grep "clone> have $tip" trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle list with all wanted commits' '
+ test_when_finished "rm -f trace*.txt" &&
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ heuristic = creationToken
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+ creationToken = 1
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+ creationToken = 2
+ EOF
+
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --single-branch --branch=left --no-tags \
+ --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from nego-bundle-list-all &&
+
+ git -C nego-bundle-list-all for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ EOF
+ test_cmp expect actual &&
+ # We already have all needed commits so no "want" needed.
+ test_grep ! "clone> want " trace-packet.txt
+'
+
#########################################################################
# HTTP tests begin here
diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh
index 4af796de67..ba03f6a09f 100755
--- a/t/t5563-simple-http-auth.sh
+++ b/t/t5563-simple-http-auth.sh
@@ -178,6 +178,122 @@ test_expect_success 'access using basic auth invalid credentials' '
EOF
'
+test_expect_success 'access using basic proactive auth' '
+ test_when_finished "per_test_cleanup" &&
+
+ set_credential_reply get <<-EOF &&
+ username=alice
+ password=secret-passwd
+ EOF
+
+ # Basic base64(alice:secret-passwd)
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
+ id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
+ EOF
+
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
+ id=1 status=200
+ id=default status=403
+ EOF
+
+ test_config_global credential.helper test-helper &&
+ test_config_global http.proactiveAuth basic &&
+ git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
+
+ expect_credential_query get <<-EOF &&
+ capability[]=authtype
+ capability[]=state
+ protocol=http
+ host=$HTTPD_DEST
+ wwwauth[]=Basic
+ EOF
+
+ expect_credential_query store <<-EOF
+ protocol=http
+ host=$HTTPD_DEST
+ username=alice
+ password=secret-passwd
+ EOF
+'
+
+test_expect_success 'access using auto proactive auth with basic default' '
+ test_when_finished "per_test_cleanup" &&
+
+ set_credential_reply get <<-EOF &&
+ username=alice
+ password=secret-passwd
+ EOF
+
+ # Basic base64(alice:secret-passwd)
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
+ id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
+ EOF
+
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
+ id=1 status=200
+ id=default status=403
+ EOF
+
+ test_config_global credential.helper test-helper &&
+ test_config_global http.proactiveAuth auto &&
+ git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
+
+ expect_credential_query get <<-EOF &&
+ capability[]=authtype
+ capability[]=state
+ protocol=http
+ host=$HTTPD_DEST
+ EOF
+
+ expect_credential_query store <<-EOF
+ protocol=http
+ host=$HTTPD_DEST
+ username=alice
+ password=secret-passwd
+ EOF
+'
+
+test_expect_success 'access using auto proactive auth with authtype from credential helper' '
+ test_when_finished "per_test_cleanup" &&
+
+ set_credential_reply get <<-EOF &&
+ capability[]=authtype
+ authtype=Bearer
+ credential=YS1naXQtdG9rZW4=
+ EOF
+
+ # Basic base64(a-git-token)
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
+ id=1 creds=Bearer YS1naXQtdG9rZW4=
+ EOF
+
+ CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
+
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
+ id=1 status=200
+ id=default status=403
+ EOF
+
+ test_config_global credential.helper test-helper &&
+ test_config_global http.proactiveAuth auto &&
+ git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
+
+ expect_credential_query get <<-EOF &&
+ capability[]=authtype
+ capability[]=state
+ protocol=http
+ host=$HTTPD_DEST
+ EOF
+
+ expect_credential_query store <<-EOF
+ capability[]=authtype
+ authtype=Bearer
+ credential=YS1naXQtdG9rZW4=
+ protocol=http
+ host=$HTTPD_DEST
+ EOF
+'
+
test_expect_success 'access using basic auth with extra challenges' '
test_when_finished "per_test_cleanup" &&
diff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh
index bb35b87071..4aef99bc28 100755
--- a/t/t5564-http-proxy.sh
+++ b/t/t5564-http-proxy.sh
@@ -39,4 +39,59 @@ test_expect_success 'clone can prompt for proxy password' '
expect_askpass pass proxuser
'
+start_socks() {
+ mkfifo socks_output &&
+ {
+ "$PERL_PATH" "$TEST_DIRECTORY/socks4-proxy.pl" "$1" >socks_output &
+ echo $! > "$TRASH_DIRECTORY/socks.pid"
+ } &&
+ read line <socks_output &&
+ test "$line" = ready
+}
+
+# The %30 tests that the correct amount of percent-encoding is applied to the
+# proxy string passed to curl.
+test_lazy_prereq SOCKS_PROXY '
+ test_have_prereq PERL &&
+ start_socks "$TRASH_DIRECTORY/%30.sock"
+'
+
+test_atexit '
+ test ! -e "$TRASH_DIRECTORY/socks.pid" ||
+ kill "$(cat "$TRASH_DIRECTORY/socks.pid")"
+'
+
+# The below tests morally ought to be gated on a prerequisite that Git is
+# linked with a libcurl that supports Unix socket paths for proxies (7.84 or
+# later), but this is not easy to test right now. Instead, we || the tests with
+# this function.
+old_libcurl_error() {
+ grep -Fx "fatal: libcurl 7.84 or later is required to support paths in proxy URLs" "$1"
+}
+
+test_expect_success SOCKS_PROXY 'clone via Unix socket' '
+ test_when_finished "rm -rf clone" &&
+ test_config_global http.proxy "socks4://localhost$PWD/%2530.sock" && {
+ {
+ GIT_TRACE_CURL=$PWD/trace git clone "$HTTPD_URL/smart/repo.git" clone 2>err &&
+ grep -i "SOCKS4 request granted" trace
+ } ||
+ old_libcurl_error err
+ }
+'
+
+test_expect_success 'Unix socket requires socks*:' - <<\EOT
+ ! git clone -c http.proxy=localhost/path https://example.com/repo.git 2>err && {
+ grep -Fx "fatal: Invalid proxy URL 'localhost/path': only SOCKS proxies support paths" err ||
+ old_libcurl_error err
+ }
+EOT
+
+test_expect_success 'Unix socket requires localhost' - <<\EOT
+ ! git clone -c http.proxy=socks4://127.0.0.1/path https://example.com/repo.git 2>err && {
+ grep -Fx "fatal: Invalid proxy URL 'socks4://127.0.0.1/path': host must be localhost if a path is present" err ||
+ old_libcurl_error err
+ }
+EOT
+
test_done
diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
index f9a9bf9503..c5f08b6799 100755
--- a/t/t5570-git-daemon.sh
+++ b/t/t5570-git-daemon.sh
@@ -4,6 +4,7 @@ test_description='test fetching over git protocol'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-git-daemon.sh
diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
index 339d8c786f..d9a320abd2 100755
--- a/t/t5605-clone-local.sh
+++ b/t/t5605-clone-local.sh
@@ -4,6 +4,7 @@ test_description='test local clone'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
repo_is_hardlinked() {
diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh
index 0d1e92d996..7ceaa8194d 100755
--- a/t/t5607-clone-bundle.sh
+++ b/t/t5607-clone-bundle.sh
@@ -4,6 +4,7 @@ test_description='some bundle related tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
@@ -138,6 +139,41 @@ test_expect_success 'fetch SHA-1 from bundle' '
git fetch --no-tags foo/tip.bundle "$(cat hash)"
'
+test_expect_success 'clone bundle with different fsckObjects configurations' '
+ test_create_repo bundle-fsck &&
+ (
+ cd bundle-fsck &&
+ test_commit A &&
+ commit_a=$(git rev-parse A) &&
+ tree_a=$(git rev-parse A^{tree}) &&
+ cat >data <<-EOF &&
+ tree $tree_a
+ parent $commit_a
+ author A U Thor
+ committer A U Thor
+
+ commit: this is a commit with bad emails
+
+ EOF
+ bad_commit=$(git hash-object --literally -t commit -w --stdin <data) &&
+ git branch bad $bad_commit &&
+ git bundle create bad.bundle bad
+ ) &&
+
+ git clone bundle-fsck/bad.bundle bundle-no-fsck &&
+
+ git -c fetch.fsckObjects=false -c transfer.fsckObjects=true \
+ clone bundle-fsck/bad.bundle bundle-fetch-no-fsck &&
+
+ test_must_fail git -c fetch.fsckObjects=true \
+ clone bundle-fsck/bad.bundle bundle-fetch-fsck 2>err &&
+ test_grep "missingEmail" err &&
+
+ test_must_fail git -c transfer.fsckObjects=true \
+ clone bundle-fsck/bad.bundle bundle-transfer-fsck 2>err &&
+ test_grep "missingEmail" err
+'
+
test_expect_success 'git bundle uses expected default format' '
git bundle create bundle HEAD^.. &&
cat >expect <<-EOF &&
diff --git a/t/t5612-clone-refspec.sh b/t/t5612-clone-refspec.sh
index 3126cfd7e9..72762de977 100755
--- a/t/t5612-clone-refspec.sh
+++ b/t/t5612-clone-refspec.sh
@@ -4,6 +4,7 @@ test_description='test refspec written by clone-command'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh
index 6289a2e8b0..f6d17ee902 100755
--- a/t/t6000-rev-list-misc.sh
+++ b/t/t6000-rev-list-misc.sh
@@ -5,6 +5,7 @@ test_description='miscellaneous rev-list tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh
index 73a2465aa0..3553bbbfe7 100755
--- a/t/t6001-rev-list-graft.sh
+++ b/t/t6001-rev-list-graft.sh
@@ -5,6 +5,7 @@ test_description='Revision traversal vs grafts and path limiter'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t6007-rev-list-cherry-pick-file.sh b/t/t6007-rev-list-cherry-pick-file.sh
index 6f3e543977..2d337d7287 100755
--- a/t/t6007-rev-list-cherry-pick-file.sh
+++ b/t/t6007-rev-list-cherry-pick-file.sh
@@ -5,6 +5,7 @@ test_description='test git rev-list --cherry-pick -- file'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# A---B---D---F
diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
index 44c726ea39..f96ea82e78 100755
--- a/t/t6010-merge-base.sh
+++ b/t/t6010-merge-base.sh
@@ -6,6 +6,7 @@
test_description='Merge base and parent list computation.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
M=1130000000
diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh
index 39793cbbd6..4128269c1d 100755
--- a/t/t6013-rev-list-reverse-parents.sh
+++ b/t/t6013-rev-list-reverse-parents.sh
@@ -5,6 +5,7 @@ test_description='--reverse combines with --parents'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
diff --git a/t/t6017-rev-list-stdin.sh b/t/t6017-rev-list-stdin.sh
index 4821b90e74..a0a40fe55c 100755
--- a/t/t6017-rev-list-stdin.sh
+++ b/t/t6017-rev-list-stdin.sh
@@ -8,6 +8,7 @@ test_description='log family learns --stdin'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check () {
diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh
index 3e6bcbf30c..fe75a06572 100755
--- a/t/t6020-bundle-misc.sh
+++ b/t/t6020-bundle-misc.sh
@@ -8,6 +8,7 @@ test_description='Test git-bundle'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-bundle.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
diff --git a/t/t6115-rev-list-du.sh b/t/t6115-rev-list-du.sh
index c0cfda62fa..21c4a211b1 100755
--- a/t/t6115-rev-list-du.sh
+++ b/t/t6115-rev-list-du.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='basic tests of rev-list --disk-usage'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# we want a mix of reachable and unreachable, as well as
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index e78315d23d..05ed2510d9 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -14,6 +14,7 @@ test_description='test describe'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check_describe () {
@@ -671,4 +672,40 @@ test_expect_success 'setup misleading taggerdates' '
check_describe newer-tag-older-commit~1 --contains unique-file~2
+test_expect_success 'describe --dirty with a file with changed stat' '
+ test_when_finished "rm -fr stat-dirty" &&
+ git init stat-dirty &&
+ (
+ cd stat-dirty &&
+
+ echo A >file &&
+ git add file &&
+ git commit -m A &&
+ git tag A -a -m A &&
+ echo "A" >expect &&
+
+ test-tool chmtime -10 file &&
+ git describe --dirty >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'describe --broken --dirty with a file with changed stat' '
+ test_when_finished "rm -fr stat-dirty" &&
+ git init stat-dirty &&
+ (
+ cd stat-dirty &&
+
+ echo A >file &&
+ git add file &&
+ git commit -m A &&
+ git tag A -a -m A &&
+ echo "A" >expect &&
+
+ test-tool chmtime -10 file &&
+ git describe --dirty --broken >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
index ba7902c9cd..82de25d549 100755
--- a/t/t6130-pathspec-noglob.sh
+++ b/t/t6130-pathspec-noglob.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='test globbing (and noglob) of pathspec limiting'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'create commits with glob characters' '
diff --git a/t/t6133-pathspec-rev-dwim.sh b/t/t6133-pathspec-rev-dwim.sh
index a290ffca0d..6dd4bbbf9f 100755
--- a/t/t6133-pathspec-rev-dwim.sh
+++ b/t/t6133-pathspec-rev-dwim.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='test dwim of revs versus pathspecs in revision parser'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh
index 2738b50c2a..729aac9842 100755
--- a/t/t6402-merge-rename.sh
+++ b/t/t6402-merge-rename.sh
@@ -4,6 +4,7 @@ test_description='Merge-recursive merging renames'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
modify () {
diff --git a/t/t6406-merge-attr.sh b/t/t6406-merge-attr.sh
index 156a1efacf..9bf9524934 100755
--- a/t/t6406-merge-attr.sh
+++ b/t/t6406-merge-attr.sh
@@ -185,7 +185,7 @@ test_expect_success !WINDOWS 'custom merge driver that is killed with a signal'
>./please-abort &&
echo "* merge=custom" >.gitattributes &&
- test_must_fail git merge main 2>err &&
+ test_expect_code 2 git merge main 2>err &&
grep "^error: failed to execute internal merge" err &&
git ls-files -u >output &&
git diff --name-only HEAD >>output &&
@@ -261,4 +261,44 @@ test_expect_success 'binary files with union attribute' '
grep -i "warning.*cannot merge.*HEAD vs. bin-main" output
'
+test_expect_success !WINDOWS 'custom merge driver that is killed with a signal on recursive merge' '
+ test_when_finished "rm -f output please-abort" &&
+ test_when_finished "git checkout side" &&
+
+ git reset --hard anchor &&
+
+ git checkout -b base-a main^ &&
+ echo base-a >text &&
+ git commit -m base-a text &&
+
+ git checkout -b base-b main^ &&
+ echo base-b >text &&
+ git commit -m base-b text &&
+
+ git checkout -b recursive-a base-a &&
+ test_must_fail git merge base-b &&
+ echo recursive-a >text &&
+ git add text &&
+ git commit -m recursive-a &&
+
+ git checkout -b recursive-b base-b &&
+ test_must_fail git merge base-a &&
+ echo recursive-b >text &&
+ git add text &&
+ git commit -m recursive-b &&
+
+ git config --replace-all \
+ merge.custom.driver "./custom-merge %O %A %B 0 %P %S %X %Y" &&
+ git config --replace-all \
+ merge.custom.name "custom merge driver for testing" &&
+
+ >./please-abort &&
+ echo "* merge=custom" >.gitattributes &&
+ test_expect_code 2 git merge recursive-a 2>err &&
+ grep "error: failed to execute internal merge" err &&
+ git ls-files -u >output &&
+ git diff --name-only HEAD >>output &&
+ test_must_be_empty output
+'
+
test_done
diff --git a/t/t6421-merge-partial-clone.sh b/t/t6421-merge-partial-clone.sh
index 711b709e75..b99f29ef9b 100755
--- a/t/t6421-merge-partial-clone.sh
+++ b/t/t6421-merge-partial-clone.sh
@@ -230,8 +230,9 @@ test_expect_merge_algorithm failure success 'Objects downloaded for single relev
grep fetch_count trace.output | cut -d "|" -f 9 | tr -d " ." >actual &&
test_cmp expect actual &&
- # Check the number of fetch commands exec-ed
- grep d0.*fetch.negotiationAlgorithm trace.output >fetches &&
+ # Check the number of fetch commands exec-ed by filtering trace to
+ # child_start events by the top-level program (2nd field == d0)
+ grep " d0 .* child_start .*fetch.negotiationAlgorithm" trace.output >fetches &&
test_line_count = 2 fetches &&
git rev-list --objects --all --missing=print |
@@ -318,8 +319,9 @@ test_expect_merge_algorithm failure success 'Objects downloaded when a directory
grep fetch_count trace.output | cut -d "|" -f 9 | tr -d " ." >actual &&
test_cmp expect actual &&
- # Check the number of fetch commands exec-ed
- grep d0.*fetch.negotiationAlgorithm trace.output >fetches &&
+ # Check the number of fetch commands exec-ed by filtering trace to
+ # child_start events by the top-level program (2nd field == d0)
+ grep " d0 .* child_start .*fetch.negotiationAlgorithm" trace.output >fetches &&
test_line_count = 1 fetches &&
git rev-list --objects --all --missing=print |
@@ -422,8 +424,9 @@ test_expect_merge_algorithm failure success 'Objects downloaded with lots of ren
grep fetch_count trace.output | cut -d "|" -f 9 | tr -d " ." >actual &&
test_cmp expect actual &&
- # Check the number of fetch commands exec-ed
- grep d0.*fetch.negotiationAlgorithm trace.output >fetches &&
+ # Check the number of fetch commands exec-ed by filtering trace to
+ # child_start events by the top-level program (2nd field == d0)
+ grep " d0 .* child_start .*fetch.negotiationAlgorithm" trace.output >fetches &&
test_line_count = 4 fetches &&
git rev-list --objects --all --missing=print |
diff --git a/t/t6427-diff3-conflict-markers.sh b/t/t6427-diff3-conflict-markers.sh
index dd5fe6a402..a13271b349 100755
--- a/t/t6427-diff3-conflict-markers.sh
+++ b/t/t6427-diff3-conflict-markers.sh
@@ -5,6 +5,7 @@ test_description='recursive merge diff3 style conflict markers'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Setup:
diff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh
index ca15e6dd6d..555f00f78a 100755
--- a/t/t6430-merge-recursive.sh
+++ b/t/t6430-merge-recursive.sh
@@ -5,6 +5,7 @@ test_description='merge-recursive backend test'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-merge.sh
diff --git a/t/t6432-merge-recursive-space-options.sh b/t/t6432-merge-recursive-space-options.sh
index db4b77e63d..c93538b0c3 100755
--- a/t/t6432-merge-recursive-space-options.sh
+++ b/t/t6432-merge-recursive-space-options.sh
@@ -14,6 +14,7 @@ test_description='merge-recursive space options
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_have_prereq SED_STRIPS_CR && SED_OPTIONS=-b
diff --git a/t/t6434-merge-recursive-rename-options.sh b/t/t6434-merge-recursive-rename-options.sh
index a11707835b..df1d0c156c 100755
--- a/t/t6434-merge-recursive-rename-options.sh
+++ b/t/t6434-merge-recursive-rename-options.sh
@@ -29,6 +29,7 @@ mentions this in a different context).
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
get_expected_stages () {
diff --git a/t/t6436-merge-overwrite.sh b/t/t6436-merge-overwrite.sh
index 4f4376421e..ccc620477d 100755
--- a/t/t6436-merge-overwrite.sh
+++ b/t/t6436-merge-overwrite.sh
@@ -7,6 +7,7 @@ Do not overwrite changes.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh
index e56ca5b0fa..a0296d6ca4 100755
--- a/t/t7006-pager.sh
+++ b/t/t7006-pager.sh
@@ -2,6 +2,7 @@
test_description='Test automatic use of a pager.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-pager.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
@@ -725,18 +726,11 @@ test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' '
test_path_is_file pager-used
'
-test_expect_success TTY 'git skips paging nonexisting command' '
- test_when_finished "rm trace.normal" &&
+test_expect_success TTY 'git errors when asked to execute nonexisting pager' '
+ test_when_finished "rm -f err" &&
test_config core.pager "does-not-exist" &&
- GIT_TRACE2="$(pwd)/trace.normal" &&
- export GIT_TRACE2 &&
- test_when_finished "unset GIT_TRACE2" &&
-
- test_terminal git log &&
-
- grep child_exit trace.normal >child-exits &&
- test_line_count = 1 child-exits &&
- grep " code:-1 " child-exits
+ test_must_fail test_terminal git log 2>err &&
+ test_grep "unable to execute pager" err
'
test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
@@ -762,7 +756,7 @@ test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
test_expect_success TTY 'non-existent pager doesnt cause crash' '
test_config pager.show invalid-pager &&
- test_terminal git show
+ test_must_fail test_terminal git show
'
test_done
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index 520f96d09f..d9add2162e 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -2,6 +2,7 @@
test_description='setup taking and sanitizing funny paths'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index cd5c20fe51..d984200c17 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -5,6 +5,7 @@
test_description='test worktree writing operations when skip-worktree is used'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh
index 11884d2fc3..06c1301222 100755
--- a/t/t7064-wtstatus-pv2.sh
+++ b/t/t7064-wtstatus-pv2.sh
@@ -4,6 +4,7 @@ test_description='git status --porcelain=v2
This test exercises porcelain V2 output for git status.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 42352dc0db..2d984eb4c6 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -23,6 +23,7 @@ Test switching across them.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_tick
@@ -497,6 +498,19 @@ test_expect_success 'checkout unmerged stage' '
test ztheirside = "z$(cat file)"
'
+test_expect_success 'checkout --ours is incompatible with switching' '
+ test_must_fail git checkout --ours 2>error &&
+ test_grep "needs the paths to check out" error &&
+
+ test_must_fail git checkout --ours HEAD 2>error &&
+ test_grep "cannot be used with switching" error &&
+
+ test_must_fail git checkout --ours main 2>error &&
+ test_grep "cannot be used with switching" error &&
+
+ git checkout --ours file
+'
+
test_expect_success 'checkout path with --merge from tree-ish is a no-no' '
setup_conflicting_index &&
test_must_fail git checkout -m HEAD -- file
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 981488885f..098d8833b6 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -12,6 +12,7 @@ subcommands of git submodule.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup - enable local submodules' '
diff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh
index cc12f99f11..52f5e28154 100755
--- a/t/t7501-commit-basic-functionality.sh
+++ b/t/t7501-commit-basic-functionality.sh
@@ -9,6 +9,7 @@ test_description='git commit'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY/lib-diff.sh"
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 2128142a61..b88383df9e 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -5,6 +5,7 @@ test_description='prepare-commit-msg hook'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'set up commits for rebasing' '
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index 802f8f704c..cdd5f2c697 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -10,6 +10,7 @@ test_description='git status advice'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index ef54cff4fa..65fd3d8552 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -29,6 +29,7 @@ Testing basic merge operations/option parsing.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-gpg.sh
diff --git a/t/t7606-merge-custom.sh b/t/t7606-merge-custom.sh
index 81fb7c474c..135cb23085 100755
--- a/t/t7606-merge-custom.sh
+++ b/t/t7606-merge-custom.sh
@@ -14,6 +14,7 @@ Testing a custom strategy.
* (tag: c0) c0
"
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'set up custom strategy' '
diff --git a/t/t7611-merge-abort.sh b/t/t7611-merge-abort.sh
index d6975ca48d..992a8f9874 100755
--- a/t/t7611-merge-abort.sh
+++ b/t/t7611-merge-abort.sh
@@ -25,6 +25,7 @@ Next, test git merge --abort with the following variables:
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t7615-diff-algo-with-mergy-operations.sh b/t/t7615-diff-algo-with-mergy-operations.sh
new file mode 100755
index 0000000000..9a83be518c
--- /dev/null
+++ b/t/t7615-diff-algo-with-mergy-operations.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+test_description='git merge and other operations that rely on merge
+
+Testing the influence of the diff algorithm on the merge output.'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ cp "$TEST_DIRECTORY"/t7615/base.c file.c &&
+ git add file.c &&
+ git commit -m c0 &&
+ git tag c0 &&
+ cp "$TEST_DIRECTORY"/t7615/ours.c file.c &&
+ git add file.c &&
+ git commit -m c1 &&
+ git tag c1 &&
+ git reset --hard c0 &&
+ cp "$TEST_DIRECTORY"/t7615/theirs.c file.c &&
+ git add file.c &&
+ git commit -m c2 &&
+ git tag c2
+'
+
+GIT_TEST_MERGE_ALGORITHM=recursive
+
+test_expect_success 'merge c2 to c1 with recursive merge strategy fails with the current default myers diff algorithm' '
+ git reset --hard c1 &&
+ test_must_fail git merge -s recursive c2
+'
+
+test_expect_success 'merge c2 to c1 with recursive merge strategy succeeds with -Xdiff-algorithm=histogram' '
+ git reset --hard c1 &&
+ git merge --strategy recursive -Xdiff-algorithm=histogram c2
+'
+
+test_expect_success 'merge c2 to c1 with recursive merge strategy succeeds with diff.algorithm = histogram' '
+ git reset --hard c1 &&
+ git config diff.algorithm histogram &&
+ git merge --strategy recursive c2
+'
+
+test_expect_success 'cherry-pick c2 to c1 with recursive merge strategy fails with the current default myers diff algorithm' '
+ git reset --hard c1 &&
+ test_must_fail git cherry-pick -s recursive c2
+'
+
+test_expect_success 'cherry-pick c2 to c1 with recursive merge strategy succeeds with -Xdiff-algorithm=histogram' '
+ git reset --hard c1 &&
+ git cherry-pick --strategy recursive -Xdiff-algorithm=histogram c2
+'
+
+test_expect_success 'cherry-pick c2 to c1 with recursive merge strategy succeeds with diff.algorithm = histogram' '
+ git reset --hard c1 &&
+ git config diff.algorithm histogram &&
+ git cherry-pick --strategy recursive c2
+'
+
+test_done
diff --git a/t/t7615/base.c b/t/t7615/base.c
new file mode 100644
index 0000000000..c64abc5936
--- /dev/null
+++ b/t/t7615/base.c
@@ -0,0 +1,17 @@
+int f(int x, int y)
+{
+ if (x == 0)
+ {
+ return y;
+ }
+ return x;
+}
+
+int g(size_t u)
+{
+ while (u < 30)
+ {
+ u++;
+ }
+ return u;
+}
diff --git a/t/t7615/ours.c b/t/t7615/ours.c
new file mode 100644
index 0000000000..44d8251397
--- /dev/null
+++ b/t/t7615/ours.c
@@ -0,0 +1,17 @@
+int g(size_t u)
+{
+ while (u < 30)
+ {
+ u++;
+ }
+ return u;
+}
+
+int h(int x, int y, int z)
+{
+ if (z == 0)
+ {
+ return x;
+ }
+ return y;
+}
diff --git a/t/t7615/theirs.c b/t/t7615/theirs.c
new file mode 100644
index 0000000000..85f02146fe
--- /dev/null
+++ b/t/t7615/theirs.c
@@ -0,0 +1,17 @@
+int f(int x, int y)
+{
+ if (x == 0)
+ {
+ return y;
+ }
+ return x;
+}
+
+int g(size_t u)
+{
+ while (u > 34)
+ {
+ u--;
+ }
+ return u;
+}
diff --git a/t/t7704-repack-cruft.sh b/t/t7704-repack-cruft.sh
index 71e1ef3a10..959e6e2648 100755
--- a/t/t7704-repack-cruft.sh
+++ b/t/t7704-repack-cruft.sh
@@ -330,7 +330,7 @@ test_expect_success '--max-cruft-size with pruning' '
# repack (and prune) with a --max-cruft-size to ensure
# that we appropriately split the resulting set of packs
git repack -d --cruft --max-cruft-size=1M \
- --cruft-expiration=10.seconds.ago &&
+ --cruft-expiration=1000.seconds.ago &&
ls $packdir/pack-*.mtimes | sort >cruft.after &&
for cruft in $(cat cruft.after)
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 875dcfd98f..af2cf2f78a 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -31,6 +31,7 @@ int main(int argc, const char **argv)
return 0;
/* char ?? */
}
+
EOF
test_expect_success setup '
diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh
index 0147de304b..3596634039 100755
--- a/t/t8002-blame.sh
+++ b/t/t8002-blame.sh
@@ -5,6 +5,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_CREATE_REPO_NO_TEMPLATE=1
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
PROG='git blame -c'
diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh
index 731265541a..6288352f57 100755
--- a/t/t8003-blame-corner-cases.sh
+++ b/t/t8003-blame-corner-cases.sh
@@ -4,6 +4,7 @@ test_description='git blame corner cases'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
pick_fc='s/^[0-9a-f^]* *\([^ ]*\) *(\([^ ]*\) .*/\1-\2/'
diff --git a/t/t8004-blame-with-conflicts.sh b/t/t8004-blame-with-conflicts.sh
index 35414a5336..2c2a0b33f9 100755
--- a/t/t8004-blame-with-conflicts.sh
+++ b/t/t8004-blame-with-conflicts.sh
@@ -6,6 +6,7 @@ test_description='git blame on conflicted files'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup first case' '
diff --git a/t/t8006-blame-textconv.sh b/t/t8006-blame-textconv.sh
index 7683515155..42f8be25a3 100755
--- a/t/t8006-blame-textconv.sh
+++ b/t/t8006-blame-textconv.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='git blame textconv support'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
find_blame() {
diff --git a/t/t8008-blame-formats.sh b/t/t8008-blame-formats.sh
index ae4b579d24..fb5d225a67 100755
--- a/t/t8008-blame-formats.sh
+++ b/t/t8008-blame-formats.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='blame output in various formats on a simple case'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
diff --git a/t/t8009-blame-vs-topicbranches.sh b/t/t8009-blame-vs-topicbranches.sh
index 72596e38b2..30331713b9 100755
--- a/t/t8009-blame-vs-topicbranches.sh
+++ b/t/t8009-blame-vs-topicbranches.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='blaming trough history with topic branches'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Creates the history shown below. '*'s mark the first parent in the merges.
diff --git a/t/t8011-blame-split-file.sh b/t/t8011-blame-split-file.sh
index bdda0c03fe..da1801f4d2 100755
--- a/t/t8011-blame-split-file.sh
+++ b/t/t8011-blame-split-file.sh
@@ -10,6 +10,8 @@ Note that we need to use "blame -C" to find the commit for all lines. We will
not bother testing that the non-C case fails to find it. That is how blame
behaves now, but it is not a property we want to make sure is retained.
'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# help avoid typing and reading long strings of similar lines
diff --git a/t/t8012-blame-colors.sh b/t/t8012-blame-colors.sh
index c3a5f6d01f..9a79c109f2 100755
--- a/t/t8012-blame-colors.sh
+++ b/t/t8012-blame-colors.sh
@@ -5,6 +5,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_CREATE_REPO_NO_TEMPLATE=1
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
PROG='git blame -c'
diff --git a/t/t8013-blame-ignore-revs.sh b/t/t8013-blame-ignore-revs.sh
index dbfbd86e83..d33788d867 100755
--- a/t/t8013-blame-ignore-revs.sh
+++ b/t/t8013-blame-ignore-revs.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='ignore revisions when blaming'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Creates:
diff --git a/t/t8014-blame-ignore-fuzzy.sh b/t/t8014-blame-ignore-fuzzy.sh
index 0bd0341301..933222cea1 100755
--- a/t/t8014-blame-ignore-fuzzy.sh
+++ b/t/t8014-blame-ignore-fuzzy.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='git blame ignore fuzzy heuristic'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
pick_author='s/^[0-9a-f^]* *(\([^ ]*\) .*/\1/'
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 58699f8e4e..64a4ab3736 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -1299,6 +1299,49 @@ test_expect_success $PREREQ 'utf8 sender is not duplicated' '
test_line_count = 1 msgfrom
'
+test_expect_success $PREREQ 'setup expect for cc list' "
+cat >expected-cc <<\EOF
+!recipient@example.com!
+!author@example.com!
+!one@example.com!
+!os@example.com!
+!odd_?=mail@example.com!
+!doug@example.com!
+!codev@example.com!
+!thor.au@example.com!
+EOF
+"
+
+test_expect_success $PREREQ 'cc list is sanitized' '
+ clean_fake_sendmail &&
+ test_commit weird_cc_body &&
+ test_when_finished "git reset --hard HEAD^" &&
+ git commit --amend -F - <<-EOF &&
+ Test Cc: sanitization.
+
+ Cc: Person, One <one@example.com>
+ Cc: Ronnie O${SQ}Sullivan <os@example.com>
+ Reviewed-by: Füñný Nâmé <odd_?=mail@example.com>
+ Reported-by: bugger on Jira
+ Reported-by: Douglas Reporter <doug@example.com> [from Jira profile]
+ BugID: 12345
+ Co-developed-by: "C. O. Developer" <codev@example.com>
+ Signed-off-by: A. U. Thor <thor.au@example.com>
+ EOF
+ git send-email -1 --to=recipient@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" >actual-show-all-headers &&
+ test_cmp expected-cc commandline1 &&
+ test_grep "^(body) Adding cc: \"Person, One\" <one@example.com>" actual-show-all-headers &&
+ test_grep "^(body) Adding cc: Ronnie O${SQ}Sullivan <os@example.com>" actual-show-all-headers &&
+ test_grep "^(body) Adding cc: =?UTF-8?q?F=C3=BC=C3=B1n=C3=BD=20N=C3=A2m=C3=A9?="\
+" <odd_?=mail@example.com>" actual-show-all-headers &&
+ test_grep "^(body) Ignoring Reported-by .* bugger on Jira" actual-show-all-headers &&
+ test_grep "^(body) Adding cc: Douglas Reporter <doug@example.com>" actual-show-all-headers &&
+ test_grep ! "12345" actual-show-all-headers &&
+ test_grep "^(body) Adding cc: \"C. O. Developer\" <codev@example.com>" actual-show-all-headers &&
+ test_grep "^(body) Adding cc: \"A. U. Thor\" <thor.au@example.com>" actual-show-all-headers
+'
+
test_expect_success $PREREQ 'sendemail.composeencoding works' '
clean_fake_sendmail &&
git config sendemail.composeencoding iso-8859-1 &&
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 7679780fb8..ccfa415384 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -13,6 +13,7 @@ or warnings to log.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-gitweb.sh
# ----------------------------------------------------------------------
diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh
index 81d5625557..b41ea19331 100755
--- a/t/t9502-gitweb-standalone-parse-output.sh
+++ b/t/t9502-gitweb-standalone-parse-output.sh
@@ -13,6 +13,7 @@ in the HTTP header or the actual script output.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-gitweb.sh
# ----------------------------------------------------------------------
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 53af8e34ac..3e6dfce248 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -5,6 +5,7 @@ test_description='git p4 tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
@@ -297,8 +298,20 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '
# p4 changes, files, or describe; just in p4 print. If P4CLIENT is unset, the
# message will include "Librarian checkout".
test_expect_success 'exit gracefully for p4 server errors' '
- test_when_finished "mv \"$db\"/depot/file1,v,hidden \"$db\"/depot/file1,v" &&
- mv "$db"/depot/file1,v "$db"/depot/file1,v,hidden &&
+ # Note that newer Perforce versions started to store files
+ # compressed in directories. The case statement handles both
+ # old and new layout.
+ case "$(echo "$db"/depot/file1*)" in
+ *,v)
+ test_when_finished "mv \"$db\"/depot/file1,v,hidden \"$db\"/depot/file1,v" &&
+ mv "$db"/depot/file1,v "$db"/depot/file1,v,hidden;;
+ *,d)
+ path="$(echo "$db"/depot/file1,d/*.gz)" &&
+ test_when_finished "mv \"$path\",hidden \"$path\"" &&
+ mv "$path" "$path",hidden;;
+ *)
+ BUG "unhandled p4d layout";;
+ esac &&
test_when_finished cleanup_git &&
test_expect_code 1 git p4 clone --dest="$git" //depot@1 >out 2>err &&
test_grep "Error from p4 print" err
diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh
index c598011635..cdbfacc727 100755
--- a/t/t9801-git-p4-branch.sh
+++ b/t/t9801-git-p4-branch.sh
@@ -5,6 +5,7 @@ test_description='git p4 tests for p4 branches'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh
index bb236cd2b5..1bc48305b0 100755
--- a/t/t9802-git-p4-filetype.sh
+++ b/t/t9802-git-p4-filetype.sh
@@ -2,6 +2,7 @@
test_description='git p4 filetype tests'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
@@ -300,10 +301,22 @@ test_expect_success SYMLINKS 'empty symlink target' '
# text
# @@
#
+ # Note that newer Perforce versions started to store files
+ # compressed in directories. The case statement handles both
+ # old and new layout.
cd "$db/depot" &&
- sed "/@target1/{; s/target1/@/; n; d; }" \
- empty-symlink,v >empty-symlink,v.tmp &&
- mv empty-symlink,v.tmp empty-symlink,v
+ case "$(echo empty-symlink*)" in
+ empty-symlink,v)
+ sed "/@target1/{; s/target1/@/; n; d; }" \
+ empty-symlink,v >empty-symlink,v.tmp &&
+ mv empty-symlink,v.tmp empty-symlink,v;;
+ empty-symlink,d)
+ path="empty-symlink,d/$(ls empty-symlink,d/ | tail -n1)" &&
+ rm "$path" &&
+ gzip </dev/null >"$path";;
+ *)
+ BUG "unhandled p4d layout";;
+ esac
) &&
(
# Make sure symlink really is empty. Asking
diff --git a/t/t9803-git-p4-shell-metachars.sh b/t/t9803-git-p4-shell-metachars.sh
index 2913277013..ab7fe16266 100755
--- a/t/t9803-git-p4-shell-metachars.sh
+++ b/t/t9803-git-p4-shell-metachars.sh
@@ -2,6 +2,7 @@
test_description='git p4 transparency to shell metachars in filenames'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9804-git-p4-label.sh b/t/t9804-git-p4-label.sh
index 3236457106..c8963fd398 100755
--- a/t/t9804-git-p4-label.sh
+++ b/t/t9804-git-p4-label.sh
@@ -2,6 +2,7 @@
test_description='git p4 label tests'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9805-git-p4-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh
index 90ef647db7..72dce3d2b4 100755
--- a/t/t9805-git-p4-skip-submit-edit.sh
+++ b/t/t9805-git-p4-skip-submit-edit.sh
@@ -2,6 +2,7 @@
test_description='git p4 skipSubmitEdit config variables'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh
index c26d297433..e4ce44ebf3 100755
--- a/t/t9806-git-p4-options.sh
+++ b/t/t9806-git-p4-options.sh
@@ -5,6 +5,7 @@ test_description='git p4 options'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9808-git-p4-chdir.sh b/t/t9808-git-p4-chdir.sh
index 58a9b3b71e..342f7f3d4a 100755
--- a/t/t9808-git-p4-chdir.sh
+++ b/t/t9808-git-p4-chdir.sh
@@ -2,6 +2,7 @@
test_description='git p4 relative chdir'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 9c9710d8c7..f33fdea889 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -2,6 +2,7 @@
test_description='git p4 client view'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
index 5fe83315ec..15e32c9f35 100755
--- a/t/t9810-git-p4-rcs.sh
+++ b/t/t9810-git-p4-rcs.sh
@@ -2,6 +2,7 @@
test_description='git p4 rcs keywords'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
CP1252="\223\224"
diff --git a/t/t9811-git-p4-label-import.sh b/t/t9811-git-p4-label-import.sh
index 5ac5383fb7..52a4b0af81 100755
--- a/t/t9811-git-p4-label-import.sh
+++ b/t/t9811-git-p4-label-import.sh
@@ -5,6 +5,7 @@ test_description='git p4 label tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh
index 254a7c2446..46aa5fd56c 100755
--- a/t/t9812-git-p4-wildcards.sh
+++ b/t/t9812-git-p4-wildcards.sh
@@ -2,6 +2,7 @@
test_description='git p4 wildcards'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9813-git-p4-preserve-users.sh b/t/t9813-git-p4-preserve-users.sh
index fd018c87a8..0efea28da2 100755
--- a/t/t9813-git-p4-preserve-users.sh
+++ b/t/t9813-git-p4-preserve-users.sh
@@ -2,6 +2,7 @@
test_description='git p4 preserve users'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh
index 2a9838f37f..00df6ebd3b 100755
--- a/t/t9814-git-p4-rename.sh
+++ b/t/t9814-git-p4-rename.sh
@@ -2,6 +2,7 @@
test_description='git p4 rename'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh
index c766fd159f..92ef9d8c24 100755
--- a/t/t9815-git-p4-submit-fail.sh
+++ b/t/t9815-git-p4-submit-fail.sh
@@ -2,6 +2,7 @@
test_description='git p4 submit failure handling'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh
index 5e904ac80d..e687fbc25f 100755
--- a/t/t9816-git-p4-locked.sh
+++ b/t/t9816-git-p4-locked.sh
@@ -2,6 +2,7 @@
test_description='git p4 locked file behavior'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9817-git-p4-exclude.sh b/t/t9817-git-p4-exclude.sh
index ec3d937c6a..3deb334fed 100755
--- a/t/t9817-git-p4-exclude.sh
+++ b/t/t9817-git-p4-exclude.sh
@@ -2,6 +2,7 @@
test_description='git p4 tests for excluded paths during clone and sync'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh
index de591d875c..091bb72bdb 100755
--- a/t/t9818-git-p4-block.sh
+++ b/t/t9818-git-p4-block.sh
@@ -2,6 +2,7 @@
test_description='git p4 fetching changes in multiple blocks'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9819-git-p4-case-folding.sh b/t/t9819-git-p4-case-folding.sh
index b4d93f0c17..985be20357 100755
--- a/t/t9819-git-p4-case-folding.sh
+++ b/t/t9819-git-p4-case-folding.sh
@@ -2,6 +2,7 @@
test_description='interaction with P4 case-folding'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
if test_have_prereq CASE_INSENSITIVE_FS
diff --git a/t/t9820-git-p4-editor-handling.sh b/t/t9820-git-p4-editor-handling.sh
index fa1bba1dd9..48e4dfb95c 100755
--- a/t/t9820-git-p4-editor-handling.sh
+++ b/t/t9820-git-p4-editor-handling.sh
@@ -2,6 +2,7 @@
test_description='git p4 handling of EDITOR'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9821-git-p4-path-variations.sh b/t/t9821-git-p4-path-variations.sh
index ef80f1690b..49691c53da 100755
--- a/t/t9821-git-p4-path-variations.sh
+++ b/t/t9821-git-p4-path-variations.sh
@@ -2,6 +2,7 @@
test_description='Clone repositories with path case variations'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d with case folding enabled' '
diff --git a/t/t9822-git-p4-path-encoding.sh b/t/t9822-git-p4-path-encoding.sh
index 572d395498..e62ed49f51 100755
--- a/t/t9822-git-p4-path-encoding.sh
+++ b/t/t9822-git-p4-path-encoding.sh
@@ -2,6 +2,7 @@
test_description='Clone repositories with non ASCII paths'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
UTF8_ESCAPED="a-\303\244_o-\303\266_u-\303\274.txt"
diff --git a/t/t9823-git-p4-mock-lfs.sh b/t/t9823-git-p4-mock-lfs.sh
index 88b76dc4d6..98a40d8af3 100755
--- a/t/t9823-git-p4-mock-lfs.sh
+++ b/t/t9823-git-p4-mock-lfs.sh
@@ -2,6 +2,7 @@
test_description='Clone repositories and store files in Mock LFS'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_file_is_not_in_mock_lfs () {
diff --git a/t/t9825-git-p4-handle-utf16-without-bom.sh b/t/t9825-git-p4-handle-utf16-without-bom.sh
index f049ff8229..d0b86537dd 100755
--- a/t/t9825-git-p4-handle-utf16-without-bom.sh
+++ b/t/t9825-git-p4-handle-utf16-without-bom.sh
@@ -2,6 +2,7 @@
test_description='git p4 handling of UTF-16 files without BOM'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
UTF16="\227\000\227\000"
@@ -22,9 +23,25 @@ test_expect_success 'init depot with UTF-16 encoded file and artificially remove
cd db &&
p4d -jc &&
# P4D automatically adds a BOM. Remove it here to make the file invalid.
- sed -e "\$d" depot/file1,v >depot/file1,v.new &&
- mv depot/file1,v.new depot/file1,v &&
- printf "@$UTF16@" >>depot/file1,v &&
+ #
+ # Note that newer Perforce versions started to store files
+ # compressed in directories. The case statement handles both
+ # old and new layout.
+ case "$(echo depot/file1*)" in
+ depot/file1,v)
+ sed -e "\$d" depot/file1,v >depot/file1,v.new &&
+ mv depot/file1,v.new depot/file1,v &&
+ printf "@$UTF16@" >>depot/file1,v;;
+ depot/file1,d)
+ path="$(echo depot/file1,d/*.gz)" &&
+ gunzip -c "$path" >"$path.unzipped" &&
+ sed -e "\$d" "$path.unzipped" >"$path.new" &&
+ printf "$UTF16" >>"$path.new" &&
+ gzip -c "$path.new" >"$path" &&
+ rm "$path.unzipped" "$path.new";;
+ *)
+ BUG "unhandled p4d layout";;
+ esac &&
p4d -jrF checkpoint.1
)
'
diff --git a/t/t9826-git-p4-keep-empty-commits.sh b/t/t9826-git-p4-keep-empty-commits.sh
index fd64afe064..54083f842e 100755
--- a/t/t9826-git-p4-keep-empty-commits.sh
+++ b/t/t9826-git-p4-keep-empty-commits.sh
@@ -2,6 +2,7 @@
test_description='Clone repositories and keep empty commits'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9827-git-p4-change-filetype.sh b/t/t9827-git-p4-change-filetype.sh
index d3670bd7a2..3476ea2fd3 100755
--- a/t/t9827-git-p4-change-filetype.sh
+++ b/t/t9827-git-p4-change-filetype.sh
@@ -2,6 +2,7 @@
test_description='git p4 support for file type change'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9828-git-p4-map-user.sh b/t/t9828-git-p4-map-user.sh
index ca6c2942bd..7c8f9e3930 100755
--- a/t/t9828-git-p4-map-user.sh
+++ b/t/t9828-git-p4-map-user.sh
@@ -2,6 +2,7 @@
test_description='Clone repositories and map users'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9829-git-p4-jobs.sh b/t/t9829-git-p4-jobs.sh
index 88cfb1fcd3..3fc0948d9c 100755
--- a/t/t9829-git-p4-jobs.sh
+++ b/t/t9829-git-p4-jobs.sh
@@ -2,6 +2,7 @@
test_description='git p4 retrieve job info'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9830-git-p4-symlink-dir.sh b/t/t9830-git-p4-symlink-dir.sh
index 3fb6960c18..02561a7f0e 100755
--- a/t/t9830-git-p4-symlink-dir.sh
+++ b/t/t9830-git-p4-symlink-dir.sh
@@ -2,6 +2,7 @@
test_description='git p4 symlinked directories'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9831-git-p4-triggers.sh b/t/t9831-git-p4-triggers.sh
index ff6c0352e6..f287f41e37 100755
--- a/t/t9831-git-p4-triggers.sh
+++ b/t/t9831-git-p4-triggers.sh
@@ -2,6 +2,7 @@
test_description='git p4 with server triggers'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh
index 6b3cb0414a..a266775408 100755
--- a/t/t9832-unshelve.sh
+++ b/t/t9832-unshelve.sh
@@ -6,6 +6,7 @@ last_shelved_change () {
test_description='git p4 unshelve'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9833-errors.sh b/t/t9833-errors.sh
index e22369ccdf..da1d30c142 100755
--- a/t/t9833-errors.sh
+++ b/t/t9833-errors.sh
@@ -2,6 +2,7 @@
test_description='git p4 errors'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9834-git-p4-file-dir-bug.sh b/t/t9834-git-p4-file-dir-bug.sh
index dac67e89d7..565870fc74 100755
--- a/t/t9834-git-p4-file-dir-bug.sh
+++ b/t/t9834-git-p4-file-dir-bug.sh
@@ -6,6 +6,7 @@ This test creates files and directories with the same name in perforce and
checks that git-p4 recovers from the error at the same time as the perforce
repository.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh
index 036bf79c66..ad20ffdede 100755
--- a/t/t9835-git-p4-metadata-encoding-python2.sh
+++ b/t/t9835-git-p4-metadata-encoding-python2.sh
@@ -6,6 +6,7 @@ This test checks that the import process handles inconsistent text
encoding in p4 metadata (author names, commit messages, etc) without
failing, and produces maximally sane output in git.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
python_target_version='2'
diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh
index 63350dc4b5..71ae763399 100755
--- a/t/t9836-git-p4-metadata-encoding-python3.sh
+++ b/t/t9836-git-p4-metadata-encoding-python3.sh
@@ -6,6 +6,7 @@ This test checks that the import process handles inconsistent text
encoding in p4 metadata (author names, commit messages, etc) without
failing, and produces maximally sane output in git.'
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-git-p4.sh
python_target_version='3'
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 932d5ad759..cc6aa9f0cd 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -16,6 +16,7 @@ test_untraceable=UnfortunatelyYes
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-bash.sh
complete ()
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index d667dda654..95e9955bca 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -8,6 +8,7 @@ test_description='test git-specific bash prompt functions'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./lib-bash.sh
. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 1ea9f31225..fde9bf54fc 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -872,6 +872,24 @@ test_verify_prereq () {
BUG "'$test_prereq' does not look like a prereq"
}
+# assign the variable named by "$1" with the contents of "$2";
+# if "$2" is "-", then read stdin into "$1" instead
+test_body_or_stdin () {
+ if test "$2" != "-"
+ then
+ eval "$1=\$2"
+ return
+ fi
+
+ # start with a newline, to match hanging newline from open-quote style
+ eval "$1=\$LF"
+ local test_line
+ while IFS= read -r test_line
+ do
+ eval "$1=\${$1}\${test_line}\${LF}"
+ done
+}
+
test_expect_failure () {
test_start_ "$@"
test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
@@ -881,9 +899,11 @@ test_expect_failure () {
export test_prereq
if ! test_skip "$@"
then
+ local test_body
+ test_body_or_stdin test_body "$2"
test -n "$test_skip_test_preamble" ||
- say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
- if test_run_ "$2" expecting_failure
+ say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $test_body"
+ if test_run_ "$test_body" expecting_failure
then
test_known_broken_ok_ "$1"
else
@@ -902,13 +922,15 @@ test_expect_success () {
export test_prereq
if ! test_skip "$@"
then
+ local test_body
+ test_body_or_stdin test_body "$2"
test -n "$test_skip_test_preamble" ||
- say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
- if test_run_ "$2"
+ say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $test_body"
+ if test_run_ "$test_body"
then
test_ok_ "$1"
else
- test_failure_ "$@"
+ test_failure_ "$1" "$test_body"
fi
fi
test_finish_
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 79d3e0e7d9..54247604cb 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1269,9 +1269,12 @@ check_test_results_san_file_ () {
then
say "As TEST_PASSES_SANITIZE_LEAK=true isn't set the above leak is 'ok' with GIT_TEST_PASSING_SANITIZE_LEAK=check" &&
invert_exit_code=t
- else
- say "With GIT_TEST_SANITIZE_LEAK_LOG=true our logs revealed a memory leak, exit non-zero!" &&
+ elif test "$test_failure" = 0
+ then
+ say "Our logs revealed a memory leak, exit non-zero!" &&
invert_exit_code=t
+ else
+ say "Our logs revealed a memory leak..."
fi
}
@@ -1575,33 +1578,28 @@ then
test_done
fi
- if test_bool_env GIT_TEST_SANITIZE_LEAK_LOG false
+ if ! mkdir -p "$TEST_RESULTS_SAN_DIR"
then
- if ! mkdir -p "$TEST_RESULTS_SAN_DIR"
- then
- BAIL_OUT "cannot create $TEST_RESULTS_SAN_DIR"
- fi &&
- TEST_RESULTS_SAN_FILE="$TEST_RESULTS_SAN_DIR/$TEST_RESULTS_SAN_FILE_PFX"
+ BAIL_OUT "cannot create $TEST_RESULTS_SAN_DIR"
+ fi &&
+ TEST_RESULTS_SAN_FILE="$TEST_RESULTS_SAN_DIR/$TEST_RESULTS_SAN_FILE_PFX"
- # In case "test-results" is left over from a previous
- # run: Only report if new leaks show up.
- TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP=$(nr_san_dir_leaks_)
+ # In case "test-results" is left over from a previous
+ # run: Only report if new leaks show up.
+ TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP=$(nr_san_dir_leaks_)
- # Don't litter *.leak dirs if there was nothing to report
- test_atexit "rmdir \"$TEST_RESULTS_SAN_DIR\" 2>/dev/null || :"
+ # Don't litter *.leak dirs if there was nothing to report
+ test_atexit "rmdir \"$TEST_RESULTS_SAN_DIR\" 2>/dev/null || :"
+
+ prepend_var LSAN_OPTIONS : dedup_token_length=9999
+ prepend_var LSAN_OPTIONS : log_exe_name=1
+ prepend_var LSAN_OPTIONS : log_path=\"$TEST_RESULTS_SAN_FILE\"
+ export LSAN_OPTIONS
- prepend_var LSAN_OPTIONS : dedup_token_length=9999
- prepend_var LSAN_OPTIONS : log_exe_name=1
- prepend_var LSAN_OPTIONS : log_path=\"$TEST_RESULTS_SAN_FILE\"
- export LSAN_OPTIONS
- fi
elif test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" ||
test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false
then
BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_PASSING_SANITIZE_LEAK=true"
-elif test_bool_env GIT_TEST_SANITIZE_LEAK_LOG false
-then
- BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_SANITIZE_LEAK_LOG=true"
fi
if test "${GIT_TEST_CHAIN_LINT:-1}" != 0 &&
diff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c
index a4a75db735..8bf0709c41 100644
--- a/t/unit-tests/t-example-decorate.c
+++ b/t/unit-tests/t-example-decorate.c
@@ -15,36 +15,29 @@ static void t_add(struct test_vars *vars)
{
void *ret = add_decoration(&vars->n, vars->one, &vars->decoration_a);
- if (!check(ret == NULL))
- test_msg("when adding a brand-new object, NULL should be returned");
+ check(ret == NULL);
ret = add_decoration(&vars->n, vars->two, NULL);
- if (!check(ret == NULL))
- test_msg("when adding a brand-new object, NULL should be returned");
+ check(ret == NULL);
}
static void t_readd(struct test_vars *vars)
{
void *ret = add_decoration(&vars->n, vars->one, NULL);
- if (!check(ret == &vars->decoration_a))
- test_msg("when readding an already existing object, existing decoration should be returned");
+ check(ret == &vars->decoration_a);
ret = add_decoration(&vars->n, vars->two, &vars->decoration_b);
- if (!check(ret == NULL))
- test_msg("when readding an already existing object, existing decoration should be returned");
+ check(ret == NULL);
}
static void t_lookup(struct test_vars *vars)
{
void *ret = lookup_decoration(&vars->n, vars->one);
- if (!check(ret == NULL))
- test_msg("lookup should return added declaration");
+ check(ret == NULL);
ret = lookup_decoration(&vars->n, vars->two);
- if (!check(ret == &vars->decoration_b))
- test_msg("lookup should return added declaration");
+ check(ret == &vars->decoration_b);
ret = lookup_decoration(&vars->n, vars->three);
- if (!check(ret == NULL))
- test_msg("lookup for unknown object should return NULL");
+ check(ret == NULL);
}
static void t_loop(struct test_vars *vars)
@@ -55,8 +48,7 @@ static void t_loop(struct test_vars *vars)
if (vars->n.entries[i].base)
objects_noticed++;
}
- if (!check_int(objects_noticed, ==, 2))
- test_msg("should have 2 objects");
+ check_int(objects_noticed, ==, 2);
}
int cmd_main(int argc UNUSED, const char **argv UNUSED)
diff --git a/t/unit-tests/t-oidmap.c b/t/unit-tests/t-oidmap.c
new file mode 100644
index 0000000000..b22e52d08b
--- /dev/null
+++ b/t/unit-tests/t-oidmap.c
@@ -0,0 +1,181 @@
+#include "test-lib.h"
+#include "lib-oid.h"
+#include "oidmap.h"
+#include "hash.h"
+#include "hex.h"
+
+/*
+ * Elements we will put in oidmap structs are made of a key: the entry.oid
+ * field, which is of type struct object_id, and a value: the name field (could
+ * be a refname for example).
+ */
+struct test_entry {
+ struct oidmap_entry entry;
+ char name[FLEX_ARRAY];
+};
+
+static const char *const key_val[][2] = { { "11", "one" },
+ { "22", "two" },
+ { "33", "three" } };
+
+static void setup(void (*f)(struct oidmap *map))
+{
+ struct oidmap map = OIDMAP_INIT;
+ int ret = 0;
+
+ for (size_t i = 0; i < ARRAY_SIZE(key_val); i++){
+ struct test_entry *entry;
+
+ FLEX_ALLOC_STR(entry, name, key_val[i][1]);
+ if ((ret = get_oid_arbitrary_hex(key_val[i][0], &entry->entry.oid))) {
+ free(entry);
+ break;
+ }
+ entry = oidmap_put(&map, entry);
+ if (!check(entry == NULL))
+ free(entry);
+ }
+
+ if (!ret)
+ f(&map);
+ oidmap_free(&map, 1);
+}
+
+static void t_replace(struct oidmap *map)
+{
+ struct test_entry *entry, *prev;
+
+ FLEX_ALLOC_STR(entry, name, "un");
+ if (get_oid_arbitrary_hex("11", &entry->entry.oid))
+ return;
+ prev = oidmap_put(map, entry);
+ if (!check(prev != NULL))
+ return;
+ check_str(prev->name, "one");
+ free(prev);
+
+ FLEX_ALLOC_STR(entry, name, "deux");
+ if (get_oid_arbitrary_hex("22", &entry->entry.oid))
+ return;
+ prev = oidmap_put(map, entry);
+ if (!check(prev != NULL))
+ return;
+ check_str(prev->name, "two");
+ free(prev);
+}
+
+static void t_get(struct oidmap *map)
+{
+ struct test_entry *entry;
+ struct object_id oid;
+
+ if (get_oid_arbitrary_hex("22", &oid))
+ return;
+ entry = oidmap_get(map, &oid);
+ if (!check(entry != NULL))
+ return;
+ check_str(entry->name, "two");
+
+ if (get_oid_arbitrary_hex("44", &oid))
+ return;
+ check(oidmap_get(map, &oid) == NULL);
+
+ if (get_oid_arbitrary_hex("11", &oid))
+ return;
+ entry = oidmap_get(map, &oid);
+ if (!check(entry != NULL))
+ return;
+ check_str(entry->name, "one");
+}
+
+static void t_remove(struct oidmap *map)
+{
+ struct test_entry *entry;
+ struct object_id oid;
+
+ if (get_oid_arbitrary_hex("11", &oid))
+ return;
+ entry = oidmap_remove(map, &oid);
+ if (!check(entry != NULL))
+ return;
+ check_str(entry->name, "one");
+ check(oidmap_get(map, &oid) == NULL);
+ free(entry);
+
+ if (get_oid_arbitrary_hex("22", &oid))
+ return;
+ entry = oidmap_remove(map, &oid);
+ if (!check(entry != NULL))
+ return;
+ check_str(entry->name, "two");
+ check(oidmap_get(map, &oid) == NULL);
+ free(entry);
+
+ if (get_oid_arbitrary_hex("44", &oid))
+ return;
+ check(oidmap_remove(map, &oid) == NULL);
+}
+
+static int key_val_contains(struct test_entry *entry, char seen[])
+{
+ for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) {
+ struct object_id oid;
+
+ if (get_oid_arbitrary_hex(key_val[i][0], &oid))
+ return -1;
+
+ if (oideq(&entry->entry.oid, &oid)) {
+ if (seen[i])
+ return 2;
+ seen[i] = 1;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void t_iterate(struct oidmap *map)
+{
+ struct oidmap_iter iter;
+ struct test_entry *entry;
+ char seen[ARRAY_SIZE(key_val)] = { 0 };
+ int count = 0;
+
+ oidmap_iter_init(map, &iter);
+ while ((entry = oidmap_iter_next(&iter))) {
+ int ret;
+ if (!check_int((ret = key_val_contains(entry, seen)), ==, 0)) {
+ switch (ret) {
+ case -1:
+ break; /* error message handled by get_oid_arbitrary_hex() */
+ case 1:
+ test_msg("obtained entry was not given in the input\n"
+ " name: %s\n oid: %s\n",
+ entry->name, oid_to_hex(&entry->entry.oid));
+ break;
+ case 2:
+ test_msg("duplicate entry detected\n"
+ " name: %s\n oid: %s\n",
+ entry->name, oid_to_hex(&entry->entry.oid));
+ break;
+ default:
+ test_msg("BUG: invalid return value (%d) from key_val_contains()",
+ ret);
+ break;
+ }
+ } else {
+ count++;
+ }
+ }
+ check_int(count, ==, ARRAY_SIZE(key_val));
+ check_int(hashmap_get_size(&map->map), ==, ARRAY_SIZE(key_val));
+}
+
+int cmd_main(int argc UNUSED, const char **argv UNUSED)
+{
+ TEST(setup(t_replace), "replace works");
+ TEST(setup(t_get), "get works");
+ TEST(setup(t_remove), "remove works");
+ TEST(setup(t_iterate), "iterate works");
+ return test_done();
+}
diff --git a/reftable/merged_test.c b/t/unit-tests/t-reftable-merged.c
index a9d6661c13..b6263ee8b5 100644
--- a/reftable/merged_test.c
+++ b/t/unit-tests/t-reftable-merged.c
@@ -6,27 +6,33 @@ license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
-#include "merged.h"
-
-#include "system.h"
+#include "test-lib.h"
+#include "reftable/blocksource.h"
+#include "reftable/constants.h"
+#include "reftable/merged.h"
+#include "reftable/reader.h"
+#include "reftable/reftable-error.h"
+#include "reftable/reftable-generic.h"
+#include "reftable/reftable-merged.h"
+#include "reftable/reftable-writer.h"
+
+static ssize_t strbuf_add_void(void *b, const void *data, const size_t sz)
+{
+ strbuf_add(b, data, sz);
+ return sz;
+}
-#include "basics.h"
-#include "blocksource.h"
-#include "constants.h"
-#include "reader.h"
-#include "record.h"
-#include "test_framework.h"
-#include "reftable-merged.h"
-#include "reftable-tests.h"
-#include "reftable-generic.h"
-#include "reftable-writer.h"
+static int noop_flush(void *arg)
+{
+ return 0;
+}
static void write_test_table(struct strbuf *buf,
- struct reftable_ref_record refs[], int n)
+ struct reftable_ref_record refs[], const size_t n)
{
uint64_t min = 0xffffffff;
uint64_t max = 0;
- int i = 0;
+ size_t i;
int err;
struct reftable_write_options opts = {
@@ -35,12 +41,10 @@ static void write_test_table(struct strbuf *buf,
struct reftable_writer *w = NULL;
for (i = 0; i < n; i++) {
uint64_t ui = refs[i].update_index;
- if (ui > max) {
+ if (ui > max)
max = ui;
- }
- if (ui < min) {
+ if (ui < min)
min = ui;
- }
}
w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts);
@@ -49,21 +53,19 @@ static void write_test_table(struct strbuf *buf,
for (i = 0; i < n; i++) {
uint64_t before = refs[i].update_index;
int n = reftable_writer_add_ref(w, &refs[i]);
- EXPECT(n == 0);
- EXPECT(before == refs[i].update_index);
+ check_int(n, ==, 0);
+ check_int(before, ==, refs[i].update_index);
}
err = reftable_writer_close(w);
- EXPECT_ERR(err);
+ check(!err);
reftable_writer_free(w);
}
-static void write_test_log_table(struct strbuf *buf,
- struct reftable_log_record logs[], int n,
- uint64_t update_index)
+static void write_test_log_table(struct strbuf *buf, struct reftable_log_record logs[],
+ const size_t n, const uint64_t update_index)
{
- int i = 0;
int err;
struct reftable_write_options opts = {
@@ -74,13 +76,13 @@ static void write_test_log_table(struct strbuf *buf,
w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts);
reftable_writer_set_limits(w, update_index, update_index);
- for (i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
int err = reftable_writer_add_log(w, &logs[i]);
- EXPECT_ERR(err);
+ check(!err);
}
err = reftable_writer_close(w);
- EXPECT_ERR(err);
+ check(!err);
reftable_writer_free(w);
}
@@ -88,8 +90,8 @@ static void write_test_log_table(struct strbuf *buf,
static struct reftable_merged_table *
merged_table_from_records(struct reftable_ref_record **refs,
struct reftable_block_source **source,
- struct reftable_reader ***readers, int *sizes,
- struct strbuf *buf, size_t n)
+ struct reftable_reader ***readers, const size_t *sizes,
+ struct strbuf *buf, const size_t n)
{
struct reftable_merged_table *mt = NULL;
struct reftable_table *tabs;
@@ -105,24 +107,23 @@ merged_table_from_records(struct reftable_ref_record **refs,
err = reftable_new_reader(&(*readers)[i], &(*source)[i],
"name");
- EXPECT_ERR(err);
+ check(!err);
reftable_table_from_reader(&tabs[i], (*readers)[i]);
}
err = reftable_new_merged_table(&mt, tabs, n, GIT_SHA1_FORMAT_ID);
- EXPECT_ERR(err);
+ check(!err);
return mt;
}
-static void readers_destroy(struct reftable_reader **readers, size_t n)
+static void readers_destroy(struct reftable_reader **readers, const size_t n)
{
- int i = 0;
- for (; i < n; i++)
+ for (size_t i = 0; i < n; i++)
reftable_reader_free(readers[i]);
reftable_free(readers);
}
-static void test_merged_between(void)
+static void t_merged_single_record(void)
{
struct reftable_ref_record r1[] = { {
.refname = (char *) "b",
@@ -135,37 +136,40 @@ static void test_merged_between(void)
.update_index = 2,
.value_type = REFTABLE_REF_DELETION,
} };
+ struct reftable_ref_record r3[] = { {
+ .refname = (char *) "c",
+ .update_index = 3,
+ .value_type = REFTABLE_REF_DELETION,
+ } };
- struct reftable_ref_record *refs[] = { r1, r2 };
- int sizes[] = { 1, 1 };
- struct strbuf bufs[2] = { STRBUF_INIT, STRBUF_INIT };
+ struct reftable_ref_record *refs[] = { r1, r2, r3 };
+ size_t sizes[] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) };
+ struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
struct reftable_block_source *bs = NULL;
struct reftable_reader **readers = NULL;
struct reftable_merged_table *mt =
- merged_table_from_records(refs, &bs, &readers, sizes, bufs, 2);
- int i;
- struct reftable_ref_record ref = { NULL };
- struct reftable_iterator it = { NULL };
+ merged_table_from_records(refs, &bs, &readers, sizes, bufs, 3);
+ struct reftable_ref_record ref = { 0 };
+ struct reftable_iterator it = { 0 };
int err;
merged_table_init_iter(mt, &it, BLOCK_TYPE_REF);
err = reftable_iterator_seek_ref(&it, "a");
- EXPECT_ERR(err);
+ check(!err);
err = reftable_iterator_next_ref(&it, &ref);
- EXPECT_ERR(err);
- EXPECT(ref.update_index == 2);
+ check(!err);
+ check(reftable_ref_record_equal(&r2[0], &ref, GIT_SHA1_RAWSZ));
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
- readers_destroy(readers, 2);
+ readers_destroy(readers, 3);
reftable_merged_table_free(mt);
- for (i = 0; i < ARRAY_SIZE(bufs); i++) {
+ for (size_t i = 0; i < ARRAY_SIZE(bufs); i++)
strbuf_release(&bufs[i]);
- }
reftable_free(bs);
}
-static void test_merged(void)
+static void t_merged_refs(void)
{
struct reftable_ref_record r1[] = {
{
@@ -215,27 +219,28 @@ static void test_merged(void)
};
struct reftable_ref_record *refs[] = { r1, r2, r3 };
- int sizes[3] = { 3, 1, 2 };
+ size_t sizes[3] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) };
struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
struct reftable_block_source *bs = NULL;
struct reftable_reader **readers = NULL;
struct reftable_merged_table *mt =
merged_table_from_records(refs, &bs, &readers, sizes, bufs, 3);
- struct reftable_iterator it = { NULL };
+ struct reftable_iterator it = { 0 };
int err;
struct reftable_ref_record *out = NULL;
size_t len = 0;
size_t cap = 0;
- int i = 0;
+ size_t i;
merged_table_init_iter(mt, &it, BLOCK_TYPE_REF);
err = reftable_iterator_seek_ref(&it, "a");
- EXPECT_ERR(err);
- EXPECT(reftable_merged_table_hash_id(mt) == GIT_SHA1_FORMAT_ID);
- EXPECT(reftable_merged_table_min_update_index(mt) == 1);
+ check(!err);
+ check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID);
+ check_int(reftable_merged_table_min_update_index(mt), ==, 1);
+ check_int(reftable_merged_table_max_update_index(mt), ==, 3);
while (len < 100) { /* cap loops/recursion. */
- struct reftable_ref_record ref = { NULL };
+ struct reftable_ref_record ref = { 0 };
int err = reftable_iterator_next_ref(&it, &ref);
if (err > 0)
break;
@@ -245,19 +250,16 @@ static void test_merged(void)
}
reftable_iterator_destroy(&it);
- EXPECT(ARRAY_SIZE(want) == len);
- for (i = 0; i < len; i++) {
- EXPECT(reftable_ref_record_equal(want[i], &out[i],
+ check_int(ARRAY_SIZE(want), ==, len);
+ for (i = 0; i < len; i++)
+ check(reftable_ref_record_equal(want[i], &out[i],
GIT_SHA1_RAWSZ));
- }
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i++)
reftable_ref_record_release(&out[i]);
- }
reftable_free(out);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3; i++)
strbuf_release(&bufs[i]);
- }
readers_destroy(readers, 3);
reftable_merged_table_free(mt);
reftable_free(bs);
@@ -266,8 +268,8 @@ static void test_merged(void)
static struct reftable_merged_table *
merged_table_from_log_records(struct reftable_log_record **logs,
struct reftable_block_source **source,
- struct reftable_reader ***readers, int *sizes,
- struct strbuf *buf, size_t n)
+ struct reftable_reader ***readers, const size_t *sizes,
+ struct strbuf *buf, const size_t n)
{
struct reftable_merged_table *mt = NULL;
struct reftable_table *tabs;
@@ -283,16 +285,16 @@ merged_table_from_log_records(struct reftable_log_record **logs,
err = reftable_new_reader(&(*readers)[i], &(*source)[i],
"name");
- EXPECT_ERR(err);
+ check(!err);
reftable_table_from_reader(&tabs[i], (*readers)[i]);
}
err = reftable_new_merged_table(&mt, tabs, n, GIT_SHA1_FORMAT_ID);
- EXPECT_ERR(err);
+ check(!err);
return mt;
}
-static void test_merged_logs(void)
+static void t_merged_logs(void)
{
struct reftable_log_record r1[] = {
{
@@ -347,27 +349,28 @@ static void test_merged_logs(void)
};
struct reftable_log_record *logs[] = { r1, r2, r3 };
- int sizes[3] = { 2, 1, 1 };
+ size_t sizes[3] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) };
struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
struct reftable_block_source *bs = NULL;
struct reftable_reader **readers = NULL;
struct reftable_merged_table *mt = merged_table_from_log_records(
logs, &bs, &readers, sizes, bufs, 3);
- struct reftable_iterator it = { NULL };
+ struct reftable_iterator it = { 0 };
int err;
struct reftable_log_record *out = NULL;
size_t len = 0;
size_t cap = 0;
- int i = 0;
+ size_t i;
merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG);
err = reftable_iterator_seek_log(&it, "a");
- EXPECT_ERR(err);
- EXPECT(reftable_merged_table_hash_id(mt) == GIT_SHA1_FORMAT_ID);
- EXPECT(reftable_merged_table_min_update_index(mt) == 1);
+ check(!err);
+ check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID);
+ check_int(reftable_merged_table_min_update_index(mt), ==, 1);
+ check_int(reftable_merged_table_max_update_index(mt), ==, 3);
while (len < 100) { /* cap loops/recursion. */
- struct reftable_log_record log = { NULL };
+ struct reftable_log_record log = { 0 };
int err = reftable_iterator_next_log(&it, &log);
if (err > 0)
break;
@@ -377,35 +380,32 @@ static void test_merged_logs(void)
}
reftable_iterator_destroy(&it);
- EXPECT(ARRAY_SIZE(want) == len);
- for (i = 0; i < len; i++) {
- EXPECT(reftable_log_record_equal(want[i], &out[i],
+ check_int(ARRAY_SIZE(want), ==, len);
+ for (i = 0; i < len; i++)
+ check(reftable_log_record_equal(want[i], &out[i],
GIT_SHA1_RAWSZ));
- }
merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG);
err = reftable_iterator_seek_log_at(&it, "a", 2);
- EXPECT_ERR(err);
+ check(!err);
reftable_log_record_release(&out[0]);
err = reftable_iterator_next_log(&it, &out[0]);
- EXPECT_ERR(err);
- EXPECT(reftable_log_record_equal(&out[0], &r3[0], GIT_SHA1_RAWSZ));
+ check(!err);
+ check(reftable_log_record_equal(&out[0], &r3[0], GIT_SHA1_RAWSZ));
reftable_iterator_destroy(&it);
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i++)
reftable_log_record_release(&out[i]);
- }
reftable_free(out);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3; i++)
strbuf_release(&bufs[i]);
- }
readers_destroy(readers, 3);
reftable_merged_table_free(mt);
reftable_free(bs);
}
-static void test_default_write_opts(void)
+static void t_default_write_opts(void)
{
struct reftable_write_options opts = { 0 };
struct strbuf buf = STRBUF_INIT;
@@ -417,7 +417,7 @@ static void test_default_write_opts(void)
.update_index = 1,
};
int err;
- struct reftable_block_source source = { NULL };
+ struct reftable_block_source source = { 0 };
struct reftable_table *tab = reftable_calloc(1, sizeof(*tab));
uint32_t hash_id;
struct reftable_reader *rd = NULL;
@@ -426,36 +426,38 @@ static void test_default_write_opts(void)
reftable_writer_set_limits(w, 1, 1);
err = reftable_writer_add_ref(w, &rec);
- EXPECT_ERR(err);
+ check(!err);
err = reftable_writer_close(w);
- EXPECT_ERR(err);
+ check(!err);
reftable_writer_free(w);
block_source_from_strbuf(&source, &buf);
err = reftable_new_reader(&rd, &source, "filename");
- EXPECT_ERR(err);
+ check(!err);
hash_id = reftable_reader_hash_id(rd);
- EXPECT(hash_id == GIT_SHA1_FORMAT_ID);
+ check_int(hash_id, ==, GIT_SHA1_FORMAT_ID);
reftable_table_from_reader(&tab[0], rd);
+ err = reftable_new_merged_table(&merged, tab, 1, GIT_SHA256_FORMAT_ID);
+ check_int(err, ==, REFTABLE_FORMAT_ERROR);
err = reftable_new_merged_table(&merged, tab, 1, GIT_SHA1_FORMAT_ID);
- EXPECT_ERR(err);
+ check(!err);
reftable_reader_free(rd);
reftable_merged_table_free(merged);
strbuf_release(&buf);
}
-/* XXX test refs_for(oid) */
-int merged_test_main(int argc, const char *argv[])
+int cmd_main(int argc, const char *argv[])
{
- RUN_TEST(test_merged_logs);
- RUN_TEST(test_merged_between);
- RUN_TEST(test_merged);
- RUN_TEST(test_default_write_opts);
- return 0;
+ TEST(t_default_write_opts(), "merged table with default write opts");
+ TEST(t_merged_logs(), "merged table with multiple log updates for same ref");
+ TEST(t_merged_refs(), "merged table with multiple updates to same ref");
+ TEST(t_merged_single_record(), "ref ocurring in only one record can be fetched");
+
+ return test_done();
}
diff --git a/t/unit-tests/t-reftable-pq.c b/t/unit-tests/t-reftable-pq.c
new file mode 100644
index 0000000000..039bd0f1f9
--- /dev/null
+++ b/t/unit-tests/t-reftable-pq.c
@@ -0,0 +1,152 @@
+/*
+Copyright 2020 Google LLC
+
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file or at
+https://developers.google.com/open-source/licenses/bsd
+*/
+
+#include "test-lib.h"
+#include "reftable/constants.h"
+#include "reftable/pq.h"
+
+static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq)
+{
+ for (size_t i = 1; i < pq->len; i++) {
+ size_t parent = (i - 1) / 2;
+ check(pq_less(&pq->heap[parent], &pq->heap[i]));
+ }
+}
+
+static int pq_entry_equal(struct pq_entry *a, struct pq_entry *b)
+{
+ return !reftable_record_cmp(a->rec, b->rec) && (a->index == b->index);
+}
+
+static void t_pq_record(void)
+{
+ struct merged_iter_pqueue pq = { 0 };
+ struct reftable_record recs[54];
+ size_t N = ARRAY_SIZE(recs) - 1, i;
+ char *last = NULL;
+
+ for (i = 0; i < N; i++) {
+ reftable_record_init(&recs[i], BLOCK_TYPE_REF);
+ recs[i].u.ref.refname = xstrfmt("%02"PRIuMAX, (uintmax_t)i);
+ }
+
+ i = 1;
+ do {
+ struct pq_entry e = {
+ .rec = &recs[i],
+ };
+
+ merged_iter_pqueue_add(&pq, &e);
+ merged_iter_pqueue_check(&pq);
+ i = (i * 7) % N;
+ } while (i != 1);
+
+ while (!merged_iter_pqueue_is_empty(pq)) {
+ struct pq_entry top = merged_iter_pqueue_top(pq);
+ struct pq_entry e = merged_iter_pqueue_remove(&pq);
+ merged_iter_pqueue_check(&pq);
+
+ check(pq_entry_equal(&top, &e));
+ check(reftable_record_type(e.rec) == BLOCK_TYPE_REF);
+ if (last)
+ check_int(strcmp(last, e.rec->u.ref.refname), <, 0);
+ last = e.rec->u.ref.refname;
+ }
+
+ for (i = 0; i < N; i++)
+ reftable_record_release(&recs[i]);
+ merged_iter_pqueue_release(&pq);
+}
+
+static void t_pq_index(void)
+{
+ struct merged_iter_pqueue pq = { 0 };
+ struct reftable_record recs[13];
+ char *last = NULL;
+ size_t N = ARRAY_SIZE(recs), i;
+
+ for (i = 0; i < N; i++) {
+ reftable_record_init(&recs[i], BLOCK_TYPE_REF);
+ recs[i].u.ref.refname = (char *) "refs/heads/master";
+ }
+
+ i = 1;
+ do {
+ struct pq_entry e = {
+ .rec = &recs[i],
+ .index = i,
+ };
+
+ merged_iter_pqueue_add(&pq, &e);
+ merged_iter_pqueue_check(&pq);
+ i = (i * 7) % N;
+ } while (i != 1);
+
+ for (i = N - 1; i > 0; i--) {
+ struct pq_entry top = merged_iter_pqueue_top(pq);
+ struct pq_entry e = merged_iter_pqueue_remove(&pq);
+ merged_iter_pqueue_check(&pq);
+
+ check(pq_entry_equal(&top, &e));
+ check(reftable_record_type(e.rec) == BLOCK_TYPE_REF);
+ check_int(e.index, ==, i);
+ if (last)
+ check_str(last, e.rec->u.ref.refname);
+ last = e.rec->u.ref.refname;
+ }
+
+ merged_iter_pqueue_release(&pq);
+}
+
+static void t_merged_iter_pqueue_top(void)
+{
+ struct merged_iter_pqueue pq = { 0 };
+ struct reftable_record recs[13];
+ size_t N = ARRAY_SIZE(recs), i;
+
+ for (i = 0; i < N; i++) {
+ reftable_record_init(&recs[i], BLOCK_TYPE_REF);
+ recs[i].u.ref.refname = (char *) "refs/heads/master";
+ }
+
+ i = 1;
+ do {
+ struct pq_entry e = {
+ .rec = &recs[i],
+ .index = i,
+ };
+
+ merged_iter_pqueue_add(&pq, &e);
+ merged_iter_pqueue_check(&pq);
+ i = (i * 7) % N;
+ } while (i != 1);
+
+ for (i = N - 1; i > 0; i--) {
+ struct pq_entry top = merged_iter_pqueue_top(pq);
+ struct pq_entry e = merged_iter_pqueue_remove(&pq);
+
+ merged_iter_pqueue_check(&pq);
+ check(pq_entry_equal(&top, &e));
+ check(reftable_record_equal(top.rec, &recs[i], GIT_SHA1_RAWSZ));
+ for (size_t j = 0; i < pq.len; j++) {
+ check(pq_less(&top, &pq.heap[j]));
+ check_int(top.index, >, j);
+ }
+ }
+
+ merged_iter_pqueue_release(&pq);
+}
+
+int cmd_main(int argc, const char *argv[])
+{
+ TEST(t_pq_record(), "pq works with record-based comparison");
+ TEST(t_pq_index(), "pq works with index-based comparison");
+ TEST(t_merged_iter_pqueue_top(), "merged_iter_pqueue_top works");
+
+ return test_done();
+}
diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c
new file mode 100644
index 0000000000..cb649ee419
--- /dev/null
+++ b/t/unit-tests/t-reftable-record.c
@@ -0,0 +1,551 @@
+/*
+ Copyright 2020 Google LLC
+
+ Use of this source code is governed by a BSD-style
+ license that can be found in the LICENSE file or at
+ https://developers.google.com/open-source/licenses/bsd
+*/
+
+#include "test-lib.h"
+#include "reftable/constants.h"
+#include "reftable/record.h"
+
+static void t_copy(struct reftable_record *rec)
+{
+ struct reftable_record copy;
+ uint8_t typ;
+
+ typ = reftable_record_type(rec);
+ reftable_record_init(&copy, typ);
+ reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
+ /* do it twice to catch memory leaks */
+ reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
+ check(reftable_record_equal(rec, &copy, GIT_SHA1_RAWSZ));
+
+ reftable_record_release(&copy);
+}
+
+static void t_varint_roundtrip(void)
+{
+ uint64_t inputs[] = { 0,
+ 1,
+ 27,
+ 127,
+ 128,
+ 257,
+ 4096,
+ ((uint64_t)1 << 63),
+ ((uint64_t)1 << 63) + ((uint64_t)1 << 63) - 1 };
+
+ for (size_t i = 0; i < ARRAY_SIZE(inputs); i++) {
+ uint8_t dest[10];
+
+ struct string_view out = {
+ .buf = dest,
+ .len = sizeof(dest),
+ };
+ uint64_t in = inputs[i];
+ int n = put_var_int(&out, in);
+ uint64_t got = 0;
+
+ check_int(n, >, 0);
+ out.len = n;
+ n = get_var_int(&got, &out);
+ check_int(n, >, 0);
+
+ check_int(got, ==, in);
+ }
+}
+
+static void set_hash(uint8_t *h, int j)
+{
+ for (int i = 0; i < hash_size(GIT_SHA1_FORMAT_ID); i++)
+ h[i] = (j >> i) & 0xff;
+}
+
+static void t_reftable_ref_record_comparison(void)
+{
+ struct reftable_record in[3] = {
+ {
+ .type = BLOCK_TYPE_REF,
+ .u.ref.refname = (char *) "refs/heads/master",
+ .u.ref.value_type = REFTABLE_REF_VAL1,
+ },
+ {
+ .type = BLOCK_TYPE_REF,
+ .u.ref.refname = (char *) "refs/heads/master",
+ .u.ref.value_type = REFTABLE_REF_DELETION,
+ },
+ {
+ .type = BLOCK_TYPE_REF,
+ .u.ref.refname = (char *) "HEAD",
+ .u.ref.value_type = REFTABLE_REF_SYMREF,
+ .u.ref.value.symref = (char *) "refs/heads/master",
+ },
+ };
+
+ check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+
+ check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
+
+ in[1].u.ref.value_type = in[0].u.ref.value_type;
+ check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+}
+
+static void t_reftable_ref_record_compare_name(void)
+{
+ struct reftable_ref_record recs[3] = {
+ {
+ .refname = (char *) "refs/heads/a"
+ },
+ {
+ .refname = (char *) "refs/heads/b"
+ },
+ {
+ .refname = (char *) "refs/heads/a"
+ },
+ };
+
+ check_int(reftable_ref_record_compare_name(&recs[0], &recs[1]), <, 0);
+ check_int(reftable_ref_record_compare_name(&recs[1], &recs[0]), >, 0);
+ check_int(reftable_ref_record_compare_name(&recs[0], &recs[2]), ==, 0);
+}
+
+static void t_reftable_ref_record_roundtrip(void)
+{
+ struct strbuf scratch = STRBUF_INIT;
+
+ for (int i = REFTABLE_REF_DELETION; i < REFTABLE_NR_REF_VALUETYPES; i++) {
+ struct reftable_record in = {
+ .type = BLOCK_TYPE_REF,
+ .u.ref.value_type = i,
+ };
+ struct reftable_record out = { .type = BLOCK_TYPE_REF };
+ struct strbuf key = STRBUF_INIT;
+ uint8_t buffer[1024] = { 0 };
+ struct string_view dest = {
+ .buf = buffer,
+ .len = sizeof(buffer),
+ };
+ int n, m;
+
+ in.u.ref.value_type = i;
+ switch (i) {
+ case REFTABLE_REF_DELETION:
+ break;
+ case REFTABLE_REF_VAL1:
+ set_hash(in.u.ref.value.val1, 1);
+ break;
+ case REFTABLE_REF_VAL2:
+ set_hash(in.u.ref.value.val2.value, 1);
+ set_hash(in.u.ref.value.val2.target_value, 2);
+ break;
+ case REFTABLE_REF_SYMREF:
+ in.u.ref.value.symref = xstrdup("target");
+ break;
+ }
+ in.u.ref.refname = xstrdup("refs/heads/master");
+
+ t_copy(&in);
+
+ check_int(reftable_record_val_type(&in), ==, i);
+ check_int(reftable_record_is_deletion(&in), ==, i == REFTABLE_REF_DELETION);
+
+ reftable_record_key(&in, &key);
+ n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
+ check_int(n, >, 0);
+
+ /* decode into a non-zero reftable_record to test for leaks. */
+ m = reftable_record_decode(&out, key, i, dest, GIT_SHA1_RAWSZ, &scratch);
+ check_int(n, ==, m);
+
+ check(reftable_ref_record_equal(&in.u.ref, &out.u.ref,
+ GIT_SHA1_RAWSZ));
+ reftable_record_release(&in);
+
+ strbuf_release(&key);
+ reftable_record_release(&out);
+ }
+
+ strbuf_release(&scratch);
+}
+
+static void t_reftable_log_record_comparison(void)
+{
+ struct reftable_record in[3] = {
+ {
+ .type = BLOCK_TYPE_LOG,
+ .u.log.refname = (char *) "refs/heads/master",
+ .u.log.update_index = 42,
+ },
+ {
+ .type = BLOCK_TYPE_LOG,
+ .u.log.refname = (char *) "refs/heads/master",
+ .u.log.update_index = 22,
+ },
+ {
+ .type = BLOCK_TYPE_LOG,
+ .u.log.refname = (char *) "refs/heads/main",
+ .u.log.update_index = 22,
+ },
+ };
+
+ check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
+ /* comparison should be reversed for equal keys, because
+ * comparison is now performed on the basis of update indices */
+ check_int(reftable_record_cmp(&in[0], &in[1]), <, 0);
+
+ in[1].u.log.update_index = in[0].u.log.update_index;
+ check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+}
+
+static void t_reftable_log_record_compare_key(void)
+{
+ struct reftable_log_record logs[3] = {
+ {
+ .refname = (char *) "refs/heads/a",
+ .update_index = 1,
+ },
+ {
+ .refname = (char *) "refs/heads/b",
+ .update_index = 2,
+ },
+ {
+ .refname = (char *) "refs/heads/a",
+ .update_index = 3,
+ },
+ };
+
+ check_int(reftable_log_record_compare_key(&logs[0], &logs[1]), <, 0);
+ check_int(reftable_log_record_compare_key(&logs[1], &logs[0]), >, 0);
+
+ logs[1].update_index = logs[0].update_index;
+ check_int(reftable_log_record_compare_key(&logs[0], &logs[1]), <, 0);
+
+ check_int(reftable_log_record_compare_key(&logs[0], &logs[2]), >, 0);
+ check_int(reftable_log_record_compare_key(&logs[2], &logs[0]), <, 0);
+ logs[2].update_index = logs[0].update_index;
+ check_int(reftable_log_record_compare_key(&logs[0], &logs[2]), ==, 0);
+}
+
+static void t_reftable_log_record_roundtrip(void)
+{
+ struct reftable_log_record in[] = {
+ {
+ .refname = xstrdup("refs/heads/master"),
+ .update_index = 42,
+ .value_type = REFTABLE_LOG_UPDATE,
+ .value = {
+ .update = {
+ .name = xstrdup("han-wen"),
+ .email = xstrdup("hanwen@google.com"),
+ .message = xstrdup("test"),
+ .time = 1577123507,
+ .tz_offset = 100,
+ },
+ }
+ },
+ {
+ .refname = xstrdup("refs/heads/master"),
+ .update_index = 22,
+ .value_type = REFTABLE_LOG_DELETION,
+ },
+ {
+ .refname = xstrdup("branch"),
+ .update_index = 33,
+ .value_type = REFTABLE_LOG_UPDATE,
+ }
+ };
+ struct strbuf scratch = STRBUF_INIT;
+ set_hash(in[0].value.update.new_hash, 1);
+ set_hash(in[0].value.update.old_hash, 2);
+ set_hash(in[2].value.update.new_hash, 3);
+ set_hash(in[2].value.update.old_hash, 4);
+
+ check(!reftable_log_record_is_deletion(&in[0]));
+ check(reftable_log_record_is_deletion(&in[1]));
+ check(!reftable_log_record_is_deletion(&in[2]));
+
+ for (size_t i = 0; i < ARRAY_SIZE(in); i++) {
+ struct reftable_record rec = { .type = BLOCK_TYPE_LOG };
+ struct strbuf key = STRBUF_INIT;
+ uint8_t buffer[1024] = { 0 };
+ struct string_view dest = {
+ .buf = buffer,
+ .len = sizeof(buffer),
+ };
+ /* populate out, to check for leaks. */
+ struct reftable_record out = {
+ .type = BLOCK_TYPE_LOG,
+ .u.log = {
+ .refname = xstrdup("old name"),
+ .value_type = REFTABLE_LOG_UPDATE,
+ .value = {
+ .update = {
+ .name = xstrdup("old name"),
+ .email = xstrdup("old@email"),
+ .message = xstrdup("old message"),
+ },
+ },
+ },
+ };
+ int n, m, valtype;
+
+ rec.u.log = in[i];
+
+ t_copy(&rec);
+
+ reftable_record_key(&rec, &key);
+
+ n = reftable_record_encode(&rec, dest, GIT_SHA1_RAWSZ);
+ check_int(n, >=, 0);
+ valtype = reftable_record_val_type(&rec);
+ m = reftable_record_decode(&out, key, valtype, dest,
+ GIT_SHA1_RAWSZ, &scratch);
+ check_int(n, ==, m);
+
+ check(reftable_log_record_equal(&in[i], &out.u.log,
+ GIT_SHA1_RAWSZ));
+ reftable_log_record_release(&in[i]);
+ strbuf_release(&key);
+ reftable_record_release(&out);
+ }
+
+ strbuf_release(&scratch);
+}
+
+static void t_key_roundtrip(void)
+{
+ uint8_t buffer[1024] = { 0 };
+ struct string_view dest = {
+ .buf = buffer,
+ .len = sizeof(buffer),
+ };
+ struct strbuf last_key = STRBUF_INIT;
+ struct strbuf key = STRBUF_INIT;
+ struct strbuf roundtrip = STRBUF_INIT;
+ int restart;
+ uint8_t extra;
+ int n, m;
+ uint8_t rt_extra;
+
+ strbuf_addstr(&last_key, "refs/heads/master");
+ strbuf_addstr(&key, "refs/tags/bla");
+ extra = 6;
+ n = reftable_encode_key(&restart, dest, last_key, key, extra);
+ check(!restart);
+ check_int(n, >, 0);
+
+ strbuf_addstr(&roundtrip, "refs/heads/master");
+ m = reftable_decode_key(&roundtrip, &rt_extra, dest);
+ check_int(n, ==, m);
+ check(!strbuf_cmp(&key, &roundtrip));
+ check_int(rt_extra, ==, extra);
+
+ strbuf_release(&last_key);
+ strbuf_release(&key);
+ strbuf_release(&roundtrip);
+}
+
+static void t_reftable_obj_record_comparison(void)
+{
+
+ uint8_t id_bytes[] = { 0, 1, 2, 3, 4, 5, 6 };
+ uint64_t offsets[] = { 0, 16, 32, 48, 64, 80, 96, 112};
+ struct reftable_record in[3] = {
+ {
+ .type = BLOCK_TYPE_OBJ,
+ .u.obj.hash_prefix = id_bytes,
+ .u.obj.hash_prefix_len = 7,
+ .u.obj.offsets = offsets,
+ .u.obj.offset_len = 8,
+ },
+ {
+ .type = BLOCK_TYPE_OBJ,
+ .u.obj.hash_prefix = id_bytes,
+ .u.obj.hash_prefix_len = 7,
+ .u.obj.offsets = offsets,
+ .u.obj.offset_len = 5,
+ },
+ {
+ .type = BLOCK_TYPE_OBJ,
+ .u.obj.hash_prefix = id_bytes,
+ .u.obj.hash_prefix_len = 5,
+ },
+ };
+
+ check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+
+ check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
+
+ in[1].u.obj.offset_len = in[0].u.obj.offset_len;
+ check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+}
+
+static void t_reftable_obj_record_roundtrip(void)
+{
+ uint8_t testHash1[GIT_SHA1_RAWSZ] = { 1, 2, 3, 4, 0 };
+ uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
+ struct reftable_obj_record recs[3] = {
+ {
+ .hash_prefix = testHash1,
+ .hash_prefix_len = 5,
+ .offsets = till9,
+ .offset_len = 3,
+ },
+ {
+ .hash_prefix = testHash1,
+ .hash_prefix_len = 5,
+ .offsets = till9,
+ .offset_len = 9,
+ },
+ {
+ .hash_prefix = testHash1,
+ .hash_prefix_len = 5,
+ },
+ };
+ struct strbuf scratch = STRBUF_INIT;
+
+ for (size_t i = 0; i < ARRAY_SIZE(recs); i++) {
+ uint8_t buffer[1024] = { 0 };
+ struct string_view dest = {
+ .buf = buffer,
+ .len = sizeof(buffer),
+ };
+ struct reftable_record in = {
+ .type = BLOCK_TYPE_OBJ,
+ .u = {
+ .obj = recs[i],
+ },
+ };
+ struct strbuf key = STRBUF_INIT;
+ struct reftable_record out = { .type = BLOCK_TYPE_OBJ };
+ int n, m;
+ uint8_t extra;
+
+ check(!reftable_record_is_deletion(&in));
+ t_copy(&in);
+ reftable_record_key(&in, &key);
+ n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
+ check_int(n, >, 0);
+ extra = reftable_record_val_type(&in);
+ m = reftable_record_decode(&out, key, extra, dest,
+ GIT_SHA1_RAWSZ, &scratch);
+ check_int(n, ==, m);
+
+ check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
+ strbuf_release(&key);
+ reftable_record_release(&out);
+ }
+
+ strbuf_release(&scratch);
+}
+
+static void t_reftable_index_record_comparison(void)
+{
+ struct reftable_record in[3] = {
+ {
+ .type = BLOCK_TYPE_INDEX,
+ .u.idx.offset = 22,
+ .u.idx.last_key = STRBUF_INIT,
+ },
+ {
+ .type = BLOCK_TYPE_INDEX,
+ .u.idx.offset = 32,
+ .u.idx.last_key = STRBUF_INIT,
+ },
+ {
+ .type = BLOCK_TYPE_INDEX,
+ .u.idx.offset = 32,
+ .u.idx.last_key = STRBUF_INIT,
+ },
+ };
+ strbuf_addstr(&in[0].u.idx.last_key, "refs/heads/master");
+ strbuf_addstr(&in[1].u.idx.last_key, "refs/heads/master");
+ strbuf_addstr(&in[2].u.idx.last_key, "refs/heads/branch");
+
+ check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+
+ check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
+
+ in[1].u.idx.offset = in[0].u.idx.offset;
+ check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_cmp(&in[0], &in[1]));
+
+ for (size_t i = 0; i < ARRAY_SIZE(in); i++)
+ reftable_record_release(&in[i]);
+}
+
+static void t_reftable_index_record_roundtrip(void)
+{
+ struct reftable_record in = {
+ .type = BLOCK_TYPE_INDEX,
+ .u.idx = {
+ .offset = 42,
+ .last_key = STRBUF_INIT,
+ },
+ };
+ uint8_t buffer[1024] = { 0 };
+ struct string_view dest = {
+ .buf = buffer,
+ .len = sizeof(buffer),
+ };
+ struct strbuf scratch = STRBUF_INIT;
+ struct strbuf key = STRBUF_INIT;
+ struct reftable_record out = {
+ .type = BLOCK_TYPE_INDEX,
+ .u.idx = { .last_key = STRBUF_INIT },
+ };
+ int n, m;
+ uint8_t extra;
+
+ strbuf_addstr(&in.u.idx.last_key, "refs/heads/master");
+ reftable_record_key(&in, &key);
+ t_copy(&in);
+
+ check(!reftable_record_is_deletion(&in));
+ check(!strbuf_cmp(&key, &in.u.idx.last_key));
+ n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
+ check_int(n, >, 0);
+
+ extra = reftable_record_val_type(&in);
+ m = reftable_record_decode(&out, key, extra, dest, GIT_SHA1_RAWSZ,
+ &scratch);
+ check_int(m, ==, n);
+
+ check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
+
+ reftable_record_release(&out);
+ strbuf_release(&key);
+ strbuf_release(&scratch);
+ strbuf_release(&in.u.idx.last_key);
+}
+
+int cmd_main(int argc, const char *argv[])
+{
+ TEST(t_reftable_ref_record_comparison(), "comparison operations work on ref record");
+ TEST(t_reftable_log_record_comparison(), "comparison operations work on log record");
+ TEST(t_reftable_index_record_comparison(), "comparison operations work on index record");
+ TEST(t_reftable_obj_record_comparison(), "comparison operations work on obj record");
+ TEST(t_reftable_ref_record_compare_name(), "reftable_ref_record_compare_name works");
+ TEST(t_reftable_log_record_compare_key(), "reftable_log_record_compare_key works");
+ TEST(t_reftable_log_record_roundtrip(), "record operations work on log record");
+ TEST(t_reftable_ref_record_roundtrip(), "record operations work on ref record");
+ TEST(t_varint_roundtrip(), "put_var_int and get_var_int work");
+ TEST(t_key_roundtrip(), "reftable_encode_key and reftable_decode_key work");
+ TEST(t_reftable_obj_record_roundtrip(), "record operations work on obj record");
+ TEST(t_reftable_index_record_roundtrip(), "record operations work on index record");
+
+ return test_done();
+}
diff --git a/t/unit-tests/t-reftable-tree.c b/t/unit-tests/t-reftable-tree.c
new file mode 100644
index 0000000000..e7d774d774
--- /dev/null
+++ b/t/unit-tests/t-reftable-tree.c
@@ -0,0 +1,84 @@
+/*
+Copyright 2020 Google LLC
+
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file or at
+https://developers.google.com/open-source/licenses/bsd
+*/
+
+#include "test-lib.h"
+#include "reftable/tree.h"
+
+static int t_compare(const void *a, const void *b)
+{
+ return (char *)a - (char *)b;
+}
+
+struct curry {
+ void **arr;
+ size_t len;
+};
+
+static void store(void *arg, void *key)
+{
+ struct curry *c = arg;
+ c->arr[c->len++] = key;
+}
+
+static void t_tree_search(void)
+{
+ struct tree_node *root = NULL;
+ void *values[11] = { 0 };
+ struct tree_node *nodes[11] = { 0 };
+ size_t i = 1;
+
+ /*
+ * Pseudo-randomly insert the pointers for elements between
+ * values[1] and values[10] (inclusive) in the tree.
+ */
+ do {
+ nodes[i] = tree_search(&values[i], &root, &t_compare, 1);
+ i = (i * 7) % 11;
+ } while (i != 1);
+
+ for (i = 1; i < ARRAY_SIZE(nodes); i++) {
+ check_pointer_eq(&values[i], nodes[i]->key);
+ check_pointer_eq(nodes[i], tree_search(&values[i], &root, &t_compare, 0));
+ }
+
+ check(!tree_search(values, &root, t_compare, 0));
+ tree_free(root);
+}
+
+static void t_infix_walk(void)
+{
+ struct tree_node *root = NULL;
+ void *values[11] = { 0 };
+ void *out[11] = { 0 };
+ struct curry c = {
+ .arr = (void **) &out,
+ };
+ size_t i = 1;
+ size_t count = 0;
+
+ do {
+ tree_search(&values[i], &root, t_compare, 1);
+ i = (i * 7) % 11;
+ count++;
+ } while (i != 1);
+
+ infix_walk(root, &store, &c);
+ for (i = 1; i < ARRAY_SIZE(values); i++)
+ check_pointer_eq(&values[i], out[i - 1]);
+ check(!out[i - 1]);
+ check_int(c.len, ==, count);
+ tree_free(root);
+}
+
+int cmd_main(int argc, const char *argv[])
+{
+ TEST(t_tree_search(), "tree_search works");
+ TEST(t_infix_walk(), "infix_walk works");
+
+ return test_done();
+}
diff --git a/t/unit-tests/t-strvec.c b/t/unit-tests/t-strvec.c
index d4615ab06d..fa1a041469 100644
--- a/t/unit-tests/t-strvec.c
+++ b/t/unit-tests/t-strvec.c
@@ -3,38 +3,21 @@
#include "strvec.h"
#define check_strvec(vec, ...) \
- check_strvec_loc(TEST_LOCATION(), vec, __VA_ARGS__)
-LAST_ARG_MUST_BE_NULL
-static void check_strvec_loc(const char *loc, struct strvec *vec, ...)
-{
- va_list ap;
- size_t nr = 0;
-
- va_start(ap, vec);
- while (1) {
- const char *str = va_arg(ap, const char *);
- if (!str)
- break;
-
- if (!check_uint(vec->nr, >, nr) ||
- !check_uint(vec->alloc, >, nr) ||
- !check_str(vec->v[nr], str)) {
- struct strbuf msg = STRBUF_INIT;
- strbuf_addf(&msg, "strvec index %"PRIuMAX, (uintmax_t) nr);
- test_assert(loc, msg.buf, 0);
- strbuf_release(&msg);
- va_end(ap);
- return;
- }
-
- nr++;
- }
- va_end(ap);
-
- check_uint(vec->nr, ==, nr);
- check_uint(vec->alloc, >=, nr);
- check_pointer_eq(vec->v[nr], NULL);
-}
+ do { \
+ const char *expect[] = { __VA_ARGS__ }; \
+ if (check_uint(ARRAY_SIZE(expect), >, 0) && \
+ check_pointer_eq(expect[ARRAY_SIZE(expect) - 1], NULL) && \
+ check_uint((vec)->nr, ==, ARRAY_SIZE(expect) - 1) && \
+ check_uint((vec)->nr, <=, (vec)->alloc)) { \
+ for (size_t i = 0; i < ARRAY_SIZE(expect); i++) { \
+ if (!check_str((vec)->v[i], expect[i])) { \
+ test_msg(" i: %"PRIuMAX, \
+ (uintmax_t)i); \
+ break; \
+ } \
+ } \
+ } \
+ } while (0)
static void t_static_init(void)
{
diff --git a/t/unit-tests/test-lib.h b/t/unit-tests/test-lib.h
index 2de6d715d5..c59f646fd9 100644
--- a/t/unit-tests/test-lib.h
+++ b/t/unit-tests/test-lib.h
@@ -76,8 +76,9 @@ int test_assert(const char *location, const char *check, int ok);
int check_bool_loc(const char *loc, const char *check, int ok);
/*
- * Compare two integers. Prints a message with the two values if the
- * comparison fails. NB this is not thread safe.
+ * Compare the equality of two pointers of same type. Prints a message
+ * with the two values if the equality fails. NB this is not thread
+ * safe.
*/
#define check_pointer_eq(a, b) \
(test__tmp[0].p = (a), test__tmp[1].p = (b), \
diff --git a/transport.c b/transport.c
index 139721a990..7c4af9f56f 100644
--- a/transport.c
+++ b/transport.c
@@ -186,7 +186,8 @@ static int fetch_refs_from_bundle(struct transport *transport,
if (!data->get_refs_from_bundle_called)
get_refs_from_bundle_inner(transport);
ret = unbundle(the_repository, &data->header, data->fd,
- &extra_index_pack_args, 0);
+ &extra_index_pack_args,
+ fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0);
transport->hash_algo = data->header.hash_algo;
return ret;
}
@@ -1114,6 +1115,7 @@ static struct transport_vtable builtin_smart_vtable = {
struct transport *transport_get(struct remote *remote, const char *url)
{
const char *helper;
+ char *helper_to_free = NULL;
const char *p;
struct transport *ret = xcalloc(1, sizeof(*ret));
@@ -1138,10 +1140,11 @@ struct transport *transport_get(struct remote *remote, const char *url)
while (is_urlschemechar(p == url, *p))
p++;
if (starts_with(p, "::"))
- helper = xstrndup(url, p - url);
+ helper = helper_to_free = xstrndup(url, p - url);
if (helper) {
transport_helper_init(ret, helper);
+ free(helper_to_free);
} else if (starts_with(url, "rsync:")) {
die(_("git-over-rsync is no longer supported"));
} else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {