Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml15
-rw-r--r--.gitignore5
-rw-r--r--Documentation/CodingGuidelines53
-rw-r--r--Documentation/Makefile15
-rw-r--r--Documentation/MyFirstContribution.txt2
-rw-r--r--Documentation/MyFirstObjectWalk.txt2
-rw-r--r--Documentation/RelNotes/2.30.6.txt60
-rw-r--r--Documentation/RelNotes/2.31.5.txt5
-rw-r--r--Documentation/RelNotes/2.32.4.txt5
-rw-r--r--Documentation/RelNotes/2.33.5.txt5
-rw-r--r--Documentation/RelNotes/2.34.5.txt5
-rw-r--r--Documentation/RelNotes/2.35.5.txt5
-rw-r--r--Documentation/RelNotes/2.36.3.txt5
-rw-r--r--Documentation/RelNotes/2.37.4.txt65
-rw-r--r--Documentation/RelNotes/2.38.0.txt124
-rw-r--r--Documentation/RelNotes/2.38.1.txt5
-rw-r--r--Documentation/RelNotes/2.38.2.txt60
-rw-r--r--Documentation/RelNotes/2.39.0.txt244
-rw-r--r--Documentation/ReviewingGuidelines.txt162
-rw-r--r--Documentation/SubmittingPatches4
-rwxr-xr-xDocumentation/build-docdep.perl5
-rwxr-xr-xDocumentation/cmd-list.perl2
-rw-r--r--Documentation/config.txt4
-rw-r--r--Documentation/config/bundle.txt24
-rw-r--r--Documentation/config/core.txt2
-rw-r--r--Documentation/config/diff.txt15
-rw-r--r--Documentation/config/difftool.txt28
-rw-r--r--Documentation/config/feature.txt3
-rw-r--r--Documentation/config/format.txt4
-rw-r--r--Documentation/config/fsck.txt4
-rw-r--r--Documentation/config/fsmonitor--daemon.txt11
-rw-r--r--Documentation/config/grep.txt7
-rw-r--r--Documentation/config/log.txt10
-rw-r--r--Documentation/config/mergetool.txt2
-rw-r--r--Documentation/config/notes.txt43
-rw-r--r--Documentation/config/pack.txt7
-rw-r--r--Documentation/config/protocol.txt6
-rw-r--r--Documentation/config/sendemail.txt40
-rw-r--r--Documentation/config/transfer.txt2
-rw-r--r--Documentation/fsck-msgids.txt161
-rw-r--r--Documentation/git-add.txt7
-rw-r--r--Documentation/git-am.txt7
-rw-r--r--Documentation/git-annotate.txt2
-rw-r--r--Documentation/git-apply.txt10
-rw-r--r--Documentation/git-blame.txt6
-rw-r--r--Documentation/git-branch.txt4
-rw-r--r--Documentation/git-bundle.txt2
-rw-r--r--Documentation/git-checkout.txt7
-rw-r--r--Documentation/git-clean.txt17
-rw-r--r--Documentation/git-clone.txt16
-rw-r--r--Documentation/git-column.txt7
-rw-r--r--Documentation/git-commit-graph.txt12
-rw-r--r--Documentation/git-commit.txt4
-rw-r--r--Documentation/git-credential-cache--daemon.txt4
-rw-r--r--Documentation/git-diff-files.txt2
-rw-r--r--Documentation/git-diff.txt15
-rw-r--r--Documentation/git-difftool.txt27
-rw-r--r--Documentation/git-fast-export.txt2
-rw-r--r--Documentation/git-fast-import.txt7
-rw-r--r--Documentation/git-fetch.txt7
-rw-r--r--Documentation/git-format-patch.txt11
-rw-r--r--Documentation/git-fsck.txt14
-rw-r--r--Documentation/git-fsmonitor--daemon.txt37
-rw-r--r--Documentation/git-gc.txt3
-rw-r--r--Documentation/git-grep.txt29
-rw-r--r--Documentation/git-hash-object.txt3
-rw-r--r--Documentation/git-imap-send.txt2
-rw-r--r--Documentation/git-init.txt7
-rw-r--r--Documentation/git-interpret-trailers.txt15
-rw-r--r--Documentation/git-log.txt46
-rw-r--r--Documentation/git-ls-files.txt4
-rw-r--r--Documentation/git-mailinfo.txt7
-rw-r--r--Documentation/git-maintenance.txt27
-rw-r--r--Documentation/git-merge-base.txt4
-rw-r--r--Documentation/git-merge-tree.txt76
-rw-r--r--Documentation/git-merge.txt5
-rw-r--r--Documentation/git-mergetool.txt3
-rw-r--r--Documentation/git-multi-pack-index.txt7
-rw-r--r--Documentation/git-mv.txt4
-rw-r--r--Documentation/git-notes.txt55
-rw-r--r--Documentation/git-pack-redundant.txt4
-rw-r--r--Documentation/git-patch-id.txt24
-rw-r--r--Documentation/git-prune-packed.txt2
-rw-r--r--Documentation/git-push.txt7
-rw-r--r--Documentation/git-range-diff.txt4
-rw-r--r--Documentation/git-read-tree.txt2
-rw-r--r--Documentation/git-rebase.txt34
-rw-r--r--Documentation/git-receive-pack.txt4
-rw-r--r--Documentation/git-reflog.txt17
-rw-r--r--Documentation/git-repack.txt6
-rw-r--r--Documentation/git-rerere.txt2
-rw-r--r--Documentation/git-rev-list.txt2
-rw-r--r--Documentation/git-revert.txt7
-rw-r--r--Documentation/git-send-email.txt51
-rw-r--r--Documentation/git-send-pack.txt5
-rw-r--r--Documentation/git-shortlog.txt8
-rw-r--r--Documentation/git-show-branch.txt11
-rw-r--r--Documentation/git-show-ref.txt4
-rw-r--r--Documentation/git-sparse-checkout.txt2
-rw-r--r--Documentation/git-stash.txt24
-rw-r--r--Documentation/git-status.txt2
-rw-r--r--Documentation/git-switch.txt7
-rw-r--r--Documentation/git-symbolic-ref.txt11
-rw-r--r--Documentation/git-tag.txt18
-rw-r--r--Documentation/git-update-index.txt2
-rw-r--r--Documentation/git-update-server-info.txt8
-rw-r--r--Documentation/git-upload-archive.txt4
-rw-r--r--Documentation/git-upload-pack.txt2
-rw-r--r--Documentation/git-var.txt2
-rw-r--r--Documentation/git-verify-commit.txt2
-rw-r--r--Documentation/git-verify-pack.txt2
-rw-r--r--Documentation/git-verify-tag.txt2
-rw-r--r--Documentation/git-worktree.txt3
-rw-r--r--Documentation/git.txt45
-rw-r--r--Documentation/gitcredentials.txt7
-rw-r--r--Documentation/gitformat-commit-graph.txt6
-rw-r--r--Documentation/gitprotocol-capabilities.txt4
-rw-r--r--Documentation/gitprotocol-v2.txt4
-rw-r--r--Documentation/gitremote-helpers.txt9
-rw-r--r--Documentation/glossary-content.txt27
-rw-r--r--Documentation/howto/coordinate-embargoed-releases.txt165
-rw-r--r--Documentation/howto/maintain-git.txt2
-rw-r--r--Documentation/includes/cmd-config-section-all.txt3
-rw-r--r--Documentation/includes/cmd-config-section-rest.txt3
-rwxr-xr-xDocumentation/lint-fsck-msgids.perl70
-rw-r--r--Documentation/revisions.txt2
-rw-r--r--Documentation/scalar.txt (renamed from contrib/scalar/scalar.txt)4
-rw-r--r--Documentation/technical/api-error-handling.txt2
-rw-r--r--Documentation/technical/api-parse-options.txt49
-rw-r--r--Documentation/technical/api-trace2.txt190
-rw-r--r--Documentation/technical/bitmap-format.txt39
-rw-r--r--Documentation/technical/bundle-uri.txt17
-rw-r--r--Documentation/technical/commit-graph.txt12
-rw-r--r--Documentation/technical/parallel-checkout.txt2
-rw-r--r--Documentation/technical/remembering-renames.txt4
-rw-r--r--Documentation/technical/scalar.txt61
-rw-r--r--Documentation/technical/sparse-checkout.txt1103
-rw-r--r--Documentation/user-manual.txt2
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--INSTALL5
-rw-r--r--Makefile327
l---------RelNotes2
-rw-r--r--add-interactive.c11
-rw-r--r--add-patch.c51
-rw-r--r--advice.c19
-rw-r--r--advice.h1
-rw-r--r--alias.c11
-rw-r--r--apply.c30
-rw-r--r--archive-tar.c6
-rw-r--r--archive-zip.c5
-rw-r--r--archive.c13
-rw-r--r--attr.c45
-rw-r--r--bisect.c19
-rw-r--r--block-sha1/sha1.c4
-rw-r--r--bloom.c4
-rw-r--r--builtin/add.c19
-rw-r--r--builtin/am.c14
-rw-r--r--builtin/archive.c2
-rw-r--r--builtin/bisect--helper.c308
-rw-r--r--builtin/blame.c23
-rw-r--r--builtin/branch.c99
-rw-r--r--builtin/bugreport.c3
-rw-r--r--builtin/bundle.c68
-rw-r--r--builtin/cat-file.c2
-rw-r--r--builtin/checkout.c4
-rw-r--r--builtin/clean.c2
-rw-r--r--builtin/clone.c73
-rw-r--r--builtin/commit-graph.c46
-rw-r--r--builtin/commit-tree.c5
-rw-r--r--builtin/commit.c15
-rw-r--r--builtin/config.c8
-rw-r--r--builtin/credential-cache--daemon.c4
-rw-r--r--builtin/describe.c10
-rw-r--r--builtin/diagnose.c5
-rw-r--r--builtin/diff-files.c1
-rw-r--r--builtin/diff-index.c3
-rw-r--r--builtin/diff-tree.c6
-rw-r--r--builtin/diff.c26
-rw-r--r--builtin/difftool.c36
-rw-r--r--builtin/env--helper.c2
-rw-r--r--builtin/fast-export.c4
-rw-r--r--builtin/fast-import.c2
-rw-r--r--builtin/fetch-pack.c1
-rw-r--r--builtin/fetch.c63
-rw-r--r--builtin/for-each-repo.c7
-rw-r--r--builtin/fsck.c23
-rw-r--r--builtin/fsmonitor--daemon.c15
-rw-r--r--builtin/gc.c307
-rw-r--r--builtin/grep.c48
-rw-r--r--builtin/hash-object.c5
-rw-r--r--builtin/help.c4
-rw-r--r--builtin/hook.c12
-rw-r--r--builtin/init-db.c5
-rw-r--r--builtin/interpret-trailers.c4
-rw-r--r--builtin/log.c23
-rw-r--r--builtin/ls-files.c2
-rw-r--r--builtin/ls-remote.c2
-rw-r--r--builtin/ls-tree.c13
-rw-r--r--builtin/merge-base.c2
-rw-r--r--builtin/merge-index.c4
-rw-r--r--builtin/merge-tree.c42
-rw-r--r--builtin/merge.c78
-rw-r--r--builtin/multi-pack-index.c75
-rw-r--r--builtin/mv.c161
-rw-r--r--builtin/name-rev.c3
-rw-r--r--builtin/notes.c46
-rw-r--r--builtin/pack-objects.c24
-rw-r--r--builtin/pack-redundant.c2
-rw-r--r--builtin/pack-refs.c2
-rw-r--r--builtin/patch-id.c113
-rw-r--r--builtin/pull.c147
-rw-r--r--builtin/push.c4
-rw-r--r--builtin/range-diff.c101
-rw-r--r--builtin/read-tree.c4
-rw-r--r--builtin/rebase.c290
-rw-r--r--builtin/receive-pack.c4
-rw-r--r--builtin/reflog.c49
-rw-r--r--builtin/remote.c210
-rw-r--r--builtin/repack.c196
-rw-r--r--builtin/rerere.c2
-rw-r--r--builtin/rev-list.c3
-rw-r--r--builtin/rev-parse.c9
-rw-r--r--builtin/revert.c11
-rw-r--r--builtin/rm.c7
-rw-r--r--builtin/send-pack.c1
-rw-r--r--builtin/shortlog.c88
-rw-r--r--builtin/show-branch.c9
-rw-r--r--builtin/show-ref.c11
-rw-r--r--builtin/sparse-checkout.c58
-rw-r--r--builtin/stash.c141
-rw-r--r--builtin/submodule--helper.c935
-rw-r--r--builtin/symbolic-ref.c21
-rw-r--r--builtin/tag.c10
-rw-r--r--builtin/unpack-file.c2
-rw-r--r--builtin/update-index.c6
-rw-r--r--builtin/update-server-info.c2
-rw-r--r--builtin/upload-archive.c2
-rw-r--r--builtin/upload-pack.c3
-rw-r--r--builtin/verify-commit.c2
-rw-r--r--builtin/verify-pack.c2
-rw-r--r--builtin/verify-tag.c2
-rw-r--r--builtin/worktree.c139
-rw-r--r--bundle-uri.c590
-rw-r--r--bundle-uri.h107
-rw-r--r--bundle.c42
-rw-r--r--bundle.h16
-rwxr-xr-xci/lib.sh8
-rwxr-xr-xci/run-build-and-tests.sh13
-rw-r--r--color.c2
-rw-r--r--command-list.txt3
-rw-r--r--commit-graph.c8
-rw-r--r--commit.c13
-rw-r--r--commit.h13
-rw-r--r--common-main.c1
-rw-r--r--compat/fsmonitor/fsm-ipc-darwin.c52
-rw-r--r--compat/fsmonitor/fsm-ipc-win32.c9
-rw-r--r--compat/fsmonitor/fsm-listen-darwin.c14
-rw-r--r--compat/fsmonitor/fsm-path-utils-darwin.c135
-rw-r--r--compat/fsmonitor/fsm-path-utils-win32.c145
-rw-r--r--compat/fsmonitor/fsm-settings-darwin.c77
-rw-r--r--compat/fsmonitor/fsm-settings-win32.c106
-rw-r--r--compat/mingw.c11
-rw-r--r--compat/nonblock.c2
-rw-r--r--compat/terminal.c2
-rw-r--r--config.c39
-rw-r--r--config.h1
-rw-r--r--config.mak.dev25
-rw-r--r--configure.ac3
-rw-r--r--contrib/buildsystems/CMakeLists.txt200
-rwxr-xr-xcontrib/credential/netrc/git-credential-netrc.perl5
-rw-r--r--contrib/credential/osxkeychain/git-credential-osxkeychain.c5
-rw-r--r--contrib/credential/wincred/git-credential-wincred.c7
-rw-r--r--contrib/scalar/.gitignore2
-rw-r--r--contrib/scalar/Makefile35
-rw-r--r--contrib/scalar/t/Makefile81
-rwxr-xr-xcontrib/subtree/git-subtree.sh177
-rw-r--r--contrib/subtree/git-subtree.txt16
-rw-r--r--contrib/subtree/t/Makefile1
-rwxr-xr-xcontrib/subtree/t/t7900-subtree.sh60
-rw-r--r--convert.c8
-rw-r--r--date.c6
-rw-r--r--delta-islands.c4
-rw-r--r--diagnose.c70
-rw-r--r--diff-merges.c40
-rw-r--r--diff-no-index.c18
-rw-r--r--diff.c186
-rw-r--r--diff.h2
-rw-r--r--diffcore-pickaxe.c4
-rw-r--r--dir.c8
-rw-r--r--environment.c4
-rw-r--r--exec-cmd.c2
-rw-r--r--fetch-pack.c14
-rw-r--r--fsck.h8
-rw-r--r--fsmonitor--daemon.h3
-rw-r--r--fsmonitor-ipc.c28
-rw-r--r--fsmonitor-ipc.h4
-rw-r--r--fsmonitor-path-utils.h60
-rw-r--r--fsmonitor-settings.c68
-rw-r--r--fsmonitor-settings.h4
-rw-r--r--fsmonitor.c9
-rw-r--r--gettext.c2
-rwxr-xr-xgit-bisect.sh23
-rw-r--r--git-compat-util.h37
-rwxr-xr-xgit-submodule.sh3
-rw-r--r--git.c45
-rw-r--r--gpg-interface.c9
-rw-r--r--grep.c15
-rw-r--r--grep.h1
-rw-r--r--hash.h6
-rw-r--r--hashmap.c10
-rw-r--r--help.c9
-rw-r--r--hook.c23
-rw-r--r--http-backend.c2
-rw-r--r--ident.c2
-rw-r--r--list-objects-filter-options.c81
-rw-r--r--list-objects-filter-options.h5
-rw-r--r--ll-merge.c28
-rw-r--r--log-tree.c3
-rw-r--r--ls-refs.c3
-rw-r--r--mailinfo.c2
-rw-r--r--merge-ort.c132
-rw-r--r--merge-recursive.c12
-rw-r--r--merge.c18
-rw-r--r--midx.c190
-rw-r--r--midx.h1
-rw-r--r--name-hash.c4
-rw-r--r--negotiator/default.c3
-rw-r--r--negotiator/skipping.c32
-rw-r--r--notes.c5
-rw-r--r--object-file.c19
-rw-r--r--object-name.c10
-rw-r--r--object-store.h2
-rw-r--r--object.c24
-rw-r--r--object.h6
-rw-r--r--oidmap.c2
-rw-r--r--oss-fuzz/.gitignore3
-rw-r--r--oss-fuzz/fuzz-commit-graph.c (renamed from fuzz-commit-graph.c)0
-rw-r--r--oss-fuzz/fuzz-pack-headers.c (renamed from fuzz-pack-headers.c)0
-rw-r--r--oss-fuzz/fuzz-pack-idx.c (renamed from fuzz-pack-idx.c)0
-rw-r--r--pack-bitmap-write.c120
-rw-r--r--pack-bitmap.c289
-rw-r--r--pack-bitmap.h14
-rw-r--r--packfile.c2
-rw-r--r--pager.c3
-rw-r--r--parse-options.c118
-rw-r--r--parse-options.h29
-rw-r--r--patch-ids.c12
-rw-r--r--patch-ids.h2
-rw-r--r--path.c8
-rw-r--r--perl/Git.pm36
-rw-r--r--po/bg.po1251
-rw-r--r--po/ca.po2165
-rw-r--r--po/de.po1267
-rw-r--r--po/es.po2589
-rw-r--r--po/fr.po1283
-rw-r--r--po/id.po3518
-rw-r--r--po/sv.po1198
-rw-r--r--po/tr.po1447
-rw-r--r--po/zh_CN.po1479
-rw-r--r--po/zh_TW.po1498
-rw-r--r--ppc/sha1.c72
-rw-r--r--ppc/sha1.h25
-rw-r--r--ppc/sha1ppc.S224
-rw-r--r--pretty.c15
-rw-r--r--promisor-remote.c23
-rw-r--r--promisor-remote.h11
-rw-r--r--range-diff.c8
-rw-r--r--read-cache.c61
-rw-r--r--ref-filter.c12
-rw-r--r--reflog-walk.c2
-rw-r--r--reflog.c29
-rw-r--r--refs.c99
-rw-r--r--refs.h33
-rw-r--r--refs/files-backend.c94
-rw-r--r--refs/iterator.c6
-rw-r--r--refs/packed-backend.c16
-rw-r--r--reftable/merged.c4
-rw-r--r--reftable/pq.c4
-rw-r--r--reftable/pq.h2
-rw-r--r--reftable/pq_test.c2
-rw-r--r--remote-curl.c28
-rw-r--r--remote.c22
-rw-r--r--replace-object.c3
-rw-r--r--repo-settings.c8
-rw-r--r--repository.h4
-rw-r--r--revision.c65
-rw-r--r--revision.h19
-rw-r--r--run-command.c271
-rw-r--r--run-command.h105
-rw-r--r--scalar.c (renamed from contrib/scalar/scalar.c)92
-rw-r--r--send-pack.c2
-rw-r--r--sequencer.c57
-rw-r--r--server-info.c3
-rw-r--r--sha1dc_git.h1
-rw-r--r--shallow.c12
-rw-r--r--shell.c51
-rw-r--r--shortlog.h5
-rw-r--r--sparse-index.c30
-rw-r--r--strbuf.c2
-rw-r--r--streaming.c6
-rw-r--r--string-list.c2
-rw-r--r--string-list.h7
-rw-r--r--strmap.c4
-rw-r--r--sub-process.c4
-rw-r--r--submodule-config.c10
-rw-r--r--submodule.c90
-rw-r--r--submodule.h6
-rw-r--r--t/Makefile50
-rw-r--r--t/README8
-rwxr-xr-xt/chainlint.pl770
-rw-r--r--t/chainlint.sed399
-rw-r--r--t/chainlint/blank-line-before-esac.expect18
-rw-r--r--t/chainlint/blank-line-before-esac.test19
-rw-r--r--t/chainlint/block.expect15
-rw-r--r--t/chainlint/block.test15
-rw-r--r--t/chainlint/chain-break-background.expect9
-rw-r--r--t/chainlint/chain-break-background.test10
-rw-r--r--t/chainlint/chain-break-continue.expect12
-rw-r--r--t/chainlint/chain-break-continue.test13
-rw-r--r--t/chainlint/chain-break-false.expect9
-rw-r--r--t/chainlint/chain-break-false.test10
-rw-r--r--t/chainlint/chain-break-return-exit.expect19
-rw-r--r--t/chainlint/chain-break-return-exit.test23
-rw-r--r--t/chainlint/chain-break-status.expect9
-rw-r--r--t/chainlint/chain-break-status.test11
-rw-r--r--t/chainlint/chained-block.expect9
-rw-r--r--t/chainlint/chained-block.test11
-rw-r--r--t/chainlint/chained-subshell.expect10
-rw-r--r--t/chainlint/chained-subshell.test13
-rw-r--r--t/chainlint/command-substitution-subsubshell.expect2
-rw-r--r--t/chainlint/command-substitution-subsubshell.test3
-rw-r--r--t/chainlint/complex-if-in-cuddled-loop.expect2
-rw-r--r--t/chainlint/double-here-doc.expect2
-rw-r--r--t/chainlint/double-here-doc.test12
-rw-r--r--t/chainlint/dqstring-line-splice.expect3
-rw-r--r--t/chainlint/dqstring-line-splice.test7
-rw-r--r--t/chainlint/dqstring-no-interpolate.expect11
-rw-r--r--t/chainlint/dqstring-no-interpolate.test15
-rw-r--r--t/chainlint/empty-here-doc.expect3
-rw-r--r--t/chainlint/empty-here-doc.test5
-rw-r--r--t/chainlint/exclamation.expect4
-rw-r--r--t/chainlint/exclamation.test8
-rw-r--r--t/chainlint/for-loop-abbreviated.expect5
-rw-r--r--t/chainlint/for-loop-abbreviated.test6
-rw-r--r--t/chainlint/for-loop.expect4
-rw-r--r--t/chainlint/function.expect11
-rw-r--r--t/chainlint/function.test13
-rw-r--r--t/chainlint/here-doc-indent-operator.expect5
-rw-r--r--t/chainlint/here-doc-indent-operator.test13
-rw-r--r--t/chainlint/here-doc-multi-line-string.expect3
-rw-r--r--t/chainlint/if-condition-split.expect7
-rw-r--r--t/chainlint/if-condition-split.test8
-rw-r--r--t/chainlint/if-in-loop.expect2
-rw-r--r--t/chainlint/if-in-loop.test2
-rw-r--r--t/chainlint/loop-detect-failure.expect15
-rw-r--r--t/chainlint/loop-detect-failure.test17
-rw-r--r--t/chainlint/loop-detect-status.expect18
-rw-r--r--t/chainlint/loop-detect-status.test19
-rw-r--r--t/chainlint/loop-in-if.expect2
-rw-r--r--t/chainlint/loop-upstream-pipe.expect10
-rw-r--r--t/chainlint/loop-upstream-pipe.test11
-rw-r--r--t/chainlint/multi-line-string.expect11
-rw-r--r--t/chainlint/nested-loop-detect-failure.expect31
-rw-r--r--t/chainlint/nested-loop-detect-failure.test35
-rw-r--r--t/chainlint/nested-subshell.expect2
-rw-r--r--t/chainlint/one-liner-for-loop.expect9
-rw-r--r--t/chainlint/one-liner-for-loop.test10
-rw-r--r--t/chainlint/return-loop.expect5
-rw-r--r--t/chainlint/return-loop.test6
-rw-r--r--t/chainlint/semicolon.expect2
-rw-r--r--t/chainlint/sqstring-in-sqstring.expect4
-rw-r--r--t/chainlint/sqstring-in-sqstring.test5
-rw-r--r--t/chainlint/t7900-subtree.expect13
-rw-r--r--t/chainlint/token-pasting.expect27
-rw-r--r--t/chainlint/token-pasting.test32
-rw-r--r--t/chainlint/while-loop.expect4
-rwxr-xr-xt/check-non-portable-shell.pl1
-rw-r--r--t/helper/test-bundle-uri.c95
-rw-r--r--t/helper/test-config.c2
-rw-r--r--t/helper/test-crontab.c23
-rw-r--r--t/helper/test-fake-ssh.c7
-rw-r--r--t/helper/test-mergesort.c40
-rw-r--r--t/helper/test-parse-options.c128
-rw-r--r--t/helper/test-path-utils.c3
-rw-r--r--t/helper/test-proc-receive.c2
-rw-r--r--t/helper/test-ref-store.c4
-rw-r--r--t/helper/test-run-command.c77
-rw-r--r--t/helper/test-serve-v2.c2
-rw-r--r--t/helper/test-sha1.c8
-rw-r--r--t/helper/test-submodule-config.c11
-rw-r--r--t/helper/test-submodule.c224
-rw-r--r--t/helper/test-tool-utils.h9
-rw-r--r--t/helper/test-tool.c11
-rw-r--r--t/helper/test-tool.h5
-rw-r--r--t/helper/test-trace2.c191
-rw-r--r--t/helper/test-userdiff.c2
-rw-r--r--t/lib-bitmap.sh2
-rw-r--r--t/lib-gettext.sh2
-rw-r--r--t/lib-gitweb.sh2
-rw-r--r--t/lib-httpd/apache.conf2
-rw-r--r--t/lib-submodule-update.sh1
-rw-r--r--t/perf/README4
-rw-r--r--t/perf/lib-bitmap.sh31
-rwxr-xr-xt/perf/p2000-sparse-operations.sh1
-rwxr-xr-xt/perf/p5310-pack-bitmaps.sh78
-rwxr-xr-xt/perf/p5311-pack-bitmaps-fetch.sh74
-rwxr-xr-xt/perf/p5312-pack-bitmaps-revs.sh35
-rwxr-xr-xt/perf/p5326-multi-pack-bitmaps.sh103
-rwxr-xr-xt/perf/p9210-scalar.sh39
-rw-r--r--t/perf/perf-lib.sh13
-rwxr-xr-xt/perf/run7
-rwxr-xr-xt/t0012-help.sh2
-rwxr-xr-xt/t0013-sha1dc.sh6
-rwxr-xr-xt/t0027-auto-crlf.sh7
-rwxr-xr-xt/t0033-safe-directory.sh9
-rwxr-xr-xt/t0035-safe-bare-repository.sh9
-rwxr-xr-xt/t0040-parse-options.sh253
-rwxr-xr-xt/t0060-path-utils.sh2
-rwxr-xr-xt/t0061-run-command.sh15
-rwxr-xr-xt/t0068-for-each-repo.sh6
-rwxr-xr-xt/t0092-diagnose.sh12
-rwxr-xr-xt/t0211-trace2-perf.sh95
-rw-r--r--t/t0211/scrub_perf.perl6
-rwxr-xr-xt/t0410-partial-clone.sh14
-rwxr-xr-xt/t0450-txt-doc-vs-help.sh172
-rw-r--r--t/t0450/txt-help-mismatches58
-rwxr-xr-xt/t1002-read-tree-m-u-2way.sh16
-rwxr-xr-xt/t1060-object-corruption.sh7
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh3
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh83
-rwxr-xr-xt/t1304-default-acl.sh4
-rwxr-xr-xt/t1401-symbolic-ref.sh14
-rwxr-xr-xt/t1450-fsck.sh48
-rwxr-xr-xt/t1500-rev-parse.sh4
-rwxr-xr-xt/t1502-rev-parse-parseopt.sh7
-rwxr-xr-xt/t1800-hook.sh8
-rwxr-xr-xt/t2080-parallel-checkout-basics.sh3
-rwxr-xr-xt/t2400-worktree-add.sh2
-rwxr-xr-xt/t2403-worktree-move.sh8
-rwxr-xr-xt/t2405-worktree-submodule.sh1
-rwxr-xr-xt/t3070-wildmatch.sh5
-rwxr-xr-xt/t3200-branch.sh19
-rwxr-xr-xt/t3202-show-branch.sh46
-rwxr-xr-xt/t3204-branch-name-interpretation.sh24
-rwxr-xr-xt/t3206-range-diff.sh15
-rwxr-xr-xt/t3207-branch-submodule.sh1
-rwxr-xr-xt/t3301-notes.sh5
-rwxr-xr-xt/t3305-notes-fanout.sh2
-rwxr-xr-xt/t3404-rebase-interactive.sh113
-rwxr-xr-xt/t3406-rebase-message.sh185
-rwxr-xr-xt/t3415-rebase-autosquash.sh13
-rwxr-xr-xt/t3416-rebase-onto-threedots.sh62
-rwxr-xr-xt/t3419-rebase-patch-id.sh63
-rwxr-xr-xt/t3420-rebase-autostash.sh2
-rwxr-xr-xt/t3426-rebase-submodule.sh3
-rwxr-xr-xt/t3431-rebase-fork-point.sh2
-rwxr-xr-xt/t3435-rebase-gpg-sign.sh8
-rwxr-xr-xt/t3438-rebase-broken-files.sh59
-rwxr-xr-xt/t3512-cherry-pick-submodule.sh2
-rwxr-xr-xt/t3600-rm.sh3
-rwxr-xr-xt/t3700-add.sh2
-rwxr-xr-xt/t3701-add-interactive.sh31
-rwxr-xr-xt/t3702-add-edit.sh2
-rwxr-xr-xt/t3903-stash.sh2
-rwxr-xr-xt/t3906-stash-submodule.sh2
-rwxr-xr-xt/t4012-diff-binary.sh14
-rwxr-xr-xt/t4014-format-patch.sh45
-rwxr-xr-xt/t4038-diff-combined.sh10
-rwxr-xr-xt/t4059-diff-submodule-not-initialized.sh2
-rwxr-xr-xt/t4060-diff-submodule-option-diff-format.sh2
-rwxr-xr-xt/t4067-diff-partial-clone.sh1
-rwxr-xr-xt/t4069-remerge-diff.sh30
-rwxr-xr-xt/t4141-apply-too-large.sh23
-rwxr-xr-xt/t4201-shortlog.sh39
-rwxr-xr-xt/t4202-log.sh9
-rwxr-xr-xt/t4204-patch-id.sh95
-rwxr-xr-xt/t4208-log-magic-pathspec.sh1
-rwxr-xr-xt/t4301-merge-tree-write-tree.sh626
-rwxr-xr-xt/t5000-tar-tree.sh7
-rwxr-xr-xt/t5100-mailinfo.sh4
-rwxr-xr-xt/t5310-pack-bitmaps.sh785
-rwxr-xr-xt/t5311-pack-bitmaps-shallow.sh53
-rwxr-xr-xt/t5318-commit-graph.sh4
-rwxr-xr-xt/t5319-multi-pack-index.sh94
-rwxr-xr-xt/t5320-delta-islands.sh2
-rwxr-xr-xt/t5326-multi-pack-bitmaps.sh467
-rwxr-xr-xt/t5327-multi-pack-bitmaps-rev.sh24
-rwxr-xr-xt/t5505-remote.sh31
-rwxr-xr-xt/t5510-fetch.sh1
-rwxr-xr-xt/t5516-fetch-push.sh32
-rwxr-xr-xt/t5520-pull.sh17
-rwxr-xr-xt/t5526-fetch-submodules.sh17
-rwxr-xr-xt/t5537-fetch-shallow.sh5
-rwxr-xr-xt/t5545-push-options.sh1
-rwxr-xr-xt/t5550-http-fetch-dumb.sh2
-rwxr-xr-xt/t5551-http-fetch-smart.sh77
-rwxr-xr-xt/t5557-http-get.sh39
-rwxr-xr-xt/t5558-clone-bundle-uri.sh356
-rwxr-xr-xt/t5572-pull-submodule.sh4
-rwxr-xr-xt/t5601-clone.sh24
-rwxr-xr-xt/t5604-clone-reference.sh50
-rwxr-xr-xt/t5606-clone-options.sh17
-rwxr-xr-xt/t5614-clone-submodules-shallow.sh8
-rwxr-xr-xt/t5616-partial-clone.sh2
-rwxr-xr-xt/t5617-clone-submodules-remote.sh1
-rwxr-xr-xt/t5702-protocol-v2.sh2
-rwxr-xr-xt/t5750-bundle-uri-parse.sh171
-rwxr-xr-xt/t6008-rev-list-submodule.sh3
-rwxr-xr-xt/t6030-bisect-porcelain.sh10
-rwxr-xr-xt/t6132-pathspec-exclude.sh6
-rwxr-xr-xt/t6134-pathspec-in-submodule.sh3
-rwxr-xr-xt/t6300-for-each-ref.sh40
-rwxr-xr-xt/t6400-merge-df.sh2
-rwxr-xr-xt/t6406-merge-attr.sh4
-rwxr-xr-xt/t6416-recursive-corner-cases.sh38
-rwxr-xr-xt/t6421-merge-partial-clone.sh2
-rwxr-xr-xt/t6422-merge-rename-corner-cases.sh38
-rwxr-xr-xt/t6423-merge-rename-directories.sh194
-rwxr-xr-xt/t6426-merge-skip-unneeded-updates.sh16
-rwxr-xr-xt/t6427-diff3-conflict-markers.sh10
-rwxr-xr-xt/t6428-merge-conflicts-sparse.sh2
-rwxr-xr-xt/t6429-merge-sequence-rename-caching.sh14
-rwxr-xr-xt/t6437-submodule-merge.sh8
-rwxr-xr-xt/t6500-gc.sh96
-rwxr-xr-xt/t7001-mv.sh64
-rwxr-xr-xt/t7002-mv-sparse-checkout.sh226
-rwxr-xr-xt/t7003-filter-branch.sh4
-rwxr-xr-xt/t7064-wtstatus-pv2.sh1
-rwxr-xr-xt/t7300-clean.sh1
-rwxr-xr-xt/t7400-submodule-basic.sh70
-rwxr-xr-xt/t7401-submodule-summary.sh1
-rwxr-xr-xt/t7403-submodule-sync.sh2
-rwxr-xr-xt/t7406-submodule-update.sh3
-rwxr-xr-xt/t7407-submodule-foreach.sh6
-rwxr-xr-xt/t7408-submodule-reference.sh4
-rwxr-xr-xt/t7409-submodule-detached-work-tree.sh4
-rwxr-xr-xt/t7411-submodule-config.sh39
-rwxr-xr-xt/t7412-submodule-absorbgitdirs.sh1
-rwxr-xr-xt/t7413-submodule-is-active.sh37
-rwxr-xr-xt/t7414-submodule-mistakes.sh5
-rwxr-xr-xt/t7416-submodule-dash-url.sh4
-rwxr-xr-xt/t7417-submodule-path-url.sh4
-rwxr-xr-xt/t7418-submodule-sparse-gitmodules.sh8
-rwxr-xr-xt/t7419-submodule-set-branch.sh5
-rwxr-xr-xt/t7420-submodule-set-url.sh4
-rwxr-xr-xt/t7421-submodule-summary-add.sh4
-rwxr-xr-xt/t7422-submodule-output.sh170
-rwxr-xr-xt/t7450-bad-git-dotfiles.sh6
-rwxr-xr-xt/t7506-status-submodule.sh3
-rwxr-xr-xt/t7507-commit-verbose.sh3
-rwxr-xr-xt/t7527-builtin-fsmonitor.sh22
-rwxr-xr-xt/t7600-merge.sh9
-rwxr-xr-xt/t7609-mergetool--lib.sh2
-rwxr-xr-xt/t7700-repack.sh182
-rwxr-xr-xt/t7701-repack-unpack-unreachable.sh4
-rwxr-xr-xt/t7703-repack-geometric.sh6
-rwxr-xr-xt/t7800-difftool.sh1
-rwxr-xr-xt/t7810-grep.sh15
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh5
-rwxr-xr-xt/t7900-maintenance.sh36
-rwxr-xr-xt/t9001-send-email.sh8
-rwxr-xr-xt/t9133-git-svn-nested-git-repo.sh6
-rwxr-xr-xt/t9134-git-svn-ignore-paths.sh8
-rwxr-xr-xt/t9140-git-svn-reset.sh4
-rwxr-xr-xt/t9147-git-svn-include-paths.sh8
-rwxr-xr-xt/t9210-scalar.sh (renamed from contrib/scalar/t/t9099-scalar.sh)26
-rwxr-xr-xt/t9211-scalar-clone.sh151
-rwxr-xr-xt/t9304-fast-import-marks.sh1
-rwxr-xr-xt/t9350-fast-export.sh2
-rwxr-xr-xt/t9700-perl-git.sh4
-rwxr-xr-xt/t9700/test.pl12
-rwxr-xr-xt/t9814-git-p4-rename.sh2
-rwxr-xr-xt/t9815-git-p4-submit-fail.sh4
-rwxr-xr-xt/t9850-shell.sh37
-rwxr-xr-xt/t9902-completion.sh14
-rwxr-xr-xt/t9903-bash-prompt.sh2
-rw-r--r--t/test-lib-functions.sh33
-rw-r--r--t/test-lib.sh49
-rw-r--r--tempfile.c42
-rw-r--r--tempfile.h5
-rw-r--r--tmp-objdir.c40
-rw-r--r--tmp-objdir.h6
-rw-r--r--trace2.c121
-rw-r--r--trace2.h101
-rw-r--r--trace2/tr2_ctr.c101
-rw-r--r--trace2/tr2_ctr.h104
-rw-r--r--trace2/tr2_tgt.h16
-rw-r--r--trace2/tr2_tgt_event.c47
-rw-r--r--trace2/tr2_tgt_normal.c39
-rw-r--r--trace2/tr2_tgt_perf.c43
-rw-r--r--trace2/tr2_tls.c34
-rw-r--r--trace2/tr2_tls.h55
-rw-r--r--trace2/tr2_tmr.c182
-rw-r--r--trace2/tr2_tmr.h140
-rw-r--r--trailer.c6
-rw-r--r--transport-helper.c2
-rw-r--r--transport.c13
-rw-r--r--unpack-trees.c4
-rw-r--r--upload-pack.c16
-rw-r--r--walker.c6
-rw-r--r--worktree.c59
-rw-r--r--worktree.h10
-rw-r--r--write-or-die.c1
-rw-r--r--wt-status.c14
704 files changed, 30210 insertions, 12795 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 831f4df56c5..4928cab0f1c 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -37,14 +37,14 @@ jobs:
echo "::set-output name=enabled::$enabled"
- name: skip if the commit or tree was already tested
id: skip-if-redundant
- uses: actions/github-script@v3
+ uses: actions/github-script@v6
if: steps.check-ref.outputs.enabled == 'yes'
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
try {
// Figure out workflow ID, commit and tree
- const { data: run } = await github.actions.getWorkflowRun({
+ const { data: run } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.runId,
@@ -54,7 +54,7 @@ jobs:
const tree_id = run.head_commit.tree_id;
// See whether there is a successful run for that commit or tree
- const { data: runs } = await github.actions.listWorkflowRuns({
+ const { data: runs } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 500,
@@ -238,6 +238,9 @@ jobs:
os: ubuntu
cc_package: gcc-8
pool: ubuntu-latest
+ - jobname: linux-cmake-ctest
+ cc: gcc
+ pool: ubuntu-latest
- jobname: osx-clang
cc: clang
pool: macos-latest
@@ -251,6 +254,12 @@ jobs:
- jobname: linux-leaks
cc: gcc
pool: ubuntu-latest
+ - jobname: linux-asan
+ cc: gcc
+ pool: ubuntu-latest
+ - jobname: linux-ubsan
+ cc: gcc
+ pool: ubuntu-latest
env:
CC: ${{matrix.vector.cc}}
CC_PACKAGE: ${{matrix.vector.cc_package}}
diff --git a/.gitignore b/.gitignore
index e67085f6918..7cce39270d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,4 @@
-/fuzz-commit-graph
/fuzz_corpora
-/fuzz-pack-headers
-/fuzz-pack-idx
/GIT-BUILD-OPTIONS
/GIT-CFLAGS
/GIT-LDFLAGS
@@ -182,10 +179,12 @@
/git-verify-commit
/git-verify-pack
/git-verify-tag
+/git-version
/git-web--browse
/git-whatchanged
/git-worktree
/git-write-tree
+/scalar
/git-core-*/?*
/git.res
/gitweb/GITWEB-BUILD-OPTIONS
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines
index 4c756be517a..9d5c27807a4 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -162,8 +162,6 @@ For shell scripts specifically (not exhaustive):
- We do not use \{m,n\};
- - We do not use -E;
-
- We do not use ? or + (which are \{0,1\} and \{1,\}
respectively in BRE) but that goes without saying as these
are ERE elements not BRE (note that \? and \+ are not even part
@@ -204,10 +202,19 @@ For C programs:
by e.g. "echo DEVELOPER=1 >>config.mak".
- We try to support a wide range of C compilers to compile Git with,
- including old ones. You should not use features from newer C
+ including old ones. As of Git v2.35.0 Git requires C99 (we check
+ "__STDC_VERSION__"). You should not use features from a newer C
standard, even if your compiler groks them.
- There are a few exceptions to this guideline:
+ New C99 features have been phased in gradually, if something's new
+ in C99 but not used yet don't assume that it's safe to use, some
+ compilers we target have only partial support for it. These are
+ considered safe to use:
+
+ . 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};
. since early 2012 with e1327023ea, we have been using an enum
definition whose last element is followed by a comma. This, like
@@ -223,18 +230,24 @@ For C programs:
. since early 2021 with 765dc168882, we have been using variadic
macros, mostly for printf-like trace and debug macros.
- These used to be forbidden, but we have not heard any breakage
- report, and they are assumed to be safe.
+ . since late 2021 with 44ba10d6, we have had variables declared in
+ the for loop "for (int i = 0; i < 10; i++)".
+
+ New C99 features that we cannot use yet:
+
+ . %z and %zu as a printf() argument for a size_t (the %z being for
+ the POSIX-specific ssize_t). Instead you should use
+ printf("%"PRIuMAX, (uintmax_t)v). These days the MSVC version we
+ rely on supports %z, but the C library used by MinGW does not.
+
+ . Shorthand like ".a.b = *c" in struct initializations is known to
+ trip up an older IBM XLC version, use ".a = { .b = *c }" instead.
+ See the 33665d98 (reftable: make assignments portable to AIX xlc
+ v12.01, 2022-03-28).
- Variables have to be declared at the beginning of the block, before
the first statement (i.e. -Wdeclaration-after-statement).
- - Declaring a variable in the for loop "for (int i = 0; i < 10; i++)"
- is still not allowed in this codebase. We are in the process of
- allowing it by waiting to see that 44ba10d6 (revision: use C99
- declaration of variable in for() loop, 2021-11-14) does not get
- complaints. Let's revisit this around November 2022.
-
- NULL pointers shall be written as NULL, not as 0.
- When declaring pointers, the star sides with the variable
@@ -606,7 +619,7 @@ Writing Documentation:
avoidance of gendered pronouns.
- When it becomes awkward to stick to this style, prefer "you" when
- addressing the the hypothetical user, and possibly "we" when
+ addressing the hypothetical user, and possibly "we" when
discussing how the program might react to the user. E.g.
You can use this option instead of --xyz, but we might remove
@@ -650,8 +663,8 @@ Writing Documentation:
(One or more of <file>.)
Optional parts are enclosed in square brackets:
- [<extra>]
- (Zero or one <extra>.)
+ [<file>...]
+ (Zero or more of <file>.)
--exec-path[=<path>]
(Option with an optional argument. Note that the "=" is inside the
@@ -665,6 +678,16 @@ Writing Documentation:
[-q | --quiet]
[--utf8 | --no-utf8]
+ Use spacing around "|" token(s), but not immediately after opening or
+ before closing a [] or () pair:
+ Do: [-q | --quiet]
+ Don't: [-q|--quiet]
+
+ Don't use spacing around "|" tokens when they're used to seperate the
+ alternate arguments of an option:
+ Do: --track[=(direct|inherit)]
+ Don't: --track[=(direct | inherit)]
+
Parentheses are used for grouping:
[(<rev> | <range>)...]
(Any number of either <rev> or <range>. Parens are needed to make
diff --git a/Documentation/Makefile b/Documentation/Makefile
index bd6b6fcb930..5e1a7f655c2 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -21,6 +21,7 @@ MAN1_TXT += $(filter-out \
MAN1_TXT += git.txt
MAN1_TXT += gitk.txt
MAN1_TXT += gitweb.txt
+MAN1_TXT += scalar.txt
# man5 / man7 guides (note: new guides should also be added to command-list.txt)
MAN5_TXT += gitattributes.txt
@@ -62,6 +63,7 @@ HOWTO_TXT += $(wildcard howto/*.txt)
DOC_DEP_TXT += $(wildcard *.txt)
DOC_DEP_TXT += $(wildcard config/*.txt)
+DOC_DEP_TXT += $(wildcard includes/*.txt)
ifdef MAN_FILTER
MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT))
@@ -101,6 +103,7 @@ SP_ARTICLES += howto/coordinate-embargoed-releases
API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
SP_ARTICLES += $(API_DOCS)
+TECH_DOCS += ReviewingGuidelines
TECH_DOCS += MyFirstContribution
TECH_DOCS += MyFirstObjectWalk
TECH_DOCS += SubmittingPatches
@@ -115,6 +118,7 @@ TECH_DOCS += technical/parallel-checkout
TECH_DOCS += technical/partial-clone
TECH_DOCS += technical/racy-git
TECH_DOCS += technical/reftable
+TECH_DOCS += technical/scalar
TECH_DOCS += technical/send-pack-pipeline
TECH_DOCS += technical/shallow
TECH_DOCS += technical/trivial-merge
@@ -472,8 +476,19 @@ $(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt
.PHONY: lint-docs-man-section-order
lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER)
+.PHONY: lint-docs-fsck-msgids
+LINT_DOCS_FSCK_MSGIDS = .build/lint-docs/fsck-msgids.ok
+$(LINT_DOCS_FSCK_MSGIDS): lint-fsck-msgids.perl
+$(LINT_DOCS_FSCK_MSGIDS): ../fsck.h fsck-msgids.txt
+ $(call mkdir_p_parent_template)
+ $(QUIET_GEN)$(PERL_PATH) lint-fsck-msgids.perl \
+ ../fsck.h fsck-msgids.txt $@
+
+lint-docs-fsck-msgids: $(LINT_DOCS_FSCK_MSGIDS)
+
## Lint: list of targets above
.PHONY: lint-docs
+lint-docs: lint-docs-fsck-msgids
lint-docs: lint-docs-gitlink
lint-docs: lint-docs-man-end-blurb
lint-docs: lint-docs-man-section-order
diff --git a/Documentation/MyFirstContribution.txt b/Documentation/MyFirstContribution.txt
index 1da15d9ad44..1a4be8ee0ad 100644
--- a/Documentation/MyFirstContribution.txt
+++ b/Documentation/MyFirstContribution.txt
@@ -1160,7 +1160,7 @@ all named like `v2-000n-my-commit-subject.patch`. `-v2` will also format
your patches by prefixing them with "[PATCH v2]" instead of "[PATCH]",
and your range-diff will be prefaced with "Range-diff against v1".
-Afer you run this command, `format-patch` will output the patches to the `psuh/`
+After you run this command, `format-patch` will output the patches to the `psuh/`
directory, alongside the v1 patches. Using a single directory makes it easy to
refer to the old v1 patches while proofreading the v2 patches, but you will need
to be careful to send out only the v2 patches. We will use a pattern like
diff --git a/Documentation/MyFirstObjectWalk.txt b/Documentation/MyFirstObjectWalk.txt
index 8d9e85566e6..eee513e86f4 100644
--- a/Documentation/MyFirstObjectWalk.txt
+++ b/Documentation/MyFirstObjectWalk.txt
@@ -534,7 +534,7 @@ the arguments to `traverse_commit_list()`.
- `void *show_data`: A context buffer which is passed in turn to `show_commit`
and `show_object`.
-In addition, `traverse_commit_list_filtered()` has an additional paramter:
+In addition, `traverse_commit_list_filtered()` has an additional parameter:
- `struct oidset *omitted`: A linked-list of object IDs which the provided
filter caused to be omitted.
diff --git a/Documentation/RelNotes/2.30.6.txt b/Documentation/RelNotes/2.30.6.txt
new file mode 100644
index 00000000000..d649071b794
--- /dev/null
+++ b/Documentation/RelNotes/2.30.6.txt
@@ -0,0 +1,60 @@
+Git v2.30.6 Release Notes
+=========================
+
+This release addresses the security issues CVE-2022-39253 and
+CVE-2022-39260.
+
+Fixes since v2.30.5
+-------------------
+
+ * CVE-2022-39253:
+ When relying on the `--local` clone optimization, Git dereferences
+ symbolic links in the source repository before creating hardlinks
+ (or copies) of the dereferenced link in the destination repository.
+ This can lead to surprising behavior where arbitrary files are
+ present in a repository's `$GIT_DIR` when cloning from a malicious
+ repository.
+
+ Git will no longer dereference symbolic links via the `--local`
+ clone mechanism, and will instead refuse to clone repositories that
+ have symbolic links present in the `$GIT_DIR/objects` directory.
+
+ Additionally, the value of `protocol.file.allow` is changed to be
+ "user" by default.
+
+ * CVE-2022-39260:
+ An overly-long command string given to `git shell` can result in
+ overflow in `split_cmdline()`, leading to arbitrary heap writes and
+ remote code execution when `git shell` is exposed and the directory
+ `$HOME/git-shell-commands` exists.
+
+ `git shell` is taught to refuse interactive commands that are
+ longer than 4MiB in size. `split_cmdline()` is hardened to reject
+ inputs larger than 2GiB.
+
+Credit for finding CVE-2022-39253 goes to Cory Snider of Mirantis. The
+fix was authored by Taylor Blau, with help from Johannes Schindelin.
+
+Credit for finding CVE-2022-39260 goes to Kevin Backhouse of GitHub.
+The fix was authored by Kevin Backhouse, Jeff King, and Taylor Blau.
+
+
+Jeff King (2):
+ shell: add basic tests
+ shell: limit size of interactive commands
+
+Kevin Backhouse (1):
+ alias.c: reject too-long cmdline strings in split_cmdline()
+
+Taylor Blau (11):
+ builtin/clone.c: disallow `--local` clones with symlinks
+ t/lib-submodule-update.sh: allow local submodules
+ t/t1NNN: allow local submodules
+ t/2NNNN: allow local submodules
+ t/t3NNN: allow local submodules
+ t/t4NNN: allow local submodules
+ t/t5NNN: allow local submodules
+ t/t6NNN: allow local submodules
+ t/t7NNN: allow local submodules
+ t/t9NNN: allow local submodules
+ transport: make `protocol.file.allow` be "user" by default
diff --git a/Documentation/RelNotes/2.31.5.txt b/Documentation/RelNotes/2.31.5.txt
new file mode 100644
index 00000000000..0d87e6e03fc
--- /dev/null
+++ b/Documentation/RelNotes/2.31.5.txt
@@ -0,0 +1,5 @@
+Git v2.31.5 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.32.4.txt b/Documentation/RelNotes/2.32.4.txt
new file mode 100644
index 00000000000..76c67b209ef
--- /dev/null
+++ b/Documentation/RelNotes/2.32.4.txt
@@ -0,0 +1,5 @@
+Git v2.32.4 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.33.5.txt b/Documentation/RelNotes/2.33.5.txt
new file mode 100644
index 00000000000..a63652602b2
--- /dev/null
+++ b/Documentation/RelNotes/2.33.5.txt
@@ -0,0 +1,5 @@
+Git v2.33.5 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.34.5.txt b/Documentation/RelNotes/2.34.5.txt
new file mode 100644
index 00000000000..0e8999204d4
--- /dev/null
+++ b/Documentation/RelNotes/2.34.5.txt
@@ -0,0 +1,5 @@
+Git v2.34.5 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.35.5.txt b/Documentation/RelNotes/2.35.5.txt
new file mode 100644
index 00000000000..e19cc48b334
--- /dev/null
+++ b/Documentation/RelNotes/2.35.5.txt
@@ -0,0 +1,5 @@
+Git v2.35.5 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.36.3.txt b/Documentation/RelNotes/2.36.3.txt
new file mode 100644
index 00000000000..56db77b5bdb
--- /dev/null
+++ b/Documentation/RelNotes/2.36.3.txt
@@ -0,0 +1,5 @@
+Git v2.36.3 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.37.4.txt b/Documentation/RelNotes/2.37.4.txt
new file mode 100644
index 00000000000..e42a5c16209
--- /dev/null
+++ b/Documentation/RelNotes/2.37.4.txt
@@ -0,0 +1,65 @@
+Git 2.37.4 Release Notes
+========================
+
+This primarily is to backport various fixes accumulated on the 'master'
+front since 2.37.3, and also includes the same security fixes as in
+v2.30.6.
+
+Fixes since v2.37.3
+-------------------
+
+ * CVE-2022-39253:
+ When relying on the `--local` clone optimization, Git dereferences
+ symbolic links in the source repository before creating hardlinks
+ (or copies) of the dereferenced link in the destination repository.
+ This can lead to surprising behavior where arbitrary files are
+ present in a repository's `$GIT_DIR` when cloning from a malicious
+ repository.
+
+ Git will no longer dereference symbolic links via the `--local`
+ clone mechanism, and will instead refuse to clone repositories that
+ have symbolic links present in the `$GIT_DIR/objects` directory.
+
+ Additionally, the value of `protocol.file.allow` is changed to be
+ "user" by default.
+
+ Credit for finding CVE-2022-39253 goes to Cory Snider of Mirantis.
+ The fix was authored by Taylor Blau, with help from Johannes
+ Schindelin.
+
+ * CVE-2022-39260:
+ An overly-long command string given to `git shell` can result in
+ overflow in `split_cmdline()`, leading to arbitrary heap writes and
+ remote code execution when `git shell` is exposed and the directory
+ `$HOME/git-shell-commands` exists.
+
+ `git shell` is taught to refuse interactive commands that are
+ longer than 4MiB in size. `split_cmdline()` is hardened to reject
+ inputs larger than 2GiB.
+
+ Credit for finding CVE-2022-39260 goes to Kevin Backhouse of
+ GitHub. The fix was authored by Kevin Backhouse, Jeff King, and
+ Taylor Blau.
+
+ * An earlier optimization discarded a tree-object buffer that is
+ still in use, which has been corrected.
+
+ * Fix deadlocks between main Git process and subprocess spawned via
+ the pipe_command() API, that can kill "git add -p" that was
+ reimplemented in C recently.
+
+ * xcalloc(), imitating calloc(), takes "number of elements of the
+ array", and "size of a single element", in this order. A call that
+ does not follow this ordering has been corrected.
+
+ * The preload-index codepath made copies of pathspec to give to
+ multiple threads, which were left leaked.
+
+ * Update the version of Ubuntu used for GitHub Actions CI from 18.04
+ to 22.04.
+
+ * The auto-stashed local changes created by "git merge --autostash"
+ was mixed into a conflicted state left in the working tree, which
+ has been corrected.
+
+Also contains other minor documentation updates and code clean-ups.
diff --git a/Documentation/RelNotes/2.38.0.txt b/Documentation/RelNotes/2.38.0.txt
index 91a822e62be..870581fc57e 100644
--- a/Documentation/RelNotes/2.38.0.txt
+++ b/Documentation/RelNotes/2.38.0.txt
@@ -6,7 +6,7 @@ UI, Workflows & Features
* "git remote show [-n] frotz" now pays attention to negative
pathspec.
- * "git push" sometimes perform poorly when reachability bitmaps are
+ * "git push" sometimes performs poorly when reachability bitmaps are
used, even in a repository where other operations are helped by
bitmaps. The push.useBitmaps configuration variable is introduced
to allow disabling use of reachability bitmaps only for "git push".
@@ -27,7 +27,7 @@ UI, Workflows & Features
what locale they are in by sending Accept-Language HTTP header, but
this was done only for some requests but not others.
- * Introduce a discovery.barerepository configuration variable that
+ * Introduce a safe.barerepository configuration variable that
allows users to forbid discovery of bare repositories.
* Various messages that come from the pack-bitmap codepaths have been
@@ -72,6 +72,22 @@ UI, Workflows & Features
* The bash prompt (in contrib/) learned to optionally indicate when
the index is unmerged.
+ * "git clone" command learned the "--bundle-uri" option to coordinate
+ with hosting sites the use of pre-prepared bundle files.
+
+ * "git range-diff" learned to honor pathspec argument if given.
+
+ * "git format-patch --from=<ident>" can be told to add an in-body
+ "From:" line even for commits that are authored by the given
+ <ident> with "--force-in-body-from" option.
+
+ * The built-in fsmonitor refuses to work on a network mounted
+ repositories; a configuration knob for users to override this has
+ been introduced.
+
+ * The "scalar" addition from Microsoft is now part of the core Git
+ installation.
+
Performance, Internal Implementation, Development Support etc.
@@ -114,7 +130,7 @@ Performance, Internal Implementation, Development Support etc.
* The way "git multi-pack" uses parse-options API has been improved.
- * A coccinelle rule (in contrib/) to encourage use of COPY_ARRAY
+ * A Coccinelle rule (in contrib/) to encourage use of COPY_ARRAY
macro has been improved.
* API tweak to make it easier to run fuzz testing on commit-graph parser.
@@ -139,6 +155,32 @@ Performance, Internal Implementation, Development Support etc.
* Test portability improvements.
(merge 4d1d843be7 mt/rot13-in-c later to maint).
+ * The "subcommand" mode is introduced to parse-options API and update
+ the command line parser of Git commands with subcommands.
+
+ * The pack bitmap file gained a bitmap-lookup table to speed up
+ locating the necessary bitmap for a given commit.
+
+ * The assembly version of SHA-1 implementation for PPC has been
+ removed.
+
+ * The server side that responds to "git fetch" and "git clone"
+ request has been optimized by allowing it to send objects in its
+ object store without recomputing and validating the object names.
+
+ * Annotate function parameters that are not used (but cannot be
+ removed for structural reasons), to prepare us to later compile
+ with -Wunused warning turned on.
+
+ * Share the text used to explain configuration variables used by "git
+ <subcmd>" in "git help <subcmd>" with the text from "git help config".
+
+ * "git mv A B" in a sparsely populated working tree can be asked to
+ move a path from a directory that is "in cone" to another directory
+ that is "out of cone". Handling of such a case has been improved.
+
+ * The chainlint script for our tests has been revamped.
+
Fixes since v2.37
-----------------
@@ -264,7 +306,7 @@ Fixes since v2.37
* "git fsck" reads mode from tree objects but canonicalizes the mode
before passing it to the logic to check object sanity, which has
hid broken tree objects from the checking logic. This has been
- corrected, but to help exiting projects with broken tree objects
+ corrected, but to help existing projects with broken tree objects
that they cannot fix retroactively, the severity of anomalies this
code detects has been demoted to "info" for now.
@@ -273,12 +315,10 @@ Fixes since v2.37
* An earlier optimization discarded a tree-object buffer that is
still in use, which has been corrected.
- (merge 1490d7d82d jk/is-promisor-object-keep-tree-in-use later to maint).
* Fix deadlocks between main Git process and subprocess spawned via
the pipe_command() API, that can kill "git add -p" that was
reimplemented in C recently.
- (merge 716c1f649e jk/pipe-command-nonblock later to maint).
* The sequencer machinery translated messages left in the reflog by
mistake, which has been corrected.
@@ -286,15 +326,79 @@ Fixes since v2.37
* xcalloc(), imitating calloc(), takes "number of elements of the
array", and "size of a single element", in this order. A call that
does not follow this ordering has been corrected.
- (merge c4bbd9bb8f sg/xcalloc-cocci-fix later to maint).
* The preload-index codepath made copies of pathspec to give to
multiple threads, which were left leaked.
- (merge 23578904da ad/preload-plug-memleak later to maint).
* Update the version of Ubuntu used for GitHub Actions CI from 18.04
to 22.04.
- (merge ef46584831 ds/github-actions-use-newer-ubuntu later to maint).
+
+ * The auto-stashed local changes created by "git merge --autostash"
+ was mixed into a conflicted state left in the working tree, which
+ has been corrected.
+
+ * Multi-pack index got corrupted when preferred pack changed from one
+ pack to another in a certain way, which has been corrected.
+ (merge 99e4d084ff tb/midx-with-changing-preferred-pack-fix later to maint).
+
+ * The clean-up of temporary files created via mks_tempfile_dt() was
+ racy and attempted to unlink() the leading directory when signals
+ are involved, which has been corrected.
+ (merge babe2e0559 rs/tempfile-cleanup-race-fix later to maint).
+
+ * FreeBSD portability fix for "git maintenance" that spawns "crontab"
+ to schedule tasks.
+ (merge ee69e7884e bc/gc-crontab-fix later to maint).
+
+ * Those who use diff-so-fancy as the diff-filter noticed a regression
+ or two in the code that parses the diff output in the built-in
+ version of "add -p", which has been corrected.
+ (merge 0a101676e5 js/add-p-diff-parsing-fix later to maint).
+
+ * Segfault fix-up to an earlier fix to the topic to teach "git reset"
+ and "git checkout" work better in a sparse checkout.
+ (merge 037f8ea6d9 vd/sparse-reset-checkout-fixes later to maint).
+
+ * "git diff --no-index A B" managed its the pathnames of its two
+ input files rather haphazardly, sometimes leaking them. The
+ command line argument processing has been straightened out to clean
+ it up.
+ (merge 2b43dd0eb5 rs/diff-no-index-cleanup later to maint).
+
+ * "git rev-list --verify-objects" ought to inspect the contents of
+ objects and notice corrupted ones, but it didn't when the commit
+ graph is in use, which has been corrected.
+ (merge b27ccae34b jk/rev-list-verify-objects-fix later to maint).
+
+ * More fixes to "add -p"
+ (merge 64ec8efb83 js/builtin-add-p-portability-fix later to maint).
+
+ * The parser in the script interface to parse-options in "git
+ rev-parse" has been updated to diagnose a bogus input correctly.
+ (merge f20b9c36d0 ow/rev-parse-parseopt-fix later to maint).
+
+ * The code that manages list-object-filter structure, used in partial
+ clones, leaked the instances, which has been plugged.
+ (merge 66eede4a37 jk/plug-list-object-filter-leaks later to maint).
+
+ * Fix another UI regression in the reimplemented "add -p".
+ (merge f6f0ee247f rs/add-p-worktree-mode-prompt-fix later to maint).
+
+ * "git fetch" over protocol v2 sent an incorrect ref prefix request
+ to the server and made "git pull" with configured fetch refspec
+ that does not cover the remote branch to merge with fail, which has
+ been corrected.
+ (merge 49ca2fba39 jk/proto-v2-ref-prefix-fix later to maint).
+
+ * A result from opendir() was leaking in the commit-graph expiration
+ codepath, which has been plugged.
+ (merge 12f1ae5324 ml/commit-graph-expire-dir-leak-fix later to maint).
+
+ * Just like we have coding guidelines, we now have guidelines for
+ reviewers.
+ (merge e01b851923 vd/doc-reviewing-guidelines later to maint).
* Other code cleanup, docfix, build fix, etc.
- (merge 77b9e85c0f vd/fix-perf-tests later to maint). \ No newline at end of file
+ (merge 77b9e85c0f vd/fix-perf-tests later to maint).
+ (merge 0682bc43f5 jk/test-crontab-fixes later to maint).
+ (merge b46dd1726c cc/doc-trailer-whitespace-rules later to maint).
diff --git a/Documentation/RelNotes/2.38.1.txt b/Documentation/RelNotes/2.38.1.txt
new file mode 100644
index 00000000000..b2b5854aac2
--- /dev/null
+++ b/Documentation/RelNotes/2.38.1.txt
@@ -0,0 +1,5 @@
+Git v2.38.1 Release Notes
+=========================
+
+This release merges the security fix that appears in v2.30.6; see
+the release notes for that version for details.
diff --git a/Documentation/RelNotes/2.38.2.txt b/Documentation/RelNotes/2.38.2.txt
new file mode 100644
index 00000000000..086b900f6c6
--- /dev/null
+++ b/Documentation/RelNotes/2.38.2.txt
@@ -0,0 +1,60 @@
+Git 2.38.2 Release Notes
+========================
+
+This is to backport various fixes accumulated during the development
+towards Git 2.39, the next feature release.
+
+
+Fixes since v2.38.1
+-------------------
+
+ * Update CodingGuidelines to clarify what features to use and avoid
+ in C99.
+
+ * The codepath that reads from the index v4 had unaligned memory
+ accesses, which has been corrected.
+
+ * "git remote rename" failed to rename a remote without fetch
+ refspec, which has been corrected.
+
+ * "git clone" did not like to see the "--bare" and the "--origin"
+ options used together without a good reason.
+
+ * Fix messages incorrectly marked for translation.
+
+ * "git fsck" failed to release contents of tree objects already used
+ from the memory, which has been fixed.
+
+ * "git rebase -i" can mistakenly attempt to apply a fixup to a commit
+ itself, which has been corrected.
+
+ * In read-only repositories, "git merge-tree" tried to come up with a
+ merge result tree object, which it failed (which is not wrong) and
+ led to a segfault (which is bad), which has been corrected.
+
+ * Force C locale while running tests around httpd to make sure we can
+ find expected error messages in the log.
+
+ * Fix a logic in "mailinfo -b" that miscomputed the length of a
+ substring, which lead to an out-of-bounds access.
+
+ * The codepath to sign learned to report errors when it fails to read
+ from "ssh-keygen".
+
+ * "GIT_EDITOR=: git branch --edit-description" resulted in failure,
+ which has been corrected.
+
+ * Documentation on various Boolean GIT_* environment variables have
+ been clarified.
+
+ * "git multi-pack-index repack/expire" used to repack unreachable
+ cruft into a new pack, which have been corrected.
+
+ * The code to clean temporary object directories (used for
+ quarantine) tried to remove them inside its signal handler, which
+ was a no-no.
+
+ * "git branch --edit-description" on an unborh branch misleadingly
+ said that no such branch exists, which has been corrected.
+
+Also contains various documentation updates and code clean-ups.
diff --git a/Documentation/RelNotes/2.39.0.txt b/Documentation/RelNotes/2.39.0.txt
new file mode 100644
index 00000000000..f21f9494757
--- /dev/null
+++ b/Documentation/RelNotes/2.39.0.txt
@@ -0,0 +1,244 @@
+Git v2.39 Release Notes
+=======================
+
+UI, Workflows & Features
+------------------------
+
+ * "git grep" learned to expand the sparse-index more lazily and on
+ demand in a sparse checkout.
+
+ * By default, use of fsmonitor on a repository on networked
+ filesystem is disabled. Add knobs to make it workable on macOS.
+
+ * After checking out a "branch" that is a symbolic-ref that points at
+ another branch, "git symbolic-ref HEAD" reports the underlying
+ branch, not the symbolic-ref the user gave checkout as argument.
+ The command learned the "--no-recurse" option to stop after
+ dereferencing a symbolic-ref only once.
+
+ * "git branch --edit-description @{-1}" is now a way to edit branch
+ description of the branch you were on before switching to the
+ current branch.
+
+ * "git merge-tree --stdin" is a new way to request a series of merges
+ and report the merge results.
+
+ * "git shortlog" learned to group by the "format" string.
+
+ * A new "--include-whitespace" option is added to "git patch-id", and
+ existing bugs in the internal patch-id logic that did not match
+ what "git patch-id" produces have been corrected.
+
+ * Enable gc.cruftpacks by default for those who opt into
+ feature.experimental setting.
+
+Performance, Internal Implementation, Development Support etc.
+--------------------------------------------------------------
+
+ * With a bit of header twiddling, use the native regexp library on
+ macOS instead of the compat/ one.
+
+ * Prepare for GNU [ef]grep that throw warning of their uses.
+
+ * Sources related to fuzz testing have been moved down to their own
+ directory.
+
+ * Most credential helpers ignored unknown entries in a credential
+ description, but a few died upon seeing them. The latter were
+ taught to ignore them, too
+
+ * "scalar unregister" in a repository that is already been
+ unregistered reported an error.
+
+ * Remove error detection from a function that fetches from promisor
+ remotes, and make it die when such a fetch fails to bring all the
+ requested objects, to give an early failure to various operations.
+
+ * Update CodingGuidelines to clarify what features to use and avoid
+ in C99.
+
+ * Avoid false-positive from LSan whose assumption may be broken with
+ higher optimization levels.
+
+ * Enable address and undefined sanitizer tasks at GitHub Actions CI.
+
+ * More UNUSED annotation to help using -Wunused option with the
+ compiler.
+ (merge 4b992f0a24 jk/unused-anno-more later to maint).
+
+ * Rewrite a deep recursion in the skipping negotiator to use a loop
+ with on-heap prio queue to avoid stack wastage.
+
+ * Add documentation for message IDs in fsck error messages.
+
+ * Define the logical elements of a "bundle list", data structure to
+ store them in-core, format to transfer them, and code to parse
+ them.
+
+ * The role the security mailing list plays in an embargoed release
+ has been documented.
+
+ * Two new facilities, "timer" and "counter", are introduced to the
+ trace2 API.
+
+ * Code simplification by using strvec_pushf() instead of building an
+ argument in a separate strbuf.
+
+ * Make sure generated dependency file is stably sorted to help
+ developers debugging their build issues.
+
+ * The glossary entries for "commit-graph file" and "reachability
+ bitmap" have been added.
+
+ * Various tests exercising the transfer.credentialsInUrl
+ configuration are taught to avoid making requests which require
+ resolving localhost to reduce CI-flakiness.
+
+ * A redundant diagnostic message is dropped from test_path_is_missing().
+
+ * Simplify the run-command API.
+
+Fixes since v2.38
+-----------------
+
+ * The codepath that reads from the index v4 had unaligned memory
+ accesses, which has been corrected.
+
+ * Fix messages incorrectly marked for translation.
+
+ * "git fsck" failed to release contents of tree objects already used
+ from the memory, which has been fixed.
+
+ * "git clone" did not like to see the "--bare" and the "--origin"
+ options used together without a good reason.
+
+ * "git remote rename" failed to rename a remote without fetch
+ refspec, which has been corrected.
+
+ * Documentation on various Boolean GIT_* environment variables have
+ been clarified.
+
+ * "git rebase -i" can mistakenly attempt to apply a fixup to a commit
+ itself, which has been corrected.
+
+ * "git multi-pack-index repack/expire" used to repack unreachable
+ cruft into a new pack, which have been corrected.
+
+ * In read-only repositories, "git merge-tree" tried to come up with a
+ merge result tree object, which it failed (which is not wrong) and
+ led to a segfault (which is bad), which has been corrected.
+
+ * Force C locale while running tests around httpd to make sure we can
+ find expected error messages in the log.
+
+ * Fix a logic in "mailinfo -b" that miscomputed the length of a
+ substring, which lead to an out-of-bounds access.
+
+ * The codepath to sign learned to report errors when it fails to read
+ from "ssh-keygen".
+
+ * Code clean-up that results in plugging a leak.
+
+ * "GIT_EDITOR=: git branch --edit-description" resulted in failure,
+ which has been corrected.
+
+ * The code to clean temporary object directories (used for
+ quarantine) tried to remove them inside its signal handler, which
+ was a no-no.
+
+ * Update comment in the Makefile about the RUNTIME_PREFIX config knob.
+
+ * Clarify that "the sentence after <area>: prefix does not begin with
+ a capital letter" rule applies only to the commit title.
+
+ * "git branch --edit-description" on an unborh branch misleadingly
+ said that no such branch exists, which has been corrected.
+
+ * Work around older clang that warns against C99 zero initialization
+ syntax for struct.
+
+ * Giving "--invert-grep" and "--all-match" without "--grep" to the
+ "git log" command resulted in an attempt to access grep pattern
+ expression structure that has not been allocated, which has been
+ corrected.
+ (merge db84376f98 ab/grep-simplify-extended-expression later to maint).
+
+ * "git diff rev^!" did not show combined diff to go to the rev from
+ its parents.
+ (merge a79c6b6081 rs/diff-caret-bang-with-parents later to maint).
+
+ * Allow configuration files in "protected" scopes to include other
+ configuration files.
+ (merge ecec57b3c9 gc/bare-repo-discovery later to maint).
+
+ * Give a bit more diversity to macOS CI by using sha1dc in one of the
+ jobs (the other one tests Apple Common Crypto).
+ (merge 1ad5c3df35 jc/ci-osx-with-sha1dc later to maint).
+
+ * A bugfix with tracing support in midx codepath
+ (merge e9c3839944 tb/midx-bitmap-selection-fix later to maint).
+
+ * When geometric repacking feature is in use together with the
+ --pack-kept-objects option, we lost packs marked with .keep files.
+ (merge 197443e80a tb/save-keep-pack-during-geometric-repack later to maint).
+
+ * Move a global variable added as a hack during regression fixes to
+ its proper place in the API.
+ (merge 0b0ab95f17 ab/run-hook-api-cleanup later to maint).
+
+ * Update to build procedure with VS using CMake/CTest.
+ (merge c858750b41 js/cmake-updates later to maint).
+
+ * The short-help text shown by "git cmd -h" and the synopsis text
+ shown at the beginning of "git help cmd" have been made more
+ consistent.
+
+ * When creating a multi-pack bitmap, remove per-pack bitmap files
+ unconditionally as they will never be consulted.
+ (merge 55d902cd61 tb/remove-unused-pack-bitmap later to maint).
+
+ * Fix a longstanding syntax error in Git.pm error codepath.
+
+ * "git diff --stat" etc. were invented back when everything was ASCII
+ and strlen() was a way to measure the display width of a string;
+ adjust them to compute the display width assuming UTF-8 pathnames.
+ (merge ce8529b2bb tb/diffstat-with-utf8-strwidth later to maint).
+
+ * "git branch --edit-description" can exit with status -1 which is
+ not a good practice; it learned to use 1 as everybody else instead.
+
+ * "git apply" limits its input to a bit less than 1 GiB.
+
+ * Merging a branch with directory renames into a branch that changes
+ the directory to a symlink was mishandled by the ort merge
+ strategy, which has been corrected.
+
+ * A bugfix to "git subtree" in its split and merge features.
+
+ * Fix some bugs in the reflog messages when rebasing and changes the
+ reflog messages of "rebase --apply" to match "rebase --merge" with
+ the aim of making the reflog easier to parse.
+
+ * "git rebase --keep-base" used to discard the commits that are
+ already cherry-picked to the upstream, even when "keep-base" meant
+ that the base, on top of which the history is being rebuilt, does
+ not yet include these cherry-picked commits. The --keep-base
+ option now implies --reapply-cherry-picks and --no-fork-point
+ options.
+
+ * The way "git repack" creared temporary files when it received a
+ signal was prone to deadlocking, which has been corrected.
+
+ * Various tests exercising the transfer.credentialsInUrl
+ configuration are taught to avoid making requests which require
+ resolving localhost to reduce CI-flakiness.
+
+ * The adjust_shared_perm() helper function learned to refrain from
+ setting the "g+s" bit on directories when it is not necessary.
+
+ * "git archive" mistakenly complained twice about a missing
+ executable, which has been corrected.
+
+ * Other code cleanup, docfix, build fix, etc.
+ (merge 413bc6d20a ds/cmd-main-reorder later to maint).
+ (merge 8d2863e4ed nw/t1002-cleanup later to maint).
diff --git a/Documentation/ReviewingGuidelines.txt b/Documentation/ReviewingGuidelines.txt
new file mode 100644
index 00000000000..0e323d54779
--- /dev/null
+++ b/Documentation/ReviewingGuidelines.txt
@@ -0,0 +1,162 @@
+Reviewing Patches in the Git Project
+====================================
+
+Introduction
+------------
+The Git development community is a widely distributed, diverse, ever-changing
+group of individuals. Asynchronous communication via the Git mailing list poses
+unique challenges when reviewing or discussing patches. This document contains
+some guiding principles and helpful tools you can use to make your reviews both
+more efficient for yourself and more effective for other contributors.
+
+Note that none of the recommendations here are binding or in any way a
+requirement of participation in the Git community. They are provided as a
+resource to supplement your skills as a contributor.
+
+Principles
+----------
+
+Selecting patch(es) to review
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you are looking for a patch series in need of review, start by checking
+latest "What's cooking in git.git" email
+(https://lore.kernel.org/git/xmqqilm1yp3m.fsf@gitster.g/[example]). The "What's
+cooking" emails & replies can be found using the query `s:"What's cooking"` on
+the https://lore.kernel.org/git/[`lore.kernel.org` mailing list archive];
+alternatively, you can find the contents of the "What's cooking" email tracked
+in `whats-cooking.txt` on the `todo` branch of Git. Topics tagged with "Needs
+review" and those in the "[New Topics]" section are typically those that would
+benefit the most from additional review.
+
+Patches can also be searched manually in the mailing list archive using a query
+like `s:"PATCH" -s:"Re:"`. You can browse these results for topics relevant to
+your expertise or interest.
+
+If you've already contributed to Git, you may also be CC'd in another
+contributor's patch series. These are topics where the author feels that your
+attention is warranted. This may be because their patch changes something you
+wrote previously (making you a good judge of whether the new approach does or
+doesn't work), or because you have the expertise to provide an exceptionally
+helpful review. There is no requirement to review these patches but, in the
+spirit of open source collaboration, you should strongly consider doing so.
+
+Reviewing patches
+~~~~~~~~~~~~~~~~~
+While every contributor takes their own approach to reviewing patches, here are
+some general pieces of advice to make your reviews as clear and helpful as
+possible. The advice is broken into two rough categories: high-level reviewing
+guidance, and concrete tips for interacting with patches on the mailing list.
+
+==== High-level guidance
+- Remember to review the content of commit messages for correctness and clarity,
+ in addition to the code change in the patch's diff. The commit message of a
+ patch should accurately and fully explain the code change being made in the
+ diff.
+
+- Reviewing test coverage is an important - but easy to overlook - component of
+ reviews. A patch's changes may be covered by existing tests, or new tests may
+ be introduced to exercise new behavior. Checking out a patch or series locally
+ allows you to manually mutate lines of new & existing tests to verify expected
+ pass/fail behavior. You can use this information to verify proper coverage or
+ to suggest additional tests the author could add.
+
+- When providing a recommendation, be as clear as possible about whether you
+ consider it "blocking" (the code would be broken or otherwise made worse if an
+ issue isn't fixed) or "non-blocking" (the patch could be made better by taking
+ the recommendation, but acceptance of the series does not require it).
+ Non-blocking recommendations can be particularly ambiguous when they are
+ related to - but outside the scope of - a series ("nice-to-have"s), or when
+ they represent only stylistic differences between the author and reviewer.
+
+- When commenting on an issue, try to include suggestions for how the author
+ 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
+ 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.
+
+==== Performing your review
+- Provide your review comments per-patch in a plaintext "Reply-All" email to the
+ relevant patch. Comments should be made inline, immediately below the relevant
+ section(s).
+
+- You may find that the limited context provided in the patch diff is sometimes
+ insufficient for a thorough review. In such cases, you can review patches in
+ your local tree by either applying patches with linkgit:git-am[1] or checking
+ out the associated branch from https://github.com/gitster/git once the series
+ is tracked there.
+
+- Large, complicated patch diffs are sometimes unavoidable, such as when they
+ refactor existing code. If you find such a patch difficult to parse, try
+ reviewing the diff produced with the `--color-moved` and/or
+ `--ignore-space-change` options.
+
+- If a patch is long, you are encouraged to delete parts of it that are
+ unrelated to your review from the email reply. Make sure to leave enough
+ context for readers to understand your comments!
+
+- If you cannot complete a full review of a series all at once, consider letting
+ the author know (on- or off-list) if/when you plan to review the rest of the
+ series.
+
+Completing a review
+~~~~~~~~~~~~~~~~~~~
+Once each patch of a series is reviewed, the author (and/or other contributors)
+may discuss the review(s). This may result in no changes being applied, or the
+author will send a new version of their patch(es).
+
+After a series is rerolled in response to your or others' review, make sure to
+re-review the updates. If you are happy with the state of the patch series,
+explicitly indicate your approval (typically with a reply to the latest
+version's cover letter). Optionally, you can let the author know that they can
+add a "Reviewed-by: <you>" trailer if they resubmit the reviewed patch verbatim
+in a later iteration of the series.
+
+Finally, subsequent "What's cooking" emails may explicitly ask whether a
+reviewed topic is ready for merging to the `next` branch (typically phrased
+"Will merge to \'next\'?"). You can help the maintainer and author by responding
+with a short description of the state of your (and others', if applicable)
+review, including the links to the relevant thread(s).
+
+Terminology
+-----------
+nit: ::
+ Denotes a small issue that should be fixed, such as a typographical error
+ or mis-alignment of conditions in an `if()` statement.
+
+aside: ::
+optional: ::
+non-blocking: ::
+ Indicates to the reader that the following comment should not block the
+ acceptance of the patch or series. These are typically recommendations
+ related to code organization & style, or musings about topics related to
+ the patch in question, but beyond its scope.
+
+s/<before>/<after>/::
+ Shorthand for "you wrote <before>, but I think you meant <after>," usually
+ for misspellings or other typographical errors. The syntax is a reference
+ to "substitute" command commonly found in Unix tools such as `ed`, `sed`,
+ `vim`, and `perl`.
+
+cover letter::
+ The "Patch 0" of a multi-patch series. This email describes the
+ high-level intent and structure of the patch series to readers on the
+ Git mailing list. It is also where the changelog notes and range-diff of
+ subsequent versions are provided by the author.
++
+On single-patch submissions, cover letter content is typically not sent as a
+separate email. Instead, it is inserted between the end of the patch's commit
+message (after the `---`) and the beginning of the diff.
+
+#leftoverbits::
+ Used by either an author or a reviewer to describe features or suggested
+ changes that are out-of-scope of a given patch or series, but are relevant
+ to the topic for the sake of discussion.
+
+See Also
+--------
+link:MyFirstContribution.html[MyFirstContribution]
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 5bd795e5dbf..927f7329a55 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -153,7 +153,9 @@ files you are modifying to see the current conventions.
[[summary-section]]
The title sentence after the "area:" prefix omits the full stop at the
-end, and its first word is not capitalized unless there is a reason to
+end, and its first word is not capitalized (the omission
+of capitalization applies only to the word after the "area:"
+prefix of the title) unless there is a reason to
capitalize it other than because it is the first word in the sentence.
E.g. "doc: clarify...", not "doc: Clarify...", or "githooks.txt:
improve...", not "githooks.txt: Improve...". But "refs: HEAD is also
diff --git a/Documentation/build-docdep.perl b/Documentation/build-docdep.perl
index ba4205e0302..1b3ac8fdd95 100755
--- a/Documentation/build-docdep.perl
+++ b/Documentation/build-docdep.perl
@@ -38,9 +38,10 @@ while ($changed) {
}
}
-while (my ($text, $included) = each %include) {
+foreach my $text (sort keys %include) {
+ my $included = $include{$text};
if (! exists $included{$text} &&
(my $base = $text) =~ s/\.txt$//) {
- print "$base.html $base.xml : ", join(" ", keys %$included), "\n";
+ print "$base.html $base.xml : ", join(" ", sort keys %$included), "\n";
}
}
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index af5da45d287..755a110bc48 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -10,7 +10,7 @@ sub format_one {
$state = 0;
open I, '<', "$name.txt" or die "No such file $name.txt";
while (<I>) {
- if (/^git[a-z0-9-]*\(([0-9])\)$/) {
+ if (/^(?:git|scalar)[a-z0-9-]*\(([0-9])\)$/) {
$mansection = $1;
next;
}
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5b5b9765699..0e93aef8626 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -387,6 +387,8 @@ include::config/branch.txt[]
include::config/browser.txt[]
+include::config/bundle.txt[]
+
include::config/checkout.txt[]
include::config/clean.txt[]
@@ -423,6 +425,8 @@ include::config/filter.txt[]
include::config/fsck.txt[]
+include::config/fsmonitor--daemon.txt[]
+
include::config/gc.txt[]
include::config/gitcvs.txt[]
diff --git a/Documentation/config/bundle.txt b/Documentation/config/bundle.txt
new file mode 100644
index 00000000000..daa21eb674a
--- /dev/null
+++ b/Documentation/config/bundle.txt
@@ -0,0 +1,24 @@
+bundle.*::
+ The `bundle.*` keys may appear in a bundle list file found via the
+ `git clone --bundle-uri` option. These keys currently have no effect
+ if placed in a repository config file, though this will change in the
+ future. See link:technical/bundle-uri.html[the bundle URI design
+ document] for more details.
+
+bundle.version::
+ This integer value advertises the version of the bundle list format
+ used by the bundle list. Currently, the only accepted value is `1`.
+
+bundle.mode::
+ This string value should be either `all` or `any`. This value describes
+ whether all of the advertised bundles are required to unbundle a
+ complete understanding of the bundled information (`all`) or if any one
+ of the listed bundle URIs is sufficient (`any`).
+
+bundle.<id>.*::
+ The `bundle.<id>.*` keys are used to describe a single item in the
+ bundle list, grouped under `<id>` for identification purposes.
+
+bundle.<id>.uri::
+ This string value defines the URI by which Git can reach the contents
+ of this `<id>`. This URI may be a bundle file or another bundle list.
diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
index 37afbaf5a41..dfbdaf00b8b 100644
--- a/Documentation/config/core.txt
+++ b/Documentation/config/core.txt
@@ -618,7 +618,7 @@ but risks losing recent work in the event of an unclean system shutdown.
* `loose-object` hardens objects added to the repo in loose-object form.
* `pack` hardens objects added to the repo in packfile form.
* `pack-metadata` hardens packfile bitmaps and indexes.
-* `commit-graph` hardens the commit graph file.
+* `commit-graph` hardens the commit-graph file.
* `index` hardens the index when it is modified.
* `objects` is an aggregate option that is equivalent to
`loose-object,pack`.
diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt
index 32f84838ac1..35a7bf86d77 100644
--- a/Documentation/config/diff.txt
+++ b/Documentation/config/diff.txt
@@ -178,21 +178,6 @@ diff.<driver>.cachetextconv::
Set this option to true to make the diff driver cache the text
conversion outputs. See linkgit:gitattributes[5] for details.
-diff.tool::
- Controls which diff tool is used by linkgit:git-difftool[1].
- This variable overrides the value configured in `merge.tool`.
- The list below shows the valid built-in values.
- Any other value is treated as a custom diff tool and requires
- that a corresponding difftool.<tool>.cmd variable is defined.
-
-diff.guitool::
- Controls which diff tool is used by linkgit:git-difftool[1] when
- the -g/--gui flag is specified. This variable overrides the value
- configured in `merge.guitool`. The list below shows the valid
- built-in values. Any other value is treated as a custom diff tool
- and requires that a corresponding difftool.<guitool>.cmd variable
- is defined.
-
include::../mergetools-diff.txt[]
diff.indentHeuristic::
diff --git a/Documentation/config/difftool.txt b/Documentation/config/difftool.txt
index 67625944804..a3f82112102 100644
--- a/Documentation/config/difftool.txt
+++ b/Documentation/config/difftool.txt
@@ -1,6 +1,17 @@
-difftool.<tool>.path::
- Override the path for the given tool. This is useful in case
- your tool is not in the PATH.
+diff.tool::
+ Controls which diff tool is used by linkgit:git-difftool[1].
+ This variable overrides the value configured in `merge.tool`.
+ The list below shows the valid built-in values.
+ Any other value is treated as a custom diff tool and requires
+ that a corresponding difftool.<tool>.cmd variable is defined.
+
+diff.guitool::
+ Controls which diff tool is used by linkgit:git-difftool[1] when
+ the -g/--gui flag is specified. This variable overrides the value
+ configured in `merge.guitool`. The list below shows the valid
+ built-in values. Any other value is treated as a custom diff tool
+ and requires that a corresponding difftool.<guitool>.cmd variable
+ is defined.
difftool.<tool>.cmd::
Specify the command to invoke the specified diff tool.
@@ -9,6 +20,17 @@ difftool.<tool>.cmd::
file containing the contents of the diff pre-image and 'REMOTE'
is set to the name of the temporary file containing the contents
of the diff post-image.
++
+See the `--tool=<tool>` option in linkgit:git-difftool[1] for more details.
+
+difftool.<tool>.path::
+ Override the path for the given tool. This is useful in case
+ your tool is not in the PATH.
+
+difftool.trustExitCode::
+ Exit difftool if the invoked diff tool returns a non-zero exit status.
++
+See the `--trust-exit-code` option in linkgit:git-difftool[1] for more details.
difftool.prompt::
Prompt before each invocation of the diff tool.
diff --git a/Documentation/config/feature.txt b/Documentation/config/feature.txt
index cdecd04e5bb..95975e50912 100644
--- a/Documentation/config/feature.txt
+++ b/Documentation/config/feature.txt
@@ -14,6 +14,9 @@ feature.experimental::
+
* `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by
skipping more commits at a time, reducing the number of round trips.
++
+* `gc.cruftPacks=true` reduces disk space used by unreachable objects during
+garbage collection, preventing loose object explosions.
feature.manyFiles::
Enable config options that optimize for repos with many files in the
diff --git a/Documentation/config/format.txt b/Documentation/config/format.txt
index fdbc06a4d2a..c7303d8d9f0 100644
--- a/Documentation/config/format.txt
+++ b/Documentation/config/format.txt
@@ -15,6 +15,10 @@ format.from::
different. If set to a non-boolean value, format-patch uses that
value instead of your committer identity. Defaults to false.
+format.forceInBodyFrom::
+ Provides the default value for the `--[no-]force-in-body-from`
+ option to format-patch. Defaults to false.
+
format.numbered::
A boolean which can enable or disable sequence numbers in patch
subjects. It defaults to "auto" which enables it only if there
diff --git a/Documentation/config/fsck.txt b/Documentation/config/fsck.txt
index 450e8c38e34..a3c865df567 100644
--- a/Documentation/config/fsck.txt
+++ b/Documentation/config/fsck.txt
@@ -35,6 +35,10 @@ allow new instances of the same breakages go unnoticed.
Setting an unknown `fsck.<msg-id>` value will cause fsck to die, but
doing the same for `receive.fsck.<msg-id>` and `fetch.fsck.<msg-id>`
will only cause git to warn.
++
+See `Fsck Messages` section of linkgit:git-fsck[1] for supported
+values of `<msg-id>`.
+
fsck.skipList::
The path to a list of object names (i.e. one unabbreviated SHA-1 per
diff --git a/Documentation/config/fsmonitor--daemon.txt b/Documentation/config/fsmonitor--daemon.txt
new file mode 100644
index 00000000000..c225c6c9e74
--- /dev/null
+++ b/Documentation/config/fsmonitor--daemon.txt
@@ -0,0 +1,11 @@
+fsmonitor.allowRemote::
+ By default, the fsmonitor daemon refuses to work against network-mounted
+ repositories. Setting `fsmonitor.allowRemote` to `true` overrides this
+ behavior. Only respected when `core.fsmonitor` is set to `true`.
+
+fsmonitor.socketDir::
+ This Mac OS-specific option, if set, specifies the directory in
+ which to create the Unix domain socket used for communication
+ between the fsmonitor daemon and various Git commands. The directory must
+ reside on a native Mac OS filesystem. Only respected when `core.fsmonitor`
+ is set to `true`.
diff --git a/Documentation/config/grep.txt b/Documentation/config/grep.txt
index 182edd813a5..e521f20390c 100644
--- a/Documentation/config/grep.txt
+++ b/Documentation/config/grep.txt
@@ -17,8 +17,11 @@ grep.extendedRegexp::
other than 'default'.
grep.threads::
- Number of grep worker threads to use.
- See `grep.threads` in linkgit:git-grep[1] for more information.
+ Number of grep worker threads to use. If unset (or set to 0), Git will
+ use as many threads as the number of logical cores available.
+
+grep.fullName::
+ If set to true, enable `--full-name` option by default.
grep.fallbackToNoIndex::
If set to true, fall back to git grep --no-index if git grep
diff --git a/Documentation/config/log.txt b/Documentation/config/log.txt
index 5250ba45fb4..5f96cf87fb9 100644
--- a/Documentation/config/log.txt
+++ b/Documentation/config/log.txt
@@ -7,6 +7,10 @@ log.date::
Set the default date-time mode for the 'log' command.
Setting a value for log.date is similar to using 'git log''s
`--date` option. See linkgit:git-log[1] for details.
++
+If the format is set to "auto:foo" and the pager is in use, format
+"foo" will be the used for the date format. Otherwise "default" will
+be used.
log.decorate::
Print out the ref names of any commits that are shown by the log
@@ -30,9 +34,9 @@ log.excludeDecoration::
option.
log.diffMerges::
- Set default diff format to be used for merge commits. See
- `--diff-merges` in linkgit:git-log[1] for details.
- Defaults to `separate`.
+ Set diff format to be used when `--diff-merges=on` is
+ specified, see `--diff-merges` in linkgit:git-log[1] for
+ details. Defaults to `separate`.
log.follow::
If `true`, `git log` will act as if the `--follow` option was used when
diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 90b38097002..e779a122d8a 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -59,7 +59,7 @@ mergetool.hideResolved::
possible and write the 'MERGED' file containing conflict markers around
any conflicts that it cannot resolve; 'LOCAL' and 'REMOTE' normally
represent the versions of the file from before Git's conflict
- resolution. This flag causes 'LOCAL' and 'REMOTE' to be overwriten so
+ resolution. This flag causes 'LOCAL' and 'REMOTE' to be overwritten so
that only the unresolved conflicts are presented to the merge tool. Can
be configured per-tool via the `mergetool.<tool>.hideResolved`
configuration variable. Defaults to `false`.
diff --git a/Documentation/config/notes.txt b/Documentation/config/notes.txt
index aeef56d49ae..c7c4811734b 100644
--- a/Documentation/config/notes.txt
+++ b/Documentation/config/notes.txt
@@ -3,6 +3,9 @@ notes.mergeStrategy::
conflicts. Must be one of `manual`, `ours`, `theirs`, `union`, or
`cat_sort_uniq`. Defaults to `manual`. See "NOTES MERGE STRATEGIES"
section of linkgit:git-notes[1] for more information on each strategy.
++
+This setting can be overridden by passing the `--strategy` option to
+linkgit:git-notes[1].
notes.<name>.mergeStrategy::
Which merge strategy to choose when doing a notes merge into
@@ -11,28 +14,35 @@ notes.<name>.mergeStrategy::
linkgit:git-notes[1] for more information on the available strategies.
notes.displayRef::
- The (fully qualified) refname from which to show notes when
- showing commit messages. The value of this variable can be set
- to a glob, in which case notes from all matching refs will be
- shown. You may also specify this configuration variable
- several times. A warning will be issued for refs that do not
- exist, but a glob that does not match any refs is silently
- ignored.
+ Which ref (or refs, if a glob or specified more than once), in
+ addition to the default set by `core.notesRef` or
+ `GIT_NOTES_REF`, to read notes from when showing commit
+ messages with the 'git log' family of commands.
+
This setting can be overridden with the `GIT_NOTES_DISPLAY_REF`
environment variable, which must be a colon separated list of refs or
globs.
+
+A warning will be issued for refs that do not exist,
+but a glob that does not match any refs is silently ignored.
++
+This setting can be disabled by the `--no-notes` option to the 'git
+log' family of commands, or by the `--notes=<ref>` option accepted by
+those commands.
++
The effective value of "core.notesRef" (possibly overridden by
GIT_NOTES_REF) is also implicitly added to the list of refs to be
displayed.
notes.rewrite.<command>::
When rewriting commits with <command> (currently `amend` or
- `rebase`) and this variable is set to `true`, Git
- automatically copies your notes from the original to the
- rewritten commit. Defaults to `true`, but see
- "notes.rewriteRef" below.
+ `rebase`), if this variable is `false`, git will not copy
+ notes from the original to the rewritten commit. Defaults to
+ `true`. See also "`notes.rewriteRef`" below.
++
+This setting can be overridden with the `GIT_NOTES_REWRITE_REF`
+environment variable, which must be a colon separated list of refs or
+globs.
notes.rewriteMode::
When copying notes during a rewrite (see the
@@ -46,14 +56,13 @@ environment variable.
notes.rewriteRef::
When copying notes during a rewrite, specifies the (fully
- qualified) ref whose notes should be copied. The ref may be a
- glob, in which case notes in all matching refs will be copied.
- You may also specify this configuration several times.
+ qualified) ref whose notes should be copied. May be a glob,
+ in which case notes in all matching refs will be copied. You
+ may also specify this configuration several times.
+
Does not have a default value; you must configure this variable to
enable note rewriting. Set it to `refs/notes/commits` to enable
rewriting for the default commit notes.
+
-This setting can be overridden with the `GIT_NOTES_REWRITE_REF`
-environment variable, which must be a colon separated list of refs or
-globs.
+Can be overridden with the `GIT_NOTES_REWRITE_REF` environment variable.
+See `notes.rewrite.<command>` above for a further description of its format.
diff --git a/Documentation/config/pack.txt b/Documentation/config/pack.txt
index 3e581eab84a..53093d99969 100644
--- a/Documentation/config/pack.txt
+++ b/Documentation/config/pack.txt
@@ -164,6 +164,13 @@ When writing a multi-pack reachability bitmap, no new namehashes are
computed; instead, any namehashes stored in an existing bitmap are
permuted into their appropriate location when writing a new bitmap.
+pack.writeBitmapLookupTable::
+ When true, Git will include a "lookup table" section in the
+ bitmap index (if one is written). This table is used to defer
+ loading individual bitmaps as late as possible. This can be
+ beneficial in repositories that have relatively large bitmap
+ indexes. Defaults to false.
+
pack.writeReverseIndex::
When true, git will write a corresponding .rev file (see:
linkgit:gitformat-pack[5])
diff --git a/Documentation/config/protocol.txt b/Documentation/config/protocol.txt
index 57603818514..a9bf187a933 100644
--- a/Documentation/config/protocol.txt
+++ b/Documentation/config/protocol.txt
@@ -1,10 +1,10 @@
protocol.allow::
If set, provide a user defined default policy for all protocols which
don't explicitly have a policy (`protocol.<name>.allow`). By default,
- if unset, known-safe protocols (http, https, git, ssh, file) have a
+ if unset, known-safe protocols (http, https, git, ssh) have a
default policy of `always`, known-dangerous protocols (ext) have a
- default policy of `never`, and all other protocols have a default
- policy of `user`. Supported policies:
+ default policy of `never`, and all other protocols (including file)
+ have a default policy of `user`. Supported policies:
+
--
diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt
index 50baa5d6bfb..51da7088a84 100644
--- a/Documentation/config/sendemail.txt
+++ b/Documentation/config/sendemail.txt
@@ -18,17 +18,49 @@ sendemail.<identity>.*::
identity is selected, through either the command-line or
`sendemail.identity`.
+sendemail.multiEdit::
+ If true (default), a single editor instance will be spawned to edit
+ files you have to edit (patches when `--annotate` is used, and the
+ summary when `--compose` is used). If false, files will be edited one
+ after the other, spawning a new editor each time.
+
+sendemail.confirm::
+ Sets the default for whether to confirm before sending. Must be
+ one of 'always', 'never', 'cc', 'compose', or 'auto'. See `--confirm`
+ in the linkgit:git-send-email[1] documentation for the meaning of these
+ values.
+
sendemail.aliasesFile::
+ To avoid typing long email addresses, point this to one or more
+ email aliases files. You must also supply `sendemail.aliasFileType`.
+
sendemail.aliasFileType::
+ Format of the file(s) specified in sendemail.aliasesFile. Must be
+ one of 'mutt', 'mailrc', 'pine', 'elm', or 'gnus', or 'sendmail'.
++
+What an alias file in each format looks like can be found in
+the documentation of the email program of the same name. The
+differences and limitations from the standard formats are
+described below:
++
+--
+sendmail;;
+* Quoted aliases and quoted addresses are not supported: lines that
+ contain a `"` symbol are ignored.
+* Redirection to a file (`/path/name`) or pipe (`|command`) is not
+ supported.
+* File inclusion (`:include: /path/name`) is not supported.
+* Warnings are printed on the standard error output for any
+ explicitly unsupported constructs, and any other lines that are not
+ recognized by the parser.
+--
sendemail.annotate::
sendemail.bcc::
sendemail.cc::
sendemail.ccCmd::
sendemail.chainReplyTo::
-sendemail.confirm::
sendemail.envelopeSender::
sendemail.from::
-sendemail.multiEdit::
sendemail.signedoffbycc::
sendemail.smtpPass::
sendemail.suppresscc::
@@ -44,7 +76,9 @@ sendemail.thread::
sendemail.transferEncoding::
sendemail.validate::
sendemail.xmailer::
- See linkgit:git-send-email[1] for description.
+ These configuration variables all provide a default for
+ linkgit:git-send-email[1] command-line options. See its
+ documentation for details.
sendemail.signedoffcc (deprecated)::
Deprecated alias for `sendemail.signedoffbycc`.
diff --git a/Documentation/config/transfer.txt b/Documentation/config/transfer.txt
index 7ed917f5fc5..264812cca4d 100644
--- a/Documentation/config/transfer.txt
+++ b/Documentation/config/transfer.txt
@@ -13,7 +13,7 @@ Note that this is currently limited to detecting credentials in
You might want to enable this to prevent inadvertent credentials
exposure, e.g. because:
+
-* The OS or system where you're running git may not provide way way or
+* The OS or system where you're running git may not provide a way or
otherwise allow you to configure the permissions of the
configuration file where the username and/or password are stored.
* Even if it does, having such data stored "at rest" might expose you
diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt
new file mode 100644
index 00000000000..7af76ff99a5
--- /dev/null
+++ b/Documentation/fsck-msgids.txt
@@ -0,0 +1,161 @@
+`badDate`::
+ (ERROR) Invalid date format in an author/committer line.
+
+`badDateOverflow`::
+ (ERROR) Invalid date value in an author/committer line.
+
+`badEmail`::
+ (ERROR) Invalid email format in an author/committer line.
+
+`badFilemode`::
+ (INFO) A tree contains a bad filemode entry.
+
+`badName`::
+ (ERROR) An author/committer name is empty.
+
+`badObjectSha1`::
+ (ERROR) An object has a bad sha1.
+
+`badParentSha1`::
+ (ERROR) A commit object has a bad parent sha1.
+
+`badTagName`::
+ (INFO) A tag has an invalid format.
+
+`badTimezone`::
+ (ERROR) Found an invalid time zone in an author/committer line.
+
+`badTree`::
+ (ERROR) A tree cannot be parsed.
+
+`badTreeSha1`::
+ (ERROR) A tree has an invalid format.
+
+`badType`::
+ (ERROR) Found an invalid object type.
+
+`duplicateEntries`::
+ (ERROR) A tree contains duplicate file entries.
+
+`emptyName`::
+ (WARN) A path contains an empty name.
+
+`extraHeaderEntry`::
+ (IGNORE) Extra headers found after `tagger`.
+
+`fullPathname`::
+ (WARN) A path contains the full path starting with "/".
+
+`gitattributesSymlink`::
+ (INFO) `.gitattributes` is a symlink.
+
+`gitignoreSymlink`::
+ (INFO) `.gitignore` is a symlink.
+
+`gitmodulesBlob`::
+ (ERROR) A non-blob found at `.gitmodules`.
+
+`gitmodulesLarge`::
+ (ERROR) The `.gitmodules` file is too large to parse.
+
+`gitmodulesMissing`::
+ (ERROR) Unable to read `.gitmodules` blob.
+
+`gitmodulesName`::
+ (ERROR) A submodule name is invalid.
+
+`gitmodulesParse`::
+ (INFO) Could not parse `.gitmodules` blob.
+
+`gitmodulesLarge`;
+ (ERROR) `.gitmodules` blob is too large to parse.
+
+`gitmodulesPath`::
+ (ERROR) `.gitmodules` path is invalid.
+
+`gitmodulesSymlink`::
+ (ERROR) `.gitmodules` is a symlink.
+
+`gitmodulesUpdate`::
+ (ERROR) Found an invalid submodule update setting.
+
+`gitmodulesUrl`::
+ (ERROR) Found an invalid submodule url.
+
+`hasDot`::
+ (WARN) A tree contains an entry named `.`.
+
+`hasDotdot`::
+ (WARN) A tree contains an entry named `..`.
+
+`hasDotgit`::
+ (WARN) A tree contains an entry named `.git`.
+
+`mailmapSymlink`::
+ (INFO) `.mailmap` is a symlink.
+
+`missingAuthor`::
+ (ERROR) Author is missing.
+
+`missingCommitter`::
+ (ERROR) Committer is missing.
+
+`missingEmail`::
+ (ERROR) Email is missing in an author/committer line.
+
+`missingNameBeforeEmail`::
+ (ERROR) Missing name before an email in an author/committer line.
+
+`missingObject`::
+ (ERROR) Missing `object` line in tag object.
+
+`missingSpaceBeforeDate`::
+ (ERROR) Missing space before date in an author/committer line.
+
+`missingSpaceBeforeEmail`::
+ (ERROR) Missing space before the email in author/committer line.
+
+`missingTag`::
+ (ERROR) Unexpected end after `type` line in a tag object.
+
+`missingTagEntry`::
+ (ERROR) Missing `tag` line in a tag object.
+
+`missingTaggerEntry`::
+ (INFO) Missing `tagger` line in a tag object.
+
+`missingTree`::
+ (ERROR) Missing `tree` line in a commit object.
+
+`missingType`::
+ (ERROR) Invalid type value on the `type` line in a tag object.
+
+`missingTypeEntry`::
+ (ERROR) Missing `type` line in a tag object.
+
+`multipleAuthors`::
+ (ERROR) Multiple author lines found in a commit.
+
+`nulInCommit`::
+ (WARN) Found a NUL byte in the commit object body.
+
+`nulInHeader`::
+ (FATAL) NUL byte exists in the object header.
+
+`nullSha1`::
+ (WARN) Tree contains entries pointing to a null sha1.
+
+`treeNotSorted`::
+ (ERROR) A tree is not properly sorted.
+
+`unknownType`::
+ (ERROR) Found an unknown object type.
+
+`unterminatedHeader`::
+ (FATAL) Missing end-of-line in the object header.
+
+`zeroPaddedDate`::
+ (ERROR) Found a zero padded date in an author/commiter line.
+
+`zeroPaddedFilemode`::
+ (WARN) Found a zero padded filemode in a tree.
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 9b37f356542..a030d33c6e7 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -433,6 +433,13 @@ they will make the patch impossible to apply:
* deleting context or removal lines
* modifying the contents of context or removal lines
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/add.txt[]
+
SEE ALSO
--------
linkgit:git-status[1]
diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index 320da6c4f76..326276e51ce 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -258,6 +258,13 @@ This command can run `applypatch-msg`, `pre-applypatch`,
and `post-applypatch` hooks. See linkgit:githooks[5] for more
information.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/am.txt[]
+
SEE ALSO
--------
linkgit:git-apply[1].
diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.txt
index e44a831339d..5ae8aabe0f8 100644
--- a/Documentation/git-annotate.txt
+++ b/Documentation/git-annotate.txt
@@ -8,7 +8,7 @@ git-annotate - Annotate file lines with commit information
SYNOPSIS
--------
[verse]
-'git annotate' [<options>] <file> [<revision>]
+'git annotate' [<options>] [<rev-opts>] [<rev>] [--] <file>
DESCRIPTION
-----------
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index b6d77f42068..1d478cbe9b5 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -263,13 +263,9 @@ has no effect when `--index` or `--cached` is in use.
CONFIGURATION
-------------
-apply.ignoreWhitespace::
- Set to 'change' if you want changes in whitespace to be ignored by default.
- Set to one of: no, none, never, false if you want changes in
- whitespace to be significant.
-apply.whitespace::
- When no `--whitespace` flag is given from the command
- line, this configuration item is used as the default.
+include::includes/cmd-config-section-all.txt[]
+
+include::config/apply.txt[]
SUBMODULES
----------
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index d7a46cc6744..4400a17330b 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -241,6 +241,12 @@ MAPPING AUTHORS
See linkgit:gitmailmap[5].
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/blame.txt[]
SEE ALSO
--------
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index ae82378349d..12c5f84e3be 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -336,6 +336,10 @@ CONFIGURATION
`--list` is used or implied. The default is to use a pager.
See linkgit:git-config[1].
+include::includes/cmd-config-section-rest.txt[]
+
+include::config/branch.txt[]
+
EXAMPLES
--------
diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt
index 6da61722431..18a022b4b40 100644
--- a/Documentation/git-bundle.txt
+++ b/Documentation/git-bundle.txt
@@ -42,7 +42,7 @@ BUNDLE FORMAT
Bundles are `.pack` files (see linkgit:git-pack-objects[1]) with a
header indicating what references are contained within the bundle.
-Like the the packed archive format itself bundles can either be
+Like the packed archive format itself bundles can either be
self-contained, or be created using exclusions.
See the "OBJECT PREREQUISITES" section below.
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 9f37e22e130..4cb9d555b4b 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -600,6 +600,13 @@ $ edit frotz
$ git add frotz
------------
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/checkout.txt[]
+
SEE ALSO
--------
linkgit:git-switch[1],
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index a7f309dff5a..160d08b86bb 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree
SYNOPSIS
--------
[verse]
-'git clean' [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...
+'git clean' [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] [<pathspec>...]
DESCRIPTION
-----------
@@ -20,16 +20,16 @@ Normally, only files unknown to Git are removed, but if the `-x`
option is specified, ignored files are also removed. This can, for
example, be useful to remove all build products.
-If any optional `<path>...` arguments are given, only those paths
-are affected.
+If any optional `<pathspec>...` arguments are given, only those paths
+that match the pathspec are affected.
OPTIONS
-------
-d::
- Normally, when no <path> is specified, git clean will not
+ Normally, when no <pathspec> is specified, git clean will not
recurse into untracked directories to avoid removing too much.
Specify -d to have it recurse into such directories as well.
- If any paths are specified, -d is irrelevant; all untracked
+ If a <pathspec> is specified, -d is irrelevant; all untracked
files matching the specified paths (with exceptions for nested
git directories mentioned under `--force`) will be removed.
@@ -133,6 +133,13 @@ help::
Show brief usage of interactive git-clean.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/clean.txt[]
+
SEE ALSO
--------
linkgit:gitignore[5]
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 632bd1348ea..d6434d262d6 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -323,6 +323,13 @@ or `--mirror` is given)
for `host.xz:foo/.git`). Cloning into an existing directory
is only allowed if the directory is empty.
+--bundle-uri=<uri>::
+ Before fetching from the remote, fetch a bundle from the given
+ `<uri>` and unbundle the data into the local repository. The refs
+ in the bundle will be stored under the hidden `refs/bundle/*`
+ namespace. This option is incompatible with `--depth`,
+ `--shallow-since`, and `--shallow-exclude`.
+
:git-clone: 1
include::urls.txt[]
@@ -363,6 +370,15 @@ $ cd my-linux
$ git clone --bare -l /home/proj/.git /pub/scm/proj.git
------------
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/init.txt[]
+
+include::config/clone.txt[]
+
GIT
---
diff --git a/Documentation/git-column.txt b/Documentation/git-column.txt
index 6cea9ab4638..18431647a2d 100644
--- a/Documentation/git-column.txt
+++ b/Documentation/git-column.txt
@@ -74,6 +74,13 @@ v2.4.3 v2.4.4 v2.4.5 v2.4.6 v2.4.7
v2.4.8 v2.4.9
------------
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/column.txt[]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt
index 047decdb65b..c8dbceba014 100644
--- a/Documentation/git-commit-graph.txt
+++ b/Documentation/git-commit-graph.txt
@@ -10,7 +10,10 @@ SYNOPSIS
--------
[verse]
'git commit-graph verify' [--object-dir <dir>] [--shallow] [--[no-]progress]
-'git commit-graph write' <options> [--object-dir <dir>] [--[no-]progress]
+'git commit-graph write' [--object-dir <dir>] [--append]
+ [--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits]
+ [--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress]
+ <split options>
DESCRIPTION
@@ -142,6 +145,13 @@ $ git show-ref -s | git commit-graph write --stdin-commits
$ git rev-parse HEAD | git commit-graph write --stdin-commits --append
------------------------------------------------
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/commitgraph.txt[]
+
FILE FORMAT
-----------
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 6c60bf98f9f..225c6c9f2e5 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -557,6 +557,10 @@ The editor used to edit the commit log message will be chosen from the
`VISUAL` environment variable, or the `EDITOR` environment variable (in that
order). See linkgit:git-var[1] for details.
+include::includes/cmd-config-section-rest.txt[]
+
+include::config/commit.txt[]
+
HOOKS
-----
This command can run `commit-msg`, `prepare-commit-msg`, `pre-commit`,
diff --git a/Documentation/git-credential-cache--daemon.txt b/Documentation/git-credential-cache--daemon.txt
index 01e1c214dd8..650a15a7edf 100644
--- a/Documentation/git-credential-cache--daemon.txt
+++ b/Documentation/git-credential-cache--daemon.txt
@@ -8,7 +8,7 @@ git-credential-cache--daemon - Temporarily store user credentials in memory
SYNOPSIS
--------
[verse]
-'git credential-cache{litdd}daemon' [--debug] <socket>
+'git credential-cache{litdd}daemon' [--debug] <socket-path>
DESCRIPTION
-----------
@@ -16,7 +16,7 @@ DESCRIPTION
NOTE: You probably don't want to invoke this command yourself; it is
started automatically when you use linkgit:git-credential-cache[1].
-This command listens on the Unix domain socket specified by `<socket>`
+This command listens on the Unix domain socket specified by `<socket-path>`
for `git-credential-cache` clients. Clients may store and retrieve
credentials. Each credential is held for a timeout specified by the
client; once no credentials are held, the daemon exits.
diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt
index bf1febb9ae7..591e3801b7b 100644
--- a/Documentation/git-diff-files.txt
+++ b/Documentation/git-diff-files.txt
@@ -9,7 +9,7 @@ git-diff-files - Compares files in the working tree and the index
SYNOPSIS
--------
[verse]
-'git diff-files' [-q] [-0|-1|-2|-3|-c|--cc] [<common-diff-options>] [<path>...]
+'git diff-files' [-q] [-0 | -1 | -2 | -3 | -c | --cc] [<common-diff-options>] [<path>...]
DESCRIPTION
-----------
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 6236c75c9b8..52b679256c4 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -79,10 +79,10 @@ If --merge-base is given, use the merge base of the two commits for the
This form is to view the results of a merge commit. The first
listed <commit> must be the merge itself; the remaining two or
- more commits should be its parents. A convenient way to produce
- the desired set of revisions is to use the `^@` suffix.
- For instance, if `master` names a merge commit, `git diff master
- master^@` gives the same combined diff as `git show master`.
+ more commits should be its parents. Convenient ways to produce
+ the desired set of revisions are to use the suffixes `^@` and
+ `^!`. If A is a merge commit, then `git diff A A^@`,
+ `git diff A^!` and `git show A` all give the same combined diff.
'git diff' [<options>] <commit>..<commit> [--] [<path>...]::
@@ -213,6 +213,13 @@ $ git diff -R <2>
rewrites (very expensive).
<2> Output diff in reverse.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/diff.txt[]
+
SEE ALSO
--------
diff(1),
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 143b0c49d73..9d14c3c9f09 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -113,33 +113,14 @@ instead. `--no-symlinks` is the default on Windows.
See linkgit:git-diff[1] for the full list of supported options.
-CONFIG VARIABLES
-----------------
+CONFIGURATION
+-------------
'git difftool' falls back to 'git mergetool' config variables when the
difftool equivalents have not been defined.
-diff.tool::
- The default diff tool to use.
+include::includes/cmd-config-section-rest.txt[]
-diff.guitool::
- The default diff tool to use when `--gui` is specified.
-
-difftool.<tool>.path::
- Override the path for the given tool. This is useful in case
- your tool is not in the PATH.
-
-difftool.<tool>.cmd::
- Specify the command to invoke the specified diff tool.
-+
-See the `--tool=<tool>` option above for more details.
-
-difftool.prompt::
- Prompt before each invocation of the diff tool.
-
-difftool.trustExitCode::
- Exit difftool if the invoked diff tool returns a non-zero exit status.
-+
-See the `--trust-exit-code` option above for more details.
+include::config/difftool.txt[]
SEE ALSO
--------
diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index 1978dbdc6ad..4643ddbe68f 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -9,7 +9,7 @@ git-fast-export - Git data exporter
SYNOPSIS
--------
[verse]
-'git fast-export [<options>]' | 'git fast-import'
+'git fast-export' [<options>] | 'git fast-import'
DESCRIPTION
-----------
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 39cfa05b28b..8b5dd6add00 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -1564,6 +1564,13 @@ operator can use this facility to peek at the objects and refs from an
import in progress, at the cost of some added running time and worse
compression.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/fastimport.txt[]
+
SEE ALSO
--------
linkgit:git-fast-export[1]
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index e9d364669af..63d9569e164 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -285,6 +285,13 @@ linkgit:git-gc[1]).
include::transfer-data-leaks.txt[]
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/fetch.txt[]
+
BUGS
----
Using --recurse-submodules can only fetch new commits in submodules that are
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index be797d7a28f..dfcc7da4c21 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -275,6 +275,17 @@ header). Note also that `git send-email` already handles this
transformation for you, and this option should not be used if you are
feeding the result to `git send-email`.
+--[no-]force-in-body-from::
+ With the e-mail sender specified via the `--from` option, by
+ default, an in-body "From:" to identify the real author of
+ the commit is added at the top of the commit log message if
+ the sender is different from the author. With this option,
+ the in-body "From:" is added even when the sender and the
+ author have the same name and address, which may help if the
+ mailing list software mangles the sender's identity.
+ Defaults to the value of the `format.forceInBodyFrom`
+ configuration variable.
+
--add-header=<header>::
Add an arbitrary header to the email headers. This is in addition
to any configured headers, and may be used multiple times.
diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt
index 5088783dccb..b6a0f8a085c 100644
--- a/Documentation/git-fsck.txt
+++ b/Documentation/git-fsck.txt
@@ -107,6 +107,8 @@ care about this output and want to speed it up further.
CONFIGURATION
-------------
+include::includes/cmd-config-section-all.txt[]
+
include::config/fsck.txt[]
DISCUSSION
@@ -150,6 +152,18 @@ hash mismatch <object>::
object database value.
This indicates a serious data integrity problem.
+
+FSCK MESSAGES
+-------------
+
+The following lists the types of errors `git fsck` detects and what
+each error means, with their default severity. The severity of the
+error, other than those that are marked as "(FATAL)", can be tweaked
+by setting the corresponding `fsck.<msg-id>` configuration variable.
+
+include::fsck-msgids.txt[]
+
+
Environment Variables
---------------------
diff --git a/Documentation/git-fsmonitor--daemon.txt b/Documentation/git-fsmonitor--daemon.txt
index cc142fb8612..8238eadb0e1 100644
--- a/Documentation/git-fsmonitor--daemon.txt
+++ b/Documentation/git-fsmonitor--daemon.txt
@@ -3,7 +3,7 @@ git-fsmonitor{litdd}daemon(1)
NAME
----
-git-fsmonitor--daemon - A Built-in File System Monitor
+git-fsmonitor--daemon - A Built-in Filesystem Monitor
SYNOPSIS
--------
@@ -17,7 +17,7 @@ DESCRIPTION
-----------
A daemon to watch the working directory for file and directory
-changes using platform-specific file system notification facilities.
+changes using platform-specific filesystem notification facilities.
This daemon communicates directly with commands like `git status`
using the link:technical/api-simple-ipc.html[simple IPC] interface
@@ -63,13 +63,44 @@ CAVEATS
-------
The fsmonitor daemon does not currently know about submodules and does
-not know to filter out file system events that happen within a
+not know to filter out filesystem events that happen within a
submodule. If fsmonitor daemon is watching a super repo and a file is
modified within the working directory of a submodule, it will report
the change (as happening against the super repo). However, the client
will properly ignore these extra events, so performance may be affected
but it will not cause an incorrect result.
+By default, the fsmonitor daemon refuses to work against network-mounted
+repositories; this may be overridden by setting `fsmonitor.allowRemote` to
+`true`. Note, however, that the fsmonitor daemon is not guaranteed to work
+correctly with all network-mounted repositories and such use is considered
+experimental.
+
+On Mac OS, the inter-process communication (IPC) between various Git
+commands and the fsmonitor daemon is done via a Unix domain socket (UDS) -- a
+special type of file -- which is supported by native Mac OS filesystems,
+but not on network-mounted filesystems, NTFS, or FAT32. Other filesystems
+may or may not have the needed support; the fsmonitor daemon is not guaranteed
+to work with these filesystems and such use is considered experimental.
+
+By default, the socket is created in the `.git` directory, however, if the
+`.git` directory is on a network-mounted filesystem, it will be instead be
+created at `$HOME/.git-fsmonitor-*` unless `$HOME` itself is on a
+network-mounted filesystem in which case you must set the configuration
+variable `fsmonitor.socketDir` to the path of a directory on a Mac OS native
+filesystem in which to create the socket file.
+
+If none of the above directories (`.git`, `$HOME`, or `fsmonitor.socketDir`)
+is on a native Mac OS file filesystem the fsmonitor daemon will report an
+error that will cause the daemon and the currently running command to exit.
+
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/fsmonitor--daemon.txt[]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index 0af7540a0c8..a65c9aa62d6 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -110,8 +110,7 @@ users and their repositories.
CONFIGURATION
-------------
-The below documentation is the same as what's found in
-linkgit:git-config[1]:
+include::includes/cmd-config-section-all.txt[]
include::config/gc.txt[]
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 58d944bd578..dabdbe8471d 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -343,34 +343,9 @@ performance in this case, it might be desirable to use `--threads=1`.
CONFIGURATION
-------------
-grep.lineNumber::
- If set to true, enable `-n` option by default.
-
-grep.column::
- If set to true, enable the `--column` option by default.
-
-grep.patternType::
- Set the default matching behavior. Using a value of 'basic', 'extended',
- 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`,
- `--fixed-strings`, or `--perl-regexp` option accordingly, while the
- value 'default' will return to the default matching behavior.
-
-grep.extendedRegexp::
- If set to true, enable `--extended-regexp` option by default. This
- option is ignored when the `grep.patternType` option is set to a value
- other than 'default'.
-
-grep.threads::
- Number of grep worker threads to use. If unset (or set to 0), Git will
- use as many threads as the number of logical cores available.
-
-grep.fullName::
- If set to true, enable `--full-name` option by default.
-
-grep.fallbackToNoIndex::
- If set to true, fall back to git grep --no-index if git grep
- is executed outside of a git repository. Defaults to false.
+include::includes/cmd-config-section-all.txt[]
+include::config/grep.txt[]
GIT
---
diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index df9e2c58bdb..472b5bb995b 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -9,7 +9,8 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
SYNOPSIS
--------
[verse]
-'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin [--literally]] [--] <file>...
+'git hash-object' [-t <type>] [-w] [--path=<file> | --no-filters]
+ [--stdin [--literally]] [--] <file>...
'git hash-object' [-t <type>] [-w] --stdin-paths [--no-filters]
DESCRIPTION
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 63cf498ce9f..f7b18515141 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -54,6 +54,8 @@ CONFIGURATION
To use the tool, `imap.folder` and either `imap.tunnel` or `imap.host` must be set
to appropriate values.
+include::includes/cmd-config-section-rest.txt[]
+
include::config/imap.txt[]
EXAMPLES
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index ad921fe782e..160dea1372c 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -169,6 +169,13 @@ $ git commit <3>
<2> Add all existing files to the index.
<3> Record the pristine state as the first commit in the history.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/init.txt[]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.txt
index 956a01d184f..22ff3a603e0 100644
--- a/Documentation/git-interpret-trailers.txt
+++ b/Documentation/git-interpret-trailers.txt
@@ -8,8 +8,9 @@ git-interpret-trailers - Add or parse structured information in commit messages
SYNOPSIS
--------
[verse]
-'git interpret-trailers' [<options>] [(--trailer <token>[(=|:)<value>])...] [<file>...]
-'git interpret-trailers' [<options>] [--parse] [<file>...]
+'git interpret-trailers' [--in-place] [--trim-empty]
+ [(--trailer <token>[(=|:)<value>])...]
+ [--parse] [<file>...]
DESCRIPTION
-----------
@@ -60,10 +61,12 @@ non-whitespace lines before a line that starts with '---' (followed by a
space or the end of the line). Such three minus signs start the patch
part of the message. See also `--no-divider` below.
-When reading trailers, there can be whitespaces after the
-token, the separator and the value. There can also be whitespaces
-inside the token and the value. The value may be split over multiple lines with
-each subsequent line starting with whitespace, like the "folding" in RFC 822.
+When reading trailers, there can be no whitespace before or inside the
+token, but any number of regular space and tab characters are allowed
+between the token and the separator. There can be whitespaces before,
+inside or after the value. The value may be split over multiple lines
+with each subsequent line starting with at least one whitespace, like
+the "folding" in RFC 822.
Note that 'trailers' do not follow and are not intended to follow many
rules for RFC 822 headers. For example they do not follow
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index b1285aee3c2..2a66cf88807 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -209,47 +209,11 @@ i18n.logOutputEncoding::
Defaults to the value of `i18n.commitEncoding` if set, and UTF-8
otherwise.
-log.date::
- Default format for human-readable dates. (Compare the
- `--date` option.) Defaults to "default", which means to write
- dates like `Sat May 8 19:35:34 2010 -0500`.
-+
-If the format is set to "auto:foo" and the pager is in use, format
-"foo" will be the used for the date format. Otherwise "default" will
-be used.
-
-log.follow::
- If `true`, `git log` will act as if the `--follow` option was used when
- a single <path> is given. This has the same limitations as `--follow`,
- i.e. it cannot be used to follow multiple files and does not work well
- on non-linear history.
-
-log.showRoot::
- If `false`, `git log` and related commands will not treat the
- initial commit as a big creation event. Any root commits in
- `git log -p` output would be shown without a diff attached.
- The default is `true`.
-
-log.showSignature::
- If `true`, `git log` and related commands will act as if the
- `--show-signature` option was passed to them.
-
-mailmap.*::
- See linkgit:git-shortlog[1].
-
-notes.displayRef::
- Which refs, in addition to the default set by `core.notesRef`
- or `GIT_NOTES_REF`, to read notes from when showing commit
- messages with the `log` family of commands. See
- linkgit:git-notes[1].
-+
-May be an unabbreviated ref name or a glob and may be specified
-multiple times. A warning will be issued for refs that do not exist,
-but a glob that does not match any refs is silently ignored.
-+
-This setting can be disabled by the `--no-notes` option,
-overridden by the `GIT_NOTES_DISPLAY_REF` environment variable,
-and overridden by the `--notes=<ref>` option.
+include::includes/cmd-config-section-rest.txt[]
+
+include::config/log.txt[]
+
+include::config/notes.txt[]
GIT
---
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index d7986419c25..440043cdb8e 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -10,8 +10,8 @@ SYNOPSIS
--------
[verse]
'git ls-files' [-z] [-t] [-v] [-f]
- [-c|--cached] [-d|--deleted] [-o|--others] [-i|--|ignored]
- [-s|--stage] [-u|--unmerged] [-k|--|killed] [-m|--modified]
+ [-c|--cached] [-d|--deleted] [-o|--others] [-i|--ignored]
+ [-s|--stage] [-u|--unmerged] [-k|--killed] [-m|--modified]
[--directory [--no-empty-directory]] [--eol]
[--deduplicate]
[-x <pattern>|--exclude=<pattern>]
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index 3fcfd965fde..28060283c70 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -115,6 +115,13 @@ If no such configuration option has been set, `warn` will be used.
<patch>::
The patch extracted from e-mail.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/mailinfo.txt[]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.txt
index e56bad28c65..eb3ae9fbd59 100644
--- a/Documentation/git-maintenance.txt
+++ b/Documentation/git-maintenance.txt
@@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git maintenance' run [<options>]
'git maintenance' start [--scheduler=<scheduler>]
-'git maintenance' (stop|register|unregister)
+'git maintenance' (stop|register|unregister) [<options>]
DESCRIPTION
@@ -50,13 +50,13 @@ stop::
the background maintenance is restarted later.
register::
- Initialize Git config values so any scheduled maintenance will
- start running on this repository. This adds the repository to the
- `maintenance.repo` config variable in the current user's global
- config and enables some recommended configuration values for
- `maintenance.<task>.schedule`. The tasks that are enabled are safe
- for running in the background without disrupting foreground
- processes.
+ Initialize Git config values so any scheduled maintenance will start
+ running on this repository. This adds the repository to the
+ `maintenance.repo` config variable in the current user's global config,
+ or the config specified by --config option, and enables some
+ recommended configuration values for `maintenance.<task>.schedule`. The
+ tasks that are enabled are safe for running in the background without
+ disrupting foreground processes.
+
The `register` subcommand will also set the `maintenance.strategy` config
value to `incremental`, if this value is not previously set. The
@@ -79,6 +79,10 @@ unregister::
Remove the current repository from background maintenance. This
only removes the repository from the configured list. It does not
stop the background maintenance processes from running.
++
+The `unregister` subcommand will report an error if the current repository
+is not already registered. Use the `--force` option to return success even
+when the current repository is not registered.
TASKS
-----
@@ -397,6 +401,13 @@ If you want to customize the background tasks, please rename the tasks
so future calls to `git maintenance (start|stop)` do not overwrite your
custom tasks.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/maintenance.txt[]
+
GIT
---
diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index 2d944e0851f..b01ba3d3565 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -9,8 +9,8 @@ git-merge-base - Find as good common ancestors as possible for a merge
SYNOPSIS
--------
[verse]
-'git merge-base' [-a|--all] <commit> <commit>...
-'git merge-base' [-a|--all] --octopus <commit>...
+'git merge-base' [-a | --all] <commit> <commit>...
+'git merge-base' [-a | --all] --octopus <commit>...
'git merge-base' --is-ancestor <commit> <commit>
'git merge-base' --independent <commit>...
'git merge-base' --fork-point <ref> [<commit>]
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index d6c356740ef..04bcc416e6e 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -81,6 +81,31 @@ Whereas for a conflicted merge, the output is by default of the form:
These are discussed individually below.
+However, there is an exception. If `--stdin` is passed, then there is
+an extra section at the beginning, a NUL character at the end, and then
+all the sections repeat for each line of input. Thus, if the first merge
+is conflicted and the second is clean, the output would be of the form:
+
+ <Merge status>
+ <OID of toplevel tree>
+ <Conflicted file info>
+ <Informational messages>
+ NUL
+ <Merge status>
+ <OID of toplevel tree>
+ NUL
+
+[[MS]]
+Merge status
+~~~~~~~~~~~~
+
+This is an integer status followed by a NUL character. The integer status is:
+
+ 0: merge had conflicts
+ 1: merge was clean
+ &lt;0: something prevented the merge from running (e.g. access to repository
+ objects denied by filesystem)
+
[[OIDTLT]]
OID of toplevel tree
~~~~~~~~~~~~~~~~~~~~
@@ -108,18 +133,50 @@ character instead of a newline character.
Informational messages
~~~~~~~~~~~~~~~~~~~~~~
-This always starts with a blank line (or NUL if `-z` is passed) to
-separate it from the previous sections, and then has free-form
-messages about the merge, such as:
+This section provides informational messages, typically about
+conflicts. The format of the section varies significantly depending
+on whether `-z` is passed.
+
+If `-z` is passed:
+
+The output format is zero or more conflict informational records, each
+of the form:
+
+ <list-of-paths><conflict-type>NUL<conflict-message>NUL
+
+where <list-of-paths> is of the form
+
+ <number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL
+
+and includes paths (or branch names) affected by the conflict or
+informational message in <conflict-message>. Also, <conflict-type> is a
+stable string explaining the type of conflict, such as
+
+ * "Auto-merging"
+ * "CONFLICT (rename/delete)"
+ * "CONFLICT (submodule lacks merge base)"
+ * "CONFLICT (binary)"
+
+and <conflict-message> is a more detailed message about the conflict which often
+(but not always) embeds the <stable-short-type-description> within it. These
+strings may change in future Git versions. Some examples:
* "Auto-merging <file>"
* "CONFLICT (rename/delete): <oldfile> renamed...but deleted in..."
- * "Failed to merge submodule <submodule> (<reason>)"
+ * "Failed to merge submodule <submodule> (no merge base)"
* "Warning: cannot merge binary files: <filename>"
-Note that these free-form messages will never have a NUL character
-in or between them, even if -z is passed. It is simply a large block
-of text taking up the remainder of the output.
+If `-z` is NOT passed:
+
+This section starts with a blank line to separate it from the previous
+sections, and then only contains the <conflict-message> information
+from the previous section (separated by newlines). These are
+non-stable strings that should not be parsed by scripts, and are just
+meant for human consumption. Also, note that while <conflict-message>
+strings usually do not contain embedded newlines, they sometimes do.
+(However, the free-form messages will never have an embedded NUL
+character). So, the entire block of information is meant for human
+readers as an agglomeration of all conflict messages.
EXIT STATUS
-----------
@@ -127,7 +184,10 @@ EXIT STATUS
For a successful, non-conflicted merge, the exit status is 0. When the
merge has conflicts, the exit status is 1. If the merge is not able to
complete (or start) due to some kind of error, the exit status is
-something other than 0 or 1 (and the output is unspecified).
+something other than 0 or 1 (and the output is unspecified). When
+--stdin is passed, the return status is 0 for both successful and
+conflicted merges, and something other than 0 or 1 if it cannot complete
+all the requested merges.
USAGE NOTES
-----------
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index fee1dc2df28..2d6a1391c89 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -383,13 +383,16 @@ include::merge-strategies.txt[]
CONFIGURATION
-------------
-include::config/merge.txt[]
branch.<name>.mergeOptions::
Sets default options for merging into branch <name>. The syntax and
supported options are the same as those of 'git merge', but option
values containing whitespace characters are currently not supported.
+include::includes/cmd-config-section-rest.txt[]
+
+include::config/merge.txt[]
+
SEE ALSO
--------
linkgit:git-fmt-merge-msg[1], linkgit:git-pull[1],
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index f784027bc13..c44e205629b 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -102,6 +102,9 @@ success of the resolution after the custom tool has exited.
CONFIGURATION
-------------
:git-mergetool: 1
+
+include::includes/cmd-config-section-all.txt[]
+
include::config/mergetool.txt[]
TEMPORARY FILES
diff --git a/Documentation/git-multi-pack-index.txt b/Documentation/git-multi-pack-index.txt
index a48c3d5ea63..3696506eb35 100644
--- a/Documentation/git-multi-pack-index.txt
+++ b/Documentation/git-multi-pack-index.txt
@@ -70,9 +70,10 @@ verify::
Verify the contents of the MIDX file.
expire::
- Delete the pack-files that are tracked by the MIDX file, but
- have no objects referenced by the MIDX. Rewrite the MIDX file
- afterward to remove all references to these pack-files.
+ Delete the pack-files that are tracked by the MIDX file, but
+ have no objects referenced by the MIDX (with the exception of
+ `.keep` packs and cruft packs). Rewrite the MIDX file afterward
+ to remove all references to these pack-files.
repack::
Create a new pack-file containing objects in small pack-files
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index 79449bf98fe..fb0220fd18d 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -9,7 +9,7 @@ git-mv - Move or rename a file, a directory, or a symlink
SYNOPSIS
--------
[verse]
-'git mv' <options>... <args>...
+'git mv' [<options>] <source>... <destination>
DESCRIPTION
-----------
@@ -30,7 +30,7 @@ OPTIONS
-------
-f::
--force::
- Force renaming or moving of a file even if the target exists
+ Force renaming or moving of a file even if the <destination> exists.
-k::
Skip move or rename actions which would lead to an error
condition. An error happens when a source is neither existing nor
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index 0a4200674c4..efbc10f0f59 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -44,7 +44,7 @@ using the `--notes` option. Such notes are added as a patch commentary
after a three dash separator line.
To change which notes are shown by 'git log', see the
-"notes.displayRef" configuration in linkgit:git-log[1].
+"notes.displayRef" discussion in <<CONFIGURATION>>.
See the "notes.rewrite.<command>" configuration for a way to carry
notes across commands that rewrite commits.
@@ -307,6 +307,7 @@ with 'git log', so if you use such notes, you'll probably need to write
some special-purpose tools to do something useful with them.
+[[CONFIGURATION]]
CONFIGURATION
-------------
@@ -316,57 +317,9 @@ core.notesRef::
This setting can be overridden through the environment and
command line.
-notes.mergeStrategy::
- Which merge strategy to choose by default when resolving notes
- conflicts. Must be one of `manual`, `ours`, `theirs`, `union`, or
- `cat_sort_uniq`. Defaults to `manual`. See "NOTES MERGE STRATEGIES"
- section above for more information on each strategy.
-+
-This setting can be overridden by passing the `--strategy` option.
-
-notes.<name>.mergeStrategy::
- Which merge strategy to choose when doing a notes merge into
- refs/notes/<name>. This overrides the more general
- "notes.mergeStrategy". See the "NOTES MERGE STRATEGIES" section above
- for more information on each available strategy.
-
-notes.displayRef::
- Which ref (or refs, if a glob or specified more than once), in
- addition to the default set by `core.notesRef` or
- `GIT_NOTES_REF`, to read notes from when showing commit
- messages with the 'git log' family of commands.
- This setting can be overridden on the command line or by the
- `GIT_NOTES_DISPLAY_REF` environment variable.
- See linkgit:git-log[1].
-
-notes.rewrite.<command>::
- When rewriting commits with <command> (currently `amend` or
- `rebase`), if this variable is `false`, git will not copy
- notes from the original to the rewritten commit. Defaults to
- `true`. See also "`notes.rewriteRef`" below.
-+
-This setting can be overridden by the `GIT_NOTES_REWRITE_REF`
-environment variable.
+include::includes/cmd-config-section-rest.txt[]
-notes.rewriteMode::
- When copying notes during a rewrite, what to do if the target
- commit already has a note. Must be one of `overwrite`,
- `concatenate`, `cat_sort_uniq`, or `ignore`. Defaults to
- `concatenate`.
-+
-This setting can be overridden with the `GIT_NOTES_REWRITE_MODE`
-environment variable.
-
-notes.rewriteRef::
- When copying notes during a rewrite, specifies the (fully
- qualified) ref whose notes should be copied. May be a glob,
- in which case notes in all matching refs will be copied. You
- may also specify this configuration several times.
-+
-Does not have a default value; you must configure this variable to
-enable note rewriting.
-+
-Can be overridden with the `GIT_NOTES_REWRITE_REF` environment variable.
+include::config/notes.txt[]
ENVIRONMENT
diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt
index ee7034b5e52..99ef13839d4 100644
--- a/Documentation/git-pack-redundant.txt
+++ b/Documentation/git-pack-redundant.txt
@@ -9,7 +9,7 @@ git-pack-redundant - Find redundant pack files
SYNOPSIS
--------
[verse]
-'git pack-redundant' [ --verbose ] [ --alt-odb ] ( --all | <pack-filename>... )
+'git pack-redundant' [--verbose] [--alt-odb] (--all | <pack-filename>...)
DESCRIPTION
-----------
@@ -34,7 +34,7 @@ OPTIONS
--alt-odb::
Don't require objects present in packs from alternate object
- directories to be present in local packs.
+ database (odb) directories to be present in local packs.
--verbose::
Outputs some statistics to stderr. Has a small performance penalty.
diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.txt
index 442caff8a9c..1d15fa45d51 100644
--- a/Documentation/git-patch-id.txt
+++ b/Documentation/git-patch-id.txt
@@ -8,18 +8,18 @@ git-patch-id - Compute unique ID for a patch
SYNOPSIS
--------
[verse]
-'git patch-id' [--stable | --unstable]
+'git patch-id' [--stable | --unstable | --verbatim]
DESCRIPTION
-----------
Read a patch from the standard input and compute the patch ID for it.
A "patch ID" is nothing but a sum of SHA-1 of the file diffs associated with a
-patch, with whitespace and line numbers ignored. As such, it's "reasonably
-stable", but at the same time also reasonably unique, i.e., two patches that
-have the same "patch ID" are almost guaranteed to be the same thing.
+patch, with line numbers ignored. As such, it's "reasonably stable", but at
+the same time also reasonably unique, i.e., two patches that have the same
+"patch ID" are almost guaranteed to be the same thing.
-IOW, you can use this thing to look for likely duplicate commits.
+The main usecase for this command is to look for likely duplicate commits.
When dealing with 'git diff-tree' output, it takes advantage of
the fact that the patch is prefixed with the object name of the
@@ -30,6 +30,12 @@ This can be used to make a mapping from patch ID to commit ID.
OPTIONS
-------
+--verbatim::
+ Calculate the patch-id of the input as it is given, do not strip
+ any whitespace.
+
+ This is the default if patchid.verbatim is true.
+
--stable::
Use a "stable" sum of hashes as the patch ID. With this option:
- Reordering file diffs that make up a patch does not affect the ID.
@@ -45,14 +51,16 @@ OPTIONS
of "-O<orderfile>", thereby making existing databases storing such
"unstable" or historical patch-ids unusable.
+ - All whitespace within the patch is ignored and does not affect the id.
+
This is the default if patchid.stable is set to true.
--unstable::
Use an "unstable" hash as the patch ID. With this option,
the result produced is compatible with the patch-id value produced
- by git 1.9 and older. Users with pre-existing databases storing
- patch-ids produced by git 1.9 and older (who do not deal with reordered
- patches) may want to use this option.
+ by git 1.9 and older and whitespace is ignored. Users with pre-existing
+ databases storing patch-ids produced by git 1.9 and older (who do not deal
+ with reordered patches) may want to use this option.
This is the default.
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
index 9fed59a3172..844d6f808a0 100644
--- a/Documentation/git-prune-packed.txt
+++ b/Documentation/git-prune-packed.txt
@@ -9,7 +9,7 @@ git-prune-packed - Remove extra objects that are already in pack files
SYNOPSIS
--------
[verse]
-'git prune-packed' [-n|--dry-run] [-q|--quiet]
+'git prune-packed' [-n | --dry-run] [-q | --quiet]
DESCRIPTION
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 2f25aa3a291..def7657ef9c 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -692,6 +692,13 @@ a `git gc` command on the origin repository.
include::transfer-data-leaks.txt[]
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/push.txt[]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-range-diff.txt b/Documentation/git-range-diff.txt
index fe350d7f405..0b393715d70 100644
--- a/Documentation/git-range-diff.txt
+++ b/Documentation/git-range-diff.txt
@@ -12,6 +12,7 @@ SYNOPSIS
[--no-dual-color] [--creation-factor=<factor>]
[--left-only | --right-only]
( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> )
+ [[--] <path>...]
DESCRIPTION
-----------
@@ -19,6 +20,9 @@ DESCRIPTION
This command shows the differences between two versions of a patch
series, or more generally, two commit ranges (ignoring merge commits).
+In the presence of `<path>` arguments, these commit ranges are limited
+accordingly.
+
To that end, it first finds pairs of commits from both commit ranges
that correspond with each other. Two commits are said to correspond when
the diff between their patches (i.e. the author information, the commit
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index b9bfdc0a319..7567955bad8 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -9,7 +9,7 @@ git-read-tree - Reads tree information into the index
SYNOPSIS
--------
[verse]
-'git read-tree' [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>]
+'git read-tree' [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>)
[-u | -i]] [--index-output=<file>] [--no-sparse-checkout]
(--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 1877942180e..f9675bd24e6 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -218,12 +218,14 @@ leave out at most one of A and B, in which case it defaults to HEAD.
merge base of `<upstream>` and `<branch>`. Running
`git rebase --keep-base <upstream> <branch>` is equivalent to
running
- `git rebase --onto <upstream>...<branch> <upstream> <branch>`.
+ `git rebase --reapply-cherry-picks --no-fork-point --onto <upstream>...<branch> <upstream> <branch>`.
+
This option is useful in the case where one is developing a feature on
top of an upstream branch. While the feature is being worked on, the
upstream branch may advance and it may not be the best idea to keep
-rebasing on top of the upstream but to keep the base commit as-is.
+rebasing on top of the upstream but to keep the base commit as-is. As
+the base commit is unchanged this option implies `--reapply-cherry-picks`
+to avoid losing commits.
+
Although both this option and `--fork-point` find the merge base between
`<upstream>` and `<branch>`, this option uses the merge base as the _starting
@@ -278,7 +280,8 @@ See also INCOMPATIBLE OPTIONS below.
Note that commits which start empty are kept (unless `--no-keep-empty`
is specified), and commits which are clean cherry-picks (as determined
by `git log --cherry-mark ...`) are detected and dropped as a
-preliminary step (unless `--reapply-cherry-picks` is passed).
+preliminary step (unless `--reapply-cherry-picks` or `--keep-base` is
+passed).
+
See also INCOMPATIBLE OPTIONS below.
@@ -311,13 +314,16 @@ See also INCOMPATIBLE OPTIONS below.
upstream changes, the behavior towards them is controlled by
the `--empty` flag.)
+
-By default (or if `--no-reapply-cherry-picks` is given), these commits
-will be automatically dropped. Because this necessitates reading all
-upstream commits, this can be expensive in repos with a large number
-of upstream commits that need to be read. When using the 'merge'
-backend, warnings will be issued for each dropped commit (unless
-`--quiet` is given). Advice will also be issued unless
-`advice.skippedCherryPicks` is set to false (see linkgit:git-config[1]).
+
+In the absence of `--keep-base` (or if `--no-reapply-cherry-picks` is
+given), these commits will be automatically dropped. Because this
+necessitates reading all upstream commits, this can be expensive in
+repositories with a large number of upstream commits that need to be
+read. When using the 'merge' backend, warnings will be issued for each
+dropped commit (unless `--quiet` is given). Advice will also be issued
+unless `advice.skippedCherryPicks` is set to false (see
+linkgit:git-config[1]).
+
+
`--reapply-cherry-picks` allows rebase to forgo reading all upstream
commits, potentially improving performance.
@@ -443,9 +449,9 @@ When `--fork-point` is active, 'fork_point' will be used instead of
<branch>` command (see linkgit:git-merge-base[1]). If 'fork_point'
ends up being empty, the `<upstream>` will be used as a fallback.
+
-If `<upstream>` is given on the command line, then the default is
-`--no-fork-point`, otherwise the default is `--fork-point`. See also
-`rebase.forkpoint` in linkgit:git-config[1].
+If `<upstream>` or `--keep-base` is given on the command line, then
+the default is `--no-fork-point`, otherwise the default is
+`--fork-point`. See also `rebase.forkpoint` in linkgit:git-config[1].
+
If your branch was based on `<upstream>` but `<upstream>` was rewound and
your branch contains commits which were dropped, this option can be used
@@ -1259,6 +1265,8 @@ merge cmake
CONFIGURATION
-------------
+include::includes/cmd-config-section-all.txt[]
+
include::config/rebase.txt[]
include::config/sequencer.txt[]
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 014a78409b9..65ff518ccff 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -9,7 +9,7 @@ git-receive-pack - Receive what is pushed into the repository
SYNOPSIS
--------
[verse]
-'git-receive-pack' <directory>
+'git receive-pack' <git-dir>
DESCRIPTION
-----------
@@ -38,7 +38,7 @@ its behavior, see linkgit:git-config[1].
OPTIONS
-------
-<directory>::
+<git-dir>::
The repository to sync into.
--http-backend-info-refs::
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index db9d46edfa9..ec64cbff4c6 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -9,15 +9,7 @@ git-reflog - Manage reflog information
SYNOPSIS
--------
[verse]
-'git reflog' <subcommand> <options>
-
-DESCRIPTION
------------
-The command takes various subcommands, and different options
-depending on the subcommand:
-
-[verse]
-'git reflog' ['show'] [<log-options>] [<ref>]
+'git reflog' [show] [<log-options>] [<ref>]
'git reflog expire' [--expire=<time>] [--expire-unreachable=<time>]
[--rewrite] [--updateref] [--stale-fix]
[--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]
@@ -25,6 +17,10 @@ depending on the subcommand:
[--dry-run | -n] [--verbose] <ref>@{<specifier>}...
'git reflog exists' <ref>
+DESCRIPTION
+-----------
+This command manages the information recorded in the reflogs.
+
Reference logs, or "reflogs", record when the tips of branches and
other references were updated in the local repository. Reflogs are
useful in various Git commands, to specify the old value of a
@@ -33,7 +29,8 @@ moves ago", `master@{one.week.ago}` means "where master used to point
to one week ago in this local repository", and so on. See
linkgit:gitrevisions[7] for more details.
-This command manages the information recorded in the reflogs.
+The command takes various subcommands, and different options
+depending on the subcommand:
The "show" subcommand (which is also the default, in the absence of
any subcommands) shows the log of the reference provided in the
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 0bf13893d81..4017157949e 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -74,6 +74,12 @@ to the new separate pack will be written.
immediately instead of waiting for the next `git gc` invocation.
Only useful with `--cruft -d`.
+--expire-to=<dir>::
+ Write a cruft pack containing pruned objects (if any) to the
+ directory `<dir>`. This option is useful for keeping a copy of
+ any pruned objects in a separate directory as a backup. Only
+ useful with `--cruft -d`.
+
-l::
Pass the `--local` option to 'git pack-objects'. See
linkgit:git-pack-objects[1].
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 4cfc8833780..992b469270c 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -8,7 +8,7 @@ git-rerere - Reuse recorded resolution of conflicted merges
SYNOPSIS
--------
[verse]
-'git rerere' ['clear'|'forget' <pathspec>|'diff'|'remaining'|'status'|'gc']
+'git rerere' [clear | forget <pathspec>... | diff | status | remaining | gc]
DESCRIPTION
-----------
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 20bb8e82176..51029a22715 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -9,7 +9,7 @@ git-rev-list - Lists commit objects in reverse chronological order
SYNOPSIS
--------
[verse]
-'git rev-list' [<options>] <commit>... [[--] <path>...]
+'git rev-list' [<options>] <commit>... [--] [<path>...]
DESCRIPTION
-----------
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index 0105a54c1a5..5016755efb6 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -142,6 +142,13 @@ EXAMPLES
changes. The revert only modifies the working tree and the
index.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/revert.txt[]
+
SEE ALSO
--------
linkgit:git-cherry-pick[1]
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 41cd8cb4247..765b2df8530 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -178,9 +178,18 @@ Sending
for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH.
--smtp-encryption=<encryption>::
- Specify the encryption to use, either 'ssl' or 'tls'. Any other
- value reverts to plain SMTP. Default is the value of
- `sendemail.smtpEncryption`.
+ Specify in what way encrypting begins for the SMTP connection.
+ Valid values are 'ssl' and 'tls'. Any other value reverts to plain
+ (unencrypted) SMTP, which defaults to port 25.
+ Despite the names, both values will use the same newer version of TLS,
+ but for historic reasons have these names. 'ssl' refers to "implicit"
+ encryption (sometimes called SMTPS), that uses port 465 by default.
+ 'tls' refers to "explicit" encryption (often known as STARTTLS),
+ that uses port 25 by default. Other ports might be used by the SMTP
+ server, which are not the default. Commonly found alternative port for
+ 'tls' and unencrypted is 587. You need to check your provider's
+ documentation or your server configuration to make sure
+ for your own case. Default is the value of `sendemail.smtpEncryption`.
--smtp-domain=<FQDN>::
Specifies the Fully Qualified Domain Name (FQDN) used in the
@@ -456,41 +465,9 @@ Information
CONFIGURATION
-------------
-sendemail.aliasesFile::
- To avoid typing long email addresses, point this to one or more
- email aliases files. You must also supply `sendemail.aliasFileType`.
+include::includes/cmd-config-section-all.txt[]
-sendemail.aliasFileType::
- Format of the file(s) specified in sendemail.aliasesFile. Must be
- one of 'mutt', 'mailrc', 'pine', 'elm', or 'gnus', or 'sendmail'.
-+
-What an alias file in each format looks like can be found in
-the documentation of the email program of the same name. The
-differences and limitations from the standard formats are
-described below:
-+
---
-sendmail;;
-* Quoted aliases and quoted addresses are not supported: lines that
- contain a `"` symbol are ignored.
-* Redirection to a file (`/path/name`) or pipe (`|command`) is not
- supported.
-* File inclusion (`:include: /path/name`) is not supported.
-* Warnings are printed on the standard error output for any
- explicitly unsupported constructs, and any other lines that are not
- recognized by the parser.
---
-
-sendemail.multiEdit::
- If true (default), a single editor instance will be spawned to edit
- files you have to edit (patches when `--annotate` is used, and the
- summary when `--compose` is used). If false, files will be edited one
- after the other, spawning a new editor each time.
-
-sendemail.confirm::
- Sets the default for whether to confirm before sending. Must be
- one of 'always', 'never', 'cc', 'compose', or 'auto'. See `--confirm`
- in the previous section for the meaning of these values.
+include::config/sendemail.txt[]
EXAMPLES
--------
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index be41f119740..595b002152f 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -9,9 +9,10 @@ git-send-pack - Push objects over Git protocol to another repository
SYNOPSIS
--------
[verse]
-'git send-pack' [--dry-run] [--force] [--receive-pack=<git-receive-pack>]
+'git send-pack' [--mirror] [--dry-run] [--force]
+ [--receive-pack=<git-receive-pack>]
[--verbose] [--thin] [--atomic]
- [--[no-]signed|--signed=(true|false|if-asked)]
+ [--[no-]signed | --signed=(true|false|if-asked)]
[<host>:]<directory> (--all | <ref>...)
DESCRIPTION
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
index f64e77047b2..7d0277d033d 100644
--- a/Documentation/git-shortlog.txt
+++ b/Documentation/git-shortlog.txt
@@ -47,6 +47,11 @@ OPTIONS
Each pretty-printed commit will be rewrapped before it is shown.
+--date=<format>::
+ Show dates formatted according to the given date string. (See
+ the `--date` option in the "Commit Formatting" section of
+ linkgit:git-log[1]). Useful with `--group=format:<format>`.
+
--group=<type>::
Group commits based on `<type>`. If no `--group` option is
specified, the default is `author`. `<type>` is one of:
@@ -59,6 +64,9 @@ OPTIONS
example, if your project uses `Reviewed-by` trailers, you might want
to see who has been reviewing with
`git shortlog -ns --group=trailer:reviewed-by`.
+ - `format:<format>`, any string accepted by the `--format` option of
+ 'git log'. (See the "PRETTY FORMATS" section of
+ linkgit:git-log[1].)
+
Note that commits that do not include the trailer will not be counted.
Likewise, commits with multiple trailers (e.g., multiple signoffs) may
diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt
index 5cc2fcefbab..71f608b1ff1 100644
--- a/Documentation/git-show-branch.txt
+++ b/Documentation/git-show-branch.txt
@@ -8,12 +8,12 @@ git-show-branch - Show branches and their commits
SYNOPSIS
--------
[verse]
-'git show-branch' [-a|--all] [-r|--remotes] [--topo-order | --date-order]
+'git show-branch' [-a | --all] [-r | --remotes] [--topo-order | --date-order]
[--current] [--color[=<when>] | --no-color] [--sparse]
[--more=<n> | --list | --independent | --merge-base]
[--no-name | --sha1-name] [--topics]
[(<rev> | <glob>)...]
-'git show-branch' (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]
+'git show-branch' (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]
DESCRIPTION
-----------
@@ -199,6 +199,13 @@ shows 10 reflog entries going back from the tip as of 1 hour ago.
Without `--list`, the output also shows how these tips are
topologically related with each other.
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/showbranch.txt[]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
index ab4d271925d..d1d56f68b43 100644
--- a/Documentation/git-show-ref.txt
+++ b/Documentation/git-show-ref.txt
@@ -8,8 +8,8 @@ git-show-ref - List references in a local repository
SYNOPSIS
--------
[verse]
-'git show-ref' [-q|--quiet] [--verify] [--head] [-d|--dereference]
- [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
+'git show-ref' [-q | --quiet] [--verify] [--head] [-d | --dereference]
+ [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]
[--heads] [--] [<pattern>...]
'git show-ref' --exclude-existing[=<pattern>]
diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt
index 3776705bf53..68392d2a56e 100644
--- a/Documentation/git-sparse-checkout.txt
+++ b/Documentation/git-sparse-checkout.txt
@@ -9,7 +9,7 @@ git-sparse-checkout - Reduce your working tree to a subset of tracked files
SYNOPSIS
--------
[verse]
-'git sparse-checkout <subcommand> [<options>]'
+'git sparse-checkout' (init | list | set | add | reapply | disable) [<options>]
DESCRIPTION
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index 6e15f475257..f4bb6114d91 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -9,17 +9,20 @@ SYNOPSIS
--------
[verse]
'git stash' list [<log-options>]
-'git stash' show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]
-'git stash' drop [-q|--quiet] [<stash>]
-'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
+'git stash' show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
+'git stash' drop [-q | --quiet] [<stash>]
+'git stash' pop [--index] [-q | --quiet] [<stash>]
+'git stash' apply [--index] [-q | --quiet] [<stash>]
'git stash' branch <branchname> [<stash>]
-'git stash' [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet]
- [-u|--include-untracked] [-a|--all] [-m|--message <message>]
+'git stash' [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
+ [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
[--pathspec-from-file=<file> [--pathspec-file-nul]]
[--] [<pathspec>...]]
+'git stash' save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
+ [-u | --include-untracked] [-a | --all] [<message>]
'git stash' clear
'git stash' create [<message>]
-'git stash' store [-m|--message <message>] [-q|--quiet] <commit>
+'git stash' store [(-m | --message) <message>] [-q | --quiet] <commit>
DESCRIPTION
-----------
@@ -47,7 +50,7 @@ stash index (e.g. the integer `n` is equivalent to `stash@{n}`).
COMMANDS
--------
-push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]::
+push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [(-m|--message) <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]::
Save your local modifications to a new 'stash entry' and roll them
back to HEAD (in the working tree and in the index).
@@ -382,6 +385,13 @@ grep commit | cut -d\ -f3 |
xargs git log --merges --no-walk --grep=WIP
----------------------------------------------------------------
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/stash.txt[]
+
SEE ALSO
--------
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 54a4b29b473..5e438a7fdc1 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -9,7 +9,7 @@ git-status - Show the working tree status
SYNOPSIS
--------
[verse]
-'git status' [<options>...] [--] [<pathspec>...]
+'git status' [<options>] [--] [<pathspec>...]
DESCRIPTION
-----------
diff --git a/Documentation/git-switch.txt b/Documentation/git-switch.txt
index bbcbdceb459..c60fc9c138b 100644
--- a/Documentation/git-switch.txt
+++ b/Documentation/git-switch.txt
@@ -265,6 +265,13 @@ always create a new name for it (without switching away):
$ git switch -c good-surprises
------------
+CONFIGURATION
+-------------
+
+include::includes/cmd-config-section-all.txt[]
+
+include::config/checkout.txt[]
+
SEE ALSO
--------
linkgit:git-checkout[1],
diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt
index ef68ad2b711..102c83eb19e 100644
--- a/Documentation/git-symbolic-ref.txt
+++ b/Documentation/git-symbolic-ref.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git symbolic-ref' [-m <reason>] <name> <ref>
-'git symbolic-ref' [-q] [--short] <name>
+'git symbolic-ref' [-q] [--short] [--no-recurse] <name>
'git symbolic-ref' --delete [-q] <name>
DESCRIPTION
@@ -46,6 +46,15 @@ OPTIONS
When showing the value of <name> as a symbolic ref, try to shorten the
value, e.g. from `refs/heads/master` to `master`.
+--recurse::
+--no-recurse::
+ When showing the value of <name> as a symbolic ref, if
+ <name> refers to another symbolic ref, follow such a chain
+ of symbolic refs until the result no longer points at a
+ symbolic ref (`--recurse`, which is the default).
+ `--no-recurse` stops after dereferencing only a single level
+ of symbolic ref.
+
-m::
Update the reflog for <name> with <reason>. This is valid only
when creating or updating a symbolic ref.
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 31a97a1b6c5..fdc72b5875a 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -9,7 +9,7 @@ git-tag - Create, list, delete or verify a tag object signed with GPG
SYNOPSIS
--------
[verse]
-'git tag' [-a | -s | -u <keyid>] [-f] [-m <msg> | -F <file>] [-e]
+'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]
<tagname> [<commit> | <object>]
'git tag' -d <tagname>...
'git tag' [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]
@@ -26,19 +26,19 @@ to delete, list or verify tags.
Unless `-f` is given, the named tag must not yet exist.
-If one of `-a`, `-s`, or `-u <keyid>` is passed, the command
+If one of `-a`, `-s`, or `-u <key-id>` is passed, the command
creates a 'tag' object, and requires a tag message. Unless
`-m <msg>` or `-F <file>` is given, an editor is started for the user to type
in the tag message.
-If `-m <msg>` or `-F <file>` is given and `-a`, `-s`, and `-u <keyid>`
+If `-m <msg>` or `-F <file>` is given and `-a`, `-s`, and `-u <key-id>`
are absent, `-a` is implied.
Otherwise, a tag reference that points directly at the given object
(i.e., a lightweight tag) is created.
A GnuPG signed tag object will be created when `-s` or `-u
-<keyid>` is used. When `-u <keyid>` is not used, the
+<key-id>` is used. When `-u <key-id>` is not used, the
committer identity for the current user is used to find the
GnuPG key for signing. The configuration variable `gpg.program`
is used to specify custom GnuPG binary.
@@ -72,8 +72,8 @@ OPTIONS
Override `tag.gpgSign` configuration variable that is
set to force each and every tag to be signed.
--u <keyid>::
---local-user=<keyid>::
+-u <key-id>::
+--local-user=<key-id>::
Make a GPG-signed tag, using the given key.
-f::
@@ -164,14 +164,14 @@ This option is only applicable when listing tags without annotation lines.
Use the given tag message (instead of prompting).
If multiple `-m` options are given, their values are
concatenated as separate paragraphs.
- Implies `-a` if none of `-a`, `-s`, or `-u <keyid>`
+ Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
is given.
-F <file>::
--file=<file>::
Take the tag message from the given file. Use '-' to
read the message from the standard input.
- Implies `-a` if none of `-a`, `-s`, or `-u <keyid>`
+ Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
is given.
-e::
@@ -220,7 +220,7 @@ it in the repository configuration as follows:
-------------------------------------
[user]
- signingKey = <gpg-keyid>
+ signingKey = <gpg-key_id>
-------------------------------------
`pager.tag` is only respected when listing tags, i.e., when `-l` is
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 5ea2f2c60e4..f4bb9c5daf9 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -420,7 +420,7 @@ as `switch`, `pull`, `merge`) will avoid writing these files.
However, these commands will sometimes write these files anyway in
important cases such as conflicts during a merge or rebase. Git
commands will also avoid treating the lack of such files as an
-intentional deletion; for example `git add -u` will not not stage a
+intentional deletion; for example `git add -u` will not stage a
deletion for these files and `git commit -a` will not make a commit
deleting them either.
diff --git a/Documentation/git-update-server-info.txt b/Documentation/git-update-server-info.txt
index 969bb2e15f1..17e429dbd09 100644
--- a/Documentation/git-update-server-info.txt
+++ b/Documentation/git-update-server-info.txt
@@ -9,7 +9,7 @@ git-update-server-info - Update auxiliary info file to help dumb servers
SYNOPSIS
--------
[verse]
-'git update-server-info'
+'git update-server-info' [-f | --force]
DESCRIPTION
-----------
@@ -19,6 +19,12 @@ $GIT_OBJECT_DIRECTORY/info directories to help clients discover
what references and packs the server has. This command
generates such auxiliary files.
+OPTIONS
+-------
+-f::
+--force::
+ update the info files from scratch.
+
OUTPUT
------
diff --git a/Documentation/git-upload-archive.txt b/Documentation/git-upload-archive.txt
index fba0f1c1b27..e8eb10baad7 100644
--- a/Documentation/git-upload-archive.txt
+++ b/Documentation/git-upload-archive.txt
@@ -9,7 +9,7 @@ git-upload-archive - Send archive back to git-archive
SYNOPSIS
--------
[verse]
-'git upload-archive' <directory>
+'git upload-archive' <repository>
DESCRIPTION
-----------
@@ -54,7 +54,7 @@ access via non-smart-http.
OPTIONS
-------
-<directory>::
+<repository>::
The repository to get a tar archive from.
GIT
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
index 3f89d640772..b656b475675 100644
--- a/Documentation/git-upload-pack.txt
+++ b/Documentation/git-upload-pack.txt
@@ -40,7 +40,7 @@ OPTIONS
Used by linkgit:git-http-backend[1] to serve up
`$GIT_URL/info/refs?service=git-upload-pack` requests. See
"Smart Clients" in linkgit:gitprotocol-http[5] and "HTTP
- Transport" in in the linkgit:gitprotocol-v2[5]
+ Transport" in the linkgit:gitprotocol-v2[5]
documentation. Also understood by
linkgit:git-receive-pack[1].
diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt
index 387cc1b9142..6aa521fab23 100644
--- a/Documentation/git-var.txt
+++ b/Documentation/git-var.txt
@@ -9,7 +9,7 @@ git-var - Show a Git logical variable
SYNOPSIS
--------
[verse]
-'git var' ( -l | <variable> )
+'git var' (-l | <variable>)
DESCRIPTION
-----------
diff --git a/Documentation/git-verify-commit.txt b/Documentation/git-verify-commit.txt
index 92097f6673d..aee4c40eac4 100644
--- a/Documentation/git-verify-commit.txt
+++ b/Documentation/git-verify-commit.txt
@@ -8,7 +8,7 @@ git-verify-commit - Check the GPG signature of commits
SYNOPSIS
--------
[verse]
-'git verify-commit' <commit>...
+'git verify-commit' [-v | --verbose] [--raw] <commit>...
DESCRIPTION
-----------
diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt
index 61ca6d04c20..b8720dce8ab 100644
--- a/Documentation/git-verify-pack.txt
+++ b/Documentation/git-verify-pack.txt
@@ -9,7 +9,7 @@ git-verify-pack - Validate packed Git archive files
SYNOPSIS
--------
[verse]
-'git verify-pack' [-v|--verbose] [-s|--stat-only] [--] <pack>.idx ...
+'git verify-pack' [-v | --verbose] [-s | --stat-only] [--] <pack>.idx...
DESCRIPTION
diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt
index 0b8075dad96..81d50ecc4c6 100644
--- a/Documentation/git-verify-tag.txt
+++ b/Documentation/git-verify-tag.txt
@@ -8,7 +8,7 @@ git-verify-tag - Check the GPG signature of tags
SYNOPSIS
--------
[verse]
-'git verify-tag' [--format=<format>] <tag>...
+'git verify-tag' [-v | --verbose] [--format=<format>] [--raw] <tag>...
DESCRIPTION
-----------
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index ada30c86a7c..063d6eeb99d 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -9,7 +9,8 @@ git-worktree - Manage multiple working trees
SYNOPSIS
--------
[verse]
-'git worktree add' [-f] [--detach] [--checkout] [--lock [--reason <string>]] [-b <new-branch>] <path> [<commit-ish>]
+'git worktree add' [-f] [--detach] [--checkout] [--lock [--reason <string>]]
+ [-b <new-branch>] <path> [<commit-ish>]
'git worktree list' [-v | --porcelain [-z]]
'git worktree lock' [--reason <string>] <worktree>
'git worktree move' <worktree> <new-path>
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 0ef7f5e4ece..1d33e083ab8 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -344,7 +344,7 @@ Repository, command and file interfaces
This documentation discusses repository and command interfaces which
users are expected to interact with directly. See `--user-formats` in
-linkgit:git-help[1] for more details on the critera.
+linkgit:git-help[1] for more details on the criteria.
include::cmds-userinterfaces.txt[]
@@ -458,7 +458,12 @@ Please see linkgit:gitglossary[7].
Environment Variables
---------------------
-Various Git commands use the following environment variables:
+Various Git commands pay attention to environment variables and change
+their behavior. The environment variables marked as "Boolean" take
+their values the same way as Boolean valued configuration variables, e.g.
+"true", "yes", "on" and positive numbers are taken as "yes".
+
+Here are the variables:
The Git Repository
~~~~~~~~~~~~~~~~~~
@@ -467,13 +472,13 @@ is worth noting that they may be used/overridden by SCMS sitting above
Git so take care if using a foreign front-end.
`GIT_INDEX_FILE`::
- This environment allows the specification of an alternate
+ This environment variable specifies an alternate
index file. If not specified, the default of `$GIT_DIR/index`
is used.
`GIT_INDEX_VERSION`::
- This environment variable allows the specification of an index
- version for new repositories. It won't affect existing index
+ This environment variable specifies what index version is used
+ when writing the index file out. It won't affect existing index
files. By default index file version 2 or 3 is used. See
linkgit:git-update-index[1] for more information.
@@ -530,7 +535,7 @@ double-quotes and respecting backslash escapes. E.g., the value
When run in a directory that does not have ".git" repository
directory, Git tries to find such a directory in the parent
directories to find the top of the working tree, but by default it
- does not cross filesystem boundaries. This environment variable
+ does not cross filesystem boundaries. This Boolean environment variable
can be set to true to tell Git not to stop at filesystem
boundaries. Like `GIT_CEILING_DIRECTORIES`, this will not affect
an explicit repository directory set via `GIT_DIR` or on the
@@ -682,6 +687,11 @@ for further details.
plink or tortoiseplink. This variable overrides the config setting
`ssh.variant` that serves the same purpose.
+`GIT_SSL_NO_VERIFY`::
+ Setting and exporting this environment variable to any value
+ tells Git not to verify the SSL certificate when fetching or
+ pushing over HTTPS.
+
`GIT_ASKPASS`::
If this environment variable is set, then Git commands which need to
acquire passwords or passphrases (e.g. for HTTP or IMAP authentication)
@@ -690,7 +700,7 @@ for further details.
option in linkgit:git-config[1].
`GIT_TERMINAL_PROMPT`::
- If this environment variable is set to `0`, git will not prompt
+ If this Boolean environment variable is set to false, git will not prompt
on the terminal (e.g., when asking for HTTP authentication).
`GIT_CONFIG_GLOBAL`::
@@ -705,13 +715,14 @@ for further details.
`GIT_CONFIG_NOSYSTEM`::
Whether to skip reading settings from the system-wide
- `$(prefix)/etc/gitconfig` file. This environment variable can
+ `$(prefix)/etc/gitconfig` file. This Boolean environment variable can
be used along with `$HOME` and `$XDG_CONFIG_HOME` to create a
predictable environment for a picky script, or you can set it
- temporarily to avoid using a buggy `/etc/gitconfig` file while
+ to true to temporarily avoid using a buggy `/etc/gitconfig` file while
waiting for someone with sufficient permissions to fix it.
`GIT_FLUSH`::
+// NEEDSWORK: make it into a usual Boolean environment variable
If this environment variable is set to "1", then commands such
as 'git blame' (in incremental mode), 'git rev-list', 'git log',
'git check-attr' and 'git check-ignore' will
@@ -852,11 +863,11 @@ for full details.
`GIT_TRACE_REDACT`::
By default, when tracing is activated, Git redacts the values of
cookies, the "Authorization:" header, the "Proxy-Authorization:"
- header and packfile URIs. Set this variable to `0` to prevent this
+ header and packfile URIs. Set this Boolean environment variable to false to prevent this
redaction.
`GIT_LITERAL_PATHSPECS`::
- Setting this variable to `1` will cause Git to treat all
+ Setting this Boolean environment variable to true will cause Git to treat all
pathspecs literally, rather than as glob patterns. For example,
running `GIT_LITERAL_PATHSPECS=1 git log -- '*.c'` will search
for commits that touch the path `*.c`, not any paths that the
@@ -865,15 +876,15 @@ for full details.
`git ls-tree`, `--raw` diff output, etc).
`GIT_GLOB_PATHSPECS`::
- Setting this variable to `1` will cause Git to treat all
+ Setting this Boolean environment variable to true will cause Git to treat all
pathspecs as glob patterns (aka "glob" magic).
`GIT_NOGLOB_PATHSPECS`::
- Setting this variable to `1` will cause Git to treat all
+ Setting this Boolean environment variable to true will cause Git to treat all
pathspecs as literal (aka "literal" magic).
`GIT_ICASE_PATHSPECS`::
- Setting this variable to `1` will cause Git to treat all
+ Setting this Boolean environment variable to true will cause Git to treat all
pathspecs as case-insensitive.
`GIT_REFLOG_ACTION`::
@@ -887,7 +898,7 @@ for full details.
end user, to be recorded in the body of the reflog.
`GIT_REF_PARANOIA`::
- If set to `0`, ignore broken or badly named refs when iterating
+ If this Boolean environment variable is set to false, ignore broken or badly named refs when iterating
over lists of refs. Normally Git will try to include any such
refs, which may cause some operations to fail. This is usually
preferable, as potentially destructive operations (e.g.,
@@ -906,7 +917,7 @@ for full details.
`protocol.allow` in linkgit:git-config[1] for more details.
`GIT_PROTOCOL_FROM_USER`::
- Set to 0 to prevent protocols used by fetch/push/clone which are
+ Set this Boolean environment variable to false to prevent protocols used by fetch/push/clone which are
configured to the `user` state. This is useful to restrict recursive
submodule initialization from an untrusted repository or for programs
which feed potentially-untrusted URLS to git commands. See
@@ -934,7 +945,7 @@ only affects clones and fetches; it is not yet used for pushes (but may
be in the future).
`GIT_OPTIONAL_LOCKS`::
- If set to `0`, Git will complete any requested operation without
+ If this Boolean environment variable is set to false, Git will complete any requested operation without
performing any optional sub-operations that require taking a lock.
For example, this will prevent `git status` from refreshing the
index as a side effect. This is useful for processes running in
diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.txt
index 80517b4eb2c..6df50e8a144 100644
--- a/Documentation/gitcredentials.txt
+++ b/Documentation/gitcredentials.txt
@@ -17,9 +17,10 @@ DESCRIPTION
Git will sometimes need credentials from the user in order to perform
operations; for example, it may need to ask for a username and password
-in order to access a remote repository over HTTP. This manual describes
-the mechanisms Git uses to request these credentials, as well as some
-features to avoid inputting these credentials repeatedly.
+in order to access a remote repository over HTTP. Some remotes accept
+a personal access token or OAuth access token as a password. This
+manual describes the mechanisms Git uses to request these credentials,
+as well as some features to avoid inputting these credentials repeatedly.
REQUESTING CREDENTIALS
----------------------
diff --git a/Documentation/gitformat-commit-graph.txt b/Documentation/gitformat-commit-graph.txt
index 7324665716d..31cad585e23 100644
--- a/Documentation/gitformat-commit-graph.txt
+++ b/Documentation/gitformat-commit-graph.txt
@@ -3,7 +3,7 @@ gitformat-commit-graph(5)
NAME
----
-gitformat-commit-graph - Git commit graph format
+gitformat-commit-graph - Git commit-graph format
SYNOPSIS
--------
@@ -14,7 +14,7 @@ $GIT_DIR/objects/info/commit-graphs/*
DESCRIPTION
-----------
-The Git commit graph stores a list of commit OIDs and some associated
+The Git commit-graph stores a list of commit OIDs and some associated
metadata, including:
- The generation number of the commit.
@@ -34,7 +34,7 @@ corresponding to the array position within the list of commit OIDs. Due
to some special constants we use to track parents, we can store at most
(1 << 30) + (1 << 29) + (1 << 28) - 1 (around 1.8 billion) commits.
-== Commit graph files have the following format:
+== Commit-graph files have the following format:
In order to allow extensions that add extra data to the graph, we organize
the body into "chunks" and provide a binary lookup table at the beginning
diff --git a/Documentation/gitprotocol-capabilities.txt b/Documentation/gitprotocol-capabilities.txt
index c6dcc7d565d..0fb5ea0c1ca 100644
--- a/Documentation/gitprotocol-capabilities.txt
+++ b/Documentation/gitprotocol-capabilities.txt
@@ -388,8 +388,8 @@ the server as well.
Session IDs should be unique to a given process. They must fit within a
packet-line, and must not contain non-printable or whitespace characters. The
current implementation uses trace2 session IDs (see
-link:api-trace2.html[api-trace2] for details), but this may change and users of
-the session ID should not rely on this fact.
+link:technical/api-trace2.html[api-trace2] for details), but this may change
+and users of the session ID should not rely on this fact.
GIT
---
diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt
index c9c0f9160b2..59bf41cefb9 100644
--- a/Documentation/gitprotocol-v2.txt
+++ b/Documentation/gitprotocol-v2.txt
@@ -544,8 +544,8 @@ the server as well.
Session IDs should be unique to a given process. They must fit within a
packet-line, and must not contain non-printable or whitespace characters. The
current implementation uses trace2 session IDs (see
-link:api-trace2.html[api-trace2] for details), but this may change and users of
-the session ID should not rely on this fact.
+link:technical/api-trace2.html[api-trace2] for details), but this may change
+and users of the session ID should not rely on this fact.
object-info
~~~~~~~~~~~
diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt
index 6f1e269ae43..ed8da428c98 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -168,6 +168,9 @@ Supported commands: 'list', 'import'.
Can guarantee that when a clone is requested, the received
pack is self contained and is connected.
+'get'::
+ Can use the 'get' command to download a file from a given URI.
+
If a helper advertises 'connect', Git will use it if possible and
fall back to another capability if the helper requests so when
connecting (see the 'connect' command under COMMANDS).
@@ -418,6 +421,12 @@ Supported if the helper has the "connect" capability.
+
Supported if the helper has the "stateless-connect" capability.
+'get' <uri> <path>::
+ Downloads the file from the given `<uri>` to the given `<path>`. If
+ `<path>.temp` exists, then Git assumes that the `.temp` file is a
+ partial download from a previous attempt and will resume the
+ download from that position.
+
If a fatal error occurs, the program writes the error message to
stderr and exits. The caller should expect that a suitable error
message has been printed if the child closes the connection without
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index aa2f41f5e70..5a537268e27 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -20,7 +20,7 @@
[[def_branch]]branch::
A "branch" is a line of development. The most recent
<<def_commit,commit>> on a branch is referred to as the tip of
- that branch. The tip of the branch is referenced by a branch
+ that branch. The tip of the branch is <<def_ref,referenced>> by a branch
<<def_head,head>>, which moves forward as additional development
is done on the branch. A single Git
<<def_repository,repository>> can track an arbitrary number of
@@ -75,6 +75,21 @@ state in the Git history, by creating a new commit representing the current
state of the <<def_index,index>> and advancing <<def_HEAD,HEAD>>
to point at the new commit.
+[[def_commit_graph_general]]commit graph concept, representations and usage::
+ A synonym for the <<def_DAG,DAG>> structure formed by the commits
+ in the object database, <<def_ref,referenced>> by branch tips,
+ using their <<def_chain,chain>> of linked commits.
+ This structure is the definitive commit graph. The
+ graph can be represented in other ways, e.g. the
+ <<def_commit_graph_file,"commit-graph" file>>.
+
+[[def_commit_graph_file]]commit-graph file::
+ The "commit-graph" (normally hyphenated) file is a supplemental
+ representation of the <<def_commit_graph_general,commit graph>>
+ which accelerates commit graph walks. The "commit-graph" file is
+ stored either in the .git/objects/info directory or in the info
+ directory of an alternate object database.
+
[[def_commit_object]]commit object::
An <<def_object,object>> which contains the information about a
particular <<def_revision,revision>>, such as <<def_parent,parents>>, committer,
@@ -262,7 +277,7 @@ This commit is referred to as a "merge commit", or sometimes just a
identified by its <<def_object_name,object name>>. The objects usually
live in `$GIT_DIR/objects/`.
-[[def_object_identifier]]object identifier::
+[[def_object_identifier]]object identifier (oid)::
Synonym for <<def_object_name,object name>>.
[[def_object_name]]object name::
@@ -493,6 +508,14 @@ exclude;;
<<def_tree_object,trees>> to the trees or <<def_blob_object,blobs>>
that they contain.
+[[def_reachability_bitmap]]reachability bitmaps::
+ Reachability bitmaps store information about the
+ <<def_reachable,reachability>> of a selected set of commits in
+ a packfile, or a multi-pack index (MIDX), to speed up object search.
+ The bitmaps are stored in a ".bitmap" file. A repository may have at
+ most one bitmap file in use. The bitmap file may belong to either one
+ pack, or the repository's multi-pack index (if it exists).
+
[[def_rebase]]rebase::
To reapply a series of changes from a <<def_branch,branch>> to a
different base, and reset the <<def_head,head>> of that branch
diff --git a/Documentation/howto/coordinate-embargoed-releases.txt b/Documentation/howto/coordinate-embargoed-releases.txt
index 601aae88e9a..e653775bab1 100644
--- a/Documentation/howto/coordinate-embargoed-releases.txt
+++ b/Documentation/howto/coordinate-embargoed-releases.txt
@@ -1,9 +1,10 @@
Content-type: text/asciidoc
-Abstract: When a critical vulnerability is discovered and fixed, we follow this
- script to coordinate a public release.
+Abstract: When a vulnerability is reported, we follow these guidelines to
+ assess the vulnerability, create and review a fix, and coordinate embargoed
+ security releases.
How we coordinate embargoed releases
-====================================
+------------------------------------
To protect Git users from critical vulnerabilities, we do not just release
fixed versions like regular maintenance releases. Instead, we coordinate
@@ -11,33 +12,147 @@ releases with packagers, keeping the fixes under an embargo until the release
date. That way, users will have a chance to upgrade on that date, no matter
what Operating System or distribution they run.
-Open a Security Advisory draft
-------------------------------
+The `git-security` mailing list
+-------------------------------
+
+Responsible disclosures of vulnerabilities, analysis, proposed fixes as
+well as the orchestration of coordinated embargoed releases all happen on the
+`git-security` mailing list at <git-security@googlegroups.com>.
+
+In this context, the term "embargo" refers to the time period that information
+about a vulnerability is kept under wraps and only shared on a need-to-know
+basis. This is necessary to protect Git's users from bad actors who would
+otherwise be made aware of attack vectors that could be exploited. "Lifting the
+embargo" refers to publishing the version that fixes the vulnerabilities.
+
+Audience of the `git-security` mailing list
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Anybody may contact the `git-security` mailing list by sending an email
+to <git-security@googlegroups.com>, though the archive is closed to the
+public and only accessible to subscribed members.
+
+There are a few dozen subscribed members: core Git developers who are trusted
+with addressing vulnerabilities, and stakeholders (i.e. owners of products
+affected by security vulnerabilities in Git).
+
+Most of the discussions revolve around assessing the severity of the reported
+issue (including the decision whether the report is security-relevant or can be
+redirected to the public mailing list), how to remediate the issue, determining
+the timeline of the disclosure as well as aligning priorities and
+requirements.
-The first step is to https://github.com/git/git/security/advisories/new[open an
-advisory]. Technically, it is not necessary, but it is convenient and saves a
-bit of hassle. This advisory can also be used to obtain the CVE number and it
-will give us a private fork associated with it that can be used to collaborate
-on a fix.
+Communications
+~~~~~~~~~~~~~~
-Release date of the embargoed version
--------------------------------------
+If you are a stakeholder, it is a good idea to pay close attention to the
+discussions, as pertinent information may be buried in the middle of a lively
+conversation that might not look relevant to your interests. For example, the
+tentative timeline might be agreed upon in the middle of discussing code
+comment formatting in one of the patches and whether or not to combine fixes
+for multiple, separate vulnerabilities into the same embargoed release. Most
+mail threads are not usually structured specifically to communicate
+agreements, assessments or timelines.
-If the vulnerability affects Windows users, we want to have our friends over at
-Visual Studio on board. This means we need to target a "Patch Tuesday" (i.e. a
-second Tuesday of the month), at the minimum three weeks from heads-up to
-coordinated release.
+Typical timeline
+----------------
-If the vulnerability affects the server side, or can benefit from scans on the
-server side (i.e. if `git fsck` can detect an attack), it is important to give
-all involved Git repository hosting sites enough time to scan all of those
-repositories.
+- A potential vulnerability is reported to the `git-security` mailing list.
+
+- The members of the git-security list start a discussion to give an initial
+ assessment of the severity of the reported potential vulnerability.
+ We aspire to do so within a few days.
+
+- After discussion, if consensus is reached that it is not critical enough
+ to warrant any embargo, the reporter is redirected to the public Git mailing
+ list. This ends the reporter's interaction with the `git-security` list.
+
+- If it is deemed critical enough for an embargo, ideas are presented on how to
+ address the vulnerability.
+
+- Usually around that time, the Git maintainer or their delegate(s) open a draft
+ security advisory in the `git/git` repository on GitHub (see below for more
+ details).
+
+- Code review can take place in a variety of different locations,
+ depending on context. These are: patches sent inline on the git-security list,
+ a private fork on GitHub associated with the draft security advisory, or the
+ git/cabal repository.
+
+- Contributors working on a fix should consider beginning by sending
+ patches to the git-security list (inline with the original thread), since they
+ are accessible to all subscribers, along with the original reporter.
+
+- Once the review has settled and everyone involved in the review agrees that
+ the patches are nearing the finish line, the Git maintainer, and others
+ determine a release date as well as the release trains that are serviced. The
+ decision regarding which versions need a backported fix is based on input from
+ the reporter, the contributor who worked on the patches, and from
+ stakeholders. Operators of hosting sites who may want to analyze whether the
+ given issue is exploited via any of the repositories they host, and binary
+ packagers who want to make sure their product gets patched adequately against
+ the vulnerability, for example, may want to give their input at this stage.
+
+- While the Git community does its best to accommodate the specific timeline
+ requests of the various binary packagers, the nature of the issue may preclude
+ a prolonged release schedule. For fixes deemed urgent, it may be in the best
+ interest of the Git users community to shorten the disclosure and release
+ timeline, and packagers may need to adapt accordingly.
+
+- Subsequently, branches with the fixes are pushed to the git/cabal repository.
+
+- The tags are created by the Git maintainer and pushed to the same repository.
+
+- The Git for Windows, Git for macOS, BSD, Debian, etc. maintainers prepare the
+ corresponding release artifacts, based on the tags created that have been
+ prepared by the Git maintainer.
+
+- The release artifacts prepared by various binary packagers can be
+ made available to stakeholders under embargo via a mail to the
+ `git-security` list.
+
+- Less than a week before the release, a mail with the relevant information is
+ sent to <distros@vs.openwall.org> (see below), a list used to pre-announce
+ embargoed releases of open source projects to the stakeholders of all major
+ distributions of Linux as well as other OSes.
+
+- Public communication is then prepared in advance of the release date. This
+ includes blog posts and mails to the Git and Git for Windows mailing lists.
+
+- On the day of the release, at around 10am Pacific Time, the Git maintainer
+ pushes the tag and the `master` branch to the public repository, then sends
+ out an announcement mail.
+
+- Once the tag is pushed, the Git for Windows maintainer publishes the
+ corresponding tag and creates a GitHub Release with the associated release
+ artifacts (Git for Windows installer, Portable Git, MinGit, etc).
+
+- Git for Windows release is then announced via a mail to the public Git and
+ Git for Windows mailing lists as well as via a tweet.
+
+- Ditto for distribution packagers for Linux and other platforms:
+ their releases are announced via their preferred channels.
+
+- A mail to <oss-security@lists.openwall.org> (see below for details) is sent
+ as a follow-up to the <distros@vs.openwall.org> one, describing the
+ vulnerability in detail, often including a proof of concept of an exploit.
+
+Note: The Git project makes no guarantees about timelines, but aims to keep
+embargoes reasonably short in the interest of keeping Git's users safe.
+
+Opening a Security Advisory draft
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The first step is to https://github.com/git/git/security/advisories/new[open
+an advisory]. Technically, this is not necessary. However, it is the most
+convenient way to obtain the CVE number and it give us a private repository
+associated with it that can be used to collaborate on a fix.
Notifying the Linux distributions
----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At most two weeks before release date, we need to send a notification to
-distros@vs.openwall.org, preferably less than 7 days before the release date.
+<distros@vs.openwall.org>, preferably less than 7 days before the release date.
This will reach most (all?) Linux distributions. See an example below, and the
guidelines for this mailing list at
https://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists[here].
@@ -65,7 +180,7 @@ created using a command like this:
tar cJvf cve-xxx.bundle.tar.xz cve-xxx.bundle
Example mail to distros@vs.openwall.org
----------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
....
To: distros@vs.openwall.org
@@ -101,7 +216,7 @@ Thanks,
....
Example mail to oss-security@lists.openwall.com
------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
....
To: oss-security@lists.openwall.com
@@ -128,4 +243,4 @@ it goes to <developer>.
Thanks,
<name>
-....
+.... \ No newline at end of file
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
index a67130debb6..215e2edb0f5 100644
--- a/Documentation/howto/maintain-git.txt
+++ b/Documentation/howto/maintain-git.txt
@@ -256,7 +256,7 @@ by doing the following:
merged to 'next', add it at the end of the list. Then:
$ git checkout -B jch master
- $ Meta/redo-jch.sh -c1
+ $ sh Meta/redo-jch.sh -c1
to rebuild the 'jch' branch from scratch. "-c1" tells the script
to stop merging at the first line that begins with '###'
diff --git a/Documentation/includes/cmd-config-section-all.txt b/Documentation/includes/cmd-config-section-all.txt
new file mode 100644
index 00000000000..296a239f2ab
--- /dev/null
+++ b/Documentation/includes/cmd-config-section-all.txt
@@ -0,0 +1,3 @@
+Everything below this line in this section is selectively included
+from the linkgit:git-config[1] documentation. The content is the same
+as what's found there:
diff --git a/Documentation/includes/cmd-config-section-rest.txt b/Documentation/includes/cmd-config-section-rest.txt
new file mode 100644
index 00000000000..b1e7682c1dc
--- /dev/null
+++ b/Documentation/includes/cmd-config-section-rest.txt
@@ -0,0 +1,3 @@
+Everything above this line in this section isn't included from the
+linkgit:git-config[1] documentation. The content that follows is the
+same as what's found there:
diff --git a/Documentation/lint-fsck-msgids.perl b/Documentation/lint-fsck-msgids.perl
new file mode 100755
index 00000000000..1233ffe8153
--- /dev/null
+++ b/Documentation/lint-fsck-msgids.perl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+my ($fsck_h, $fsck_msgids_txt, $okfile) = @ARGV;
+
+my (%in_fsck_h, $fh, $bad);
+
+open($fh, "<", "$fsck_h") or die;
+while (<$fh>) {
+ if (/^\s+FUNC\(([0-9A-Z_]+), ([A-Z]+)\)/) {
+ my ($name, $severity) = ($1, $2);
+ my ($first) = 1;
+ $name = join('',
+ map {
+ y/A-Z/a-z/;
+ if (!$first) {
+ s/^(.)/uc($1)/e;
+ } else {
+ $first = 0;
+ }
+ $_;
+ }
+ split(/_/, $name));
+ $in_fsck_h{$name} = $severity;
+ }
+}
+close($fh);
+
+open($fh, "<", "$fsck_msgids_txt") or die;
+my ($previous, $current);
+while (<$fh>) {
+ if (!defined $current) {
+ if (/^\`([a-zA-Z0-9]*)\`::/) {
+ $current = $1;
+ if ((defined $previous) &&
+ ($current le $previous)) {
+ print STDERR "$previous >= $current in doc\n";
+ $bad = 1;
+ }
+ }
+ } elsif (/^\s+\(([A-Z]+)\) /) {
+ my ($level) = $1;
+ if (!exists $in_fsck_h{$current}) {
+ print STDERR "$current does not exist in fsck.h\n";
+ $bad = 1;
+ } elsif ($in_fsck_h{$current} eq "") {
+ print STDERR "$current defined twice\n";
+ $bad = 1;
+ } elsif ($in_fsck_h{$current} ne $level) {
+ print STDERR "$current severity $level != $in_fsck_h{$current}\n";
+ $bad = 1;
+ }
+ $previous = $current;
+ $in_fsck_h{$current} = ""; # mark as seen.
+ undef $current;
+ }
+}
+close($fh);
+
+for my $key (keys %in_fsck_h) {
+ if ($in_fsck_h{$key} ne "") {
+ print STDERR "$key not explained in doc.\n";
+ $bad = 1;
+ }
+}
+
+die if ($bad);
+
+open($fh, ">", "$okfile");
+print $fh "good\n";
+close($fh);
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index e3e350126df..0d2e55d7819 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -363,7 +363,7 @@ Revision Range Summary
'<rev>{caret}!', e.g. 'HEAD{caret}!'::
A suffix '{caret}' followed by an exclamation mark is the same
- as giving commit '<rev>' and then all its parents prefixed with
+ as giving commit '<rev>' and all its parents prefixed with
'{caret}' to exclude them (and their ancestors).
'<rev>{caret}-<n>', e.g. 'HEAD{caret}-, HEAD{caret}-2'::
diff --git a/contrib/scalar/scalar.txt b/Documentation/scalar.txt
index 1a12dc45077..f33436c7f65 100644
--- a/contrib/scalar/scalar.txt
+++ b/Documentation/scalar.txt
@@ -161,6 +161,6 @@ SEE ALSO
--------
linkgit:git-clone[1], linkgit:git-maintenance[1].
-Scalar
+GIT
---
-Associated with the linkgit:git[1] suite
+Part of the linkgit:git[1] suite
diff --git a/Documentation/technical/api-error-handling.txt b/Documentation/technical/api-error-handling.txt
index 70bf1d3e522..665c4960b44 100644
--- a/Documentation/technical/api-error-handling.txt
+++ b/Documentation/technical/api-error-handling.txt
@@ -46,7 +46,7 @@ parse-options.c.
returns -1 after reporting the situation to the caller.
These reports will be logged via the trace2 facility. See the "error"
-event in link:api-trace2.txt[trace2 API].
+event in link:api-trace2.html[trace2 API].
Customizable error handlers
---------------------------
diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt
index acfd5dc1d8b..61fa6ee1678 100644
--- a/Documentation/technical/api-parse-options.txt
+++ b/Documentation/technical/api-parse-options.txt
@@ -8,7 +8,8 @@ Basics
------
The argument vector `argv[]` may usually contain mandatory or optional
-'non-option arguments', e.g. a filename or a branch, and 'options'.
+'non-option arguments', e.g. a filename or a branch, 'options', and
+'subcommands'.
Options are optional arguments that start with a dash and
that allow to change the behavior of a command.
@@ -48,6 +49,33 @@ The parse-options API allows:
option, e.g. `-a -b --option -- --this-is-a-file` indicates that
`--this-is-a-file` must not be processed as an option.
+Subcommands are special in a couple of ways:
+
+* Subcommands only have long form, and they have no double dash prefix, no
+ negated form, and no description, and they don't take any arguments, and
+ can't be abbreviated.
+
+* There must be exactly one subcommand among the arguments, or zero if the
+ command has a default operation mode.
+
+* All arguments following the subcommand are considered to be arguments of
+ the subcommand, and, conversely, arguments meant for the subcommand may
+ not precede the subcommand.
+
+Therefore, if the options array contains at least one subcommand and
+`parse_options()` encounters the first dashless argument, it will either:
+
+* stop and return, if that dashless argument is a known subcommand, setting
+ `value` to the function pointer associated with that subcommand, storing
+ the name of the subcommand in argv[0], and leaving the rest of the
+ arguments unprocessed, or
+
+* stop and return, if it was invoked with the `PARSE_OPT_SUBCOMMAND_OPTIONAL`
+ flag and that dashless argument doesn't match any subcommands, leaving
+ `value` unchanged and the rest of the arguments unprocessed, or
+
+* show error and usage, and abort.
+
Steps to parse options
----------------------
@@ -90,8 +118,8 @@ Flags are the bitwise-or of:
Keep the first argument, which contains the program name. It's
removed from argv[] by default.
-`PARSE_OPT_KEEP_UNKNOWN`::
- Keep unknown arguments instead of erroring out. This doesn't
+`PARSE_OPT_KEEP_UNKNOWN_OPT`::
+ Keep unknown options instead of erroring out. This doesn't
work for all combinations of arguments as users might expect
it to do. E.g. if the first argument in `--unknown --known`
takes a value (which we can't know), the second one is
@@ -101,6 +129,8 @@ Flags are the bitwise-or of:
non-option, not as a value belonging to the unknown option,
the parser early. That's why parse_options() errors out if
both options are set.
+ Note that non-option arguments are always kept, even without
+ this flag.
`PARSE_OPT_NO_INTERNAL_HELP`::
By default, parse_options() handles `-h`, `--help` and
@@ -108,6 +138,13 @@ Flags are the bitwise-or of:
turns it off and allows one to add custom handlers for these
options, or to just leave them unknown.
+`PARSE_OPT_SUBCOMMAND_OPTIONAL`::
+ Don't error out when no subcommand is specified.
+
+Note that `PARSE_OPT_STOP_AT_NON_OPTION` is incompatible with subcommands;
+while `PARSE_OPT_KEEP_DASHDASH` and `PARSE_OPT_KEEP_UNKNOWN_OPT` can only be
+used with subcommands when combined with `PARSE_OPT_SUBCOMMAND_OPTIONAL`.
+
Data Structure
--------------
@@ -236,10 +273,14 @@ There are some macros to easily define options:
`OPT_CMDMODE(short, long, &int_var, description, enum_val)`::
Define an "operation mode" option, only one of which in the same
group of "operating mode" options that share the same `int_var`
- can be given by the user. `enum_val` is set to `int_var` when the
+ can be given by the user. `int_var` is set to `enum_val` when the
option is used, but an error is reported if other "operating mode"
option has already set its value to the same `int_var`.
+ In new commands consider using subcommands instead.
+`OPT_SUBCOMMAND(long, &fn_ptr, subcommand_fn)`::
+ Define a subcommand. `subcommand_fn` is put into `fn_ptr` when
+ this subcommand is used.
The last element of the array must be `OPT_END()`.
diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt
index 2afa28bb5aa..de5fc250595 100644
--- a/Documentation/technical/api-trace2.txt
+++ b/Documentation/technical/api-trace2.txt
@@ -148,20 +148,18 @@ filename collisions).
== Trace2 API
-All public Trace2 functions and macros are defined in `trace2.h` and
-`trace2.c`. All public symbols are prefixed with `trace2_`.
+The Trace2 public API is defined and documented in `trace2.h`; refer to it for
+more information. All public functions and macros are prefixed
+with `trace2_` and are implemented in `trace2.c`.
There are no public Trace2 data structures.
The Trace2 code also defines a set of private functions and data types
in the `trace2/` directory. These symbols are prefixed with `tr2_`
-and should only be used by functions in `trace2.c`.
+and should only be used by functions in `trace2.c` (or other private
+source files in `trace2/`).
-== Conventions for Public Functions and Macros
-
-The functions defined by the Trace2 API are declared and documented
-in `trace2.h`. It defines the API functions and wrapper macros for
-Trace2.
+=== Conventions for Public Functions and Macros
Some functions have a `_fl()` suffix to indicate that they take `file`
and `line-number` arguments.
@@ -172,52 +170,7 @@ take a `va_list` argument.
Some functions have a `_printf_fl()` suffix to indicate that they also
take a `printf()` style format with a variable number of arguments.
-There are CPP wrapper macros and `#ifdef`s to hide most of these details.
-See `trace2.h` for more details. The following discussion will only
-describe the simplified forms.
-
-== Public API
-
-All Trace2 API functions send a message to all of the active
-Trace2 Targets. This section describes the set of available
-messages.
-
-It helps to divide these functions into groups for discussion
-purposes.
-
-=== Basic Command Messages
-
-These are concerned with the lifetime of the overall git process.
-e.g: `void trace2_initialize_clock()`, `void trace2_initialize()`,
-`int trace2_is_enabled()`, `void trace2_cmd_start(int argc, const char **argv)`.
-
-=== Command Detail Messages
-
-These are concerned with describing the specific Git command
-after the command line, config, and environment are inspected.
-e.g: `void trace2_cmd_name(const char *name)`,
-`void trace2_cmd_mode(const char *mode)`.
-
-=== Child Process Messages
-
-These are concerned with the various spawned child processes,
-including shell scripts, git commands, editors, pagers, and hooks.
-
-e.g: `void trace2_child_start(struct child_process *cmd)`.
-
-=== Git Thread Messages
-
-These messages are concerned with Git thread usage.
-
-e.g: `void trace2_thread_start(const char *thread_name)`.
-
-=== Region and Data Messages
-
-These are concerned with recording performance data
-over regions or spans of code. e.g:
-`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`.
-
-Refer to trace2.h for details about all trace2 functions.
+CPP wrapper macros are defined to hide most of these details.
== Trace2 Target Formats
@@ -685,8 +638,8 @@ The "exec_id" field is a command-unique id and is only useful if the
`"thread_start"`::
This event is generated when a thread is started. It is
- generated from *within* the new thread's thread-proc (for TLS
- reasons).
+ generated from *within* the new thread's thread-proc (because
+ it needs to access data in the thread's thread-local storage).
+
------------
{
@@ -698,7 +651,7 @@ The "exec_id" field is a command-unique id and is only useful if the
`"thread_exit"`::
This event is generated when a thread exits. It is generated
- from *within* the thread's thread-proc (for TLS reasons).
+ from *within* the thread's thread-proc.
+
------------
{
@@ -816,6 +769,73 @@ The "value" field may be an integer or a string.
}
------------
+`"th_timer"`::
+ This event logs the amount of time that a stopwatch timer was
+ running in the thread. This event is generated when a thread
+ exits for timers that requested per-thread events.
++
+------------
+{
+ "event":"th_timer",
+ ...
+ "category":"my_category",
+ "name":"my_timer",
+ "intervals":5, # number of time it was started/stopped
+ "t_total":0.052741, # total time in seconds it was running
+ "t_min":0.010061, # shortest interval
+ "t_max":0.011648 # longest interval
+}
+------------
+
+`"timer"`::
+ This event logs the amount of time that a stopwatch timer was
+ running aggregated across all threads. This event is generated
+ when the process exits.
++
+------------
+{
+ "event":"timer",
+ ...
+ "category":"my_category",
+ "name":"my_timer",
+ "intervals":5, # number of time it was started/stopped
+ "t_total":0.052741, # total time in seconds it was running
+ "t_min":0.010061, # shortest interval
+ "t_max":0.011648 # longest interval
+}
+------------
+
+`"th_counter"`::
+ This event logs the value of a counter variable in a thread.
+ This event is generated when a thread exits for counters that
+ requested per-thread events.
++
+------------
+{
+ "event":"th_counter",
+ ...
+ "category":"my_category",
+ "name":"my_counter",
+ "count":23
+}
+------------
+
+`"counter"`::
+ This event logs the value of a counter variable across all threads.
+ This event is generated when the process exits. The total value
+ reported here is the sum across all threads.
++
+------------
+{
+ "event":"counter",
+ ...
+ "category":"my_category",
+ "name":"my_counter",
+ "count":23
+}
+------------
+
+
== Example Trace2 API Usage
Here is a hypothetical usage of the Trace2 API showing the intended
@@ -1206,7 +1226,7 @@ worked on 508 items at offset 2032. Thread "th04" worked on 508 items
at offset 508.
+
This example also shows that thread names are assigned in a racy manner
-as each thread starts and allocates TLS storage.
+as each thread starts.
Config (def param) Events::
@@ -1247,6 +1267,60 @@ d0 | main | data | r0 | 0.002126 | 0.002126 | fsy
d0 | main | exit | | 0.000470 | | | code:0
d0 | main | atexit | | 0.000477 | | | code:0
----------------
+
+Stopwatch Timer Events::
+
+ Measure the time spent in a function call or span of code
+ that might be called from many places within the code
+ throughout the life of the process.
++
+----------------
+static void expensive_function(void)
+{
+ trace2_timer_start(TRACE2_TIMER_ID_TEST1);
+ ...
+ sleep_millisec(1000); // Do something expensive
+ ...
+ trace2_timer_stop(TRACE2_TIMER_ID_TEST1);
+}
+
+static int ut_100timer(int argc, const char **argv)
+{
+ ...
+
+ expensive_function();
+
+ // Do something else 1...
+
+ expensive_function();
+
+ // Do something else 2...
+
+ expensive_function();
+
+ return 0;
+}
+----------------
++
+In this example, we measure the total time spent in
+`expensive_function()` regardless of when it is called
+in the overall flow of the program.
++
+----------------
+$ export GIT_TRACE2_PERF_BRIEF=1
+$ export GIT_TRACE2_PERF=~/log.perf
+$ t/helper/test-tool trace2 100timer 3 1000
+...
+$ cat ~/log.perf
+d0 | main | version | | | | | ...
+d0 | main | start | | 0.001453 | | | t/helper/test-tool trace2 100timer 3 1000
+d0 | main | cmd_name | | | | | trace2 (trace2)
+d0 | main | exit | | 3.003667 | | | code:0
+d0 | main | timer | | | | test | name:test1 intervals:3 total:3.001686 min:1.000254 max:1.000929
+d0 | main | atexit | | 3.003796 | | | code:0
+----------------
+
+
== Future Work
=== Relationship to the Existing Trace Api (api-trace.txt)
diff --git a/Documentation/technical/bitmap-format.txt b/Documentation/technical/bitmap-format.txt
index a85f58f5153..c2e652b71a7 100644
--- a/Documentation/technical/bitmap-format.txt
+++ b/Documentation/technical/bitmap-format.txt
@@ -72,6 +72,17 @@ MIDXs, both the bit-cache and rev-cache extensions are required.
pack/MIDX. The format and meaning of the name-hash is
described below.
+ ** {empty}
+ BITMAP_OPT_LOOKUP_TABLE (0x10): :::
+ If present, the end of the bitmap file contains a table
+ containing a list of `N` <commit_pos, offset, xor_row>
+ triplets. The format and meaning of the table is described
+ below.
++
+NOTE: Unlike the xor_offset used to compress an individual bitmap,
+`xor_row` stores an *absolute* index into the lookup table, not a location
+relative to the current entry.
+
4-byte entry count (network byte order): ::
The total count of entries (bitmapped commits) in this bitmap index.
@@ -216,3 +227,31 @@ Note that this hashing scheme is tied to the BITMAP_OPT_HASH_CACHE flag.
If implementations want to choose a different hashing scheme, they are
free to do so, but MUST allocate a new header flag (because comparing
hashes made under two different schemes would be pointless).
+
+Commit lookup table
+-------------------
+
+If the BITMAP_OPT_LOOKUP_TABLE flag is set, the last `N * (4 + 8 + 4)`
+bytes (preceding the name-hash cache and trailing hash) of the `.bitmap`
+file contains a lookup table specifying the information needed to get
+the desired bitmap from the entries without parsing previous unnecessary
+bitmaps.
+
+For a `.bitmap` containing `nr_entries` reachability bitmaps, the table
+contains a list of `nr_entries` <commit_pos, offset, xor_row> triplets
+(sorted in the ascending order of `commit_pos`). The content of i'th
+triplet is -
+
+ * {empty}
+ commit_pos (4 byte integer, network byte order): ::
+ It stores the object position of a commit (in the midx or pack
+ index).
+
+ * {empty}
+ offset (8 byte integer, network byte order): ::
+ The offset from which that commit's bitmap can be read.
+
+ * {empty}
+ xor_row (4 byte integer, network byte order): ::
+ The position of the triplet whose bitmap is used to compress
+ this one, or `0xffffffff` if no such bitmap exists.
diff --git a/Documentation/technical/bundle-uri.txt b/Documentation/technical/bundle-uri.txt
index c25c42378ab..b78d01d9adf 100644
--- a/Documentation/technical/bundle-uri.txt
+++ b/Documentation/technical/bundle-uri.txt
@@ -3,8 +3,7 @@ Bundle URIs
Git bundles are files that store a pack-file along with some extra metadata,
including a set of refs and a (possibly empty) set of necessary commits. See
-linkgit:git-bundle[1] and link:bundle-format.txt[the bundle format] for more
-information.
+linkgit:git-bundle[1] and linkgit:gitformat-bundle[5] for more information.
Bundle URIs are locations where Git can download one or more bundles in
order to bootstrap the object database in advance of fetching the remaining
@@ -154,8 +153,8 @@ bundle.<id>.filter::
bundle.<id>.creationToken::
This value is a nonnegative 64-bit integer used for sorting the bundles
- the list. This is used to download a subset of bundles during a fetch
- when `bundle.heuristic=creationToken`.
+ list. This is used to download a subset of bundles during a fetch when
+ `bundle.heuristic=creationToken`.
bundle.<id>.location::
This string value advertises a real-world location from where the bundle
@@ -235,8 +234,8 @@ will interact with bundle URIs according to the following flow:
making those OIDs present. When all required OIDs are present, the
client unbundles that data using a refspec. The default refspec is
`+refs/heads/*:refs/bundles/*`, but this can be configured. These refs
- are stored so that later `git fetch` negotiations can communicate the
- bundled refs as `have`s, reducing the size of the fetch over the Git
+ are stored so that later `git fetch` negotiations can communicate each
+ bundled ref as a `have`, reducing the size of the fetch over the Git
protocol. To allow pruning refs from this ref namespace, Git may
introduce a numbered namespace (such as `refs/bundles/<i>/*`) such that
stale bundle refs can be deleted.
@@ -290,7 +289,7 @@ expect that the process will end when all prerequisite commit OIDs in a
thin bundle are already in the object database.
When using the `creationToken` heuristic, the client can avoid downloading
-any bundles if their creation tokenss are not larger than the stored
+any bundles if their creation tokens are not larger than the stored
creation token. After fetching new bundles, Git updates this local
creation token.
@@ -319,7 +318,7 @@ Here are a few example error conditions:
Git's other HTTP protocols in terms of handling specific 400-level
errors.
-* The server reports any other failure reponse.
+* The server reports any other failure response.
* The client receives data that is not parsable as a bundle or bundle list.
@@ -447,7 +446,7 @@ created every hour, and then once a day those "hourly" bundles could be
merged into a "daily" bundle. The daily bundles are merged into the
oldest bundle after 30 days.
-It is recommened that this bundle strategy is repeated with the `blob:none`
+It is recommended that this bundle strategy is repeated with the `blob:none`
filter if clients of this repository are expecting to use blobless partial
clones. This list of blobless bundles stays in the same list as the full
bundles, but uses the `bundle.<id>.filter` key to separate the two groups.
diff --git a/Documentation/technical/commit-graph.txt b/Documentation/technical/commit-graph.txt
index f05e7bda1a9..86fed0de0f7 100644
--- a/Documentation/technical/commit-graph.txt
+++ b/Documentation/technical/commit-graph.txt
@@ -1,4 +1,4 @@
-Git Commit Graph Design Notes
+Git Commit-Graph Design Notes
=============================
Git walks the commit graph for many reasons, including:
@@ -17,7 +17,7 @@ There are two main costs here:
The commit-graph file is a supplemental data structure that accelerates
commit graph walks. If a user downgrades or disables the 'core.commitGraph'
-config setting, then the existing ODB is sufficient. The file is stored
+config setting, then the existing object database is sufficient. The file is stored
as "commit-graph" either in the .git/objects/info directory or in the info
directory of an alternate.
@@ -40,7 +40,7 @@ Values 1-4 satisfy the requirements of parse_commit_gently().
There are two definitions of generation number:
1. Corrected committer dates (generation number v2)
-2. Topological levels (generation nummber v1)
+2. Topological levels (generation number v1)
Define "corrected committer date" of a commit recursively as follows:
@@ -48,7 +48,7 @@ Define "corrected committer date" of a commit recursively as follows:
equal to its committer date.
* A commit with at least one parent has corrected committer date equal to
- the maximum of its commiter date and one more than the largest corrected
+ the maximum of its committer date and one more than the largest corrected
committer date among its parents.
* As a special case, a root commit with timestamp zero has corrected commit
@@ -95,7 +95,7 @@ with default order), but is not used when the topological order is
required (such as merge base calculations, "git log --graph").
In practice, we expect some commits to be created recently and not stored
-in the commit graph. We can treat these commits as having "infinite"
+in the commit-graph. We can treat these commits as having "infinite"
generation number and walk until reaching commits with known generation
number.
@@ -149,7 +149,7 @@ Design Details
helpful for these clones, anyway. The commit-graph will not be read or
written when shallow commits are present.
-Commit Graphs Chains
+Commit-Graphs Chains
--------------------
Typically, repos grow with near-constant velocity (commits per day). Over time,
diff --git a/Documentation/technical/parallel-checkout.txt b/Documentation/technical/parallel-checkout.txt
index e790258a1ad..47c9b6183cf 100644
--- a/Documentation/technical/parallel-checkout.txt
+++ b/Documentation/technical/parallel-checkout.txt
@@ -56,7 +56,7 @@ Rejected Multi-Threaded Solution
The most "straightforward" implementation would be to spread the set of
to-be-updated cache entries across multiple threads. But due to the
-thread-unsafe functions in the ODB code, we would have to use locks to
+thread-unsafe functions in the object database code, we would have to use locks to
coordinate the parallel operation. An early prototype of this solution
showed that the multi-threaded checkout would bring performance
improvements over the sequential code, but there was still too much lock
diff --git a/Documentation/technical/remembering-renames.txt b/Documentation/technical/remembering-renames.txt
index 2fd5cc88e0b..1e34d913901 100644
--- a/Documentation/technical/remembering-renames.txt
+++ b/Documentation/technical/remembering-renames.txt
@@ -20,7 +20,7 @@ Outline:
3. Why any rename on MERGE_SIDE1 in any given pick is _almost_ always also
a rename on MERGE_SIDE1 for the next pick
- 4. A detailed description of the the counter-examples to #3.
+ 4. A detailed description of the counter-examples to #3.
5. Why the special cases in #4 are still fully reasonable to use to pair
up files for three-way content merging in the merge machinery, and why
@@ -407,7 +407,7 @@ considered to be "irrelevant". See for example the following commits:
no longer relevant", 2021-03-13)
Relevance is always determined by what the _other_ side of history has
-done, in terms of modifing a file that our side renamed, or adding a
+done, in terms of modifying a file that our side renamed, or adding a
file to a directory which our side renamed. This means that a path
that is "irrelevant" when picking the first commit of a series in a
rebase or cherry-pick, may suddenly become "relevant" when picking the
diff --git a/Documentation/technical/scalar.txt b/Documentation/technical/scalar.txt
index 0600150b3ad..921cb104c3c 100644
--- a/Documentation/technical/scalar.txt
+++ b/Documentation/technical/scalar.txt
@@ -64,64 +64,3 @@ some "global" `git` options (e.g., `-c` and `-C`).
Because `scalar` is not invoked as a Git subcommand (like `git scalar`), it is
built and installed as its own executable in the `bin/` directory, alongside
`git`, `git-gui`, etc.
-
-Roadmap
--------
-
-NOTE: this section will be removed once the remaining tasks outlined in this
-roadmap are complete.
-
-Scalar is a large enough project that it is being upstreamed incrementally,
-living in `contrib/` until it is feature-complete. So far, the following patch
-series have been accepted:
-
-- `scalar-the-beginning`: The initial patch series which sets up
- `contrib/scalar/` and populates it with a minimal `scalar` command that
- demonstrates the fundamental ideas.
-
-- `scalar-c-and-C`: The `scalar` command learns about two options that can be
- specified before the command, `-c <key>=<value>` and `-C <directory>`.
-
-- `scalar-diagnose`: The `scalar` command is taught the `diagnose` subcommand.
-
-- `scalar-generalize-diagnose`: Move the functionality of `scalar diagnose`
- into `git diagnose` and `git bugreport --diagnose`.
-
-- 'scalar-add-fsmonitor: Enable the built-in FSMonitor in Scalar
- enlistments. At the end of this series, Scalar should be feature-complete
- from the perspective of a user.
-
-Roughly speaking (and subject to change), the following series are needed to
-"finish" this initial version of Scalar:
-
-- Move Scalar to toplevel: Move Scalar out of `contrib/` and into the root of
- `git`. This includes a variety of related updates, including:
- - building & installing Scalar in the Git root-level 'make [install]'.
- - builing & testing Scalar as part of CI.
- - moving and expanding test coverage of Scalar (including perf tests).
- - implementing 'scalar help'/'git help scalar' to display scalar
- documentation.
-
-Finally, there are two additional patch series that exist in Microsoft's fork of
-Git, but there is no current plan to upstream them. There are some interesting
-ideas there, but the implementation is too specific to Azure Repos and/or VFS
-for Git to be of much help in general.
-
-These still exist mainly because the GVFS protocol is what Azure Repos has
-instead of partial clone, while Git is focused on improving partial clone:
-
-- `scalar-with-gvfs`: The primary purpose of this patch series is to support
- existing Scalar users whose repositories are hosted in Azure Repos (which does
- not support Git's partial clones, but supports its predecessor, the GVFS
- protocol, which is used by Scalar to emulate the partial clone).
-
- Since the GVFS protocol will never be supported by core Git, this patch series
- will remain in Microsoft's fork of Git.
-
-- `run-scalar-functional-tests`: The Scalar project developed a quite
- comprehensive set of integration tests (or, "Functional Tests"). They are the
- sole remaining part of the original C#-based Scalar project, and this patch
- adds a GitHub workflow that runs them all.
-
- Since the tests partially depend on features that are only provided in the
- `scalar-with-gvfs` patch series, this patch cannot be upstreamed.
diff --git a/Documentation/technical/sparse-checkout.txt b/Documentation/technical/sparse-checkout.txt
new file mode 100644
index 00000000000..fa0d01cbda4
--- /dev/null
+++ b/Documentation/technical/sparse-checkout.txt
@@ -0,0 +1,1103 @@
+Table of contents:
+
+ * Terminology
+ * Purpose of sparse-checkouts
+ * Usecases of primary concern
+ * Oversimplified mental models ("Cliff Notes" for this document!)
+ * Desired behavior
+ * Behavior classes
+ * Subcommand-dependent defaults
+ * Sparse specification vs. sparsity patterns
+ * Implementation Questions
+ * Implementation Goals/Plans
+ * Known bugs
+ * Reference Emails
+
+
+=== Terminology ===
+
+cone mode: one of two modes for specifying the desired subset of files
+ in a sparse-checkout. In cone-mode, the user specifies
+ directories (getting both everything under that directory as
+ well as everything in leading directories), while in non-cone
+ mode, the user specifies gitignore-style patterns. Controlled
+ by the --[no-]cone option to sparse-checkout init|set.
+
+SKIP_WORKTREE: When tracked files do not match the sparse specification and
+ are removed from the working tree, the file in the index is marked
+ with a SKIP_WORKTREE bit. Note that if a tracked file has the
+ SKIP_WORKTREE bit set but the file is later written by the user to
+ the working tree anyway, the SKIP_WORKTREE bit will be cleared at
+ the beginning of any subsequent Git operation.
+
+ Most sparse checkout users are unaware of this implementation
+ detail, and the term should generally be avoided in user-facing
+ descriptions and command flags. Unfortunately, prior to the
+ `sparse-checkout` subcommand this low-level detail was exposed,
+ and as of time of writing, is still exposed in various places.
+
+sparse-checkout: a subcommand in git used to reduce the files present in
+ the working tree to a subset of all tracked files. Also, the
+ name of the file in the $GIT_DIR/info directory used to track
+ the sparsity patterns corresponding to the user's desired
+ subset.
+
+sparse cone: see cone mode
+
+sparse directory: An entry in the index corresponding to a directory, which
+ appears in the index instead of all the files under that directory
+ that would normally appear. See also sparse-index. Something that
+ can cause confusion is that the "sparse directory" does NOT match
+ the sparse specification, i.e. the directory is NOT present in the
+ working tree. May be renamed in the future (e.g. to "skipped
+ directory").
+
+sparse index: A special mode for sparse-checkout that also makes the
+ index sparse by recording a directory entry in lieu of all the
+ files underneath that directory (thus making that a "skipped
+ directory" which unfortunately has also been called a "sparse
+ directory"), and does this for potentially multiple
+ directories. Controlled by the --[no-]sparse-index option to
+ init|set|reapply.
+
+sparsity patterns: patterns from $GIT_DIR/info/sparse-checkout used to
+ define the set of files of interest. A warning: It is easy to
+ over-use this term (or the shortened "patterns" term), for two
+ reasons: (1) users in cone mode specify directories rather than
+ patterns (their directories are transformed into patterns, but
+ users may think you are talking about non-cone mode if you use the
+ word "patterns"), and (b) the sparse specification might
+ transiently differ in the working tree or index from the sparsity
+ patterns (see "Sparse specification vs. sparsity patterns").
+
+sparse specification: The set of paths in the user's area of focus. This
+ is typically just the tracked files that match the sparsity
+ patterns, but the sparse specification can temporarily differ and
+ include additional files. (See also "Sparse specification
+ vs. sparsity patterns")
+
+ * When working with history, the sparse specification is exactly
+ the set of files matching the sparsity patterns.
+ * When interacting with the working tree, the sparse specification
+ is the set of tracked files with a clear SKIP_WORKTREE bit or
+ tracked files present in the working copy.
+ * When modifying or showing results from the index, the sparse
+ specification is the set of files with a clear SKIP_WORKTREE bit
+ or that differ in the index from HEAD.
+ * If working with the index and the working copy, the sparse
+ specification is the union of the paths from above.
+
+vivifying: When a command restores a tracked file to the working tree (and
+ hopefully also clears the SKIP_WORKTREE bit in the index for that
+ file), this is referred to as "vivifying" the file.
+
+
+=== Purpose of sparse-checkouts ===
+
+sparse-checkouts exist to allow users to work with a subset of their
+files.
+
+You can think of sparse-checkouts as subdividing "tracked" files into two
+categories -- a sparse subset, and all the rest. Implementationally, we
+mark "all the rest" in the index with a SKIP_WORKTREE bit and leave them
+out of the working tree. The SKIP_WORKTREE files are still tracked, just
+not present in the working tree.
+
+In the past, sparse-checkouts were defined by "SKIP_WORKTREE means the file
+is missing from the working tree but pretend the file contents match HEAD".
+That was not only bogus (it actually meant the file missing from the
+working tree matched the index rather than HEAD), but it was also a
+low-level detail which only provided decent behavior for a few commands.
+There were a surprising number of ways in which that guiding principle gave
+command results that violated user expectations, and as such was a bad
+mental model. However, it persisted for many years and may still be found
+in some corners of the code base.
+
+Anyway, the idea of "working with a subset of files" is simple enough, but
+there are multiple different high-level usecases which affect how some Git
+subcommands should behave. Further, even if we only considered one of
+those usecases, sparse-checkouts can modify different subcommands in over a
+half dozen different ways. Let's start by considering the high level
+usecases:
+
+ A) Users are _only_ interested in the sparse portion of the repo
+
+ A*) Users are _only_ interested in the sparse portion of the repo
+ that they have downloaded so far
+
+ B) Users want a sparse working tree, but are working in a larger whole
+
+ C) sparse-checkout is a behind-the-scenes implementation detail allowing
+ Git to work with a specially crafted in-house virtual file system;
+ users are actually working with a "full" working tree that is
+ lazily populated, and sparse-checkout helps with the lazy population
+ piece.
+
+It may be worth explaining each of these in a bit more detail:
+
+
+ (Behavior A) Users are _only_ interested in the sparse portion of the repo
+
+These folks might know there are other things in the repository, but
+don't care. They are uninterested in other parts of the repository, and
+only want to know about changes within their area of interest. Showing
+them other files from history (e.g. from diff/log/grep/etc.) is a
+usability annoyance, potentially a huge one since other changes in
+history may dwarf the changes they are interested in.
+
+Some of these users also arrive at this usecase from wanting to use partial
+clones together with sparse checkouts (in a way where they have downloaded
+blobs within the sparse specification) and do disconnected development.
+Not only do these users generally not care about other parts of the
+repository, but consider it a blocker for Git commands to try to operate on
+those. If commands attempt to access paths in history outside the sparsity
+specification, then the partial clone will attempt to download additional
+blobs on demand, fail, and then fail the user's command. (This may be
+unavoidable in some cases, e.g. when `git merge` has non-trivial changes to
+reconcile outside the sparse specification, but we should limit how often
+users are forced to connect to the network.)
+
+Also, even for users using partial clones that do not mind being
+always connected to the network, the need to download blobs as
+side-effects of various other commands (such as the printed diffstat
+after a merge or pull) can lead to worries about local repository size
+growing unnecessarily[10].
+
+ (Behavior A*) Users are _only_ interested in the sparse portion of the repo
+ that they have downloaded so far (a variant on the first usecase)
+
+This variant is driven by folks who using partial clones together with
+sparse checkouts and do disconnected development (so far sounding like a
+subset of behavior A users) and doing so on very large repositories. The
+reason for yet another variant is that downloading even just the blobs
+through history within their sparse specification may be too much, so they
+only download some. They would still like operations to succeed without
+network connectivity, though, so things like `git log -S${SEARCH_TERM} -p`
+or `git grep ${SEARCH_TERM} OLDREV ` would need to be prepared to provide
+partial results that depend on what happens to have been downloaded.
+
+This variant could be viewed as Behavior A with the sparse specification
+for history querying operations modified from "sparsity patterns" to
+"sparsity patterns limited to the blobs we have already downloaded".
+
+ (Behavior B) Users want a sparse working tree, but are working in a
+ larger whole
+
+Stolee described this usecase this way[11]:
+
+"I'm also focused on users that know that they are a part of a larger
+whole. They know they are operating on a large repository but focus on
+what they need to contribute their part. I expect multiple "roles" to
+use very different, almost disjoint parts of the codebase. Some other
+"architect" users operate across the entire tree or hop between different
+sections of the codebase as necessary. In this situation, I'm wary of
+scoping too many features to the sparse-checkout definition, especially
+"git log," as it can be too confusing to have their view of the codebase
+depend on your "point of view."
+
+People might also end up wanting behavior B due to complex inter-project
+dependencies. The initial attempts to use sparse-checkouts usually involve
+the directories you are directly interested in plus what those directories
+depend upon within your repository. But there's a monkey wrench here: if
+you have integration tests, they invert the hierarchy: to run integration
+tests, you need not only what you are interested in and its in-tree
+dependencies, you also need everything that depends upon what you are
+interested in or that depends upon one of your dependencies...AND you need
+all the in-tree dependencies of that expanded group. That can easily
+change your sparse-checkout into a nearly dense one.
+
+Naturally, that tends to kill the benefits of sparse-checkouts. There are
+a couple solutions to this conundrum: either avoid grabbing in-repo
+dependencies (maybe have built versions of your in-repo dependencies pulled
+from a CI cache somewhere), or say that users shouldn't run integration
+tests directly and instead do it on the CI server when they submit a code
+review. Or do both. Regardless of whether you stub out your in-repo
+dependencies or stub out the things that depend upon you, there is
+certainly a reason to want to query and be aware of those other stubbed-out
+parts of the repository, particularly when the dependencies are complex or
+change relatively frequently. Thus, for such uses, sparse-checkouts can be
+used to limit what you directly build and modify, but these users do not
+necessarily want their sparse checkout paths to limit their queries of
+versions in history.
+
+Some people may also be interested in behavior B over behavior A simply as
+a performance workaround: if they are using non-cone mode, then they have
+to deal with its inherent quadratic performance problems. In that mode,
+every operation that checks whether paths match the sparsity specification
+can be expensive. As such, these users may only be willing to pay for
+those expensive checks when interacting with the working copy, and may
+prefer getting "unrelated" results from their history queries over having
+slow commands.
+
+ (Behavior C) sparse-checkout is an implementational detail supporting a
+ special VFS.
+
+This usecase goes slightly against the traditional definition of
+sparse-checkout in that it actually tries to present a full or dense
+checkout to the user. However, this usecase utilizes the same underlying
+technical underpinnings in a new way which does provide some performance
+advantages to users. The basic idea is that a company can have an in-house
+Git-aware Virtual File System which pretends all files are present in the
+working tree, by intercepting all file system accesses and using those to
+fetch and write accessed files on demand via partial clones. The VFS uses
+sparse-checkout to prevent Git from writing or paying attention to many
+files, and manually updates the sparse checkout patterns itself based on
+user access and modification of files in the working tree. See commit
+ecc7c8841d ("repo_read_index: add config to expect files outside sparse
+patterns", 2022-02-25) and the link at [17] for a more detailed description
+of such a VFS.
+
+The biggest difference here is that users are completely unaware that the
+sparse-checkout machinery is even in use. The sparse patterns are not
+specified by the user but rather are under the complete control of the VFS
+(and the patterns are updated frequently and dynamically by it). The user
+will perceive the checkout as dense, and commands should thus behave as if
+all files are present.
+
+
+=== Usecases of primary concern ===
+
+Most of the rest of this document will focus on Behavior A and Behavior
+B. Some notes about the other two cases and why we are not focusing on
+them:
+
+ (Behavior A*)
+
+Supporting this usecase is estimated to be difficult and a lot of work.
+There are no plans to implement it currently, but it may be a potential
+future alternative. Knowing about the existence of additional alternatives
+may affect our choice of command line flags (e.g. if we need tri-state or
+quad-state flags rather than just binary flags), so it was still important
+to at least note.
+
+Further, I believe the descriptions below for Behavior A are probably still
+valid for this usecase, with the only exception being that it redefines the
+sparse specification to restrict it to already-downloaded blobs. The hard
+part is in making commands capable of respecting that modified definition.
+
+ (Behavior C)
+
+This usecase violates some of the early sparse-checkout documented
+assumptions (since files marked as SKIP_WORKTREE will be displayed to users
+as present in the working tree). That violation may mean various
+sparse-checkout related behaviors are not well suited to this usecase and
+we may need tweaks -- to both documentation and code -- to handle it.
+However, this usecase is also perhaps the simplest model to support in that
+everything behaves like a dense checkout with a few exceptions (e.g. branch
+checkouts and switches write fewer things, knowing the VFS will lazily
+write the rest on an as-needed basis).
+
+Since there is no publically available VFS-related code for folks to try,
+the number of folks who can test such a usecase is limited.
+
+The primary reason to note the Behavior C usecase is that as we fix things
+to better support Behaviors A and B, there may be additional places where
+we need to make tweaks allowing folks in this usecase to get the original
+non-sparse treatment. For an example, see ecc7c8841d ("repo_read_index:
+add config to expect files outside sparse patterns", 2022-02-25). The
+secondary reason to note Behavior C, is so that folks taking advantage of
+Behavior C do not assume they are part of the Behavior B camp and propose
+patches that break things for the real Behavior B folks.
+
+
+=== Oversimplified mental models ===
+
+An oversimplification of the differences in the above behaviors is:
+
+ Behavior A: Restrict worktree and history operations to sparse specification
+ Behavior B: Restrict worktree operations to sparse specification; have any
+ history operations work across all files
+ Behavior C: Do not restrict either worktree or history operations to the
+ sparse specification...with the exception of branch checkouts or
+ switches which avoid writing files that will match the index so
+ they can later lazily be populated instead.
+
+
+=== Desired behavior ===
+
+As noted previously, despite the simple idea of just working with a subset
+of files, there are a range of different behavioral changes that need to be
+made to different subcommands to work well with such a feature. See
+[1,2,3,4,5,6,7,8,9,10] for various examples. In particular, at [2], we saw
+that mere composition of other commands that individually worked correctly
+in a sparse-checkout context did not imply that the higher level command
+would work correctly; it sometimes requires further tweaks. So,
+understanding these differences can be beneficial.
+
+* Commands behaving the same regardless of high-level use-case
+
+ * commands that only look at files within the sparsity specification
+
+ * diff (without --cached or REVISION arguments)
+ * grep (without --cached or REVISION arguments)
+ * diff-files
+
+ * commands that restore files to the working tree that match sparsity
+ patterns, and remove unmodified files that don't match those
+ patterns:
+
+ * switch
+ * checkout (the switch-like half)
+ * read-tree
+ * reset --hard
+
+ * commands that write conflicted files to the working tree, but otherwise
+ will omit writing files to the working tree that do not match the
+ sparsity patterns:
+
+ * merge
+ * rebase
+ * cherry-pick
+ * revert
+
+ * `am` and `apply --cached` should probably be in this section but
+ are buggy (see the "Known bugs" section below)
+
+ The behavior for these commands somewhat depends upon the merge
+ strategy being used:
+ * `ort` behaves as described above
+ * `recursive` tries to not vivify files unnecessarily, but does sometimes
+ vivify files without conflicts.
+ * `octopus` and `resolve` will always vivify any file changed in the merge
+ relative to the first parent, which is rather suboptimal.
+
+ It is also important to note that these commands WILL update the index
+ outside the sparse specification relative to when the operation began,
+ BUT these commands often make a commit just before or after such that
+ by the end of the operation there is no change to the index outside the
+ sparse specification. Of course, if the operation hits conflicts or
+ does not make a commit, then these operations clearly can modify the
+ index outside the sparse specification.
+
+ Finally, it is important to note that at least the first four of these
+ commands also try to remove differences between the sparse
+ specification and the sparsity patterns (much like the commands in the
+ previous section).
+
+ * commands that always ignore sparsity since commits must be full-tree
+
+ * archive
+ * bundle
+ * commit
+ * format-patch
+ * fast-export
+ * fast-import
+ * commit-tree
+
+ * commands that write any modified file to the working tree (conflicted
+ or not, and whether those paths match sparsity patterns or not):
+
+ * stash
+ * apply (without `--index` or `--cached`)
+
+* Commands that may slightly differ for behavior A vs. behavior B:
+
+ Commands in this category behave mostly the same between the two
+ behaviors, but may differ in verbosity and types of warning and error
+ messages.
+
+ * commands that make modifications to which files are tracked:
+ * add
+ * rm
+ * mv
+ * update-index
+
+ The fact that files can move between the 'tracked' and 'untracked'
+ categories means some commands will have to treat untracked files
+ differently. But if we have to treat untracked files differently,
+ then additional commands may also need changes:
+
+ * status
+ * clean
+
+ In particular, `status` may need to report any untracked files outside
+ the sparsity specification as an erroneous condition (especially to
+ avoid the user trying to `git add` them, forcing `git add` to display
+ an error).
+
+ It's not clear to me exactly how (or even if) `clean` would change,
+ but it's the other command that also affects untracked files.
+
+ `update-index` may be slightly special. Its --[no-]skip-worktree flag
+ may need to ignore the sparse specification by its nature. Also, its
+ current --[no-]ignore-skip-worktree-entries default is totally bogus.
+
+ * commands for manually tweaking paths in both the index and the working tree
+ * `restore`
+ * the restore-like half of `checkout`
+
+ These commands should be similar to add/rm/mv in that they should
+ only operate on the sparse specification by default, and require a
+ special flag to operate on all files.
+
+ Also, note that these commands currently have a number of issues (see
+ the "Known bugs" section below)
+
+* Commands that significantly differ for behavior A vs. behavior B:
+
+ * commands that query history
+ * diff (with --cached or REVISION arguments)
+ * grep (with --cached or REVISION arguments)
+ * show (when given commit arguments)
+ * blame (only matters when one or more -C flags are passed)
+ * and annotate
+ * log
+ * whatchanged
+ * ls-files
+ * diff-index
+ * diff-tree
+ * ls-tree
+
+ Note: for log and whatchanged, revision walking logic is unaffected
+ but displaying of patches is affected by scoping the command to the
+ sparse-checkout. (The fact that revision walking is unaffected is
+ why rev-list, shortlog, show-branch, and bisect are not in this
+ list.)
+
+ ls-files may be slightly special in that e.g. `git ls-files -t` is
+ often used to see what is sparse and what is not. Perhaps -t should
+ always work on the full tree?
+
+* Commands I don't know how to classify
+
+ * range-diff
+
+ Is this like `log` or `format-patch`?
+
+ * cherry
+
+ See range-diff
+
+* Commands unaffected by sparse-checkouts
+
+ * shortlog
+ * show-branch
+ * rev-list
+ * bisect
+
+ * branch
+ * describe
+ * fetch
+ * gc
+ * init
+ * maintenance
+ * notes
+ * pull (merge & rebase have the necessary changes)
+ * push
+ * submodule
+ * tag
+
+ * config
+ * filter-branch (works in separate checkout without sparse-checkout setup)
+ * pack-refs
+ * prune
+ * remote
+ * repack
+ * replace
+
+ * bugreport
+ * count-objects
+ * fsck
+ * gitweb
+ * help
+ * instaweb
+ * merge-tree (doesn't touch worktree or index, and merges always compute full-tree)
+ * rerere
+ * verify-commit
+ * verify-tag
+
+ * commit-graph
+ * hash-object
+ * index-pack
+ * mktag
+ * mktree
+ * multi-pack-index
+ * pack-objects
+ * prune-packed
+ * symbolic-ref
+ * unpack-objects
+ * update-ref
+ * write-tree (operates on index, possibly optimized to use sparse dir entries)
+
+ * for-each-ref
+ * get-tar-commit-id
+ * ls-remote
+ * merge-base (merges are computed full tree, so merge base should be too)
+ * name-rev
+ * pack-redundant
+ * rev-parse
+ * show-index
+ * show-ref
+ * unpack-file
+ * var
+ * verify-pack
+
+ * <Everything under 'Interacting with Others' in 'git help --all'>
+ * <Everything under 'Low-level...Syncing' in 'git help --all'>
+ * <Everything under 'Low-level...Internal Helpers' in 'git help --all'>
+ * <Everything under 'External commands' in 'git help --all'>
+
+* Commands that might be affected, but who cares?
+
+ * merge-file
+ * merge-index
+ * gitk?
+
+
+=== Behavior classes ===
+
+From the above there are a few classes of behavior:
+
+ * "restrict"
+
+ Commands in this class only read or write files in the working tree
+ within the sparse specification.
+
+ When moving to a new commit (e.g. switch, reset --hard), these commands
+ may update index files outside the sparse specification as of the start
+ of the operation, but by the end of the operation those index files
+ will match HEAD again and thus those files will again be outside the
+ sparse specification.
+
+ When paths are explicitly specified, these paths are intersected with
+ the sparse specification and will only operate on such paths.
+ (e.g. `git restore [--staged] -- '*.png'`, `git reset -p -- '*.md'`)
+
+ Some of these commands may also attempt, at the end of their operation,
+ to cull transient differences between the sparse specification and the
+ sparsity patterns (see "Sparse specification vs. sparsity patterns" for
+ details, but this basically means either removing unmodified files not
+ matching the sparsity patterns and marking those files as
+ SKIP_WORKTREE, or vivifying files that match the sparsity patterns and
+ marking those files as !SKIP_WORKTREE).
+
+ * "restrict modulo conflicts"
+
+ Commands in this class generally behave like the "restrict" class,
+ except that:
+ (1) they will ignore the sparse specification and write files with
+ conflicts to the working tree (thus temporarily expanding the
+ sparse specification to include such files.)
+ (2) they are grouped with commands which move to a new commit, since
+ they often create a commit and then move to it, even though we
+ know there are many exceptions to moving to the new commit. (For
+ example, the user may rebase a commit that becomes empty, or have
+ a cherry-pick which conflicts, or a user could run `merge
+ --no-commit`, and we also view `apply --index` kind of like `am
+ --no-commit`.) As such, these commands can make changes to index
+ files outside the sparse specification, though they'll mark such
+ files with SKIP_WORKTREE.
+
+ * "restrict also specially applied to untracked files"
+
+ Commands in this class generally behave like the "restrict" class,
+ except that they have to handle untracked files differently too, often
+ because these commands are dealing with files changing state between
+ 'tracked' and 'untracked'. Often, this may mean printing an error
+ message if the command had nothing to do, but the arguments may have
+ referred to files whose tracked-ness state could have changed were it
+ not for the sparsity patterns excluding them.
+
+ * "no restrict"
+
+ Commands in this class ignore the sparse specification entirely.
+
+ * "restrict or no restrict dependent upon behavior A vs. behavior B"
+
+ Commands in this class behave like "no restrict" for folks in the
+ behavior B camp, and like "restrict" for folks in the behavior A camp.
+ However, when behaving like "restrict" a warning of some sort might be
+ provided that history queries have been limited by the sparse-checkout
+ specification.
+
+
+=== Subcommand-dependent defaults ===
+
+Note that we have different defaults depending on the command for the
+desired behavior :
+
+ * Commands defaulting to "restrict":
+ * diff-files
+ * diff (without --cached or REVISION arguments)
+ * grep (without --cached or REVISION arguments)
+ * switch
+ * checkout (the switch-like half)
+ * reset (<commit>)
+
+ * restore
+ * checkout (the restore-like half)
+ * checkout-index
+ * reset (with pathspec)
+
+ This behavior makes sense; these interact with the working tree.
+
+ * Commands defaulting to "restrict modulo conflicts":
+ * merge
+ * rebase
+ * cherry-pick
+ * revert
+
+ * am
+ * apply --index (which is kind of like an `am --no-commit`)
+
+ * read-tree (especially with -m or -u; is kind of like a --no-commit merge)
+ * reset (<tree-ish>, due to similarity to read-tree)
+
+ These also interact with the working tree, but require slightly
+ different behavior either so that (a) conflicts can be resolved or (b)
+ because they are kind of like a merge-without-commit operation.
+
+ (See also the "Known bugs" section below regarding `am` and `apply`)
+
+ * Commands defaulting to "no restrict":
+ * archive
+ * bundle
+ * commit
+ * format-patch
+ * fast-export
+ * fast-import
+ * commit-tree
+
+ * stash
+ * apply (without `--index`)
+
+ These have completely different defaults and perhaps deserve the most
+ detailed explanation:
+
+ In the case of commands in the first group (format-patch,
+ fast-export, bundle, archive, etc.), these are commands for
+ communicating history, which will be broken if they restrict to a
+ subset of the repository. As such, they operate on full paths and
+ have no `--restrict` option for overriding. Some of these commands may
+ take paths for manually restricting what is exported, but it needs to
+ be very explicit.
+
+ In the case of stash, it needs to vivify files to avoid losing the
+ user's changes.
+
+ In the case of apply without `--index`, that command needs to update
+ the working tree without the index (or the index without the working
+ tree if `--cached` is passed), and if we restrict those updates to the
+ sparse specification then we'll lose changes from the user.
+
+ * Commands defaulting to "restrict also specially applied to untracked files":
+ * add
+ * rm
+ * mv
+ * update-index
+ * status
+ * clean (?)
+
+ Our original implementation for the first three of these commands was
+ "no restrict", but it had some severe usability issues:
+ * `git add <somefile>` if honored and outside the sparse
+ specification, can result in the file randomly disappearing later
+ when some subsequent command is run (since various commands
+ automatically clean up unmodified files outside the sparse
+ specification).
+ * `git rm '*.jpg'` could very negatively surprise users if it deletes
+ files outside the range of the user's interest.
+ * `git mv` has similar surprises when moving into or out of the cone,
+ so best to restrict by default
+
+ So, we switched `add` and `rm` to default to "restrict", which made
+ usability problems much less severe and less frequent, but we still got
+ complaints because commands like:
+ git add <file-outside-sparse-specification>
+ git rm <file-outside-sparse-specification>
+ would silently do nothing. We should instead print an error in those
+ cases to get usability right.
+
+ update-index needs to be updated to match, and status and maybe clean
+ also need to be updated to specially handle untracked paths.
+
+ There may be a difference in here between behavior A and behavior B in
+ terms of verboseness of errors or additional warnings.
+
+ * Commands falling under "restrict or no restrict dependent upon behavior
+ A vs. behavior B"
+
+ * diff (with --cached or REVISION arguments)
+ * grep (with --cached or REVISION arguments)
+ * show (when given commit arguments)
+ * blame (only matters when one or more -C flags passed)
+ * and annotate
+ * log
+ * and variants: shortlog, gitk, show-branch, whatchanged, rev-list
+ * ls-files
+ * diff-index
+ * diff-tree
+ * ls-tree
+
+ For now, we default to behavior B for these, which want a default of
+ "no restrict".
+
+ Note that two of these commands -- diff and grep -- also appeared in a
+ different list with a default of "restrict", but only when limited to
+ searching the working tree. The working tree vs. history distinction
+ is fundamental in how behavior B operates, so this is expected. Note,
+ though, that for diff and grep with --cached, when doing "restrict"
+ behavior, the difference between sparse specification and sparsity
+ patterns is important to handle.
+
+ "restrict" may make more sense as the long term default for these[12].
+ Also, supporting "restrict" for these commands might be a fair amount
+ of work to implement, meaning it might be implemented over multiple
+ releases. If that behavior were the default in the commands that
+ supported it, that would force behavior B users to need to learn to
+ slowly add additional flags to their commands, depending on git
+ version, to get the behavior they want. That gradual switchover would
+ be painful, so we should avoid it at least until it's fully
+ implemented.
+
+
+=== Sparse specification vs. sparsity patterns ===
+
+In a well-behaved situation, the sparse specification is given directly
+by the $GIT_DIR/info/sparse-checkout file. However, it can transiently
+diverge for a few reasons:
+
+ * needing to resolve conflicts (merging will vivify conflicted files)
+ * running Git commands that implicitly vivify files (e.g. "git stash apply")
+ * running Git commands that explicitly vivify files (e.g. "git checkout
+ --ignore-skip-worktree-bits FILENAME")
+ * other commands that write to these files (perhaps a user copies it
+ from elsewhere)
+
+For the last item, note that we do automatically clear the SKIP_WORKTREE
+bit for files that are present in the working tree. This has been true
+since 82386b4496 ("Merge branch 'en/present-despite-skipped'",
+2022-03-09)
+
+However, such a situation is transient because:
+
+ * Such transient differences can and will be automatically removed as
+ a side-effect of commands which call unpack_trees() (checkout,
+ merge, reset, etc.).
+ * Users can also request such transient differences be corrected via
+ running `git sparse-checkout reapply`. Various places recommend
+ running that command.
+ * Additional commands are also welcome to implicitly fix these
+ differences; we may add more in the future.
+
+While we avoid dropping unstaged changes or files which have conflicts,
+we otherwise aggressively try to fix these transient differences. If
+users want these differences to persist, they should run the `set` or
+`add` subcommands of `git sparse-checkout` to reflect their intended
+sparse specification.
+
+However, when we need to do a query on history restricted to the
+"relevant subset of files" such a transiently expanded sparse
+specification is ignored. There are a couple reasons for this:
+
+ * The behavior wanted when doing something like
+ git grep expression REVISION
+ is roughly what the users would expect from
+ git checkout REVISION && git grep expression
+ (modulo a "REVISION:" prefix), which has a couple ramifications:
+
+ * REVISION may have paths not in the current index, so there is no
+ path we can consult for a SKIP_WORKTREE setting for those paths.
+
+ * Since `checkout` is one of those commands that tries to remove
+ transient differences in the sparse specification, it makes sense
+ to use the corrected sparse specification
+ (i.e. $GIT_DIR/info/sparse-checkout) rather than attempting to
+ consult SKIP_WORKTREE anyway.
+
+So, a transiently expanded (or restricted) sparse specification applies to
+the working tree, but not to history queries where we always use the
+sparsity patterns. (See [16] for an early discussion of this.)
+
+Similar to a transiently expanded sparse specification of the working tree
+based on additional files being present in the working tree, we also need
+to consider additional files being modified in the index. In particular,
+if the user has staged changes to files (relative to HEAD) that do not
+match the sparsity patterns, and the file is not present in the working
+tree, we still want to consider the file part of the sparse specification
+if we are specifically performing a query related to the index (e.g. git
+diff --cached [REVISION], git diff-index [REVISION], git restore --staged
+--source=REVISION -- PATHS, etc.) Note that a transiently expanded sparse
+specification for the index usually only matters under behavior A, since
+under behavior B index operations are lumped with history and tend to
+operate full-tree.
+
+
+=== Implementation Questions ===
+
+ * Do the options --scope={sparse,all} sound good to others? Are there better
+ options?
+ * Names in use, or appearing in patches, or previously suggested:
+ * --sparse/--dense
+ * --ignore-skip-worktree-bits
+ * --ignore-skip-worktree-entries
+ * --ignore-sparsity
+ * --[no-]restrict-to-sparse-paths
+ * --full-tree/--sparse-tree
+ * --[no-]restrict
+ * --scope={sparse,all}
+ * --focus/--unfocus
+ * --limit/--unlimited
+ * Rationale making me lean slightly towards --scope={sparse,all}:
+ * We want a name that works for many commands, so we need a name that
+ does not conflict
+ * We know that we have more than two possible usecases, so it is best
+ to avoid a flag that appears to be binary.
+ * --scope={sparse,all} isn't overly long and seems relatively
+ explanatory
+ * `--sparse`, as used in add/rm/mv, is totally backwards for
+ grep/log/etc. Changing the meaning of `--sparse` for these
+ commands would fix the backwardness, but possibly break existing
+ scripts. Using a new name pairing would allow us to treat
+ `--sparse` in these commands as a deprecated alias.
+ * There is a different `--sparse`/`--dense` pair for commands using
+ revision machinery, so using that naming might cause confusion
+ * There is also a `--sparse` in both pack-objects and show-branch, which
+ don't conflict but do suggest that `--sparse` is overloaded
+ * The name --ignore-skip-worktree-bits is a double negative, is
+ quite a mouthful, refers to an implementation detail that many
+ users may not be familiar with, and we'd need a negation for it
+ which would probably be even more ridiculously long. (But we
+ can make --ignore-skip-worktree-bits a deprecated alias for
+ --no-restrict.)
+
+ * If a config option is added (sparse.scope?) what should the values and
+ description be? "sparse" (behavior A), "worktree-sparse-history-dense"
+ (behavior B), "dense" (behavior C)? There's a risk of confusion,
+ because even for Behaviors A and B we want some commands to be
+ full-tree and others to operate sparsely, so the wording may need to be
+ more tied to the usecases and somehow explain that. Also, right now,
+ the primary difference we are focusing is just the history-querying
+ commands (log/diff/grep). Previous config suggestion here: [13]
+
+ * Is `--no-expand` a good alias for ls-files's `--sparse` option?
+ (`--sparse` does not map to either `--scope=sparse` or `--scope=all`,
+ because in non-cone mode it does nothing and in cone-mode it shows the
+ sparse directory entries which are technically outside the sparse
+ specification)
+
+ * Under Behavior A:
+ * Does ls-files' `--no-expand` override the default `--scope=all`, or
+ does it need an extra flag?
+ * Does ls-files' `-t` option imply `--scope=all`?
+ * Does update-index's `--[no-]skip-worktree` option imply `--scope=all`?
+
+ * sparse-checkout: once behavior A is fully implemented, should we take
+ an interim measure to ease people into switching the default? Namely,
+ if folks are not already in a sparse checkout, then require
+ `sparse-checkout init/set` to take a
+ `--set-scope=(sparse|worktree-sparse-history-dense|dense)` flag (which
+ would set sparse.scope according to the setting given), and throw an
+ error if the flag is not provided? That error would be a great place
+ to warn folks that the default may change in the future, and get them
+ used to specifying what they want so that the eventual default switch
+ is seamless for them.
+
+
+=== Implementation Goals/Plans ===
+
+ * Get buy-in on this document in general.
+
+ * Figure out answers to the 'Implementation Questions' sections (above)
+
+ * Fix bugs in the 'Known bugs' section (below)
+
+ * Provide some kind of method for backfilling the blobs within the sparse
+ specification in a partial clone
+
+ [Below here is kind of spitballing since the first two haven't been resolved]
+
+ * update-index: flip the default to --no-ignore-skip-worktree-entries,
+ nuke this stupid "Oh, there's a bug? Let me add a flag to let users
+ request that they not trigger this bug." flag
+
+ * Flags & Config
+ * Make `--sparse` in add/rm/mv a deprecated alias for `--scope=all`
+ * Make `--ignore-skip-worktree-bits` in checkout-index/checkout/restore
+ a deprecated aliases for `--scope=all`
+ * Create config option (sparse.scope?), tie it to the "Cliff notes"
+ overview
+
+ * Add --scope=sparse (and --scope=all) flag to each of the history querying
+ commands. IMPORTANT: make sure diff machinery changes don't mess with
+ format-patch, fast-export, etc.
+
+=== Known bugs ===
+
+This list used to be a lot longer (see e.g. [1,2,3,4,5,6,7,8,9]), but we've
+been working on it.
+
+0. Behavior A is not well supported in Git. (Behavior B didn't used to
+ be either, but was the easier of the two to implement.)
+
+1. am and apply:
+
+ apply, without `--index` or `--cached`, relies on files being present
+ in the working copy, and also writes to them unconditionally. As
+ such, it should first check for the files' presence, and if found to
+ be SKIP_WORKTREE, then clear the bit and vivify the paths, then do
+ its work. Currently, it just throws an error.
+
+ apply, with either `--cached` or `--index`, will not preserve the
+ SKIP_WORKTREE bit. This is fine if the file has conflicts, but
+ otherwise SKIP_WORKTREE bits should be preserved for --cached and
+ probably also for --index.
+
+ am, if there are no conflicts, will vivify files and fail to preserve
+ the SKIP_WORKTREE bit. If there are conflicts and `-3` is not
+ specified, it will vivify files and then complain the patch doesn't
+ apply. If there are conflicts and `-3` is specified, it will vivify
+ files and then complain that those vivified files would be
+ overwritten by merge.
+
+2. reset --hard:
+
+ reset --hard provides confusing error message (works correctly, but
+ misleads the user into believing it didn't):
+
+ $ touch addme
+ $ git add addme
+ $ git ls-files -t
+ H addme
+ H tracked
+ S tracked-but-maybe-skipped
+ $ git reset --hard # usually works great
+ error: Path 'addme' not uptodate; will not remove from working tree.
+ HEAD is now at bdbbb6f third
+ $ git ls-files -t
+ H tracked
+ S tracked-but-maybe-skipped
+ $ ls -1
+ tracked
+
+ `git reset --hard` DID remove addme from the index and the working tree, contrary
+ to the error message, but in line with how reset --hard should behave.
+
+3. read-tree
+
+ `read-tree` doesn't apply the 'SKIP_WORKTREE' bit to *any* of the
+ entries it reads into the index, resulting in all your files suddenly
+ appearing to be "deleted".
+
+4. Checkout, restore:
+
+ These command do not handle path & revision arguments appropriately:
+
+ $ ls
+ tracked
+ $ git ls-files -t
+ H tracked
+ S tracked-but-maybe-skipped
+ $ git status --porcelain
+ $ git checkout -- '*skipped'
+ error: pathspec '*skipped' did not match any file(s) known to git
+ $ git ls-files -- '*skipped'
+ tracked-but-maybe-skipped
+ $ git checkout HEAD -- '*skipped'
+ error: pathspec '*skipped' did not match any file(s) known to git
+ $ git ls-tree HEAD | grep skipped
+ 100644 blob 276f5a64354b791b13840f02047738c77ad0584f tracked-but-maybe-skipped
+ $ git status --porcelain
+ $ git checkout HEAD~1 -- '*skipped'
+ $ git ls-files -t
+ H tracked
+ H tracked-but-maybe-skipped
+ $ git status --porcelain
+ M tracked-but-maybe-skipped
+ $ git checkout HEAD -- '*skipped'
+ $ git status --porcelain
+ $
+
+ Note that checkout without a revision (or restore --staged) fails to
+ find a file to restore from the index, even though ls-files shows
+ such a file certainly exists.
+
+ Similar issues occur with HEAD (--source=HEAD in restore's case),
+ but suddenly works when HEAD~1 is specified. And then after that it
+ will work with HEAD specified, even though it didn't before.
+
+ Directories are also an issue:
+
+ $ git sparse-checkout set nomatches
+ $ git status
+ On branch main
+ You are in a sparse checkout with 0% of tracked files present.
+
+ nothing to commit, working tree clean
+ $ git checkout .
+ error: pathspec '.' did not match any file(s) known to git
+ $ git checkout HEAD~1 .
+ Updated 1 path from 58916d9
+ $ git ls-files -t
+ S tracked
+ H tracked-but-maybe-skipped
+
+5. checkout and restore --staged, continued:
+
+ These commands do not correctly scope operations to the sparse
+ specification, and make it worse by not setting important SKIP_WORKTREE
+ bits:
+
+ $ git restore --source OLDREV --staged outside-sparse-cone/
+ $ git status --porcelain
+ MD outside-sparse-cone/file1
+ MD outside-sparse-cone/file2
+ MD outside-sparse-cone/file3
+
+ We can add a --scope=all mode to `git restore` to let it operate outside
+ the sparse specification, but then it will be important to set the
+ SKIP_WORKTREE bits appropriately.
+
+6. Performance issues; see:
+ https://lore.kernel.org/git/CABPp-BEkJQoKZsQGCYioyga_uoDQ6iBeW+FKr8JhyuuTMK1RDw@mail.gmail.com/
+
+
+=== Reference Emails ===
+
+Emails that detail various bugs we've had in sparse-checkout:
+
+[1] (Original descriptions of behavior A & behavior B)
+ https://lore.kernel.org/git/CABPp-BGJ_Nvi5TmgriD9Bh6eNXE2EDq2f8e8QKXAeYG3BxZafA@mail.gmail.com/
+[2] (Fix stash applications in sparse checkouts; bugs from behavioral differences)
+ https://lore.kernel.org/git/ccfedc7140dbf63ba26a15f93bd3885180b26517.1606861519.git.gitgitgadget@gmail.com/
+[3] (Present-despite-skipped entries)
+ https://lore.kernel.org/git/11d46a399d26c913787b704d2b7169cafc28d639.1642175983.git.gitgitgadget@gmail.com/
+[4] (Clone --no-checkout interaction)
+ https://lore.kernel.org/git/pull.801.v2.git.git.1591324899170.gitgitgadget@gmail.com/ (clone --no-checkout)
+[5] (The need for update_sparsity() and avoiding `read-tree -mu HEAD`)
+ https://lore.kernel.org/git/3a1f084641eb47515b5a41ed4409a36128913309.1585270142.git.gitgitgadget@gmail.com/
+[6] (SKIP_WORKTREE is advisory, not mandatory)
+ https://lore.kernel.org/git/844306c3e86ef67591cc086decb2b760e7d710a3.1585270142.git.gitgitgadget@gmail.com/
+[7] (`worktree add` should copy sparsity settings from current worktree)
+ https://lore.kernel.org/git/c51cb3714e7b1d2f8c9370fe87eca9984ff4859f.1644269584.git.gitgitgadget@gmail.com/
+[8] (Avoid negative surprises in add, rm, and mv)
+ https://lore.kernel.org/git/cover.1617914011.git.matheus.bernardino@usp.br/
+ https://lore.kernel.org/git/pull.1018.v4.git.1632497954.gitgitgadget@gmail.com/
+[9] (Move from out-of-cone to in-cone)
+ https://lore.kernel.org/git/20220630023737.473690-6-shaoxuan.yuan02@gmail.com/
+ https://lore.kernel.org/git/20220630023737.473690-4-shaoxuan.yuan02@gmail.com/
+[10] (Unnecessarily downloading objects outside sparse specification)
+ https://lore.kernel.org/git/CAOLTT8QfwOi9yx_qZZgyGa8iL8kHWutEED7ok_jxwTcYT_hf9Q@mail.gmail.com/
+
+[11] (Stolee's comments on high-level usecases)
+ https://lore.kernel.org/git/1a1e33f6-3514-9afc-0a28-5a6b85bd8014@gmail.com/
+
+[12] Others commenting on eventually switching default to behavior A:
+ * https://lore.kernel.org/git/xmqqh719pcoo.fsf@gitster.g/
+ * https://lore.kernel.org/git/xmqqzgeqw0sy.fsf@gitster.g/
+ * https://lore.kernel.org/git/a86af661-cf58-a4e5-0214-a67d3a794d7e@github.com/
+
+[13] Previous config name suggestion and description
+ * https://lore.kernel.org/git/CABPp-BE6zW0nJSStcVU=_DoDBnPgLqOR8pkTXK3dW11=T01OhA@mail.gmail.com/
+
+[14] Tangential issue: switch to cone mode as default sparse specification mechanism:
+ https://lore.kernel.org/git/a1b68fd6126eb341ef3637bb93fedad4309b36d0.1650594746.git.gitgitgadget@gmail.com/
+
+[15] Lengthy email on grep behavior, covering what should be searched:
+ * https://lore.kernel.org/git/CABPp-BGVO3QdbfE84uF_3QDF0-y2iHHh6G5FAFzNRfeRitkuHw@mail.gmail.com/
+
+[16] Email explaining sparsity patterns vs. SKIP_WORKTREE and history operations,
+ search for the parenthetical comment starting "We do not check".
+ https://lore.kernel.org/git/CABPp-BFsCPPNOZ92JQRJeGyNd0e-TCW-LcLyr0i_+VSQJP+GCg@mail.gmail.com/
+
+[17] https://lore.kernel.org/git/20220207190320.2960362-1-jonathantanmy@google.com/
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index ca9decdd952..dc9c6a663a9 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -3133,7 +3133,7 @@ those "loose" objects.
You can save space and make Git faster by moving these loose objects in
to a "pack file", which stores a group of objects in an efficient
compressed format; the details of how pack files are formatted can be
-found in link:gitformat-pack[5].
+found in linkgit:gitformat-pack[5].
To put the loose objects into a pack, just run git repack:
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 6ec9e34282b..e3eaeb49264 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.37.GIT
+DEF_VER=v2.38.GIT
LF='
'
diff --git a/INSTALL b/INSTALL
index 4140a3f5c8b..33447883974 100644
--- a/INSTALL
+++ b/INSTALL
@@ -133,11 +133,6 @@ Issues of note:
you are using libcurl older than 7.34.0. Otherwise you can use
NO_OPENSSL without losing git-imap-send.
- By default, git uses OpenSSL for SHA1 but it will use its own
- library (inspired by Mozilla's) with either NO_OPENSSL or
- BLK_SHA1. Also included is a version optimized for PowerPC
- (PPC_SHA1).
-
- "libcurl" library is used for fetching and pushing
repositories over http:// or https://, as well as by
git-imap-send if the curl version is >= 7.34.0. If you do
diff --git a/Makefile b/Makefile
index 17b4940568f..1a23e817768 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,20 @@ all::
# Import tree-wide shared Makefile behavior and libraries
include shared.mak
+# == Makefile defines ==
+#
+# These defines change the behavior of the Makefile itself, but have
+# no impact on what it builds:
+#
# Define V=1 to have a more verbose compile.
#
+# == Portability and optional library defines ==
+#
+# These defines indicate what Git can expect from the OS, what
+# libraries are available etc. Much of this is auto-detected in
+# config.mak.uname, or in configure.ac when using the optional "make
+# configure && ./configure" (see INSTALL).
+#
# Define SHELL_PATH to a POSIX shell if your /bin/sh is broken.
#
# Define SANE_TOOL_PATH to a colon-separated list of paths to prepend
@@ -30,68 +42,8 @@ include shared.mak
#
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
#
-# Define USE_LIBPCRE if you have and want to use libpcre. Various
-# commands such as log and grep offer runtime options to use
-# Perl-compatible regular expressions instead of standard or extended
-# POSIX regular expressions.
-#
-# Only libpcre version 2 is supported. USE_LIBPCRE2 is a synonym for
-# USE_LIBPCRE, support for the old USE_LIBPCRE1 has been removed.
-#
-# Define LIBPCREDIR=/foo/bar if your PCRE header and library files are
-# in /foo/bar/include and /foo/bar/lib directories.
-#
# Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header.
#
-# Define NO_CURL if you do not have libcurl installed. git-http-fetch and
-# git-http-push are not built, and you cannot use http:// and https://
-# transports (neither smart nor dumb).
-#
-# Define CURLDIR=/foo/bar if your curl header and library files are in
-# /foo/bar/include and /foo/bar/lib directories.
-#
-# Define CURL_CONFIG to curl's configuration program that prints information
-# about the library (e.g., its version number). The default is 'curl-config'.
-#
-# Define CURL_LDFLAGS to specify flags that you need to link when using libcurl,
-# if you do not want to rely on the libraries provided by CURL_CONFIG. The
-# default value is a result of `curl-config --libs`. An example value for
-# CURL_LDFLAGS is as follows:
-#
-# CURL_LDFLAGS=-lcurl
-#
-# Define NO_EXPAT if you do not have expat installed. git-http-push is
-# not built, and you cannot push using http:// and https:// transports (dumb).
-#
-# Define EXPATDIR=/foo/bar if your expat header and library files are in
-# /foo/bar/include and /foo/bar/lib directories.
-#
-# Define EXPAT_NEEDS_XMLPARSE_H if you have an old version of expat (e.g.,
-# 1.1 or 1.2) that provides xmlparse.h instead of expat.h.
-#
-# Define NO_GETTEXT if you don't want Git output to be translated.
-# A translated Git requires GNU libintl or another gettext implementation,
-# plus libintl-perl at runtime.
-#
-# Define USE_GETTEXT_SCHEME and set it to 'fallthrough', if you don't trust
-# the installed gettext translation of the shell scripts output.
-#
-# Define HAVE_LIBCHARSET_H if you haven't set NO_GETTEXT and you can't
-# trust the langinfo.h's nl_langinfo(CODESET) function to return the
-# current character set. GNU and Solaris have a nl_langinfo(CODESET),
-# FreeBSD can use either, but MinGW and some others need to use
-# libcharset.h's locale_charset() instead.
-#
-# Define CHARSET_LIB to the library you need to link with in order to
-# use locale_charset() function. On some platforms this needs to set to
-# -lcharset, on others to -liconv .
-#
-# Define LIBC_CONTAINS_LIBINTL if your gettext implementation doesn't
-# need -lintl when linking.
-#
-# Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
-# doesn't support GNU extensions like --check and --statistics
-#
# Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
# it specifies.
#
@@ -152,42 +104,6 @@ include shared.mak
# and do not want to use Apple's CommonCrypto library. This allows you
# to provide your own OpenSSL library, for example from MacPorts.
#
-# Define BLK_SHA1 environment variable to make use of the bundled
-# optimized C SHA1 routine.
-#
-# Define PPC_SHA1 environment variable when running make to make use of
-# a bundled SHA1 routine optimized for PowerPC.
-#
-# Define DC_SHA1 to unconditionally enable the collision-detecting sha1
-# algorithm. This is slower, but may detect attempted collision attacks.
-# Takes priority over other *_SHA1 knobs.
-#
-# Define DC_SHA1_EXTERNAL in addition to DC_SHA1 if you want to build / link
-# git with the external SHA1 collision-detect library.
-# Without this option, i.e. the default behavior is to build git with its
-# own built-in code (or submodule).
-#
-# Define DC_SHA1_SUBMODULE in addition to DC_SHA1 to use the
-# sha1collisiondetection shipped as a submodule instead of the
-# non-submodule copy in sha1dc/. This is an experimental option used
-# by the git project to migrate to using sha1collisiondetection as a
-# submodule.
-#
-# Define OPENSSL_SHA1 environment variable when running make to link
-# with the SHA1 routine from openssl library.
-#
-# Define SHA1_MAX_BLOCK_SIZE to limit the amount of data that will be hashed
-# in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO
-# wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.
-#
-# Define BLK_SHA256 to use the built-in SHA-256 routines.
-#
-# Define NETTLE_SHA256 to use the SHA-256 routines in libnettle.
-#
-# Define GCRYPT_SHA256 to use the SHA-256 routines in libgcrypt.
-#
-# Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL.
-#
# Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
#
# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
@@ -493,6 +409,151 @@ include shared.mak
# to the "<name>" of the corresponding `compat/fsmonitor/fsm-settings-<name>.c`
# that implements the `fsm_os_settings__*()` routines.
#
+# === Optional library: libintl ===
+#
+# Define NO_GETTEXT if you don't want Git output to be translated.
+# A translated Git requires GNU libintl or another gettext implementation,
+# plus libintl-perl at runtime.
+#
+# Define USE_GETTEXT_SCHEME and set it to 'fallthrough', if you don't trust
+# the installed gettext translation of the shell scripts output.
+#
+# Define HAVE_LIBCHARSET_H if you haven't set NO_GETTEXT and you can't
+# trust the langinfo.h's nl_langinfo(CODESET) function to return the
+# current character set. GNU and Solaris have a nl_langinfo(CODESET),
+# FreeBSD can use either, but MinGW and some others need to use
+# libcharset.h's locale_charset() instead.
+#
+# Define CHARSET_LIB to the library you need to link with in order to
+# use locale_charset() function. On some platforms this needs to set to
+# -lcharset, on others to -liconv .
+#
+# Define LIBC_CONTAINS_LIBINTL if your gettext implementation doesn't
+# need -lintl when linking.
+#
+# Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
+# doesn't support GNU extensions like --check and --statistics
+#
+# === Optional library: libexpat ===
+#
+# Define NO_EXPAT if you do not have expat installed. git-http-push is
+# not built, and you cannot push using http:// and https:// transports (dumb).
+#
+# Define EXPATDIR=/foo/bar if your expat header and library files are in
+# /foo/bar/include and /foo/bar/lib directories.
+#
+# Define EXPAT_NEEDS_XMLPARSE_H if you have an old version of expat (e.g.,
+# 1.1 or 1.2) that provides xmlparse.h instead of expat.h.
+
+# === Optional library: libcurl ===
+#
+# Define NO_CURL if you do not have libcurl installed. git-http-fetch and
+# git-http-push are not built, and you cannot use http:// and https://
+# transports (neither smart nor dumb).
+#
+# Define CURLDIR=/foo/bar if your curl header and library files are in
+# /foo/bar/include and /foo/bar/lib directories.
+#
+# Define CURL_CONFIG to curl's configuration program that prints information
+# about the library (e.g., its version number). The default is 'curl-config'.
+#
+# Define CURL_LDFLAGS to specify flags that you need to link when using libcurl,
+# if you do not want to rely on the libraries provided by CURL_CONFIG. The
+# default value is a result of `curl-config --libs`. An example value for
+# CURL_LDFLAGS is as follows:
+#
+# CURL_LDFLAGS=-lcurl
+#
+# === Optional library: libpcre2 ===
+#
+# Define USE_LIBPCRE if you have and want to use libpcre. Various
+# commands such as log and grep offer runtime options to use
+# Perl-compatible regular expressions instead of standard or extended
+# POSIX regular expressions.
+#
+# Only libpcre version 2 is supported. USE_LIBPCRE2 is a synonym for
+# USE_LIBPCRE, support for the old USE_LIBPCRE1 has been removed.
+#
+# Define LIBPCREDIR=/foo/bar if your PCRE header and library files are
+# in /foo/bar/include and /foo/bar/lib directories.
+#
+# == SHA-1 and SHA-256 defines ==
+#
+# === SHA-1 backend ===
+#
+# ==== Security ====
+#
+# Due to the SHAttered (https://shattered.io) attack vector on SHA-1
+# it's strongly recommended to use the sha1collisiondetection
+# counter-cryptanalysis library for SHA-1 hashing.
+#
+# If you know that you can trust the repository contents, or where
+# potential SHA-1 attacks are otherwise mitigated the other backends
+# listed in "SHA-1 implementations" are faster than
+# sha1collisiondetection.
+#
+# ==== Default SHA-1 backend ====
+#
+# If no *_SHA1 backend is picked, the first supported one listed in
+# "SHA-1 implementations" will be picked.
+#
+# ==== Options common to all SHA-1 implementations ====
+#
+# Define SHA1_MAX_BLOCK_SIZE to limit the amount of data that will be hashed
+# in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO
+# wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.
+#
+# ==== SHA-1 implementations ====
+#
+# Define OPENSSL_SHA1 to link to the SHA-1 routines from the OpenSSL
+# library.
+#
+# Define BLK_SHA1 to make use of optimized C SHA-1 routines bundled
+# with git (in the block-sha1/ directory).
+#
+# Define NO_APPLE_COMMON_CRYPTO on OSX to opt-out of using the
+# "APPLE_COMMON_CRYPTO" backend for SHA-1, which is currently the
+# default on that OS. On macOS 01.4 (Tiger) or older,
+# NO_APPLE_COMMON_CRYPTO is defined by default.
+#
+# If don't enable any of the *_SHA1 settings in this section, Git will
+# default to its built-in sha1collisiondetection library, which is a
+# collision-detecting sha1 This is slower, but may detect attempted
+# collision attacks.
+#
+# ==== Options for the sha1collisiondetection library ====
+#
+# Define DC_SHA1_EXTERNAL if you want to build / link
+# git with the external SHA1 collision-detect library.
+# Without this option, i.e. the default behavior is to build git with its
+# own built-in code (or submodule).
+#
+# Define DC_SHA1_SUBMODULE to use the
+# sha1collisiondetection shipped as a submodule instead of the
+# non-submodule copy in sha1dc/. This is an experimental option used
+# by the git project to migrate to using sha1collisiondetection as a
+# submodule.
+#
+# === SHA-256 backend ===
+#
+# ==== Security ====
+#
+# Unlike SHA-1 the SHA-256 algorithm does not suffer from any known
+# vulnerabilities, so any implementation will do.
+#
+# ==== SHA-256 implementations ====
+#
+# Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL.
+#
+# Define NETTLE_SHA256 to use the SHA-256 routines in libnettle.
+#
+# Define GCRYPT_SHA256 to use the SHA-256 routines in libgcrypt.
+#
+# If don't enable any of the *_SHA256 settings in this section, Git
+# will default to its built-in sha256 implementation.
+#
+# == DEVELOPER defines ==
+#
# Define DEVELOPER to enable more compiler warnings. Compiler version
# and family are auto detected, but could be overridden by defining
# COMPILER_FEATURES (see config.mak.dev). You can still set
@@ -532,8 +593,9 @@ GIT-VERSION-FILE: FORCE
# template_dir
# sysconfdir
# can be specified as a relative path some/where/else;
-# this is interpreted as relative to $(prefix) and "git" at
-# runtime figures out where they are based on the path to the executable.
+# this is interpreted as relative to $(prefix) and "git" built with
+# RUNTIME_PREFIX flag will figure out (at runtime) where they are
+# based on the path to the executable.
# Additionally, the following will be treated as relative by "git" if they
# begin with "$(prefix)/":
# mandir
@@ -608,7 +670,9 @@ FUZZ_OBJS =
FUZZ_PROGRAMS =
GIT_OBJS =
LIB_OBJS =
+SCALAR_OBJS =
OBJECTS =
+OTHER_PROGRAMS =
PROGRAM_OBJS =
PROGRAMS =
EXCLUDED_PROGRAMS =
@@ -689,9 +753,9 @@ SCRIPTS = $(SCRIPT_SH_GEN) \
ETAGS_TARGET = TAGS
-FUZZ_OBJS += fuzz-commit-graph.o
-FUZZ_OBJS += fuzz-pack-headers.o
-FUZZ_OBJS += fuzz-pack-idx.o
+FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
+FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
+FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
.PHONY: fuzz-objs
fuzz-objs: $(FUZZ_OBJS)
@@ -722,6 +786,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
TEST_BUILTINS_OBJS += test-advise.o
TEST_BUILTINS_OBJS += test-bitmap.o
TEST_BUILTINS_OBJS += test-bloom.o
+TEST_BUILTINS_OBJS += test-bundle-uri.o
TEST_BUILTINS_OBJS += test-chmtime.o
TEST_BUILTINS_OBJS += test-config.o
TEST_BUILTINS_OBJS += test-crontab.o
@@ -786,6 +851,7 @@ TEST_BUILTINS_OBJS += test-strcmp-offset.o
TEST_BUILTINS_OBJS += test-string-list.o
TEST_BUILTINS_OBJS += test-submodule-config.o
TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
+TEST_BUILTINS_OBJS += test-submodule.o
TEST_BUILTINS_OBJS += test-subprocess.o
TEST_BUILTINS_OBJS += test-trace2.o
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
@@ -818,13 +884,16 @@ BUILT_INS += git-show$X
BUILT_INS += git-stage$X
BUILT_INS += git-status$X
BUILT_INS += git-switch$X
+BUILT_INS += git-version$X
BUILT_INS += git-whatchanged$X
# what 'all' will build but not install in gitexecdir
-OTHER_PROGRAMS = git$X
+OTHER_PROGRAMS += git$X
+OTHER_PROGRAMS += scalar$X
# what test wrappers are needed and 'install' will install, in bindir
BINDIR_PROGRAMS_NEED_X += git
+BINDIR_PROGRAMS_NEED_X += scalar
BINDIR_PROGRAMS_NEED_X += git-receive-pack
BINDIR_PROGRAMS_NEED_X += git-shell
BINDIR_PROGRAMS_NEED_X += git-upload-archive
@@ -907,6 +976,7 @@ LIB_OBJS += blob.o
LIB_OBJS += bloom.o
LIB_OBJS += branch.o
LIB_OBJS += bulk-checkin.o
+LIB_OBJS += bundle-uri.o
LIB_OBJS += bundle.o
LIB_OBJS += cache-tree.o
LIB_OBJS += cbtree.o
@@ -1090,6 +1160,7 @@ LIB_OBJS += trace.o
LIB_OBJS += trace2.o
LIB_OBJS += trace2/tr2_cfg.o
LIB_OBJS += trace2/tr2_cmd_name.o
+LIB_OBJS += trace2/tr2_ctr.o
LIB_OBJS += trace2/tr2_dst.o
LIB_OBJS += trace2/tr2_sid.o
LIB_OBJS += trace2/tr2_sysenv.o
@@ -1098,6 +1169,7 @@ LIB_OBJS += trace2/tr2_tgt_event.o
LIB_OBJS += trace2/tr2_tgt_normal.o
LIB_OBJS += trace2/tr2_tgt_perf.o
LIB_OBJS += trace2/tr2_tls.o
+LIB_OBJS += trace2/tr2_tmr.o
LIB_OBJS += trailer.o
LIB_OBJS += transport-helper.o
LIB_OBJS += transport.o
@@ -1376,6 +1448,7 @@ BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS
endif
ifneq ($(filter leak,$(SANITIZERS)),)
BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS
+BASIC_CFLAGS += -O0
SANITIZE_LEAK = YesCompiledWithIt
endif
ifneq ($(filter address,$(SANITIZERS)),)
@@ -1480,7 +1553,6 @@ ifeq ($(uname_S),Darwin)
APPLE_COMMON_CRYPTO = YesPlease
COMPAT_CFLAGS += -DAPPLE_COMMON_CRYPTO
endif
- NO_REGEX = YesPlease
PTHREAD_LIBS =
endif
@@ -1844,6 +1916,10 @@ ifdef APPLE_COMMON_CRYPTO
SHA1_MAX_BLOCK_SIZE = 1024L*1024L*1024L
endif
+ifdef PPC_SHA1
+$(error the PPC_SHA1 flag has been removed along with the PowerPC-specific SHA-1 implementation.)
+endif
+
ifdef OPENSSL_SHA1
EXTLIBS += $(LIB_4_CRYPTO)
BASIC_CFLAGS += -DSHA1_OPENSSL
@@ -1852,15 +1928,10 @@ ifdef BLK_SHA1
LIB_OBJS += block-sha1/sha1.o
BASIC_CFLAGS += -DSHA1_BLK
else
-ifdef PPC_SHA1
- LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
- BASIC_CFLAGS += -DSHA1_PPC
-else
ifdef APPLE_COMMON_CRYPTO
COMPAT_CFLAGS += -DCOMMON_DIGEST_FOR_OPENSSL
BASIC_CFLAGS += -DSHA1_APPLE
else
- DC_SHA1 := YesPlease
BASIC_CFLAGS += -DSHA1_DC
LIB_OBJS += sha1dc_git.o
ifdef DC_SHA1_EXTERNAL
@@ -1889,7 +1960,6 @@ endif
endif
endif
endif
-endif
ifdef OPENSSL_SHA256
EXTLIBS += $(LIB_4_CRYPTO)
@@ -2078,11 +2148,13 @@ ifdef FSMONITOR_DAEMON_BACKEND
COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND
COMPAT_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o
COMPAT_OBJS += compat/fsmonitor/fsm-health-$(FSMONITOR_DAEMON_BACKEND).o
+ COMPAT_OBJS += compat/fsmonitor/fsm-ipc-$(FSMONITOR_DAEMON_BACKEND).o
endif
ifdef FSMONITOR_OS_SETTINGS
COMPAT_CFLAGS += -DHAVE_FSMONITOR_OS_SETTINGS
COMPAT_OBJS += compat/fsmonitor/fsm-settings-$(FSMONITOR_OS_SETTINGS).o
+ COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o
endif
ifeq ($(TCLTK_PATH),)
@@ -2264,7 +2336,7 @@ profile-fast: profile-clean
all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
ifneq (,$X)
- $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
+ $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
endif
all::
@@ -2587,7 +2659,12 @@ GIT_OBJS += git.o
.PHONY: git-objs
git-objs: $(GIT_OBJS)
+SCALAR_OBJS += scalar.o
+.PHONY: scalar-objs
+scalar-objs: $(SCALAR_OBJS)
+
OBJECTS += $(GIT_OBJS)
+OBJECTS += $(SCALAR_OBJS)
OBJECTS += $(PROGRAM_OBJS)
OBJECTS += $(TEST_OBJS)
OBJECTS += $(XDIFF_OBJS)
@@ -2598,10 +2675,6 @@ ifndef NO_CURL
OBJECTS += http.o http-walker.o remote-curl.o
endif
-SCALAR_SOURCES := contrib/scalar/scalar.c
-SCALAR_OBJECTS := $(SCALAR_SOURCES:c=o)
-OBJECTS += $(SCALAR_OBJECTS)
-
.PHONY: objects
objects: $(OBJECTS)
@@ -2636,13 +2709,7 @@ missing_compdb_dir =
compdb_args =
endif
-ASM_SRC := $(wildcard $(OBJECTS:o=S))
-ASM_OBJ := $(ASM_SRC:S=o)
-C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
-
-$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
- $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
-$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
+$(OBJECTS): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
%.s: %.c GIT-CFLAGS FORCE
@@ -2733,7 +2800,7 @@ $(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o GIT-LDFLAGS $(GITLIBS
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIBS)
-contrib/scalar/scalar$X: $(SCALAR_OBJECTS) GIT-LDFLAGS $(GITLIBS)
+scalar$X: scalar.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
$(filter %.o,$^) $(LIBS)
@@ -2789,8 +2856,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
--keyword=__ --keyword=N__ --keyword="__n:1,2"
MSGMERGE_FLAGS = --add-location --backup=off --update
-LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(SCALAR_SOURCES) \
- $(GENERATED_H))
+LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(GENERATED_H))
LOCALIZED_SH = $(sort $(SCRIPT_SH) git-sh-setup.sh)
LOCALIZED_PERL = $(sort $(SCRIPT_PERL))
@@ -3025,9 +3091,9 @@ GIT-BUILD-OPTIONS: FORCE
@echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@+
@echo NO_PTHREADS=\''$(subst ','\'',$(subst ','\'',$(NO_PTHREADS)))'\' >>$@+
@echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@+
+ @echo NO_REGEX=\''$(subst ','\'',$(subst ','\'',$(NO_REGEX)))'\' >>$@+
@echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
@echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
- @echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
@echo SANITIZE_LEAK=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_LEAK)))'\' >>$@+
@echo SANITIZE_ADDRESS=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_ADDRESS)))'\' >>$@+
@echo X=\'$(X)\' >>$@+
@@ -3104,7 +3170,7 @@ bin-wrappers/%: wrap-for-bin.sh
$(call mkdir_p_parent_template)
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@@BUILD_DIR@@|$(shell pwd)|' \
- -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
+ -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))$(if $(filter-out $(BINDIR_PROGRAMS_NO_X),$(@F)),$(X),)|' < $< > $@ && \
chmod +x $@
# GNU make supports exporting all variables by "export" without parameters.
@@ -3134,7 +3200,7 @@ t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB)
check-sha1:: t/helper/test-tool$X
t/helper/test-sha1.sh
-SP_OBJ = $(patsubst %.o,%.sp,$(C_OBJ))
+SP_OBJ = $(patsubst %.o,%.sp,$(OBJECTS))
$(SP_OBJ): %.sp: %.c %.o
$(QUIET_SP)cgcc -no-compile $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) \
@@ -3400,14 +3466,14 @@ ifndef NO_TCLTK
$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
endif
ifneq (,$X)
- $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) git$X)), test '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p' -ef '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p$X' || $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
+ $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p' -ef '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p$X' || $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
endif
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \
{ test "$$bindir/" = "$$execdir/" || \
- for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \
+ for p in $(OTHER_PROGRAMS) $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \
$(RM) "$$execdir/$$p" && \
test -n "$(INSTALL_SYMLINKS)" && \
ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" "$$execdir/$$p" || \
@@ -3583,7 +3649,7 @@ clean: profile-clean coverage-clean cocciclean
$(RM) git.res
$(RM) $(OBJECTS)
$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)
- $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
+ $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)
$(RM) $(TEST_PROGRAMS)
$(RM) $(FUZZ_PROGRAMS)
$(RM) $(SP_OBJ)
@@ -3634,6 +3700,7 @@ ALL_COMMANDS += git-citool
ALL_COMMANDS += git-gui
ALL_COMMANDS += gitk
ALL_COMMANDS += gitweb
+ALL_COMMANDS += scalar
.PHONY: check-docs
check-docs::
diff --git a/RelNotes b/RelNotes
index d505db645be..758368388a4 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.38.0.txt \ No newline at end of file
+Documentation/RelNotes/2.39.0.txt \ No newline at end of file
diff --git a/add-interactive.c b/add-interactive.c
index 22fcd3412ca..ecc5ae1b249 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -430,7 +430,7 @@ struct pathname_entry {
struct file_item *item;
};
-static int pathname_entry_cmp(const void *unused_cmp_data,
+static int pathname_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *he1,
const struct hashmap_entry *he2,
const void *name)
@@ -997,18 +997,17 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps,
count = list_and_choose(s, files, opts);
opts->flags = 0;
if (count > 0) {
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&args, "git", "diff", "-p", "--cached",
+ strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached",
oid_to_hex(!is_initial ? &oid :
s->r->hash_algo->empty_tree),
"--", NULL);
for (i = 0; i < files->items.nr; i++)
if (files->selected[i])
- strvec_push(&args,
+ strvec_push(&cmd.args,
files->items.items[i].string);
- res = run_command_v_opt(args.v, 0);
- strvec_clear(&args);
+ res = run_command(&cmd);
}
putchar('\n');
diff --git a/add-patch.c b/add-patch.c
index 509ca04456b..33ecd8398a1 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -191,10 +191,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -213,10 +213,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -238,6 +238,7 @@ struct hunk_header {
* include the newline.
*/
size_t extra_start, extra_end, colored_extra_start, colored_extra_end;
+ unsigned suppress_colored_line_range:1;
};
struct hunk {
@@ -358,15 +359,14 @@ static int parse_hunk_header(struct add_p_state *s, struct hunk *hunk)
if (!eol)
eol = s->colored.buf + s->colored.len;
p = memmem(line, eol - line, "@@ -", 4);
- if (!p)
- return error(_("could not parse colored hunk header '%.*s'"),
- (int)(eol - line), line);
- p = memmem(p + 4, eol - p - 4, " @@", 3);
- if (!p)
- return error(_("could not parse colored hunk header '%.*s'"),
- (int)(eol - line), line);
+ if (p && (p = memmem(p + 4, eol - p - 4, " @@", 3))) {
+ header->colored_extra_start = p + 3 - s->colored.buf;
+ } else {
+ /* could not parse colored hunk header, leave as-is */
+ header->colored_extra_start = hunk->colored_start;
+ header->suppress_colored_line_range = 1;
+ }
hunk->colored_start = eol - s->colored.buf + (*eol == '\n');
- header->colored_extra_start = p + 3 - s->colored.buf;
header->colored_extra_end = hunk->colored_start;
return 0;
@@ -419,7 +419,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
}
color_arg_index = args.nr;
/* Use `--no-color` explicitly, just in case `diff.color = always`. */
- strvec_pushl(&args, "--no-color", "-p", "--", NULL);
+ strvec_pushl(&args, "--no-color", "--ignore-submodules=dirty", "-p",
+ "--", NULL);
for (i = 0; i < ps->nr; i++)
strvec_push(&args, ps->items[i].original);
@@ -592,7 +593,10 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
if (colored_eol)
colored_p = colored_eol + 1;
else if (p != pend)
- /* colored shorter than non-colored? */
+ /* non-colored has more lines? */
+ goto mismatched_output;
+ else if (colored_p == colored_pend)
+ /* last line has no matching colored one? */
goto mismatched_output;
else
colored_p = colored_pend;
@@ -656,6 +660,15 @@ static void render_hunk(struct add_p_state *s, struct hunk *hunk,
if (!colored) {
p = s->plain.buf + header->extra_start;
len = header->extra_end - header->extra_start;
+ } else if (header->suppress_colored_line_range) {
+ strbuf_add(out,
+ s->colored.buf + header->colored_extra_start,
+ header->colored_extra_end -
+ header->colored_extra_start);
+
+ strbuf_add(out, s->colored.buf + hunk->colored_start,
+ hunk->colored_end - hunk->colored_start);
+ return;
} else {
strbuf_addstr(out, s->s.fraginfo_color);
p = s->colored.buf + header->colored_extra_start;
@@ -1547,7 +1560,7 @@ soft_increment:
strbuf_remove(&s->answer, 0, 1);
strbuf_trim(&s->answer);
i = hunk_index - DISPLAY_HUNKS_LINES / 2;
- if (i < file_diff->mode_change)
+ if (i < (int)file_diff->mode_change)
i = file_diff->mode_change;
while (s->answer.len == 0) {
i = display_hunks(s, file_diff, i);
diff --git a/advice.c b/advice.c
index 6fda9edbc24..fd189689437 100644
--- a/advice.c
+++ b/advice.c
@@ -261,3 +261,22 @@ void detach_advice(const char *new_name)
fprintf(stderr, fmt, new_name);
}
+
+void advise_on_moving_dirty_path(struct string_list *pathspec_list)
+{
+ struct string_list_item *item;
+
+ if (!pathspec_list->nr)
+ return;
+
+ fprintf(stderr, _("The following paths have been moved outside the\n"
+ "sparse-checkout definition but are not sparse due to local\n"
+ "modifications.\n"));
+ for_each_string_list_item(item, pathspec_list)
+ fprintf(stderr, "%s\n", item->string);
+
+ advise_if_enabled(ADVICE_UPDATE_SPARSE_PATH,
+ _("To correct the sparsity of these paths, do the following:\n"
+ "* Use \"git add --sparse <paths>\" to update the index\n"
+ "* Use \"git sparse-checkout reapply\" to apply the sparsity rules"));
+}
diff --git a/advice.h b/advice.h
index 7ddc6cbc1ac..07e0f76833e 100644
--- a/advice.h
+++ b/advice.h
@@ -74,5 +74,6 @@ void NORETURN die_conclude_merge(void);
void NORETURN die_ff_impossible(void);
void advise_on_updating_sparse_paths(struct string_list *pathspec_list);
void detach_advice(const char *new_name);
+void advise_on_moving_dirty_path(struct string_list *pathspec_list);
#endif /* ADVICE_H */
diff --git a/alias.c b/alias.c
index c4715380205..00abde08173 100644
--- a/alias.c
+++ b/alias.c
@@ -46,14 +46,16 @@ void list_aliases(struct string_list *list)
#define SPLIT_CMDLINE_BAD_ENDING 1
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
+#define SPLIT_CMDLINE_ARGC_OVERFLOW 3
static const char *split_cmdline_errors[] = {
N_("cmdline ends with \\"),
- N_("unclosed quote")
+ N_("unclosed quote"),
+ N_("too many arguments"),
};
int split_cmdline(char *cmdline, const char ***argv)
{
- int src, dst, count = 0, size = 16;
+ size_t src, dst, count = 0, size = 16;
char quoted = 0;
ALLOC_ARRAY(*argv, size);
@@ -96,6 +98,11 @@ int split_cmdline(char *cmdline, const char ***argv)
return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
}
+ if (count >= INT_MAX) {
+ FREE_AND_NULL(*argv);
+ return -SPLIT_CMDLINE_ARGC_OVERFLOW;
+ }
+
ALLOC_GROW(*argv, count + 1, size);
(*argv)[count] = NULL;
diff --git a/apply.c b/apply.c
index 2b7cd930efa..bc338143134 100644
--- a/apply.c
+++ b/apply.c
@@ -125,7 +125,7 @@ void clear_apply_state(struct apply_state *state)
/* &state->fn_table is cleared at the end of apply_patch() */
}
-static void mute_routine(const char *msg, va_list params)
+static void mute_routine(const char *msg UNUSED, va_list params UNUSED)
{
/* do nothing */
}
@@ -386,9 +386,19 @@ static void say_patch_name(FILE *output, const char *fmt, struct patch *patch)
#define SLOP (16)
+/*
+ * apply.c isn't equipped to handle arbitrarily large patches, because
+ * it intermingles `unsigned long` with `int` for the type used to store
+ * buffer lengths.
+ *
+ * Only process patches that are just shy of 1 GiB large in order to
+ * avoid any truncation or overflow issues.
+ */
+#define MAX_APPLY_SIZE (1024UL * 1024 * 1023)
+
static int read_patch_file(struct strbuf *sb, int fd)
{
- if (strbuf_read(sb, fd, 0) < 0)
+ if (strbuf_read(sb, fd, 0) < 0 || sb->len >= MAX_APPLY_SIZE)
return error_errno("git apply: failed to read");
/*
@@ -892,9 +902,9 @@ static int parse_traditional_patch(struct apply_state *state,
return 0;
}
-static int gitdiff_hdrend(struct gitdiff_data *state,
- const char *line,
- struct patch *patch)
+static int gitdiff_hdrend(struct gitdiff_data *state UNUSED,
+ const char *line UNUSED,
+ struct patch *patch UNUSED)
{
return 1;
}
@@ -1044,7 +1054,7 @@ static int gitdiff_renamedst(struct gitdiff_data *state,
return 0;
}
-static int gitdiff_similarity(struct gitdiff_data *state,
+static int gitdiff_similarity(struct gitdiff_data *state UNUSED,
const char *line,
struct patch *patch)
{
@@ -1054,7 +1064,7 @@ static int gitdiff_similarity(struct gitdiff_data *state,
return 0;
}
-static int gitdiff_dissimilarity(struct gitdiff_data *state,
+static int gitdiff_dissimilarity(struct gitdiff_data *state UNUSED,
const char *line,
struct patch *patch)
{
@@ -1104,9 +1114,9 @@ static int gitdiff_index(struct gitdiff_data *state,
* This is normal for a diff that doesn't change anything: we'll fall through
* into the next diff. Tell the parser to break out.
*/
-static int gitdiff_unrecognized(struct gitdiff_data *state,
- const char *line,
- struct patch *patch)
+static int gitdiff_unrecognized(struct gitdiff_data *state UNUSED,
+ const char *line UNUSED,
+ struct patch *patch UNUSED)
{
return 1;
}
diff --git a/archive-tar.c b/archive-tar.c
index 3d77e0f7509..f8fad2946ef 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -366,7 +366,8 @@ static struct archiver *find_tar_filter(const char *name, size_t len)
return NULL;
}
-static int tar_filter_config(const char *var, const char *value, void *data)
+static int tar_filter_config(const char *var, const char *value,
+ void *data UNUSED)
{
struct archiver *ar;
const char *name;
@@ -420,7 +421,7 @@ static int git_tar_config(const char *var, const char *value, void *cb)
return tar_filter_config(var, value, cb);
}
-static int write_tar_archive(const struct archiver *ar,
+static int write_tar_archive(const struct archiver *ar UNUSED,
struct archiver_args *args)
{
int err = 0;
@@ -497,6 +498,7 @@ static int write_tar_filter_archive(const struct archiver *ar,
strvec_push(&filter.args, cmd.buf);
filter.use_shell = 1;
filter.in = -1;
+ filter.silent_exec_failure = 1;
if (start_command(&filter) < 0)
die_errno(_("unable to start '%s' filter"), cmd.buf);
diff --git a/archive-zip.c b/archive-zip.c
index 9fe43d740d8..0456f1ebf15 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -612,12 +612,13 @@ static void dos_time(timestamp_t *timestamp, int *dos_date, int *dos_time)
*dos_time = tm.tm_sec / 2 + tm.tm_min * 32 + tm.tm_hour * 2048;
}
-static int archive_zip_config(const char *var, const char *value, void *data)
+static int archive_zip_config(const char *var, const char *value,
+ void *data UNUSED)
{
return userdiff_config(var, value);
}
-static int write_zip_archive(const struct archiver *ar,
+static int write_zip_archive(const struct archiver *ar UNUSED,
struct archiver_args *args)
{
int err;
diff --git a/archive.c b/archive.c
index d5109abb894..941495f5d78 100644
--- a/archive.c
+++ b/archive.c
@@ -166,18 +166,16 @@ static int write_archive_entry(const struct object_id *oid, const char *base,
args->convert = check_attr_export_subst(check);
}
+ if (args->verbose)
+ fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
+
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
- if (args->verbose)
- fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
err = write_entry(args, oid, path.buf, path.len, mode, NULL, 0);
if (err)
return err;
return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
}
- if (args->verbose)
- fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
-
/* Stream it? */
if (S_ISREG(mode) && !args->convert &&
oid_object_info(args->repo, oid, &size) == OBJ_BLOB &&
@@ -382,7 +380,8 @@ struct path_exists_context {
struct archiver_args *args;
};
-static int reject_entry(const struct object_id *oid, struct strbuf *base,
+static int reject_entry(const struct object_id *oid UNUSED,
+ struct strbuf *base,
const char *filename, unsigned mode,
void *context)
{
@@ -499,7 +498,7 @@ static void parse_treeish_arg(const char **argv,
ar_args->time = archive_time;
}
-static void extra_file_info_clear(void *util, const char *str)
+static void extra_file_info_clear(void *util, const char *str UNUSED)
{
struct extra_file_info *info = util;
free(info->base);
diff --git a/attr.c b/attr.c
index 8a78dde69ef..42ad6de8c7c 100644
--- a/attr.c
+++ b/attr.c
@@ -23,10 +23,6 @@ static const char git_attr__unknown[] = "(builtin)unknown";
#define ATTR__UNSET NULL
#define ATTR__UNKNOWN git_attr__unknown
-#ifndef DEBUG_ATTR
-#define DEBUG_ATTR 0
-#endif
-
struct git_attr {
int attr_nr; /* unique attribute number */
char name[FLEX_ARRAY]; /* attribute name */
@@ -61,10 +57,10 @@ struct attr_hash_entry {
};
/* attr_hashmap comparison function */
-static int attr_hash_entry_cmp(const void *unused_cmp_data,
+static int attr_hash_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct attr_hash_entry *a, *b;
@@ -807,33 +803,6 @@ static struct attr_stack *read_attr(struct index_state *istate,
return res;
}
-#if DEBUG_ATTR
-static void debug_info(const char *what, struct attr_stack *elem)
-{
- fprintf(stderr, "%s: %s\n", what, elem->origin ? elem->origin : "()");
-}
-static void debug_set(const char *what, const char *match, struct git_attr *attr, const void *v)
-{
- const char *value = v;
-
- if (ATTR_TRUE(value))
- value = "set";
- else if (ATTR_FALSE(value))
- value = "unset";
- else if (ATTR_UNSET(value))
- value = "unspecified";
-
- fprintf(stderr, "%s: %s => %s (%s)\n",
- what, attr->name, (char *) value, match);
-}
-#define debug_push(a) debug_info("push", (a))
-#define debug_pop(a) debug_info("pop", (a))
-#else
-#define debug_push(a) do { ; } while (0)
-#define debug_pop(a) do { ; } while (0)
-#define debug_set(a,b,c,d) do { ; } while (0)
-#endif /* DEBUG_ATTR */
-
static const char *git_etc_gitattributes(void)
{
static const char *system_wide;
@@ -954,7 +923,6 @@ static void prepare_attr_stack(struct index_state *istate,
(!namelen || path[namelen] == '/'))
break;
- debug_pop(elem);
*stack = elem->prev;
attr_stack_free(elem);
}
@@ -1028,7 +996,7 @@ static int path_matches(const char *pathname, int pathlen,
static int macroexpand_one(struct all_attrs_item *all_attrs, int nr, int rem);
-static int fill_one(const char *what, struct all_attrs_item *all_attrs,
+static int fill_one(struct all_attrs_item *all_attrs,
const struct match_attr *a, int rem)
{
int i;
@@ -1039,9 +1007,6 @@ static int fill_one(const char *what, struct all_attrs_item *all_attrs,
const char *v = a->state[i].setto;
if (*n == ATTR__UNKNOWN) {
- debug_set(what,
- a->is_macro ? a->u.attr->name : a->u.pat.pattern,
- attr, v);
*n = v;
rem--;
rem = macroexpand_one(all_attrs, attr->attr_nr, rem);
@@ -1064,7 +1029,7 @@ static int fill(const char *path, int pathlen, int basename_offset,
continue;
if (path_matches(path, pathlen, basename_offset,
&a->u.pat, base, stack->originlen))
- rem = fill_one("fill", all_attrs, a, rem);
+ rem = fill_one(all_attrs, a, rem);
}
}
@@ -1076,7 +1041,7 @@ static int macroexpand_one(struct all_attrs_item *all_attrs, int nr, int rem)
const struct all_attrs_item *item = &all_attrs[nr];
if (item->macro && item->value == ATTR__TRUE)
- return fill_one("expand", all_attrs, item->macro, rem);
+ return fill_one(all_attrs, item->macro, rem);
else
return rem;
}
diff --git a/bisect.c b/bisect.c
index 38b3891f3a6..ec7487e6836 100644
--- a/bisect.c
+++ b/bisect.c
@@ -22,8 +22,6 @@ static struct oid_array skipped_revs;
static struct object_id *current_bad_oid;
-static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
-
static const char *term_bad;
static const char *term_good;
@@ -441,7 +439,7 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
}
static int register_ref(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+ int flags UNUSED, void *cb_data UNUSED)
{
struct strbuf good_prefix = STRBUF_INIT;
strbuf_addstr(&good_prefix, term_good);
@@ -729,20 +727,22 @@ static int is_expected_rev(const struct object_id *oid)
enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
int no_checkout)
{
- char bisect_rev_hex[GIT_MAX_HEXSZ + 1];
struct commit *commit;
struct pretty_print_context pp = {0};
struct strbuf commit_msg = STRBUF_INIT;
- oid_to_hex_r(bisect_rev_hex, bisect_rev);
update_ref(NULL, "BISECT_EXPECTED_REV", bisect_rev, NULL, 0, UPDATE_REFS_DIE_ON_ERR);
- argv_checkout[2] = bisect_rev_hex;
if (no_checkout) {
update_ref(NULL, "BISECT_HEAD", bisect_rev, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
} else {
- if (run_command_v_opt(argv_checkout, RUN_GIT_CMD))
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "checkout", "-q",
+ oid_to_hex(bisect_rev), "--", NULL);
+ if (run_command(&cmd))
/*
* Errors in `run_command()` itself, signaled by res < 0,
* and errors in the child process, signaled by res > 0
@@ -1160,8 +1160,9 @@ int estimate_bisect_steps(int all)
return (e < 3 * x) ? n : n - 1;
}
-static int mark_for_removal(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int mark_for_removal(const char *refname,
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cb_data)
{
struct string_list *refs = cb_data;
char *ref = xstrfmt("refs/bisect%s", refname);
diff --git a/block-sha1/sha1.c b/block-sha1/sha1.c
index 5974cd7dd3c..80cebd27564 100644
--- a/block-sha1/sha1.c
+++ b/block-sha1/sha1.c
@@ -28,10 +28,6 @@
* try to do the silly "optimize away loads" part because it won't
* see what the value will be).
*
- * Ben Herrenschmidt reports that on PPC, the C version comes close
- * to the optimized asm with this (ie on PPC you don't want that
- * 'volatile', since there are lots of registers).
- *
* On ARM we get the best code generation by forcing a full memory barrier
* between each SHA_ROUND, otherwise gcc happily get wild with spilling and
* the stack frame size simply explode and performance goes down the drain.
diff --git a/bloom.c b/bloom.c
index 816f063dca5..d0730525da5 100644
--- a/bloom.c
+++ b/bloom.c
@@ -163,10 +163,10 @@ void init_bloom_filters(void)
init_bloom_filter_slab(&bloom_filters);
}
-static int pathmap_cmp(const void *hashmap_cmp_fn_data,
+static int pathmap_cmp(const void *hashmap_cmp_fn_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *keydata)
+ const void *keydata UNUSED)
{
const struct pathmap_hash_entry *e1, *e2;
diff --git a/builtin/add.c b/builtin/add.c
index f84372964c8..626c71ec6aa 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -240,8 +240,8 @@ static int refresh(int verbose, const struct pathspec *pathspec)
int run_add_interactive(const char *revision, const char *patch_mode,
const struct pathspec *pathspec)
{
- int status, i;
- struct strvec argv = STRVEC_INIT;
+ int i;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int use_builtin_add_i =
git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
@@ -272,19 +272,18 @@ int run_add_interactive(const char *revision, const char *patch_mode,
return !!run_add_p(the_repository, mode, revision, pathspec);
}
- strvec_push(&argv, "add--interactive");
+ strvec_push(&cmd.args, "add--interactive");
if (patch_mode)
- strvec_push(&argv, patch_mode);
+ strvec_push(&cmd.args, patch_mode);
if (revision)
- strvec_push(&argv, revision);
- strvec_push(&argv, "--");
+ strvec_push(&cmd.args, revision);
+ strvec_push(&cmd.args, "--");
for (i = 0; i < pathspec->nr; i++)
/* pass original pathspec, to be re-parsed */
- strvec_push(&argv, pathspec->items[i].original);
+ strvec_push(&cmd.args, pathspec->items[i].original);
- status = run_command_v_opt(argv.v, RUN_GIT_CMD);
- strvec_clear(&argv);
- return status;
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
int interactive_add(const char **argv, const char *prefix, int patch)
diff --git a/builtin/am.c b/builtin/am.c
index 93bec62afa9..20aea0d2487 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -2187,14 +2187,12 @@ static int show_patch(struct am_state *state, enum show_patch_type sub_mode)
int len;
if (!is_null_oid(&state->orig_commit)) {
- const char *av[4] = { "show", NULL, "--", NULL };
- char *new_oid_str;
- int ret;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- av[1] = new_oid_str = xstrdup(oid_to_hex(&state->orig_commit));
- ret = run_command_v_opt(av, RUN_GIT_CMD);
- free(new_oid_str);
- return ret;
+ strvec_pushl(&cmd.args, "show", oid_to_hex(&state->orig_commit),
+ "--", NULL);
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
switch (sub_mode) {
@@ -2301,7 +2299,7 @@ static int parse_opt_show_current_patch(const struct option *opt, const char *ar
return 0;
}
-static int git_am_config(const char *k, const char *v, void *cb)
+static int git_am_config(const char *k, const char *v, void *cb UNUSED)
{
int status;
diff --git a/builtin/archive.c b/builtin/archive.c
index 7176b041b6d..f094390ee01 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -75,7 +75,7 @@ static int run_remote_archiver(int argc, const char **argv,
#define PARSE_OPT_KEEP_ALL ( PARSE_OPT_KEEP_DASHDASH | \
PARSE_OPT_KEEP_ARGV0 | \
- PARSE_OPT_KEEP_UNKNOWN | \
+ PARSE_OPT_KEEP_UNKNOWN_OPT | \
PARSE_OPT_NO_INTERNAL_HELP )
int cmd_archive(int argc, const char **argv, const char *prefix)
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 8a052c7111f..d4d813ebfce 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -220,18 +220,17 @@ static int bisect_reset(const char *commit)
}
if (!ref_exists("BISECT_HEAD")) {
- struct strvec argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&argv, "checkout", branch.buf, "--", NULL);
- if (run_command_v_opt(argv.v, RUN_GIT_CMD)) {
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "checkout", branch.buf, "--", NULL);
+ if (run_command(&cmd)) {
error(_("could not check out original"
" HEAD '%s'. Try 'git bisect"
" reset <commit>'."), branch.buf);
strbuf_release(&branch);
- strvec_clear(&argv);
return -1;
}
- strvec_clear(&argv);
}
strbuf_release(&branch);
@@ -329,8 +328,9 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
return 0;
}
-static int inc_nr(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int inc_nr(const char *refname UNUSED,
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cb_data)
{
unsigned int *nr = (unsigned int *)cb_data;
(*nr)++;
@@ -518,7 +518,7 @@ finish:
}
static int add_bisect_ref(const char *refname, const struct object_id *oid,
- int flags, void *cb)
+ int flags UNUSED, void *cb)
{
struct add_bisect_ref_data *data = cb;
@@ -764,11 +764,12 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, const char **a
strbuf_read_file(&start_head, git_path_bisect_start(), 0);
strbuf_trim(&start_head);
if (!no_checkout) {
- struct strvec argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&argv, "checkout", start_head.buf,
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "checkout", start_head.buf,
"--", NULL);
- if (run_command_v_opt(argv.v, RUN_GIT_CMD)) {
+ if (run_command(&cmd)) {
res = error(_("checking out '%s' failed."
" Try 'git bisect start "
"<valid-branch>'."),
@@ -1098,51 +1099,59 @@ static enum bisect_error bisect_skip(struct bisect_terms *terms, const char **ar
static int bisect_visualize(struct bisect_terms *terms, const char **argv, int argc)
{
- struct strvec args = STRVEC_INIT;
- int flags = RUN_COMMAND_NO_STDIN, res = 0;
+ struct child_process cmd = CHILD_PROCESS_INIT;
struct strbuf sb = STRBUF_INIT;
if (bisect_next_check(terms, NULL) != 0)
return BISECT_FAILED;
+ cmd.no_stdin = 1;
if (!argc) {
if ((getenv("DISPLAY") || getenv("SESSIONNAME") || getenv("MSYSTEM") ||
getenv("SECURITYSESSIONID")) && exists_in_PATH("gitk")) {
- strvec_push(&args, "gitk");
+ strvec_push(&cmd.args, "gitk");
} else {
- strvec_push(&args, "log");
- flags |= RUN_GIT_CMD;
+ strvec_push(&cmd.args, "log");
+ cmd.git_cmd = 1;
}
} else {
if (argv[0][0] == '-') {
- strvec_push(&args, "log");
- flags |= RUN_GIT_CMD;
+ strvec_push(&cmd.args, "log");
+ cmd.git_cmd = 1;
} else if (strcmp(argv[0], "tig") && !starts_with(argv[0], "git"))
- flags |= RUN_GIT_CMD;
+ cmd.git_cmd = 1;
- strvec_pushv(&args, argv);
+ strvec_pushv(&cmd.args, argv);
}
- strvec_pushl(&args, "--bisect", "--", NULL);
+ strvec_pushl(&cmd.args, "--bisect", "--", NULL);
strbuf_read_file(&sb, git_path_bisect_names(), 0);
- sq_dequote_to_strvec(sb.buf, &args);
+ sq_dequote_to_strvec(sb.buf, &cmd.args);
strbuf_release(&sb);
- res = run_command_v_opt(args.v, flags);
- strvec_clear(&args);
- return res;
+ return run_command(&cmd);
}
-static int get_first_good(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int get_first_good(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flag UNUSED, void *cb_data)
{
oidcpy(cb_data, oid);
return 1;
}
-static int verify_good(const struct bisect_terms *terms,
- const char **quoted_argv)
+static int do_bisect_run(const char *command)
+{
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ printf(_("running %s\n"), command);
+ cmd.use_shell = 1;
+ strvec_push(&cmd.args, command);
+ return run_command(&cmd);
+}
+
+static int verify_good(const struct bisect_terms *terms, const char *command)
{
int rc;
enum bisect_error res;
@@ -1162,8 +1171,7 @@ static int verify_good(const struct bisect_terms *terms,
if (res != BISECT_OK)
return -1;
- printf(_("running %s\n"), quoted_argv[0]);
- rc = run_command_v_opt(quoted_argv, RUN_USING_SHELL);
+ rc = do_bisect_run(command);
res = bisect_checkout(&current_rev, no_checkout);
if (res != BISECT_OK)
@@ -1176,7 +1184,6 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
{
int res = BISECT_OK;
struct strbuf command = STRBUF_INIT;
- struct strvec run_args = STRVEC_INIT;
const char *new_state;
int temporary_stdout_fd, saved_stdout;
int is_first_run = 1;
@@ -1191,11 +1198,8 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
return BISECT_FAILED;
}
- strvec_push(&run_args, command.buf);
-
while (1) {
- printf(_("running %s\n"), command.buf);
- res = run_command_v_opt(run_args.v, RUN_USING_SHELL);
+ res = do_bisect_run(command.buf);
/*
* Exit code 126 and 127 can either come from the shell
@@ -1205,7 +1209,7 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
* missing or non-executable script.
*/
if (is_first_run && (res == 126 || res == 127)) {
- int rc = verify_good(terms, run_args.v);
+ int rc = verify_good(terms, command.buf);
is_first_run = 0;
if (rc < 0) {
error(_("unable to verify '%s' on good"
@@ -1272,119 +1276,147 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
}
strbuf_release(&command);
- strvec_clear(&run_args);
+ return res;
+}
+
+static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED)
+{
+ if (argc > 1)
+ return error(_("--bisect-reset requires either no argument or a commit"));
+ return bisect_reset(argc ? argv[0] : NULL);
+}
+
+static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ if (argc > 1)
+ return error(_("--bisect-terms requires 0 or 1 argument"));
+ res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ set_terms(&terms, "bad", "good");
+ res = bisect_start(&terms, argv, argc);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ if (argc)
+ return error(_("--bisect-next requires 0 arguments"));
+ get_terms(&terms);
+ res = bisect_next(&terms, prefix);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__state(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ set_terms(&terms, "bad", "good");
+ get_terms(&terms);
+ res = bisect_state(&terms, argv, argc);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__log(int argc, const char **argv UNUSED, const char *prefix UNUSED)
+{
+ if (argc)
+ return error(_("--bisect-log requires 0 arguments"));
+ return bisect_log();
+}
+
+static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ if (argc != 1)
+ return error(_("no logfile given"));
+ set_terms(&terms, "bad", "good");
+ res = bisect_replay(&terms, argv[0]);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ set_terms(&terms, "bad", "good");
+ get_terms(&terms);
+ res = bisect_skip(&terms, argv, argc);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ get_terms(&terms);
+ res = bisect_visualize(&terms, argv, argc);
+ free_terms(&terms);
+ return res;
+}
+
+static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED)
+{
+ int res;
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
+
+ if (!argc)
+ return error(_("bisect run failed: no command provided."));
+ get_terms(&terms);
+ res = bisect_run(&terms, argv, argc);
+ free_terms(&terms);
return res;
}
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
{
- enum {
- BISECT_RESET = 1,
- BISECT_NEXT_CHECK,
- BISECT_TERMS,
- BISECT_START,
- BISECT_AUTOSTART,
- BISECT_NEXT,
- BISECT_STATE,
- BISECT_LOG,
- BISECT_REPLAY,
- BISECT_SKIP,
- BISECT_VISUALIZE,
- BISECT_RUN,
- } cmdmode = 0;
- int res = 0, nolog = 0;
+ int res = 0;
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
- OPT_CMDMODE(0, "bisect-reset", &cmdmode,
- N_("reset the bisection state"), BISECT_RESET),
- OPT_CMDMODE(0, "bisect-next-check", &cmdmode,
- N_("check whether bad or good terms exist"), BISECT_NEXT_CHECK),
- OPT_CMDMODE(0, "bisect-terms", &cmdmode,
- N_("print out the bisect terms"), BISECT_TERMS),
- OPT_CMDMODE(0, "bisect-start", &cmdmode,
- N_("start the bisect session"), BISECT_START),
- OPT_CMDMODE(0, "bisect-next", &cmdmode,
- N_("find the next bisection commit"), BISECT_NEXT),
- OPT_CMDMODE(0, "bisect-state", &cmdmode,
- N_("mark the state of ref (or refs)"), BISECT_STATE),
- OPT_CMDMODE(0, "bisect-log", &cmdmode,
- N_("list the bisection steps so far"), BISECT_LOG),
- OPT_CMDMODE(0, "bisect-replay", &cmdmode,
- N_("replay the bisection process from the given file"), BISECT_REPLAY),
- OPT_CMDMODE(0, "bisect-skip", &cmdmode,
- N_("skip some commits for checkout"), BISECT_SKIP),
- OPT_CMDMODE(0, "bisect-visualize", &cmdmode,
- N_("visualize the bisection"), BISECT_VISUALIZE),
- OPT_CMDMODE(0, "bisect-run", &cmdmode,
- N_("use <cmd>... to automatically bisect"), BISECT_RUN),
- OPT_BOOL(0, "no-log", &nolog,
- N_("no log for BISECT_WRITE")),
+ OPT_SUBCOMMAND("reset", &fn, cmd_bisect__reset),
+ OPT_SUBCOMMAND("terms", &fn, cmd_bisect__terms),
+ OPT_SUBCOMMAND("start", &fn, cmd_bisect__start),
+ OPT_SUBCOMMAND("next", &fn, cmd_bisect__next),
+ OPT_SUBCOMMAND("state", &fn, cmd_bisect__state),
+ OPT_SUBCOMMAND("log", &fn, cmd_bisect__log),
+ OPT_SUBCOMMAND("replay", &fn, cmd_bisect__replay),
+ OPT_SUBCOMMAND("skip", &fn, cmd_bisect__skip),
+ OPT_SUBCOMMAND("visualize", &fn, cmd_bisect__visualize),
+ OPT_SUBCOMMAND("view", &fn, cmd_bisect__visualize),
+ OPT_SUBCOMMAND("run", &fn, cmd_bisect__run),
OPT_END()
};
- struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
-
argc = parse_options(argc, argv, prefix, options,
- git_bisect_helper_usage,
- PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_UNKNOWN);
+ git_bisect_helper_usage, 0);
- if (!cmdmode)
+ if (!fn)
usage_with_options(git_bisect_helper_usage, options);
+ argc--;
+ argv++;
- switch (cmdmode) {
- case BISECT_RESET:
- if (argc > 1)
- return error(_("--bisect-reset requires either no argument or a commit"));
- res = bisect_reset(argc ? argv[0] : NULL);
- break;
- case BISECT_TERMS:
- if (argc > 1)
- return error(_("--bisect-terms requires 0 or 1 argument"));
- res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL);
- break;
- case BISECT_START:
- set_terms(&terms, "bad", "good");
- res = bisect_start(&terms, argv, argc);
- break;
- case BISECT_NEXT:
- if (argc)
- return error(_("--bisect-next requires 0 arguments"));
- get_terms(&terms);
- res = bisect_next(&terms, prefix);
- break;
- case BISECT_STATE:
- set_terms(&terms, "bad", "good");
- get_terms(&terms);
- res = bisect_state(&terms, argv, argc);
- break;
- case BISECT_LOG:
- if (argc)
- return error(_("--bisect-log requires 0 arguments"));
- res = bisect_log();
- break;
- case BISECT_REPLAY:
- if (argc != 1)
- return error(_("no logfile given"));
- set_terms(&terms, "bad", "good");
- res = bisect_replay(&terms, argv[0]);
- break;
- case BISECT_SKIP:
- set_terms(&terms, "bad", "good");
- get_terms(&terms);
- res = bisect_skip(&terms, argv, argc);
- break;
- case BISECT_VISUALIZE:
- get_terms(&terms);
- res = bisect_visualize(&terms, argv, argc);
- break;
- case BISECT_RUN:
- if (!argc)
- return error(_("bisect run failed: no command provided."));
- get_terms(&terms);
- res = bisect_run(&terms, argv, argc);
- break;
- default:
- BUG("unknown subcommand %d", cmdmode);
- }
- free_terms(&terms);
+ res = fn(argc, argv, prefix);
/*
* Handle early success
diff --git a/builtin/blame.c b/builtin/blame.c
index 02e39420b62..71f925e456c 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -30,6 +30,7 @@
#include "tag.h"
static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
+static char annotate_usage[] = N_("git annotate [<options>] [<rev-opts>] [<rev>] [--] <file>");
static const char *blame_opt_usage[] = {
blame_usage,
@@ -38,6 +39,13 @@ static const char *blame_opt_usage[] = {
NULL
};
+static const char *annotate_opt_usage[] = {
+ annotate_usage,
+ "",
+ N_("<rev-opts> are documented in git-rev-list(1)"),
+ NULL
+};
+
static int longest_file;
static int longest_author;
static int max_orig_digits;
@@ -899,6 +907,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
long anchor;
const int hexsz = the_hash_algo->hexsz;
long num_lines = 0;
+ const char *str_usage = cmd_is_annotate ? annotate_usage : blame_usage;
+ const char **opt_usage = cmd_is_annotate ? annotate_opt_usage : blame_opt_usage;
setup_default_color_by_age();
git_config(git_blame_config, &output_option);
@@ -914,12 +924,13 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
parse_options_start(&ctx, argc, argv, prefix, options,
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0);
for (;;) {
- switch (parse_options_step(&ctx, options, blame_opt_usage)) {
+ switch (parse_options_step(&ctx, options, opt_usage)) {
case PARSE_OPT_NON_OPTION:
case PARSE_OPT_UNKNOWN:
break;
case PARSE_OPT_HELP:
case PARSE_OPT_ERROR:
+ case PARSE_OPT_SUBCOMMAND:
exit(129);
case PARSE_OPT_COMPLETE:
exit(0);
@@ -933,7 +944,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
ctx.argv[0] = "--children";
reverse = 1;
}
- parse_revision_opt(&revs, &ctx, options, blame_opt_usage);
+ parse_revision_opt(&revs, &ctx, options, opt_usage);
}
parse_done:
revision_opts_finish(&revs);
@@ -1039,7 +1050,7 @@ parse_done:
switch (argc - dashdash_pos - 1) {
case 2: /* (1b) */
if (argc != 4)
- usage_with_options(blame_opt_usage, options);
+ usage_with_options(opt_usage, options);
/* reorder for the new way: <rev> -- <path> */
argv[1] = argv[3];
argv[3] = argv[2];
@@ -1050,11 +1061,11 @@ parse_done:
argv[argc] = NULL;
break;
default:
- usage_with_options(blame_opt_usage, options);
+ usage_with_options(opt_usage, options);
}
} else {
if (argc < 2)
- usage_with_options(blame_opt_usage, options);
+ usage_with_options(opt_usage, options);
if (argc == 3 && is_a_rev(argv[argc - 1])) { /* (2b) */
path = add_prefix(prefix, argv[1]);
argv[1] = argv[2];
@@ -1112,7 +1123,7 @@ parse_done:
nth_line_cb, &sb, lno, anchor,
&bottom, &top, sb.path,
the_repository->index))
- usage(blame_usage);
+ usage(str_usage);
if ((!lno && (top || bottom)) || lno < bottom)
die(Q_("file %s has only %lu line",
"file %s has only %lu lines",
diff --git a/builtin/branch.c b/builtin/branch.c
index 55cd9a6e998..15be0c03ef2 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -520,13 +520,6 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
const char *interpreted_newname = NULL;
int recovery = 0;
- if (!oldname) {
- if (copy)
- die(_("cannot copy the current branch while not on any."));
- else
- die(_("cannot rename the current branch while not on any."));
- }
-
if (strbuf_check_branch_ref(&oldref, oldname)) {
/*
* Bad name --- this could be an attempt to rename a
@@ -538,6 +531,13 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
die(_("Invalid branch name: '%s'"), oldname);
}
+ if ((copy || strcmp(head, oldname)) && !ref_exists(oldref.buf)) {
+ if (copy && !strcmp(head, oldname))
+ die(_("No commit on branch '%s' yet."), oldname);
+ else
+ die(_("No branch named '%s'."), oldname);
+ }
+
/*
* A command like "git branch -M currentbranch currentbranch" cannot
* cause the worktree to become inconsistent with HEAD, so allow it.
@@ -599,10 +599,11 @@ static GIT_PATH_FUNC(edit_description, "EDIT_DESCRIPTION")
static int edit_branch_description(const char *branch_name)
{
+ int exists;
struct strbuf buf = STRBUF_INIT;
struct strbuf name = STRBUF_INIT;
- read_branch_desc(&buf, branch_name);
+ exists = !read_branch_desc(&buf, branch_name);
if (!buf.len || buf.buf[buf.len-1] != '\n')
strbuf_addch(&buf, '\n');
strbuf_commented_addf(&buf,
@@ -619,7 +620,8 @@ static int edit_branch_description(const char *branch_name)
strbuf_stripspace(&buf, 1);
strbuf_addf(&name, "branch.%s.description", branch_name);
- git_config_set(name.buf, buf.len ? buf.buf : NULL);
+ if (buf.len || exists)
+ git_config_set(name.buf, buf.len ? buf.buf : NULL);
strbuf_release(&name);
strbuf_release(&buf);
@@ -791,53 +793,56 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
} else if (edit_description) {
const char *branch_name;
struct strbuf branch_ref = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT;
+ int ret = 1; /* assume failure */
if (!argc) {
if (filter.detached)
die(_("Cannot give description to detached HEAD"));
branch_name = head;
- } else if (argc == 1)
- branch_name = argv[0];
- else
+ } else if (argc == 1) {
+ strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ branch_name = buf.buf;
+ } else {
die(_("cannot edit description of more than one branch"));
+ }
strbuf_addf(&branch_ref, "refs/heads/%s", branch_name);
- if (!ref_exists(branch_ref.buf)) {
- strbuf_release(&branch_ref);
-
- if (!argc)
- return error(_("No commit on branch '%s' yet."),
- branch_name);
- else
- return error(_("No branch named '%s'."),
- branch_name);
- }
+ if (!ref_exists(branch_ref.buf))
+ error((!argc || !strcmp(head, branch_name))
+ ? _("No commit on branch '%s' yet.")
+ : _("No branch named '%s'."),
+ branch_name);
+ else if (!edit_branch_description(branch_name))
+ ret = 0; /* happy */
+
strbuf_release(&branch_ref);
+ strbuf_release(&buf);
- if (edit_branch_description(branch_name))
- return 1;
- } else if (copy) {
+ return ret;
+ } else if (copy || rename) {
if (!argc)
die(_("branch name required"));
+ else if ((argc == 1) && filter.detached)
+ die(copy? _("cannot copy the current branch while not on any.")
+ : _("cannot rename the current branch while not on any."));
else if (argc == 1)
- copy_or_rename_branch(head, argv[0], 1, copy > 1);
+ copy_or_rename_branch(head, argv[0], copy, copy + rename > 1);
else if (argc == 2)
- copy_or_rename_branch(argv[0], argv[1], 1, copy > 1);
+ copy_or_rename_branch(argv[0], argv[1], copy, copy + rename > 1);
else
- die(_("too many branches for a copy operation"));
- } else if (rename) {
- if (!argc)
- die(_("branch name required"));
- else if (argc == 1)
- copy_or_rename_branch(head, argv[0], 0, rename > 1);
- else if (argc == 2)
- copy_or_rename_branch(argv[0], argv[1], 0, rename > 1);
- else
- die(_("too many arguments for a rename operation"));
+ die(copy? _("too many branches for a copy operation")
+ : _("too many arguments for a rename operation"));
} else if (new_upstream) {
- struct branch *branch = branch_get(argv[0]);
+ struct branch *branch;
+ struct strbuf buf = STRBUF_INIT;
- if (argc > 1)
+ if (!argc)
+ branch = branch_get(NULL);
+ else if (argc == 1) {
+ strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ branch = branch_get(buf.buf);
+ } else
die(_("too many arguments to set new upstream"));
if (!branch) {
@@ -848,17 +853,26 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
die(_("no such branch '%s'"), argv[0]);
}
- if (!ref_exists(branch->refname))
+ if (!ref_exists(branch->refname)) {
+ if (!argc || !strcmp(head, branch->name))
+ die(_("No commit on branch '%s' yet."), branch->name);
die(_("branch '%s' does not exist"), branch->name);
+ }
dwim_and_setup_tracking(the_repository, branch->name,
new_upstream, BRANCH_TRACK_OVERRIDE,
quiet);
+ strbuf_release(&buf);
} else if (unset_upstream) {
- struct branch *branch = branch_get(argv[0]);
+ struct branch *branch;
struct strbuf buf = STRBUF_INIT;
- if (argc > 1)
+ if (!argc)
+ branch = branch_get(NULL);
+ else if (argc == 1) {
+ strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ branch = branch_get(buf.buf);
+ } else
die(_("too many arguments to unset upstream"));
if (!branch) {
@@ -871,6 +885,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (!branch_has_merge_config(branch))
die(_("Branch '%s' has no upstream information"), branch->name);
+ strbuf_reset(&buf);
strbuf_addf(&buf, "branch.%s.remote", branch->name);
git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
strbuf_reset(&buf);
diff --git a/builtin/bugreport.c b/builtin/bugreport.c
index 530895be55f..96052541cbf 100644
--- a/builtin/bugreport.c
+++ b/builtin/bugreport.c
@@ -60,7 +60,8 @@ static void get_populated_hooks(struct strbuf *hook_info, int nongit)
}
static const char * const bugreport_usage[] = {
- N_("git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--diagnose[=<mode>]"),
+ N_("git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+ " [--diagnose[=<mode>]]"),
NULL
};
diff --git a/builtin/bundle.c b/builtin/bundle.c
index 2adad545a2e..c12c09f8549 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -11,32 +11,42 @@
* bundle supporting "fetch", "pull", and "ls-remote".
*/
-static const char * const builtin_bundle_usage[] = {
- N_("git bundle create [<options>] <file> <git-rev-list args>"),
- N_("git bundle verify [<options>] <file>"),
- N_("git bundle list-heads <file> [<refname>...]"),
- N_("git bundle unbundle <file> [<refname>...]"),
- NULL
+#define BUILTIN_BUNDLE_CREATE_USAGE \
+ N_("git bundle create [-q | --quiet | --progress | --all-progress] [--all-progress-implied]\n" \
+ " [--version=<version>] <file> <git-rev-list-args>")
+#define BUILTIN_BUNDLE_VERIFY_USAGE \
+ N_("git bundle verify [-q | --quiet] <file>")
+#define BUILTIN_BUNDLE_LIST_HEADS_USAGE \
+ N_("git bundle list-heads <file> [<refname>...]")
+#define BUILTIN_BUNDLE_UNBUNDLE_USAGE \
+ N_("git bundle unbundle [--progress] <file> [<refname>...]")
+
+static char const * const builtin_bundle_usage[] = {
+ BUILTIN_BUNDLE_CREATE_USAGE,
+ BUILTIN_BUNDLE_VERIFY_USAGE,
+ BUILTIN_BUNDLE_LIST_HEADS_USAGE,
+ BUILTIN_BUNDLE_UNBUNDLE_USAGE,
+ NULL,
};
static const char * const builtin_bundle_create_usage[] = {
- N_("git bundle create [<options>] <file> <git-rev-list args>"),
- NULL
+ BUILTIN_BUNDLE_CREATE_USAGE,
+ NULL
};
static const char * const builtin_bundle_verify_usage[] = {
- N_("git bundle verify [<options>] <file>"),
- NULL
+ BUILTIN_BUNDLE_VERIFY_USAGE,
+ NULL
};
static const char * const builtin_bundle_list_heads_usage[] = {
- N_("git bundle list-heads <file> [<refname>...]"),
- NULL
+ BUILTIN_BUNDLE_LIST_HEADS_USAGE,
+ NULL
};
static const char * const builtin_bundle_unbundle_usage[] = {
- N_("git bundle unbundle <file> [<refname>...]"),
- NULL
+ BUILTIN_BUNDLE_UNBUNDLE_USAGE,
+ NULL
};
static int parse_options_cmd_bundle(int argc,
@@ -119,7 +129,8 @@ static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
goto cleanup;
}
close(bundle_fd);
- if (verify_bundle(the_repository, &header, !quiet)) {
+ if (verify_bundle(the_repository, &header,
+ quiet ? VERIFY_BUNDLE_QUIET : VERIFY_BUNDLE_VERBOSE)) {
ret = 1;
goto cleanup;
}
@@ -185,7 +196,7 @@ static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)
strvec_pushl(&extra_index_pack_args, "-v", "--progress-title",
_("Unbundling objects"), NULL);
ret = !!unbundle(the_repository, &header, bundle_fd,
- &extra_index_pack_args) ||
+ &extra_index_pack_args, 0) ||
list_bundle_refs(&header, argc, argv);
bundle_header_release(&header);
cleanup:
@@ -195,30 +206,19 @@ cleanup:
int cmd_bundle(int argc, const char **argv, const char *prefix)
{
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
+ OPT_SUBCOMMAND("create", &fn, cmd_bundle_create),
+ OPT_SUBCOMMAND("verify", &fn, cmd_bundle_verify),
+ OPT_SUBCOMMAND("list-heads", &fn, cmd_bundle_list_heads),
+ OPT_SUBCOMMAND("unbundle", &fn, cmd_bundle_unbundle),
OPT_END()
};
- int result;
argc = parse_options(argc, argv, prefix, options, builtin_bundle_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ 0);
packet_trace_identity("bundle");
- if (argc < 2)
- usage_with_options(builtin_bundle_usage, options);
-
- else if (!strcmp(argv[0], "create"))
- result = cmd_bundle_create(argc, argv, prefix);
- else if (!strcmp(argv[0], "verify"))
- result = cmd_bundle_verify(argc, argv, prefix);
- else if (!strcmp(argv[0], "list-heads"))
- result = cmd_bundle_list_heads(argc, argv, prefix);
- else if (!strcmp(argv[0], "unbundle"))
- result = cmd_bundle_unbundle(argc, argv, prefix);
- else {
- error(_("Unknown subcommand: %s"), argv[0]);
- usage_with_options(builtin_bundle_usage, options);
- }
- return result ? 1 : 0;
+ return !!fn(argc, argv, prefix);
}
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 989eee0bb4c..fa7bd891692 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -893,7 +893,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
N_("git cat-file (-t | -s) [--allow-unknown-type] <object>"),
N_("git cat-file (--batch | --batch-check | --batch-command) [--batch-all-objects]\n"
" [--buffer] [--follow-symlinks] [--unordered]\n"
- " [--textconv | --filters]"),
+ " [--textconv | --filters] [-z]"),
N_("git cat-file (--textconv | --filters)\n"
" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"),
NULL
diff --git a/builtin/checkout.c b/builtin/checkout.c
index f9d63d80b92..2a132392fbe 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -125,7 +125,7 @@ static int post_checkout_hook(struct commit *old_commit, struct commit *new_comm
}
static int update_some(const struct object_id *oid, struct strbuf *base,
- const char *pathname, unsigned mode, void *context)
+ const char *pathname, unsigned mode, void *context UNUSED)
{
int len;
struct cache_entry *ce;
@@ -990,7 +990,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
static int add_pending_uninteresting_ref(const char *refname,
const struct object_id *oid,
- int flags, void *cb_data)
+ int flags UNUSED, void *cb_data)
{
add_pending_oid(cb_data, refname, oid, UNINTERESTING);
return 0;
diff --git a/builtin/clean.c b/builtin/clean.c
index 5466636e666..40ff2c578de 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -26,7 +26,7 @@ static struct string_list del_list = STRING_LIST_INIT_DUP;
static unsigned int colopts;
static const char *const builtin_clean_usage[] = {
- N_("git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."),
+ N_("git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] [<pathspec>...]"),
NULL
};
diff --git a/builtin/clone.c b/builtin/clone.c
index c4ff4643ecd..0e4348686b6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -34,6 +34,7 @@
#include "list-objects-filter-options.h"
#include "hook.h"
#include "bundle.h"
+#include "bundle-uri.h"
/*
* Overall FIXMEs:
@@ -72,11 +73,12 @@ static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
static int option_dissociate;
static int max_jobs = -1;
static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
-static struct list_objects_filter_options filter_options;
+static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
static int option_filter_submodules = -1; /* unspecified */
static int config_filter_submodules = -1; /* unspecified */
static struct string_list server_options = STRING_LIST_INIT_NODUP;
static int option_remote_submodules;
+static const char *bundle_uri;
static int recurse_submodules_cb(const struct option *opt,
const char *arg, int unset)
@@ -160,6 +162,8 @@ static struct option builtin_clone_options[] = {
N_("any cloned submodules will use their remote-tracking branch")),
OPT_BOOL(0, "sparse", &option_sparse_checkout,
N_("initialize sparse-checkout file to include only files at root")),
+ OPT_STRING(0, "bundle-uri", &bundle_uri,
+ N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")),
OPT_END()
};
@@ -316,13 +320,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
int src_len, dest_len;
struct dir_iterator *iter;
int iter_status;
- unsigned int flags;
struct strbuf realpath = STRBUF_INIT;
mkdir_if_missing(dest->buf, 0777);
- flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS;
- iter = dir_iterator_begin(src->buf, flags);
+ iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
if (!iter)
die_errno(_("failed to start iterator over '%s'"), src->buf);
@@ -338,6 +340,10 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
strbuf_setlen(dest, dest_len);
strbuf_addstr(dest, iter->relative_path);
+ if (S_ISLNK(iter->st.st_mode))
+ die(_("symlink '%s' exists, refusing to clone with --local"),
+ iter->relative_path);
+
if (S_ISDIR(iter->st.st_mode)) {
mkdir_if_missing(dest->buf, 0777);
continue;
@@ -647,9 +653,9 @@ static void update_head(const struct ref *our, const struct ref *remote,
static int git_sparse_checkout_init(const char *repo)
{
- struct strvec argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int result = 0;
- strvec_pushl(&argv, "-C", repo, "sparse-checkout", "set", NULL);
+ strvec_pushl(&cmd.args, "-C", repo, "sparse-checkout", "set", NULL);
/*
* We must apply the setting in the current process
@@ -657,12 +663,12 @@ static int git_sparse_checkout_init(const char *repo)
*/
core_apply_sparse_checkout = 1;
- if (run_command_v_opt(argv.v, RUN_GIT_CMD)) {
+ cmd.git_cmd = 1;
+ if (run_command(&cmd)) {
error(_("failed to initialize sparse-checkout"));
result = 1;
}
- strvec_clear(&argv);
return result;
}
@@ -727,37 +733,38 @@ static int checkout(int submodule_progress, int filter_submodules)
oid_to_hex(&oid), "1", NULL);
if (!err && (option_recurse_submodules.nr > 0)) {
- struct strvec args = STRVEC_INIT;
- strvec_pushl(&args, "submodule", "update", "--require-init", "--recursive", NULL);
+ struct child_process cmd = CHILD_PROCESS_INIT;
+ strvec_pushl(&cmd.args, "submodule", "update", "--require-init",
+ "--recursive", NULL);
if (option_shallow_submodules == 1)
- strvec_push(&args, "--depth=1");
+ strvec_push(&cmd.args, "--depth=1");
if (max_jobs != -1)
- strvec_pushf(&args, "--jobs=%d", max_jobs);
+ strvec_pushf(&cmd.args, "--jobs=%d", max_jobs);
if (submodule_progress)
- strvec_push(&args, "--progress");
+ strvec_push(&cmd.args, "--progress");
if (option_verbosity < 0)
- strvec_push(&args, "--quiet");
+ strvec_push(&cmd.args, "--quiet");
if (option_remote_submodules) {
- strvec_push(&args, "--remote");
- strvec_push(&args, "--no-fetch");
+ strvec_push(&cmd.args, "--remote");
+ strvec_push(&cmd.args, "--no-fetch");
}
if (filter_submodules && filter_options.choice)
- strvec_pushf(&args, "--filter=%s",
+ strvec_pushf(&cmd.args, "--filter=%s",
expand_list_objects_filter_spec(&filter_options));
if (option_single_branch >= 0)
- strvec_push(&args, option_single_branch ?
+ strvec_push(&cmd.args, option_single_branch ?
"--single-branch" :
"--no-single-branch");
- err = run_command_v_opt(args.v, RUN_GIT_CMD);
- strvec_clear(&args);
+ cmd.git_cmd = 1;
+ err = run_command(&cmd);
}
return err;
@@ -858,11 +865,15 @@ static void write_refspec_config(const char *src_ref_prefix,
static void dissociate_from_references(void)
{
- static const char* argv[] = { "repack", "-a", "-d", NULL };
char *alternates = git_pathdup("objects/info/alternates");
if (!access(alternates, F_OK)) {
- if (run_command_v_opt(argv, RUN_GIT_CMD|RUN_COMMAND_NO_STDIN))
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ cmd.git_cmd = 1;
+ cmd.no_stdin = 1;
+ strvec_pushl(&cmd.args, "repack", "-a", "-d", NULL);
+ if (run_command(&cmd))
die(_("cannot repack to clean up"));
if (unlink(alternates) && errno != ENOENT)
die_errno(_("cannot unlink temporary alternates file"));
@@ -925,14 +936,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
option_bare = 1;
if (option_bare) {
- if (option_origin)
- die(_("options '%s' and '%s %s' cannot be used together"),
- "--bare", "--origin", option_origin);
if (real_git_dir)
die(_("options '%s' and '%s' cannot be used together"), "--bare", "--separate-git-dir");
option_no_checkout = 1;
}
+ if (bundle_uri && deepen)
+ die(_("--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-exclude"));
+
repo_name = argv[0];
path = get_repo_path(repo_name, &is_bundle);
@@ -1232,6 +1243,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (transport->smart_options && !deepen && !filter_options.choice)
transport->smart_options->check_self_contained_and_connected = 1;
+ /*
+ * Before fetching from the remote, download and install bundle
+ * data from the --bundle-uri option.
+ */
+ if (bundle_uri) {
+ /* At this point, we need the_repository to match the cloned repo. */
+ if (repo_init(the_repository, git_dir, work_tree))
+ warning(_("failed to initialize the repo, skipping bundle URI"));
+ else if (fetch_bundle_uri(the_repository, bundle_uri))
+ warning(_("failed to fetch objects from bundle URI '%s'"),
+ bundle_uri);
+ }
strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
refspec_ref_prefixes(&remote->fetch,
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index 51c4040ea6c..e8f77f535f3 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -10,13 +10,13 @@
#include "tag.h"
#define BUILTIN_COMMIT_GRAPH_VERIFY_USAGE \
- N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]")
+ N_("git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]")
#define BUILTIN_COMMIT_GRAPH_WRITE_USAGE \
- N_("git commit-graph write [--object-dir <objdir>] [--append] " \
- "[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] " \
- "[--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress] " \
- "<split options>")
+ N_("git commit-graph write [--object-dir <dir>] [--append]\n" \
+ " [--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits]\n" \
+ " [--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress]\n" \
+ " <split options>")
static const char * builtin_commit_graph_verify_usage[] = {
BUILTIN_COMMIT_GRAPH_VERIFY_USAGE,
@@ -58,7 +58,7 @@ static struct option *add_common_options(struct option *to)
return parse_options_concat(common_opts, to);
}
-static int graph_verify(int argc, const char **argv)
+static int graph_verify(int argc, const char **argv, const char *prefix)
{
struct commit_graph *graph = NULL;
struct object_directory *odb = NULL;
@@ -80,7 +80,7 @@ static int graph_verify(int argc, const char **argv)
trace2_cmd_mode("verify");
opts.progress = isatty(2);
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
options,
builtin_commit_graph_verify_usage, 0);
if (argc)
@@ -179,7 +179,7 @@ static int write_option_max_new_filters(const struct option *opt,
}
static int git_commit_graph_write_config(const char *var, const char *value,
- void *cb)
+ void *cb UNUSED)
{
if (!strcmp(var, "commitgraph.maxnewfilters"))
write_opts.max_new_filters = git_config_int(var, value);
@@ -190,7 +190,7 @@ static int git_commit_graph_write_config(const char *var, const char *value,
return 0;
}
-static int graph_write(int argc, const char **argv)
+static int graph_write(int argc, const char **argv, const char *prefix)
{
struct string_list pack_indexes = STRING_LIST_INIT_DUP;
struct strbuf buf = STRBUF_INIT;
@@ -241,7 +241,7 @@ static int graph_write(int argc, const char **argv)
git_config(git_commit_graph_write_config, &opts);
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
options,
builtin_commit_graph_write_usage, 0);
if (argc)
@@ -307,26 +307,22 @@ cleanup:
int cmd_commit_graph(int argc, const char **argv, const char *prefix)
{
- struct option *builtin_commit_graph_options = common_opts;
+ parse_opt_subcommand_fn *fn = NULL;
+ struct option builtin_commit_graph_options[] = {
+ OPT_SUBCOMMAND("verify", &fn, graph_verify),
+ OPT_SUBCOMMAND("write", &fn, graph_write),
+ OPT_END(),
+ };
+ struct option *options = parse_options_concat(builtin_commit_graph_options, common_opts);
git_config(git_default_config, NULL);
- argc = parse_options(argc, argv, prefix,
- builtin_commit_graph_options,
- builtin_commit_graph_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
- if (!argc)
- goto usage;
read_replace_refs = 0;
save_commit_buffer = 0;
- if (!strcmp(argv[0], "verify"))
- return graph_verify(argc, argv);
- else if (argc && !strcmp(argv[0], "write"))
- return graph_write(argc, argv);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_commit_graph_usage, 0);
+ FREE_AND_NULL(options);
- error(_("unrecognized subcommand: %s"), argv[0]);
-usage:
- usage_with_options(builtin_commit_graph_usage,
- builtin_commit_graph_options);
+ return fn(argc, argv, prefix);
}
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index 63ea3229333..cc8d584be2f 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -15,8 +15,9 @@
#include "parse-options.h"
static const char * const commit_tree_usage[] = {
- N_("git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] "
- "[(-F <file>)...] <tree>"),
+ N_("git commit-tree <tree> [(-p <parent>)...]"),
+ N_("git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...]\n"
+ " [(-F <file>)...] <tree>"),
NULL
};
diff --git a/builtin/commit.c b/builtin/commit.c
index fcf9c85947e..e22bdf23f5f 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -40,12 +40,19 @@
#include "pretty.h"
static const char * const builtin_commit_usage[] = {
- N_("git commit [<options>] [--] <pathspec>..."),
+ N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\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"
+ " [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
+ " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n"
+ " [--] [<pathspec>...]"),
NULL
};
static const char * const builtin_status_usage[] = {
- N_("git status [<options>] [--] <pathspec>..."),
+ N_("git status [<options>] [--] [<pathspec>...]"),
NULL
};
@@ -139,7 +146,7 @@ static int opt_pass_trailer(const struct option *opt, const char *arg, int unset
{
BUG_ON_OPT_NEG(unset);
- strvec_pushl(&trailer_args, "--trailer", arg, NULL);
+ strvec_pushl(opt->value, "--trailer", arg, NULL);
return 0;
}
@@ -1633,7 +1640,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
OPT_STRING(0, "fixup", &fixup_message, N_("[(amend|reword):]commit"), N_("use autosquash formatted message to fixup or amend/reword specified commit")),
OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")),
OPT_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")),
- OPT_CALLBACK_F(0, "trailer", NULL, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG, opt_pass_trailer),
+ OPT_CALLBACK_F(0, "trailer", &trailer_args, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG, opt_pass_trailer),
OPT_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")),
OPT_FILENAME('t', "template", &template_file, N_("use specified template file")),
OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
diff --git a/builtin/config.c b/builtin/config.c
index e7b88a9c08d..753e5fac297 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -207,7 +207,8 @@ static void show_config_scope(struct strbuf *buf)
strbuf_addch(buf, term);
}
-static int show_all_config(const char *key_, const char *value_, void *cb)
+static int show_all_config(const char *key_, const char *value_,
+ void *cb UNUSED)
{
if (show_origin || show_scope) {
struct strbuf buf = STRBUF_INIT;
@@ -458,7 +459,8 @@ static const char *get_color_slot;
static const char *get_colorbool_slot;
static char parsed_color[COLOR_MAXLEN];
-static int git_get_color_config(const char *var, const char *value, void *cb)
+static int git_get_color_config(const char *var, const char *value,
+ void *cb UNUSED)
{
if (!strcmp(var, get_color_slot)) {
if (!value)
@@ -490,7 +492,7 @@ static int get_colorbool_found;
static int get_diff_color_found;
static int get_color_ui_found;
static int git_get_colorbool_config(const char *var, const char *value,
- void *cb)
+ void *data UNUSED)
{
if (!strcmp(var, get_colorbool_slot))
get_colorbool_found = git_config_colorbool(var, value);
diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c
index 4c6c89ab0de..f3c89831d4a 100644
--- a/builtin/credential-cache--daemon.c
+++ b/builtin/credential-cache--daemon.c
@@ -267,7 +267,7 @@ int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix)
const char *socket_path;
int ignore_sighup = 0;
static const char *usage[] = {
- "git-credential-cache--daemon [opts] <socket_path>",
+ "git credential-cache--daemon [--debug] <socket-path>",
NULL
};
int debug = 0;
@@ -305,7 +305,7 @@ int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix)
int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix)
{
const char * const usage[] = {
- "git credential-cache--daemon [options] <action>",
+ "git credential-cache--daemon [--debug] <socket-path>",
"",
"credential-cache--daemon is disabled in this build of Git",
NULL
diff --git a/builtin/describe.c b/builtin/describe.c
index a76f1a1a7a7..23e3f05fb10 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -23,8 +23,9 @@
define_commit_slab(commit_names, struct commit_name *);
static const char * const describe_usage[] = {
- N_("git describe [<options>] [<commit-ish>...]"),
- N_("git describe [<options>] --dirty"),
+ N_("git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]"),
+ N_("git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]"),
+ N_("git describe <blob>"),
NULL
};
@@ -63,7 +64,7 @@ static const char *prio_names[] = {
N_("head"), N_("lightweight"), N_("annotated"),
};
-static int commit_name_neq(const void *unused_cmp_data,
+static int commit_name_neq(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *peeled)
@@ -140,7 +141,8 @@ static void add_to_known_names(const char *path,
}
}
-static int get_name(const char *path, const struct object_id *oid, int flag, void *cb_data)
+static int get_name(const char *path, const struct object_id *oid,
+ int flag UNUSED, void *cb_data UNUSED)
{
int is_tag = 0;
struct object_id peeled;
diff --git a/builtin/diagnose.c b/builtin/diagnose.c
index cd260c20155..d52015c67a4 100644
--- a/builtin/diagnose.c
+++ b/builtin/diagnose.c
@@ -3,7 +3,8 @@
#include "diagnose.h"
static const char * const diagnose_usage[] = {
- N_("git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--mode=<mode>]"),
+ N_("git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+ " [--mode=<mode>]"),
NULL
};
@@ -22,7 +23,7 @@ int cmd_diagnose(int argc, const char **argv, const char *prefix)
N_("specify a destination for the diagnostics archive")),
OPT_STRING('s', "suffix", &option_suffix, N_("format"),
N_("specify a strftime format suffix for the filename")),
- OPT_CALLBACK_F(0, "mode", &mode, N_("(stats|all)"),
+ OPT_CALLBACK_F(0, "mode", &mode, "(stats|all)",
N_("specify the content of the diagnostic archive"),
PARSE_OPT_NONEG, option_parse_diagnose),
OPT_END()
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 92cf6e1e922..096ea2fedbc 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -15,6 +15,7 @@
static const char diff_files_usage[] =
"git diff-files [-q] [-0 | -1 | -2 | -3 | -c | --cc] [<common-diff-options>] [<path>...]"
+"\n"
COMMON_DIFF_OPTIONS_HELP;
int cmd_diff_files(int argc, const char **argv, const char *prefix)
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 7d158af6b6d..aea139b9d8f 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -9,8 +9,9 @@
#include "submodule.h"
static const char diff_cache_usage[] =
-"git diff-index [-m] [--cached] "
+"git diff-index [-m] [--cached] [--merge-base] "
"[<common-diff-options>] <tree-ish> [<path>...]"
+"\n"
COMMON_DIFF_OPTIONS_HELP;
int cmd_diff_index(int argc, const char **argv, const char *prefix)
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 116097a404a..85e8c81e594 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -83,8 +83,10 @@ static int diff_tree_stdin(char *line)
}
static const char diff_tree_usage[] =
-"git diff-tree [--stdin] [-m] [-c | --cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
-"[<common-diff-options>] <tree-ish> [<tree-ish>] [<path>...]\n"
+"git diff-tree [--stdin] [-m] [-s] [-v] [--no-commit-id] [--pretty]\n"
+" [-t] [-r] [-c | --cc] [--combined-all-paths] [--root] [--merge-base]\n"
+" [<common-diff-options>] <tree-ish> [<tree-ish>] [<path>...]\n"
+"\n"
" -r diff recursively\n"
" -c show combined diff for merge commits\n"
" --cc show combined diff for merge commits removing uninteresting hunks\n"
diff --git a/builtin/diff.c b/builtin/diff.c
index 54bb3de964c..854d2c5a5c4 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -30,7 +30,8 @@ static const char builtin_diff_usage[] =
" or: git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...]\n"
" or: git diff [<options>] <commit>...<commit> [--] [<path>...]\n"
" or: git diff [<options>] <blob> <blob>\n"
-" or: git diff [<options>] --no-index [--] <path> <path>\n"
+" or: git diff [<options>] --no-index [--] <path> <path>"
+"\n"
COMMON_DIFF_OPTIONS_HELP;
static const char *blob_path(struct object_array_entry *entry)
@@ -209,7 +210,7 @@ static int builtin_diff_tree(struct rev_info *revs,
static int builtin_diff_combined(struct rev_info *revs,
int argc, const char **argv,
struct object_array_entry *ent,
- int ents)
+ int ents, int first_non_parent)
{
struct oid_array parents = OID_ARRAY_INIT;
int i;
@@ -217,11 +218,18 @@ static int builtin_diff_combined(struct rev_info *revs,
if (argc > 1)
usage(builtin_diff_usage);
+ if (first_non_parent < 0)
+ die(_("no merge given, only parents."));
+ if (first_non_parent >= ents)
+ BUG("first_non_parent out of range: %d", first_non_parent);
+
diff_merges_set_dense_combined_if_unset(revs);
- for (i = 1; i < ents; i++)
- oid_array_append(&parents, &ent[i].item->oid);
- diff_tree_combined(&ent[0].item->oid, &parents, revs);
+ for (i = 0; i < ents; i++) {
+ if (i != first_non_parent)
+ oid_array_append(&parents, &ent[i].item->oid);
+ }
+ diff_tree_combined(&ent[first_non_parent].item->oid, &parents, revs);
oid_array_clear(&parents);
return 0;
}
@@ -385,6 +393,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
int i;
struct rev_info rev;
struct object_array ent = OBJECT_ARRAY_INIT;
+ int first_non_parent = -1;
int blobs = 0, paths = 0;
struct object_array_entry *blob[2];
int nongit = 0, no_index = 0;
@@ -543,6 +552,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
continue;
obj->flags |= flags;
add_object_array(obj, name, &ent);
+ if (first_non_parent < 0 &&
+ (i >= rev.cmdline.nr || /* HEAD by hand. */
+ rev.cmdline.rev[i].whence != REV_CMD_PARENTS_ONLY))
+ first_non_parent = ent.nr - 1;
} else if (obj->type == OBJ_BLOB) {
if (2 <= blobs)
die(_("more than two blobs given: '%s'"), name);
@@ -590,7 +603,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
&ent.objects[0], &ent.objects[1]);
} else
result = builtin_diff_combined(&rev, argc, argv,
- ent.objects, ent.nr);
+ ent.objects, ent.nr,
+ first_non_parent);
result = diff_result_code(&rev.diffopt, result);
if (1 < rev.diffopt.skip_stat_unmatch)
refresh_index_quietly();
diff --git a/builtin/difftool.c b/builtin/difftool.c
index b3c509b8de3..d7f08c8a7fa 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -44,8 +44,11 @@ static int difftool_config(const char *var, const char *value, void *cb)
static int print_tool_help(void)
{
- const char *argv[] = { "mergetool", "--tool-help=diff", NULL };
- return run_command_v_opt(argv, RUN_GIT_CMD);
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "mergetool", "--tool-help=diff", NULL);
+ return run_command(&cmd);
}
static int parse_index_info(char *p, int *mode1, int *mode2,
@@ -125,10 +128,10 @@ struct working_tree_entry {
char path[FLEX_ARRAY];
};
-static int working_tree_entry_cmp(const void *unused_cmp_data,
+static int working_tree_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct working_tree_entry *a, *b;
@@ -148,10 +151,10 @@ struct pair_entry {
const char path[FLEX_ARRAY];
};
-static int pair_cmp(const void *unused_cmp_data,
+static int pair_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct pair_entry *a, *b;
@@ -184,7 +187,7 @@ struct path_entry {
char path[FLEX_ARRAY];
};
-static int path_entry_cmp(const void *unused_cmp_data,
+static int path_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *key)
@@ -360,8 +363,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
struct pair_entry *entry;
struct index_state wtindex;
struct checkout lstate, rstate;
- int flags = RUN_GIT_CMD, err = 0;
- const char *helper_argv[] = { "difftool--helper", NULL, NULL, NULL };
+ int err = 0;
+ struct child_process cmd = CHILD_PROCESS_INIT;
struct hashmap wt_modified, tmp_modified;
int indices_loaded = 0;
@@ -563,16 +566,17 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
}
strbuf_setlen(&ldir, ldir_len);
- helper_argv[1] = ldir.buf;
strbuf_setlen(&rdir, rdir_len);
- helper_argv[2] = rdir.buf;
if (extcmd) {
- helper_argv[0] = extcmd;
- flags = 0;
- } else
+ strvec_push(&cmd.args, extcmd);
+ } else {
+ strvec_push(&cmd.args, "difftool--helper");
+ cmd.git_cmd = 1;
setenv("GIT_DIFFTOOL_DIRDIFF", "true", 1);
- ret = run_command_v_opt(helper_argv, flags);
+ }
+ strvec_pushl(&cmd.args, ldir.buf, rdir.buf, NULL);
+ ret = run_command(&cmd);
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(&wtindex);
@@ -716,7 +720,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)
symlinks = has_symlinks;
argc = parse_options(argc, argv, prefix, builtin_difftool_options,
- builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN |
+ builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN_OPT |
PARSE_OPT_KEEP_DASHDASH);
if (tool_help)
diff --git a/builtin/env--helper.c b/builtin/env--helper.c
index 27349098b07..ea04c166364 100644
--- a/builtin/env--helper.c
+++ b/builtin/env--helper.c
@@ -50,7 +50,7 @@ int cmd_env__helper(int argc, const char **argv, const char *prefix)
};
argc = parse_options(argc, argv, prefix, opts, env__helper_usage,
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
if (env_default && !*env_default)
usage_with_options(env__helper_usage, opts);
if (!cmdmode)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index e1748fb98be..3b3314e7b2a 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -119,7 +119,7 @@ struct anonymized_entry_key {
size_t orig_len;
};
-static int anonymized_entry_cmp(const void *unused_cmp_data,
+static int anonymized_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
@@ -1221,7 +1221,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
revs.sources = &revision_sources;
revs.rewrite_parents = 1;
argc = parse_options(argc, argv, prefix, options, fast_export_usage,
- PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
argc = setup_revisions(argc, argv, &revs, NULL);
if (argc > 1)
usage_with_options (fast_export_usage, options);
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 14113cfd82b..7134683ab93 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -46,7 +46,7 @@ struct object_entry {
depth : DEPTH_BITS;
};
-static int object_entry_hashcmp(const void *map_data,
+static int object_entry_hashcmp(const void *map_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index f045bbbe946..afe679368de 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -62,6 +62,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
packet_trace_identity("fetch-pack");
memset(&args, 0, sizeof(args));
+ list_objects_filter_init(&args.filter_options);
args.uploadpack = "git-upload-pack";
for (i = 1; i < argc && *argv[i] == '-'; i++) {
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 368a0f5329c..7378cafeec9 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -80,7 +80,7 @@ static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
static int shown_url = 0;
static struct refspec refmap = REFSPEC_INIT_FETCH;
-static struct list_objects_filter_options filter_options;
+static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
static struct string_list server_options = STRING_LIST_INIT_DUP;
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
static int fetch_write_commit_graph = -1;
@@ -122,6 +122,8 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
fetch_parallel_config = git_config_int(k, v);
if (fetch_parallel_config < 0)
die(_("fetch.parallel cannot be negative"));
+ if (!fetch_parallel_config)
+ fetch_parallel_config = online_cpus();
return 0;
}
@@ -301,7 +303,7 @@ struct refname_hash_entry {
char refname[FLEX_ARRAY];
};
-static int refname_hash_entry_cmp(const void *hashmap_cmp_fn_data,
+static int refname_hash_entry_cmp(const void *hashmap_cmp_fn_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
@@ -329,7 +331,7 @@ static struct refname_hash_entry *refname_hash_add(struct hashmap *map,
static int add_one_refname(const char *refname,
const struct object_id *oid,
- int flag, void *cbdata)
+ int flag UNUSED, void *cbdata)
{
struct hashmap *refname_map = cbdata;
@@ -1464,8 +1466,9 @@ static void set_option(struct transport *transport, const char *name, const char
}
-static int add_oid(const char *refname, const struct object_id *oid, int flags,
- void *cb_data)
+static int add_oid(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flags UNUSED, void *cb_data)
{
struct oid_array *oids = cb_data;
@@ -1616,9 +1619,21 @@ static int do_fetch(struct transport *transport,
break;
}
}
- } else if (transport->remote && transport->remote->fetch.nr)
- refspec_ref_prefixes(&transport->remote->fetch,
- &transport_ls_refs_options.ref_prefixes);
+ } else {
+ struct branch *branch = branch_get(NULL);
+
+ if (transport->remote->fetch.nr)
+ refspec_ref_prefixes(&transport->remote->fetch,
+ &transport_ls_refs_options.ref_prefixes);
+ if (branch_has_merge_config(branch) &&
+ !strcmp(branch->remote_name, transport->remote->name)) {
+ int i;
+ for (i = 0; i < branch->merge_nr; i++) {
+ strvec_push(&transport_ls_refs_options.ref_prefixes,
+ branch->merge[i]->src);
+ }
+ }
+ }
if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
must_list_refs = 1;
@@ -1938,28 +1953,36 @@ static int fetch_multiple(struct string_list *list, int max_children)
if (max_children != 1 && list->nr != 1) {
struct parallel_fetch_state state = { argv.v, list, 0, 0 };
+ const struct run_process_parallel_opts opts = {
+ .tr2_category = "fetch",
+ .tr2_label = "parallel/fetch",
+
+ .processes = max_children,
+
+ .get_next_task = &fetch_next_remote,
+ .start_failure = &fetch_failed_to_start,
+ .task_finished = &fetch_finished,
+ .data = &state,
+ };
strvec_push(&argv, "--end-of-options");
- result = run_processes_parallel_tr2(max_children,
- &fetch_next_remote,
- &fetch_failed_to_start,
- &fetch_finished,
- &state,
- "fetch", "parallel/fetch");
-
- if (!result)
- result = state.result;
+
+ run_processes_parallel(&opts);
+ result = state.result;
} else
for (i = 0; i < list->nr; i++) {
const char *name = list->items[i].string;
- strvec_push(&argv, name);
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_pushv(&cmd.args, argv.v);
+ strvec_push(&cmd.args, name);
if (verbosity >= 0)
printf(_("Fetching %s\n"), name);
- if (run_command_v_opt(argv.v, RUN_GIT_CMD)) {
+ cmd.git_cmd = 1;
+ if (run_command(&cmd)) {
error(_("could not fetch %s"), name);
result = 1;
}
- strvec_pop(&argv);
}
strvec_clear(&argv);
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
index fd86e5a8619..6aeac371488 100644
--- a/builtin/for-each-repo.c
+++ b/builtin/for-each-repo.c
@@ -6,7 +6,7 @@
#include "string-list.h"
static const char * const for_each_repo_usage[] = {
- N_("git for-each-repo --config=<config> <command-args>"),
+ N_("git for-each-repo --config=<config> [--] <arguments>"),
NULL
};
@@ -14,13 +14,16 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv)
{
int i;
struct child_process child = CHILD_PROCESS_INIT;
+ char *abspath = interpolate_path(path, 0);
child.git_cmd = 1;
- strvec_pushl(&child.args, "-C", path, NULL);
+ strvec_pushl(&child.args, "-C", abspath, NULL);
for (i = 0; i < argc; i++)
strvec_push(&child.args, argv[i]);
+ free(abspath);
+
return run_command(&child);
}
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 6c73092f10d..7436e1a68ef 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -228,6 +228,8 @@ static void mark_unreachable_referents(const struct object_id *oid)
options.walk = mark_used;
fsck_walk(obj, NULL, &options);
+ if (obj->type == OBJ_TREE)
+ free_tree_buffer((struct tree *)obj);
}
static int mark_loose_unreachable_referents(const struct object_id *oid,
@@ -437,9 +439,6 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
out:
if (obj->type == OBJ_TREE)
free_tree_buffer((struct tree *)obj);
- if (obj->type == OBJ_COMMIT)
- free_commit_buffer(the_repository->parsed_objects,
- (struct commit *)obj);
return err;
}
@@ -488,8 +487,9 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
}
static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+ const char *email UNUSED,
+ timestamp_t timestamp, int tz UNUSED,
+ const char *message UNUSED, void *cb_data)
{
const char *refname = cb_data;
@@ -502,8 +502,9 @@ static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid
return 0;
}
-static int fsck_handle_reflog(const char *logname, const struct object_id *oid,
- int flag, void *cb_data)
+static int fsck_handle_reflog(const char *logname,
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cb_data)
{
struct strbuf refname = STRBUF_INIT;
@@ -514,7 +515,7 @@ static int fsck_handle_reflog(const char *logname, const struct object_id *oid,
}
static int fsck_handle_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data UNUSED)
{
struct object *obj;
@@ -819,7 +820,10 @@ static int mark_packed_for_connectivity(const struct object_id *oid,
}
static char const * const fsck_usage[] = {
- N_("git fsck [<options>] [<object>...]"),
+ N_("git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n"
+ " [--[no-]full] [--strict] [--verbose] [--lost-found]\n"
+ " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n"
+ " [--[no-]name-objects] [<object>...]"),
NULL
};
@@ -851,6 +855,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
errors_found = 0;
read_replace_refs = 0;
+ save_commit_buffer = 0;
argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c
index 2c109cf8b37..6f30a4f93a7 100644
--- a/builtin/fsmonitor--daemon.c
+++ b/builtin/fsmonitor--daemon.c
@@ -3,6 +3,7 @@
#include "parse-options.h"
#include "fsmonitor.h"
#include "fsmonitor-ipc.h"
+#include "fsmonitor-path-utils.h"
#include "compat/fsmonitor/fsm-health.h"
#include "compat/fsmonitor/fsm-listen.h"
#include "fsmonitor--daemon.h"
@@ -13,8 +14,8 @@
static const char * const builtin_fsmonitor__daemon_usage[] = {
N_("git fsmonitor--daemon start [<options>]"),
N_("git fsmonitor--daemon run [<options>]"),
- N_("git fsmonitor--daemon stop"),
- N_("git fsmonitor--daemon status"),
+ "git fsmonitor--daemon stop",
+ "git fsmonitor--daemon status",
NULL
};
@@ -1282,6 +1283,11 @@ static int fsmonitor_run_daemon(void)
strbuf_addstr(&state.path_worktree_watch, absolute_path(get_git_work_tree()));
state.nr_paths_watching = 1;
+ strbuf_init(&state.alias.alias, 0);
+ strbuf_init(&state.alias.points_to, 0);
+ if ((err = fsmonitor__get_alias(state.path_worktree_watch.buf, &state.alias)))
+ goto done;
+
/*
* We create and delete cookie files somewhere inside the .git
* directory to help us keep sync with the file system. If
@@ -1343,7 +1349,8 @@ static int fsmonitor_run_daemon(void)
* directory.)
*/
strbuf_init(&state.path_ipc, 0);
- strbuf_addstr(&state.path_ipc, absolute_path(fsmonitor_ipc__get_path()));
+ strbuf_addstr(&state.path_ipc,
+ absolute_path(fsmonitor_ipc__get_path(the_repository)));
/*
* Confirm that we can create platform-specific resources for the
@@ -1390,6 +1397,8 @@ done:
strbuf_release(&state.path_gitdir_watch);
strbuf_release(&state.path_cookie_prefix);
strbuf_release(&state.path_ipc);
+ strbuf_release(&state.alias.alias);
+ strbuf_release(&state.alias.points_to);
return err;
}
diff --git a/builtin/gc.c b/builtin/gc.c
index 6c222052177..ed34eadc10e 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -42,7 +42,7 @@ static const char * const builtin_gc_usage[] = {
static int pack_refs = 1;
static int prune_reflogs = 1;
-static int cruft_packs = 0;
+static int cruft_packs = -1;
static int aggressive_depth = 50;
static int aggressive_window = 250;
static int gc_auto_threshold = 6700;
@@ -167,16 +167,11 @@ static void gc_config(void)
struct maintenance_run_opts;
static int maintenance_task_pack_refs(MAYBE_UNUSED struct maintenance_run_opts *opts)
{
- struct strvec pack_refs_cmd = STRVEC_INIT;
- int ret;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&pack_refs_cmd, "pack-refs", "--all", "--prune", NULL);
-
- ret = run_command_v_opt(pack_refs_cmd.v, RUN_GIT_CMD);
-
- strvec_clear(&pack_refs_cmd);
-
- return ret;
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "pack-refs", "--all", "--prune", NULL);
+ return run_command(&cmd);
}
static int too_many_loose_objects(void)
@@ -329,7 +324,7 @@ static uint64_t estimate_repack_memory(struct packed_git *pack)
return os_cache + heap;
}
-static int keep_one_pack(struct string_list_item *item, void *data)
+static int keep_one_pack(struct string_list_item *item, void *data UNUSED)
{
strvec_pushf(&repack, "--keep-pack=%s", basename(item->string));
return 0;
@@ -542,8 +537,14 @@ static void gc_before_repack(void)
if (pack_refs && maintenance_task_pack_refs(NULL))
die(FAILED_RUN, "pack-refs");
- if (prune_reflogs && run_command_v_opt(reflog.v, RUN_GIT_CMD))
- die(FAILED_RUN, reflog.v[0]);
+ if (prune_reflogs) {
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ cmd.git_cmd = 1;
+ strvec_pushv(&cmd.args, reflog.v);
+ if (run_command(&cmd))
+ die(FAILED_RUN, reflog.v[0]);
+ }
}
int cmd_gc(int argc, const char **argv, const char *prefix)
@@ -557,6 +558,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
int daemonized = 0;
int keep_largest_pack = -1;
timestamp_t dummy;
+ struct child_process rerere_cmd = CHILD_PROCESS_INIT;
struct option builtin_gc_options[] = {
OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -600,6 +602,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (prune_expire && parse_expiry_date(prune_expire, &dummy))
die(_("failed to parse prune expiry value %s"), prune_expire);
+ prepare_repo_settings(the_repository);
+ if (cruft_packs < 0)
+ cruft_packs = the_repository->settings.gc_cruft_packs;
+
if (aggressive) {
strvec_push(&repack, "-f");
if (aggressive_depth > 0)
@@ -678,11 +684,17 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
gc_before_repack();
if (!repository_format_precious_objects) {
- if (run_command_v_opt(repack.v,
- RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE))
+ struct child_process repack_cmd = CHILD_PROCESS_INIT;
+
+ repack_cmd.git_cmd = 1;
+ repack_cmd.close_object_store = 1;
+ strvec_pushv(&repack_cmd.args, repack.v);
+ if (run_command(&repack_cmd))
die(FAILED_RUN, repack.v[0]);
if (prune_expire) {
+ struct child_process prune_cmd = CHILD_PROCESS_INIT;
+
/* run `git prune` even if using cruft packs */
strvec_push(&prune, prune_expire);
if (quiet)
@@ -690,18 +702,26 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (has_promisor_remote())
strvec_push(&prune,
"--exclude-promisor-objects");
- if (run_command_v_opt(prune.v, RUN_GIT_CMD))
+ prune_cmd.git_cmd = 1;
+ strvec_pushv(&prune_cmd.args, prune.v);
+ if (run_command(&prune_cmd))
die(FAILED_RUN, prune.v[0]);
}
}
if (prune_worktrees_expire) {
+ struct child_process prune_worktrees_cmd = CHILD_PROCESS_INIT;
+
strvec_push(&prune_worktrees, prune_worktrees_expire);
- if (run_command_v_opt(prune_worktrees.v, RUN_GIT_CMD))
+ prune_worktrees_cmd.git_cmd = 1;
+ strvec_pushv(&prune_worktrees_cmd.args, prune_worktrees.v);
+ if (run_command(&prune_worktrees_cmd))
die(FAILED_RUN, prune_worktrees.v[0]);
}
- if (run_command_v_opt(rerere.v, RUN_GIT_CMD))
+ rerere_cmd.git_cmd = 1;
+ strvec_pushv(&rerere_cmd.args, rerere.v);
+ if (run_command(&rerere_cmd))
die(FAILED_RUN, rerere.v[0]);
report_garbage = report_pack_garbage;
@@ -711,7 +731,6 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
clean_pack_garbage();
}
- prepare_repo_settings(the_repository);
if (the_repository->settings.gc_write_commit_graph == 1)
write_commit_graph_reachable(the_repository->objects->odb,
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
@@ -782,8 +801,9 @@ struct cg_auto_data {
int limit;
};
-static int dfs_on_ref(const char *refname,
- const struct object_id *oid, int flags,
+static int dfs_on_ref(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flags UNUSED,
void *cb_data)
{
struct cg_auto_data *data = (struct cg_auto_data *)cb_data;
@@ -1459,13 +1479,30 @@ static char *get_maintpath(void)
return strbuf_detach(&sb, NULL);
}
-static int maintenance_register(void)
+static char const * const builtin_maintenance_register_usage[] = {
+ "git maintenance register [--config-file <path>]",
+ NULL
+};
+
+static int maintenance_register(int argc, const char **argv, const char *prefix)
{
- int rc;
+ char *config_file = NULL;
+ struct option options[] = {
+ OPT_STRING(0, "config-file", &config_file, N_("file"), N_("use given config file")),
+ OPT_END(),
+ };
+ int found = 0;
+ const char *key = "maintenance.repo";
char *config_value;
- struct child_process config_set = CHILD_PROCESS_INIT;
- struct child_process config_get = CHILD_PROCESS_INIT;
char *maintpath = get_maintpath();
+ struct string_list_item *item;
+ const struct string_list *list;
+
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_maintenance_register_usage, 0);
+ if (argc)
+ usage_with_options(builtin_maintenance_register_usage,
+ options);
/* Disable foreground maintenance */
git_config_set("maintenance.auto", "false");
@@ -1476,46 +1513,106 @@ static int maintenance_register(void)
else
git_config_set("maintenance.strategy", "incremental");
- config_get.git_cmd = 1;
- strvec_pushl(&config_get.args, "config", "--global", "--get",
- "--fixed-value", "maintenance.repo", maintpath, NULL);
- config_get.out = -1;
-
- if (start_command(&config_get)) {
- rc = error(_("failed to run 'git config'"));
- goto done;
- }
-
- /* We already have this value in our config! */
- if (!finish_command(&config_get)) {
- rc = 0;
- goto done;
+ list = git_config_get_value_multi(key);
+ if (list) {
+ for_each_string_list_item(item, list) {
+ if (!strcmp(maintpath, item->string)) {
+ found = 1;
+ break;
+ }
+ }
}
- config_set.git_cmd = 1;
- strvec_pushl(&config_set.args, "config", "--add", "--global", "maintenance.repo",
- maintpath, NULL);
+ if (!found) {
+ int rc;
+ char *user_config = NULL, *xdg_config = NULL;
- rc = run_command(&config_set);
+ if (!config_file) {
+ git_global_config(&user_config, &xdg_config);
+ config_file = user_config;
+ if (!user_config)
+ die(_("$HOME not set"));
+ }
+ rc = git_config_set_multivar_in_file_gently(
+ config_file, "maintenance.repo", maintpath,
+ CONFIG_REGEX_NONE, 0);
+ free(user_config);
+ free(xdg_config);
+
+ if (rc)
+ die(_("unable to add '%s' value of '%s'"),
+ key, maintpath);
+ }
-done:
free(maintpath);
- return rc;
+ return 0;
}
-static int maintenance_unregister(void)
+static char const * const builtin_maintenance_unregister_usage[] = {
+ "git maintenance unregister [--config-file <path>] [--force]",
+ NULL
+};
+
+static int maintenance_unregister(int argc, const char **argv, const char *prefix)
{
- int rc;
- struct child_process config_unset = CHILD_PROCESS_INIT;
+ int force = 0;
+ char *config_file = NULL;
+ struct option options[] = {
+ OPT_STRING(0, "config-file", &config_file, N_("file"), N_("use given config file")),
+ OPT__FORCE(&force,
+ N_("return success even if repository was not registered"),
+ PARSE_OPT_NOCOMPLETE),
+ OPT_END(),
+ };
+ const char *key = "maintenance.repo";
char *maintpath = get_maintpath();
+ int found = 0;
+ struct string_list_item *item;
+ const struct string_list *list;
- config_unset.git_cmd = 1;
- strvec_pushl(&config_unset.args, "config", "--global", "--unset",
- "--fixed-value", "maintenance.repo", maintpath, NULL);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_maintenance_unregister_usage, 0);
+ if (argc)
+ usage_with_options(builtin_maintenance_unregister_usage,
+ options);
+
+ if (!config_file) {
+ list = git_config_get_value_multi(key);
+ if (list) {
+ for_each_string_list_item(item, list) {
+ if (!strcmp(maintpath, item->string)) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ if (found || config_file) {
+ int rc;
+ char *user_config = NULL, *xdg_config = NULL;
+ if (!config_file) {
+ git_global_config(&user_config, &xdg_config);
+ config_file = user_config;
+ if (!user_config)
+ die(_("$HOME not set"));
+ }
+ rc = git_config_set_multivar_in_file_gently(
+ config_file, key, NULL, maintpath,
+ CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE);
+ free(user_config);
+ free(xdg_config);
+
+ if (rc &&
+ (!force || rc == CONFIG_NOTHING_SET))
+ die(_("unable to unset '%s' value of '%s'"),
+ key, maintpath);
+ } else if (!force) {
+ die(_("repository '%s' is not registered"), maintpath);
+ }
- rc = run_command(&config_unset);
free(maintpath);
- return rc;
+ return 0;
}
static const char *get_frequency(enum schedule_priority schedule)
@@ -1852,20 +1949,16 @@ static char *schtasks_task_name(const char *frequency)
static int schtasks_remove_task(enum schedule_priority schedule)
{
const char *cmd = "schtasks";
- int result;
- struct strvec args = STRVEC_INIT;
+ struct child_process child = CHILD_PROCESS_INIT;
const char *frequency = get_frequency(schedule);
char *name = schtasks_task_name(frequency);
get_schedule_cmd(&cmd, NULL);
- strvec_split(&args, cmd);
- strvec_pushl(&args, "/delete", "/tn", name, "/f", NULL);
-
- result = run_command_v_opt(args.v, 0);
-
- strvec_clear(&args);
+ strvec_split(&child.args, cmd);
+ strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL);
free(name);
- return result;
+
+ return run_command(&child);
}
static int schtasks_remove_tasks(void)
@@ -2059,6 +2152,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)
struct child_process crontab_edit = CHILD_PROCESS_INIT;
FILE *cron_list, *cron_in;
struct strbuf line = STRBUF_INIT;
+ struct tempfile *tmpedit = NULL;
get_schedule_cmd(&cmd, NULL);
strvec_split(&crontab_list.args, cmd);
@@ -2073,6 +2167,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
/* Ignore exit code, as an empty crontab will return error. */
finish_command(&crontab_list);
+ tmpedit = mks_tempfile_t(".git_cron_edit_tmpXXXXXX");
+ if (!tmpedit) {
+ result = error(_("failed to create crontab temporary file"));
+ goto out;
+ }
+ cron_in = fdopen_tempfile(tmpedit, "w");
+ if (!cron_in) {
+ result = error(_("failed to open temporary file"));
+ goto out;
+ }
+
/*
* Read from the .lock file, filtering out the old
* schedule while appending the new schedule.
@@ -2080,19 +2185,6 @@ static int crontab_update_schedule(int run_maintenance, int fd)
cron_list = fdopen(fd, "r");
rewind(cron_list);
- strvec_split(&crontab_edit.args, cmd);
- crontab_edit.in = -1;
- crontab_edit.git_cmd = 0;
-
- if (start_command(&crontab_edit))
- return error(_("failed to run 'crontab'; your system might not support 'cron'"));
-
- cron_in = fdopen(crontab_edit.in, "w");
- if (!cron_in) {
- result = error(_("failed to open stdin of 'crontab'"));
- goto done_editing;
- }
-
while (!strbuf_getline_lf(&line, cron_list)) {
if (!in_old_region && !strcmp(line.buf, BEGIN_LINE))
in_old_region = 1;
@@ -2126,14 +2218,22 @@ static int crontab_update_schedule(int run_maintenance, int fd)
}
fflush(cron_in);
- fclose(cron_in);
- close(crontab_edit.in);
-done_editing:
+ strvec_split(&crontab_edit.args, cmd);
+ strvec_push(&crontab_edit.args, get_tempfile_path(tmpedit));
+ crontab_edit.git_cmd = 0;
+
+ if (start_command(&crontab_edit)) {
+ result = error(_("failed to run 'crontab'; your system might not support 'cron'"));
+ goto out;
+ }
+
if (finish_command(&crontab_edit))
result = error(_("'crontab' died"));
else
fclose(cron_list);
+out:
+ delete_tempfile(&tmpedit);
return result;
}
@@ -2490,6 +2590,7 @@ static int maintenance_start(int argc, const char **argv, const char *prefix)
PARSE_OPT_NONEG, maintenance_opt_scheduler),
OPT_END()
};
+ const char *register_args[] = { "register", NULL };
argc = parse_options(argc, argv, prefix, options,
builtin_maintenance_start_usage, 0);
@@ -2499,34 +2600,46 @@ static int maintenance_start(int argc, const char **argv, const char *prefix)
opts.scheduler = resolve_scheduler(opts.scheduler);
validate_scheduler(opts.scheduler);
- if (maintenance_register())
+ if (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL))
warning(_("failed to add repo to global config"));
return update_background_schedule(&opts, 1);
}
-static int maintenance_stop(void)
+static const char *const builtin_maintenance_stop_usage[] = {
+ "git maintenance stop",
+ NULL
+};
+
+static int maintenance_stop(int argc, const char **argv, const char *prefix)
{
+ struct option options[] = {
+ OPT_END()
+ };
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_maintenance_stop_usage, 0);
+ if (argc)
+ usage_with_options(builtin_maintenance_stop_usage, options);
return update_background_schedule(NULL, 0);
}
-static const char builtin_maintenance_usage[] = N_("git maintenance <subcommand> [<options>]");
+static const char * const builtin_maintenance_usage[] = {
+ N_("git maintenance <subcommand> [<options>]"),
+ NULL,
+};
int cmd_maintenance(int argc, const char **argv, const char *prefix)
{
- if (argc < 2 ||
- (argc == 2 && !strcmp(argv[1], "-h")))
- usage(builtin_maintenance_usage);
-
- if (!strcmp(argv[1], "run"))
- return maintenance_run(argc - 1, argv + 1, prefix);
- if (!strcmp(argv[1], "start"))
- return maintenance_start(argc - 1, argv + 1, prefix);
- if (!strcmp(argv[1], "stop"))
- return maintenance_stop();
- if (!strcmp(argv[1], "register"))
- return maintenance_register();
- if (!strcmp(argv[1], "unregister"))
- return maintenance_unregister();
-
- die(_("invalid subcommand: %s"), argv[1]);
+ parse_opt_subcommand_fn *fn = NULL;
+ struct option builtin_maintenance_options[] = {
+ OPT_SUBCOMMAND("run", &fn, maintenance_run),
+ OPT_SUBCOMMAND("start", &fn, maintenance_start),
+ OPT_SUBCOMMAND("stop", &fn, maintenance_stop),
+ OPT_SUBCOMMAND("register", &fn, maintenance_register),
+ OPT_SUBCOMMAND("unregister", &fn, maintenance_unregister),
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, prefix, builtin_maintenance_options,
+ builtin_maintenance_usage, 0);
+ return fn(argc, argv, prefix);
}
diff --git a/builtin/grep.c b/builtin/grep.c
index e6bcdf860cc..5fa927d4e22 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -458,6 +458,33 @@ static int grep_submodule(struct grep_opt *opt,
* subrepo's odbs to the in-memory alternates list.
*/
obj_read_lock();
+
+ /*
+ * NEEDSWORK: when reading a submodule, the sparsity settings in the
+ * superproject are incorrectly forgotten or misused. For example:
+ *
+ * 1. "command_requires_full_index"
+ * When this setting is turned on for `grep`, only the superproject
+ * knows it. All the submodules are read with their own configs
+ * and get prepare_repo_settings()'d. Therefore, these submodules
+ * "forget" the sparse-index feature switch. As a result, the index
+ * of these submodules are expanded unexpectedly.
+ *
+ * 2. "core_apply_sparse_checkout"
+ * When running `grep` in the superproject, this setting is
+ * populated using the superproject's configs. However, once
+ * initialized, this config is globally accessible and is read by
+ * prepare_repo_settings() for the submodules. For instance, if a
+ * submodule is using a sparse-checkout, however, the superproject
+ * is not, the result is that the config from the superproject will
+ * dictate the behavior for the submodule, making it "forget" its
+ * sparse-checkout state.
+ *
+ * 3. "core_sparse_checkout_cone"
+ * ditto.
+ *
+ * Note that this list is not exhaustive.
+ */
repo_read_gitmodules(subrepo, 0);
/*
@@ -520,8 +547,6 @@ static int grep_cache(struct grep_opt *opt,
if (repo_read_index(repo) < 0)
die(_("index file corrupt"));
- /* TODO: audit for interaction with sparse-index. */
- ensure_full_index(repo->index);
for (nr = 0; nr < repo->index->cache_nr; nr++) {
const struct cache_entry *ce = repo->index->cache[nr];
@@ -530,8 +555,20 @@ static int grep_cache(struct grep_opt *opt,
strbuf_setlen(&name, name_base_len);
strbuf_addstr(&name, ce->name);
+ if (S_ISSPARSEDIR(ce->ce_mode)) {
+ enum object_type type;
+ struct tree_desc tree;
+ void *data;
+ unsigned long size;
- if (S_ISREG(ce->ce_mode) &&
+ data = read_object_file(&ce->oid, &type, &size);
+ init_tree_desc(&tree, data, size);
+
+ hit |= grep_tree(opt, pathspec, &tree, &name, 0, 0);
+ strbuf_setlen(&name, name_base_len);
+ strbuf_addstr(&name, ce->name);
+ free(data);
+ } else if (S_ISREG(ce->ce_mode) &&
match_pathspec(repo->index, pathspec, name.buf, name.len, 0, NULL,
S_ISDIR(ce->ce_mode) ||
S_ISGITLINK(ce->ce_mode))) {
@@ -984,6 +1021,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_STOP_AT_NON_OPTION);
+ if (the_repository->gitdir) {
+ prepare_repo_settings(the_repository);
+ the_repository->settings.command_requires_full_index = 0;
+ }
+
if (use_index && !startup_info->have_repository) {
int fallback = 0;
git_config_get_bool("grep.fallbacktonoindex", &fallback);
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index fbae878c2b9..b5063815020 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -80,8 +80,9 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,
int cmd_hash_object(int argc, const char **argv, const char *prefix)
{
static const char * const hash_object_usage[] = {
- N_("git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] [--] <file>..."),
- "git hash-object --stdin-paths",
+ N_("git hash-object [-t <type>] [-w] [--path=<file> | --no-filters]\n"
+ " [--stdin [--literally]] [--] <file>..."),
+ N_("git hash-object [-t <type>] [-w] --stdin-paths [--no-filters]"),
NULL
};
const char *type = blob_type;
diff --git a/builtin/help.c b/builtin/help.c
index 09ac4289f13..53f2812dfb1 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -88,7 +88,7 @@ static struct option builtin_help_options[] = {
};
static const char * const builtin_help_usage[] = {
- "git help [-a|--all] [--[no-]verbose]] [--[no-]external-commands] [--[no-]aliases]",
+ "git help [-a|--all] [--[no-]verbose] [--[no-]external-commands] [--[no-]aliases]",
N_("git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"),
"git help [-g|--guides]",
"git help [-c|--config]",
@@ -440,6 +440,8 @@ static const char *cmd_to_page(const char *git_cmd)
return git_cmd;
else if (is_git_command(git_cmd))
return xstrfmt("git-%s", git_cmd);
+ else if (!strcmp("scalar", git_cmd))
+ return xstrdup(git_cmd);
else
return xstrfmt("git%s", git_cmd);
}
diff --git a/builtin/hook.c b/builtin/hook.c
index 54e5c6ec933..b6530d189ad 100644
--- a/builtin/hook.c
+++ b/builtin/hook.c
@@ -67,18 +67,14 @@ usage:
int cmd_hook(int argc, const char **argv, const char *prefix)
{
+ parse_opt_subcommand_fn *fn = NULL;
struct option builtin_hook_options[] = {
+ OPT_SUBCOMMAND("run", &fn, run),
OPT_END(),
};
argc = parse_options(argc, argv, NULL, builtin_hook_options,
- builtin_hook_usage, PARSE_OPT_STOP_AT_NON_OPTION);
- if (!argc)
- goto usage;
+ builtin_hook_usage, 0);
- if (!strcmp(argv[0], "run"))
- return run(argc, argv, prefix);
-
-usage:
- usage_with_options(builtin_hook_usage, builtin_hook_options);
+ return fn(argc, argv, prefix);
}
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 546f9c595e7..dcaaf102eaf 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -515,7 +515,10 @@ static int shared_callback(const struct option *opt, const char *arg, int unset)
}
static const char *const init_db_usage[] = {
- N_("git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [<directory>]"),
+ N_("git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
+ " [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+ " [-b <branch-name> | --initial-branch=<branch-name>]\n"
+ " [--shared[=<permissions>]] [<directory>]"),
NULL
};
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index 84748eafc01..e58627c72a9 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -13,7 +13,9 @@
#include "config.h"
static const char * const git_interpret_trailers_usage[] = {
- N_("git interpret-trailers [--in-place] [--trim-empty] [(--trailer <token>[(=|:)<value>])...] [<file>...]"),
+ N_("git interpret-trailers [--in-place] [--trim-empty]\n"
+ " [(--trailer <token>[(=|:)<value>])...]\n"
+ " [--parse] [<file>...]"),
NULL
};
diff --git a/builtin/log.c b/builtin/log.c
index fd209725e56..5eafcf26b49 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -52,6 +52,7 @@ static int default_encode_email_headers = 1;
static int decoration_style;
static int decoration_given;
static int use_mailmap_config = 1;
+static unsigned int force_in_body_from;
static const char *fmt_patch_subject_prefix = "PATCH";
static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT;
static const char *fmt_pretty;
@@ -260,7 +261,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
mailmap = use_mailmap_config;
argc = parse_options(argc, argv, prefix,
builtin_log_options, builtin_log_usage,
- PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |
PARSE_OPT_KEEP_DASHDASH);
if (quiet)
@@ -697,9 +698,10 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev)
return 0;
}
-static int show_tree_object(const struct object_id *oid,
- struct strbuf *base,
- const char *pathname, unsigned mode, void *context)
+static int show_tree_object(const struct object_id *oid UNUSED,
+ struct strbuf *base UNUSED,
+ const char *pathname, unsigned mode,
+ void *context)
{
FILE *file = context;
fprintf(file, "%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
@@ -1058,6 +1060,10 @@ static int git_format_config(const char *var, const char *value, void *cb)
from = NULL;
return 0;
}
+ if (!strcmp(var, "format.forceinbodyfrom")) {
+ force_in_body_from = git_config_bool(var, value);
+ return 0;
+ }
if (!strcmp(var, "format.notes")) {
int b = git_parse_maybe_bool(value);
if (b < 0)
@@ -1328,6 +1334,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
log.in2 = 4;
log.file = rev->diffopt.file;
log.groups = SHORTLOG_GROUP_AUTHOR;
+ shortlog_finish_setup(&log);
for (i = 0; i < nr; i++)
shortlog_add_commit(&log, list[i]);
@@ -1757,7 +1764,7 @@ static void prepare_bases(struct base_tree_info *bases,
struct object_id *patch_id;
if (*commit_base_at(&commit_base, commit))
continue;
- if (commit_patch_id(commit, &diffopt, &oid, 0, 1))
+ if (commit_patch_id(commit, &diffopt, &oid, 0))
die(_("cannot get patch id"));
ALLOC_GROW(bases->patch_id, bases->nr_patch_id + 1, bases->alloc_patch_id);
patch_id = bases->patch_id + bases->nr_patch_id;
@@ -1949,6 +1956,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
N_("show changes against <refspec> in cover letter or single patch")),
OPT_INTEGER(0, "creation-factor", &creation_factor,
N_("percentage by which creation is weighted")),
+ OPT_BOOL(0, "force-in-body-from", &force_in_body_from,
+ N_("show in-body From: even if identical to the e-mail header")),
OPT_END()
};
@@ -1989,9 +1998,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
*/
argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
builtin_format_patch_usage,
- PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |
PARSE_OPT_KEEP_DASHDASH);
+ rev.force_in_body_from = force_in_body_from;
+
/* Make sure "0000-$sub.patch" gives non-negative length for $sub */
if (fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix))
fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 779dc18e59d..4cf8a236483 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -257,7 +257,7 @@ static size_t expand_show_index(struct strbuf *sb, const char *start,
end = strchr(start + 1, ')');
if (!end)
- die(_("bad ls-files format: element '%s'"
+ die(_("bad ls-files format: element '%s' "
"does not end in ')'"), start);
len = end - start + 1;
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index df44e5cc0d1..5d5ac038716 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -7,7 +7,7 @@
static const char * const ls_remote_usage[] = {
N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
- " [-q | --quiet] [--exit-code] [--get-url]\n"
+ " [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
" [--symref] [<repository> [<refs>...]]"),
NULL
};
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index e279be8bb63..c3ea09281af 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -142,7 +142,7 @@ static int show_recursive(const char *base, size_t baselen, const char *pathname
}
static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
- const char *pathname, unsigned mode, void *context)
+ const char *pathname, unsigned mode, void *context UNUSED)
{
size_t baselen;
int recurse = 0;
@@ -213,7 +213,7 @@ static void show_tree_common_default_long(struct strbuf *base,
static int show_tree_default(const struct object_id *oid, struct strbuf *base,
const char *pathname, unsigned mode,
- void *context)
+ void *context UNUSED)
{
int early;
int recurse;
@@ -230,7 +230,8 @@ static int show_tree_default(const struct object_id *oid, struct strbuf *base,
}
static int show_tree_long(const struct object_id *oid, struct strbuf *base,
- const char *pathname, unsigned mode, void *context)
+ const char *pathname, unsigned mode,
+ void *context UNUSED)
{
int early;
int recurse;
@@ -259,7 +260,8 @@ static int show_tree_long(const struct object_id *oid, struct strbuf *base,
}
static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,
- const char *pathname, unsigned mode, void *context)
+ const char *pathname, unsigned mode,
+ void *context UNUSED)
{
int early;
int recurse;
@@ -279,7 +281,8 @@ static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,
}
static int show_tree_object(const struct object_id *oid, struct strbuf *base,
- const char *pathname, unsigned mode, void *context)
+ const char *pathname, unsigned mode,
+ void *context UNUSED)
{
int early;
int recurse;
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index a11f8c6e4bb..6f3941f2a49 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -31,8 +31,8 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
static const char * const merge_base_usage[] = {
N_("git merge-base [-a | --all] <commit> <commit>..."),
N_("git merge-base [-a | --all] --octopus <commit>..."),
- N_("git merge-base --independent <commit>..."),
N_("git merge-base --is-ancestor <commit> <commit>"),
+ N_("git merge-base --independent <commit>..."),
N_("git merge-base --fork-point <ref> [<commit>]"),
NULL
};
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index c0383fe9df9..012f52bd007 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -12,6 +12,7 @@ static int merge_entry(int pos, const char *path)
const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
char hexbuf[4][GIT_MAX_HEXSZ + 1];
char ownbuf[4][60];
+ struct child_process cmd = CHILD_PROCESS_INIT;
if (pos >= active_nr)
die("git merge-index: %s not in the cache", path);
@@ -31,7 +32,8 @@ static int merge_entry(int pos, const char *path)
if (!found)
die("git merge-index: %s not in the cache", path);
- if (run_command_v_opt(arguments, 0)) {
+ strvec_pushv(&cmd.args, arguments);
+ if (run_command(&cmd)) {
if (one_shot)
err++;
else {
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index ae5782917b9..fe853aa8f91 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -402,6 +402,7 @@ struct merge_tree_options {
int allow_unrelated_histories;
int show_messages;
int name_only;
+ int use_stdin;
};
static int real_merge(struct merge_tree_options *o,
@@ -412,6 +413,7 @@ static int real_merge(struct merge_tree_options *o,
struct commit_list *merge_bases = NULL;
struct merge_options opt;
struct merge_result result = { 0 };
+ int show_messages = o->show_messages;
parent1 = get_merge_parent(branch1);
if (!parent1)
@@ -443,9 +445,11 @@ static int real_merge(struct merge_tree_options *o,
if (result.clean < 0)
die(_("failure to merge"));
- if (o->show_messages == -1)
- o->show_messages = !result.clean;
+ if (show_messages == -1)
+ show_messages = !result.clean;
+ if (o->use_stdin)
+ printf("%d%c", result.clean, line_termination);
printf("%s%c", oid_to_hex(&result.tree->object.oid), line_termination);
if (!result.clean) {
struct string_list conflicted_files = STRING_LIST_INIT_NODUP;
@@ -467,11 +471,13 @@ static int real_merge(struct merge_tree_options *o,
}
string_list_clear(&conflicted_files, 1);
}
- if (o->show_messages) {
+ if (show_messages) {
putchar(line_termination);
merge_display_update_messages(&opt, line_termination == '\0',
&result);
}
+ if (o->use_stdin)
+ putchar(line_termination);
merge_finalize(&opt, &result);
return !result.clean; /* result.clean < 0 handled above */
}
@@ -505,6 +511,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
&o.allow_unrelated_histories,
N_("allow merging unrelated histories"),
PARSE_OPT_NONEG),
+ OPT_BOOL_F(0, "stdin",
+ &o.use_stdin,
+ N_("perform multiple merges, one per line of input"),
+ PARSE_OPT_NONEG),
OPT_END()
};
@@ -512,6 +522,32 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
original_argc = argc - 1; /* ignoring argv[0] */
argc = parse_options(argc, argv, prefix, mt_options,
merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+
+ /* Handle --stdin */
+ if (o.use_stdin) {
+ struct strbuf buf = STRBUF_INIT;
+
+ if (o.mode == MODE_TRIVIAL)
+ die(_("--trivial-merge is incompatible with all other options"));
+ line_termination = '\0';
+ while (strbuf_getline_lf(&buf, stdin) != EOF) {
+ struct strbuf **split;
+ int result;
+
+ split = strbuf_split(&buf, ' ');
+ if (!split[0] || !split[1] || split[2])
+ die(_("malformed input line: '%s'."), buf.buf);
+ strbuf_rtrim(split[0]);
+ result = real_merge(&o, split[0]->buf, split[1]->buf, prefix);
+ if (result < 0)
+ die(_("merging cannot continue; got unclean result of %d"), result);
+ strbuf_list_free(split);
+ }
+ strbuf_release(&buf);
+ return 0;
+ }
+
+ /* Figure out which mode to use */
switch (o.mode) {
default:
BUG("unexpected command mode %d", o.mode);
diff --git a/builtin/merge.c b/builtin/merge.c
index f7c92c0e64f..b3f75f55c8a 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -345,60 +345,49 @@ out:
return rc;
}
-static void read_empty(const struct object_id *oid, int verbose)
+static void read_empty(const struct object_id *oid)
{
- int i = 0;
- const char *args[7];
-
- args[i++] = "read-tree";
- if (verbose)
- args[i++] = "-v";
- args[i++] = "-m";
- args[i++] = "-u";
- args[i++] = empty_tree_oid_hex();
- args[i++] = oid_to_hex(oid);
- args[i] = NULL;
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&cmd.args, "read-tree", "-m", "-u", empty_tree_oid_hex(),
+ oid_to_hex(oid), NULL);
+ cmd.git_cmd = 1;
- if (run_command_v_opt(args, RUN_GIT_CMD))
+ if (run_command(&cmd))
die(_("read-tree failed"));
}
-static void reset_hard(const struct object_id *oid, int verbose)
+static void reset_hard(const struct object_id *oid)
{
- int i = 0;
- const char *args[6];
-
- args[i++] = "read-tree";
- if (verbose)
- args[i++] = "-v";
- args[i++] = "--reset";
- args[i++] = "-u";
- args[i++] = oid_to_hex(oid);
- args[i] = NULL;
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&cmd.args, "read-tree", "-v", "--reset", "-u",
+ oid_to_hex(oid), NULL);
+ cmd.git_cmd = 1;
- if (run_command_v_opt(args, RUN_GIT_CMD))
+ if (run_command(&cmd))
die(_("read-tree failed"));
}
static void restore_state(const struct object_id *head,
const struct object_id *stash)
{
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- reset_hard(head, 1);
+ reset_hard(head);
if (is_null_oid(stash))
goto refresh_cache;
- strvec_pushl(&args, "stash", "apply", "--index", "--quiet", NULL);
- strvec_push(&args, oid_to_hex(stash));
+ strvec_pushl(&cmd.args, "stash", "apply", "--index", "--quiet", NULL);
+ strvec_push(&cmd.args, oid_to_hex(stash));
/*
* It is OK to ignore error here, for example when there was
* nothing to restore.
*/
- run_command_v_opt(args.v, RUN_GIT_CMD);
- strvec_clear(&args);
+ cmd.git_cmd = 1;
+ run_command(&cmd);
refresh_cache:
if (discard_cache() < 0 || read_cache() < 0)
@@ -503,7 +492,8 @@ static void finish(struct commit *head_commit,
/* Run a post-merge hook */
run_hooks_l("post-merge", squash ? "1" : "0", NULL);
- apply_autostash(git_path_merge_autostash(the_repository));
+ if (new_head)
+ apply_autostash(git_path_merge_autostash(the_repository));
strbuf_release(&reflog_message);
}
@@ -1469,7 +1459,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
check_trust_level);
remote_head_oid = &remoteheads->item->object.oid;
- read_empty(remote_head_oid, 0);
+ read_empty(remote_head_oid);
update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
goto done;
@@ -1692,7 +1682,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (save_state(&stash))
oidclr(&stash);
- for (i = 0; !merge_was_ok && i < use_strategies_nr; i++) {
+ for (i = 0; i < use_strategies_nr; i++) {
int ret, cnt;
if (i) {
printf(_("Rewinding the tree to pristine...\n"));
@@ -1707,7 +1697,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
*/
wt_strategy = use_strategies[i]->name;
- ret = try_merge_strategy(use_strategies[i]->name,
+ ret = try_merge_strategy(wt_strategy,
common, remoteheads,
head_commit);
/*
@@ -1717,16 +1707,17 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
*/
if (ret < 2) {
if (!ret) {
- if (option_commit) {
- /* Automerge succeeded. */
- automerge_was_ok = 1;
- break;
- }
+ /*
+ * This strategy worked; no point in trying
+ * another.
+ */
merge_was_ok = 1;
+ best_strategy = wt_strategy;
+ break;
}
cnt = (use_strategies_nr > 1) ? evaluate_result() : 0;
if (best_cnt <= 0 || cnt <= best_cnt) {
- best_strategy = use_strategies[i]->name;
+ best_strategy = wt_strategy;
best_cnt = cnt;
}
}
@@ -1736,7 +1727,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* If we have a resulting tree, that means the strategy module
* auto resolved the merge cleanly.
*/
- if (automerge_was_ok) {
+ if (merge_was_ok && option_commit) {
+ automerge_was_ok = 1;
ret = finish_automerge(head_commit, head_subsumed,
common, remoteheads,
&result_tree, wt_strategy);
@@ -1781,6 +1773,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
"stopped before committing as requested\n"));
else
ret = suggest_conflicts();
+ if (autostash)
+ printf(_("When finished, apply stashed changes with `git stash pop`\n"));
done:
if (!automerge_was_ok) {
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index 8f24d59a753..9a18a82b057 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -56,11 +56,12 @@ static struct opts_multi_pack_index {
static int parse_object_dir(const struct option *opt, const char *arg,
int unset)
{
- free(opts.object_dir);
+ char **value = opt->value;
+ free(*value);
if (unset)
- opts.object_dir = xstrdup(get_object_directory());
+ *value = xstrdup(get_object_directory());
else
- opts.object_dir = real_pathdup(arg, 1);
+ *value = real_pathdup(arg, 1);
return 0;
}
@@ -78,7 +79,7 @@ static struct option *add_common_options(struct option *prev)
}
static int git_multi_pack_index_write_config(const char *var, const char *value,
- void *cb)
+ void *cb UNUSED)
{
if (!strcmp(var, "pack.writebitmaphashcache")) {
if (git_config_bool(var, value))
@@ -87,6 +88,13 @@ static int git_multi_pack_index_write_config(const char *var, const char *value,
opts.flags &= ~MIDX_WRITE_BITMAP_HASH_CACHE;
}
+ if (!strcmp(var, "pack.writebitmaplookuptable")) {
+ if (git_config_bool(var, value))
+ opts.flags |= MIDX_WRITE_BITMAP_LOOKUP_TABLE;
+ else
+ opts.flags &= ~MIDX_WRITE_BITMAP_LOOKUP_TABLE;
+ }
+
/*
* We should never make a fall-back call to 'git_default_config', since
* this was already called in 'cmd_multi_pack_index()'.
@@ -104,7 +112,8 @@ static void read_packs_from_stdin(struct string_list *to)
strbuf_release(&buf);
}
-static int cmd_multi_pack_index_write(int argc, const char **argv)
+static int cmd_multi_pack_index_write(int argc, const char **argv,
+ const char *prefix)
{
struct option *options;
static struct option builtin_multi_pack_index_write_options[] = {
@@ -132,7 +141,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv)
if (isatty(2))
opts.flags |= MIDX_PROGRESS;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
options, builtin_multi_pack_index_write_usage,
0);
if (argc)
@@ -160,7 +169,8 @@ static int cmd_multi_pack_index_write(int argc, const char **argv)
opts.refs_snapshot, opts.flags);
}
-static int cmd_multi_pack_index_verify(int argc, const char **argv)
+static int cmd_multi_pack_index_verify(int argc, const char **argv,
+ const char *prefix)
{
struct option *options;
static struct option builtin_multi_pack_index_verify_options[] = {
@@ -174,7 +184,7 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv)
if (isatty(2))
opts.flags |= MIDX_PROGRESS;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
options, builtin_multi_pack_index_verify_usage,
0);
if (argc)
@@ -186,7 +196,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv)
return verify_midx_file(the_repository, opts.object_dir, opts.flags);
}
-static int cmd_multi_pack_index_expire(int argc, const char **argv)
+static int cmd_multi_pack_index_expire(int argc, const char **argv,
+ const char *prefix)
{
struct option *options;
static struct option builtin_multi_pack_index_expire_options[] = {
@@ -200,7 +211,7 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv)
if (isatty(2))
opts.flags |= MIDX_PROGRESS;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
options, builtin_multi_pack_index_expire_usage,
0);
if (argc)
@@ -212,7 +223,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv)
return expire_midx_packs(the_repository, opts.object_dir, opts.flags);
}
-static int cmd_multi_pack_index_repack(int argc, const char **argv)
+static int cmd_multi_pack_index_repack(int argc, const char **argv,
+ const char *prefix)
{
struct option *options;
static struct option builtin_multi_pack_index_repack_options[] = {
@@ -229,7 +241,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv)
if (isatty(2))
opts.flags |= MIDX_PROGRESS;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
options,
builtin_multi_pack_index_repack_usage,
0);
@@ -247,7 +259,15 @@ int cmd_multi_pack_index(int argc, const char **argv,
const char *prefix)
{
int res;
- struct option *builtin_multi_pack_index_options = common_opts;
+ parse_opt_subcommand_fn *fn = NULL;
+ struct option builtin_multi_pack_index_options[] = {
+ OPT_SUBCOMMAND("repack", &fn, cmd_multi_pack_index_repack),
+ OPT_SUBCOMMAND("write", &fn, cmd_multi_pack_index_write),
+ OPT_SUBCOMMAND("verify", &fn, cmd_multi_pack_index_verify),
+ OPT_SUBCOMMAND("expire", &fn, cmd_multi_pack_index_expire),
+ OPT_END(),
+ };
+ struct option *options = parse_options_concat(builtin_multi_pack_index_options, common_opts);
git_config(git_default_config, NULL);
@@ -256,31 +276,12 @@ int cmd_multi_pack_index(int argc, const char **argv,
the_repository->objects->odb)
opts.object_dir = xstrdup(the_repository->objects->odb->path);
- argc = parse_options(argc, argv, prefix,
- builtin_multi_pack_index_options,
- builtin_multi_pack_index_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
-
- if (!argc)
- goto usage;
-
- if (!strcmp(argv[0], "repack"))
- res = cmd_multi_pack_index_repack(argc, argv);
- else if (!strcmp(argv[0], "write"))
- res = cmd_multi_pack_index_write(argc, argv);
- else if (!strcmp(argv[0], "verify"))
- res = cmd_multi_pack_index_verify(argc, argv);
- else if (!strcmp(argv[0], "expire"))
- res = cmd_multi_pack_index_expire(argc, argv);
- else {
- error(_("unrecognized subcommand: %s"), argv[0]);
- goto usage;
- }
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_multi_pack_index_usage, 0);
+ FREE_AND_NULL(options);
+
+ res = fn(argc, argv, prefix);
free(opts.object_dir);
return res;
-
-usage:
- usage_with_options(builtin_multi_pack_index_usage,
- builtin_multi_pack_index_options);
}
diff --git a/builtin/mv.c b/builtin/mv.c
index 4729bb1a1ab..3413ad1c9b1 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -21,7 +21,6 @@ static const char * const builtin_mv_usage[] = {
};
enum update_mode {
- BOTH = 0,
WORKING_DIRECTORY = (1 << 1),
INDEX = (1 << 2),
SPARSE = (1 << 3),
@@ -72,7 +71,7 @@ static const char **internal_prefix_pathspec(const char *prefix,
static const char *add_slash(const char *path)
{
size_t len = strlen(path);
- if (path[len - 1] != '/') {
+ if (len && path[len - 1] != '/') {
char *with_slash = xmalloc(st_add(len, 2));
memcpy(with_slash, path, len);
with_slash[len++] = '/';
@@ -125,16 +124,15 @@ static int index_range_of_same_dir(const char *src, int length,
}
/*
- * Check if an out-of-cone directory should be in the index. Imagine this case
- * that all the files under a directory are marked with 'CE_SKIP_WORKTREE' bit
- * and thus the directory is sparsified.
- *
- * Return 0 if such directory exist (i.e. with any of its contained files not
- * marked with CE_SKIP_WORKTREE, the directory would be present in working tree).
- * Return 1 otherwise.
+ * Given the path of a directory that does not exist on-disk, check whether the
+ * directory contains any entries in the index with the SKIP_WORKTREE flag
+ * enabled.
+ * Return 1 if such index entries exist.
+ * Return 0 otherwise.
*/
-static int check_dir_in_index(const char *name)
+static int empty_dir_has_sparse_contents(const char *name)
{
+ int ret = 0;
const char *with_slash = add_slash(name);
int length = strlen(with_slash);
@@ -144,14 +142,18 @@ static int check_dir_in_index(const char *name)
if (pos < 0) {
pos = -pos - 1;
if (pos >= the_index.cache_nr)
- return 1;
+ goto free_return;
ce = active_cache[pos];
if (strncmp(with_slash, ce->name, length))
- return 1;
+ goto free_return;
if (ce_skip_worktree(ce))
- return 0;
+ ret = 1;
}
- return 1;
+
+free_return:
+ if (with_slash != name)
+ free((char *)with_slash);
+ return ret;
}
int cmd_mv(int argc, const char **argv, const char *prefix)
@@ -168,12 +170,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
OPT_END(),
};
const char **source, **destination, **dest_path, **submodule_gitfile;
- enum update_mode *modes;
+ const char *dst_w_slash;
+ const char **src_dir = NULL;
+ int src_dir_nr = 0, src_dir_alloc = 0;
+ struct strbuf a_src_dir = STRBUF_INIT;
+ enum update_mode *modes, dst_mode = 0;
struct stat st;
struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
struct lock_file lock_file = LOCK_INIT;
struct cache_entry *ce;
struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
+ struct string_list dirty_paths = STRING_LIST_INIT_NODUP;
git_config(git_default_config, NULL);
@@ -198,6 +205,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1]))
flags = 0;
dest_path = internal_prefix_pathspec(prefix, argv + argc, 1, flags);
+ dst_w_slash = add_slash(dest_path[0]);
submodule_gitfile = xcalloc(argc, sizeof(char *));
if (dest_path[0][0] == '\0')
@@ -205,12 +213,31 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
else if (!lstat(dest_path[0], &st) &&
S_ISDIR(st.st_mode)) {
- dest_path[0] = add_slash(dest_path[0]);
- destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
+ destination = internal_prefix_pathspec(dst_w_slash, argv, argc, DUP_BASENAME);
} else {
- if (argc != 1)
+ if (!path_in_sparse_checkout(dst_w_slash, &the_index) &&
+ empty_dir_has_sparse_contents(dst_w_slash)) {
+ destination = internal_prefix_pathspec(dst_w_slash, argv, argc, DUP_BASENAME);
+ dst_mode = SKIP_WORKTREE_DIR;
+ } else if (argc != 1) {
die(_("destination '%s' is not a directory"), dest_path[0]);
- destination = dest_path;
+ } else {
+ destination = dest_path;
+ /*
+ * <destination> is a file outside of sparse-checkout
+ * cone. Insist on cone mode here for backward
+ * compatibility. We don't want dst_mode to be assigned
+ * for a file when the repo is using no-cone mode (which
+ * is deprecated at this point) sparse-checkout. As
+ * SPARSE here is only considering cone-mode situation.
+ */
+ if (!path_in_cone_mode_sparse_checkout(destination[0], &the_index))
+ dst_mode = SPARSE;
+ }
+ }
+ if (dst_w_slash != dest_path[0]) {
+ free((char *)dst_w_slash);
+ dst_w_slash = NULL;
}
/* Checking */
@@ -232,7 +259,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (pos < 0) {
const char *src_w_slash = add_slash(src);
if (!path_in_sparse_checkout(src_w_slash, &the_index) &&
- !check_dir_in_index(src)) {
+ empty_dir_has_sparse_contents(src)) {
modes[i] |= SKIP_WORKTREE_DIR;
goto dir_check;
}
@@ -290,6 +317,10 @@ dir_check:
/* last - first >= 1 */
modes[i] |= WORKING_DIRECTORY;
+
+ ALLOC_GROW(src_dir, src_dir_nr + 1, src_dir_alloc);
+ src_dir[src_dir_nr++] = src;
+
n = argc + last - first;
REALLOC_ARRAY(source, n);
REALLOC_ARRAY(destination, n);
@@ -346,6 +377,18 @@ dir_check:
goto act_on_entry;
}
+ if (ignore_sparse &&
+ (dst_mode & (SKIP_WORKTREE_DIR | SPARSE)) &&
+ index_entry_exists(&the_index, dst, strlen(dst))) {
+ bad = _("destination exists in the index");
+ if (force) {
+ if (verbose)
+ warning(_("overwriting '%s'"), dst);
+ bad = NULL;
+ } else {
+ goto act_on_entry;
+ }
+ }
/*
* We check if the paths are in the sparse-checkout
* definition as a very final check, since that
@@ -396,6 +439,7 @@ remove_entry:
const char *src = source[i], *dst = destination[i];
enum update_mode mode = modes[i];
int pos;
+ int sparse_and_dirty = 0;
struct checkout state = CHECKOUT_INIT;
state.istate = &the_index;
@@ -406,6 +450,7 @@ remove_entry:
if (show_only)
continue;
if (!(mode & (INDEX | SPARSE | SKIP_WORKTREE_DIR)) &&
+ !(dst_mode & (SKIP_WORKTREE_DIR | SPARSE)) &&
rename(src, dst) < 0) {
if (ignore_errors)
continue;
@@ -425,20 +470,81 @@ remove_entry:
pos = cache_name_pos(src, strlen(src));
assert(pos >= 0);
+ if (!(mode & SPARSE) && !lstat(src, &st))
+ sparse_and_dirty = ce_modified(active_cache[pos], &st, 0);
rename_cache_entry_at(pos, dst);
- if ((mode & SPARSE) &&
- (path_in_sparse_checkout(dst, &the_index))) {
- int dst_pos;
+ if (ignore_sparse &&
+ core_apply_sparse_checkout &&
+ core_sparse_checkout_cone) {
+ /*
+ * NEEDSWORK: we are *not* paying attention to
+ * "out-to-out" move (<source> is out-of-cone and
+ * <destination> is out-of-cone) at this point. It
+ * should be added in a future patch.
+ */
+ if ((mode & SPARSE) &&
+ path_in_sparse_checkout(dst, &the_index)) {
+ /* from out-of-cone to in-cone */
+ int dst_pos = cache_name_pos(dst, strlen(dst));
+ struct cache_entry *dst_ce = active_cache[dst_pos];
+
+ dst_ce->ce_flags &= ~CE_SKIP_WORKTREE;
+
+ if (checkout_entry(dst_ce, &state, NULL, NULL))
+ die(_("cannot checkout %s"), dst_ce->name);
+ } else if ((dst_mode & (SKIP_WORKTREE_DIR | SPARSE)) &&
+ !(mode & SPARSE) &&
+ !path_in_sparse_checkout(dst, &the_index)) {
+ /* from in-cone to out-of-cone */
+ int dst_pos = cache_name_pos(dst, strlen(dst));
+ struct cache_entry *dst_ce = active_cache[dst_pos];
- dst_pos = cache_name_pos(dst, strlen(dst));
- active_cache[dst_pos]->ce_flags &= ~CE_SKIP_WORKTREE;
+ /*
+ * if src is clean, it will suffice to remove it
+ */
+ if (!sparse_and_dirty) {
+ dst_ce->ce_flags |= CE_SKIP_WORKTREE;
+ unlink_or_warn(src);
+ } else {
+ /*
+ * if src is dirty, move it to the
+ * destination and create leading
+ * dirs if necessary
+ */
+ char *dst_dup = xstrdup(dst);
+ string_list_append(&dirty_paths, dst);
+ safe_create_leading_directories(dst_dup);
+ FREE_AND_NULL(dst_dup);
+ rename(src, dst);
+ }
+ }
+ }
+ }
- if (checkout_entry(active_cache[dst_pos], &state, NULL, NULL))
- die(_("cannot checkout %s"), active_cache[dst_pos]->name);
+ /*
+ * cleanup the empty src_dirs
+ */
+ for (i = 0; i < src_dir_nr; i++) {
+ int dummy;
+ strbuf_addstr(&a_src_dir, src_dir[i]);
+ /*
+ * if entries under a_src_dir are all moved away,
+ * recursively remove a_src_dir to cleanup
+ */
+ if (index_range_of_same_dir(a_src_dir.buf, a_src_dir.len,
+ &dummy, &dummy) < 1) {
+ remove_dir_recursively(&a_src_dir, 0);
}
+ strbuf_reset(&a_src_dir);
}
+ strbuf_release(&a_src_dir);
+ free(src_dir);
+
+ if (dirty_paths.nr)
+ advise_on_moving_dirty_path(&dirty_paths);
+
if (gitmodules_modified)
stage_updated_gitmodules(&the_index);
@@ -447,6 +553,7 @@ remove_entry:
die(_("Unable to write new index file"));
string_list_clear(&src_for_dst, 0);
+ string_list_clear(&dirty_paths, 0);
UNLEAK(source);
UNLEAK(dest_path);
free(submodule_gitfile);
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 580b1eb170e..15535e914a6 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -344,7 +344,8 @@ static int cmp_by_tag_and_age(const void *a_, const void *b_)
return a->taggerdate != b->taggerdate;
}
-static int name_ref(const char *path, const struct object_id *oid, int flags, void *cb_data)
+static int name_ref(const char *path, const struct object_id *oid,
+ int flags UNUSED, void *cb_data)
{
struct object *o = parse_object(the_repository, oid);
struct name_ref_data *data = cb_data;
diff --git a/builtin/notes.c b/builtin/notes.c
index a3d0d15a227..be51f692257 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -994,17 +994,34 @@ static int get_ref(int argc, const char **argv, const char *prefix)
int cmd_notes(int argc, const char **argv, const char *prefix)
{
- int result;
const char *override_notes_ref = NULL;
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
OPT_STRING(0, "ref", &override_notes_ref, N_("notes-ref"),
N_("use notes from <notes-ref>")),
+ OPT_SUBCOMMAND("list", &fn, list),
+ OPT_SUBCOMMAND("add", &fn, add),
+ OPT_SUBCOMMAND("copy", &fn, copy),
+ OPT_SUBCOMMAND("append", &fn, append_edit),
+ OPT_SUBCOMMAND("edit", &fn, append_edit),
+ OPT_SUBCOMMAND("show", &fn, show),
+ OPT_SUBCOMMAND("merge", &fn, merge),
+ OPT_SUBCOMMAND("remove", &fn, remove_cmd),
+ OPT_SUBCOMMAND("prune", &fn, prune),
+ OPT_SUBCOMMAND("get-ref", &fn, get_ref),
OPT_END()
};
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, options, git_notes_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ PARSE_OPT_SUBCOMMAND_OPTIONAL);
+ if (!fn) {
+ if (argc) {
+ error(_("unknown subcommand: `%s'"), argv[0]);
+ usage_with_options(git_notes_usage, options);
+ }
+ fn = list;
+ }
if (override_notes_ref) {
struct strbuf sb = STRBUF_INIT;
@@ -1014,28 +1031,5 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
strbuf_release(&sb);
}
- if (argc < 1 || !strcmp(argv[0], "list"))
- result = list(argc, argv, prefix);
- else if (!strcmp(argv[0], "add"))
- result = add(argc, argv, prefix);
- else if (!strcmp(argv[0], "copy"))
- result = copy(argc, argv, prefix);
- else if (!strcmp(argv[0], "append") || !strcmp(argv[0], "edit"))
- result = append_edit(argc, argv, prefix);
- else if (!strcmp(argv[0], "show"))
- result = show(argc, argv, prefix);
- else if (!strcmp(argv[0], "merge"))
- result = merge(argc, argv, prefix);
- else if (!strcmp(argv[0], "remove"))
- result = remove_cmd(argc, argv, prefix);
- else if (!strcmp(argv[0], "prune"))
- result = prune(argc, argv, prefix);
- else if (!strcmp(argv[0], "get-ref"))
- result = get_ref(argc, argv, prefix);
- else {
- result = error(_("unknown subcommand: %s"), argv[0]);
- usage_with_options(git_notes_usage, options);
- }
-
- return result ? 1 : 0;
+ return !!fn(argc, argv, prefix);
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 39e28cfcafc..573d0b20b76 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -180,8 +180,8 @@ static inline void oe_set_delta_size(struct packing_data *pack,
#define SET_DELTA_SIBLING(obj, val) oe_set_delta_sibling(&to_pack, obj, val)
static const char *pack_usage[] = {
- N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
- N_("git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"),
+ N_("git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]"),
+ N_("git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]"),
NULL
};
@@ -759,8 +759,8 @@ static enum write_one_status write_one(struct hashfile *f,
return WRITE_ONE_WRITTEN;
}
-static int mark_tagged(const char *path, const struct object_id *oid, int flag,
- void *cb_data)
+static int mark_tagged(const char *path UNUSED, const struct object_id *oid,
+ int flag UNUSED, void *cb_data UNUSED)
{
struct object_id peeled;
struct object_entry *entry = packlist_find(&to_pack, oid);
@@ -3035,7 +3035,8 @@ static void add_tag_chain(const struct object_id *oid)
}
}
-static int add_ref_tag(const char *tag, const struct object_id *oid, int flag, void *cb_data)
+static int add_ref_tag(const char *tag UNUSED, const struct object_id *oid,
+ int flag UNUSED, void *cb_data UNUSED)
{
struct object_id peeled;
@@ -3148,6 +3149,14 @@ static int git_pack_config(const char *k, const char *v, void *cb)
else
write_bitmap_options &= ~BITMAP_OPT_HASH_CACHE;
}
+
+ if (!strcmp(k, "pack.writebitmaplookuptable")) {
+ if (git_config_bool(k, v))
+ write_bitmap_options |= BITMAP_OPT_LOOKUP_TABLE;
+ else
+ write_bitmap_options &= ~BITMAP_OPT_LOOKUP_TABLE;
+ }
+
if (!strcmp(k, "pack.usebitmaps")) {
use_bitmap_index_default = git_config_bool(k, v);
return 0;
@@ -3950,8 +3959,9 @@ static void record_recent_commit(struct commit *commit, void *data)
}
static int mark_bitmap_preferred_tip(const char *refname,
- const struct object_id *oid, int flags,
- void *_data)
+ const struct object_id *oid,
+ int flags UNUSED,
+ void *data UNUSED)
{
struct object_id peeled;
struct object *object;
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index ed9b9013a5f..ecd49ca268f 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -14,7 +14,7 @@
#define BLKSIZE 512
static const char pack_redundant_usage[] =
-"git pack-redundant [--verbose] [--alt-odb] (--all | <filename.pack>...)";
+"git pack-redundant [--verbose] [--alt-odb] (--all | <pack-filename>...)";
static int load_all_packs, verbose, alt_odb;
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index cfbd5c36c76..27c2ca06acb 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -5,7 +5,7 @@
#include "repository.h"
static char const * const pack_refs_usage[] = {
- N_("git pack-refs [<options>]"),
+ N_("git pack-refs [--all] [--no-prune]"),
NULL
};
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index 881fcf32732..f840fbf1c7e 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -2,6 +2,7 @@
#include "builtin.h"
#include "config.h"
#include "diff.h"
+#include "parse-options.h"
static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result)
{
@@ -57,10 +58,12 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after)
}
static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
- struct strbuf *line_buf, int stable)
+ struct strbuf *line_buf, int stable, int verbatim)
{
int patchlen = 0, found_next = 0;
int before = -1, after = -1;
+ int diff_is_binary = 0;
+ char pre_oid_str[GIT_MAX_HEXSZ + 1], post_oid_str[GIT_MAX_HEXSZ + 1];
git_hash_ctx ctx;
the_hash_algo->init_fn(&ctx);
@@ -71,11 +74,14 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
const char *p = line;
int len;
- if (!skip_prefix(line, "diff-tree ", &p) &&
- !skip_prefix(line, "commit ", &p) &&
+ /* 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))
+ 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;
@@ -88,14 +94,44 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
/* Parsing diff header? */
if (before == -1) {
- if (starts_with(line, "index "))
+ if (starts_with(line, "GIT binary patch") ||
+ starts_with(line, "Binary files")) {
+ diff_is_binary = 1;
+ before = 0;
+ the_hash_algo->update_fn(&ctx, pre_oid_str,
+ strlen(pre_oid_str));
+ the_hash_algo->update_fn(&ctx, post_oid_str,
+ strlen(post_oid_str));
+ if (stable)
+ flush_one_hunk(result, &ctx);
+ continue;
+ } else if (skip_prefix(line, "index ", &p)) {
+ char *oid1_end = strstr(line, "..");
+ char *oid2_end = NULL;
+ if (oid1_end)
+ oid2_end = strstr(oid1_end, " ");
+ if (!oid2_end)
+ oid2_end = line + strlen(line) - 1;
+ if (oid1_end != NULL && oid2_end != NULL) {
+ *oid1_end = *oid2_end = '\0';
+ strlcpy(pre_oid_str, p, GIT_MAX_HEXSZ + 1);
+ strlcpy(post_oid_str, oid1_end + 2, GIT_MAX_HEXSZ + 1);
+ }
continue;
- else if (starts_with(line, "--- "))
+ } else if (starts_with(line, "--- "))
before = after = 1;
else if (!isalpha(line[0]))
break;
}
+ if (diff_is_binary) {
+ if (starts_with(line, "diff ")) {
+ diff_is_binary = 0;
+ before = -1;
+ }
+ continue;
+ }
+
/* Looking for a valid hunk header? */
if (before == 0 && after == 0) {
if (starts_with(line, "@@ -")) {
@@ -120,8 +156,8 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
if (line[0] == '+' || line[0] == ' ')
after--;
- /* Compute the sha without whitespace */
- len = remove_space(line);
+ /* Add line to hash algo (possibly removing whitespace) */
+ len = verbatim ? strlen(line) : remove_space(line);
patchlen += len;
the_hash_algo->update_fn(&ctx, line, len);
}
@@ -134,7 +170,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
return patchlen;
}
-static void generate_id_list(int stable)
+static void generate_id_list(int stable, int verbatim)
{
struct object_id oid, n, result;
int patchlen;
@@ -142,21 +178,32 @@ static void generate_id_list(int stable)
oidclr(&oid);
while (!feof(stdin)) {
- patchlen = get_one_patchid(&n, &result, &line_buf, stable);
+ patchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim);
flush_current_id(patchlen, &oid, &result);
oidcpy(&oid, &n);
}
strbuf_release(&line_buf);
}
-static const char patch_id_usage[] = "git patch-id [--stable | --unstable]";
+static const char *const patch_id_usage[] = {
+ N_("git patch-id [--stable | --unstable | --verbatim]"), NULL
+};
+
+struct patch_id_opts {
+ int stable;
+ int verbatim;
+};
static int git_patch_id_config(const char *var, const char *value, void *cb)
{
- int *stable = cb;
+ struct patch_id_opts *opts = cb;
if (!strcmp(var, "patchid.stable")) {
- *stable = git_config_bool(var, value);
+ opts->stable = git_config_bool(var, value);
+ return 0;
+ }
+ if (!strcmp(var, "patchid.verbatim")) {
+ opts->verbatim = git_config_bool(var, value);
return 0;
}
@@ -165,21 +212,29 @@ static int git_patch_id_config(const char *var, const char *value, void *cb)
int cmd_patch_id(int argc, const char **argv, const char *prefix)
{
- int stable = -1;
-
- git_config(git_patch_id_config, &stable);
-
- /* If nothing is set, default to unstable. */
- if (stable < 0)
- stable = 0;
-
- if (argc == 2 && !strcmp(argv[1], "--stable"))
- stable = 1;
- else if (argc == 2 && !strcmp(argv[1], "--unstable"))
- stable = 0;
- else if (argc != 1)
- usage(patch_id_usage);
-
- generate_id_list(stable);
+ /* if nothing is set, default to unstable */
+ struct patch_id_opts config = {0, 0};
+ int opts = 0;
+ struct option builtin_patch_id_options[] = {
+ OPT_CMDMODE(0, "unstable", &opts,
+ N_("use the unstable patch-id algorithm"), 1),
+ OPT_CMDMODE(0, "stable", &opts,
+ N_("use the stable patch-id algorithm"), 2),
+ OPT_CMDMODE(0, "verbatim", &opts,
+ N_("don't strip whitespace from the patch"), 3),
+ OPT_END()
+ };
+
+ git_config(git_patch_id_config, &config);
+
+ /* verbatim implies stable */
+ if (config.verbatim)
+ config.stable = 1;
+
+ argc = parse_options(argc, argv, prefix, builtin_patch_id_options,
+ patch_id_usage, 0);
+
+ generate_id_list(opts ? opts > 1 : config.stable,
+ opts ? opts == 3 : config.verbatim);
return 0;
}
diff --git a/builtin/pull.c b/builtin/pull.c
index 403a24d7ca6..b21edd767aa 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -515,76 +515,75 @@ static void parse_repo_refspecs(int argc, const char **argv, const char **repo,
*/
static int run_fetch(const char *repo, const char **refspecs)
{
- struct strvec args = STRVEC_INIT;
- int ret;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&args, "fetch", "--update-head-ok", NULL);
+ strvec_pushl(&cmd.args, "fetch", "--update-head-ok", NULL);
/* Shared options */
- argv_push_verbosity(&args);
+ argv_push_verbosity(&cmd.args);
if (opt_progress)
- strvec_push(&args, opt_progress);
+ strvec_push(&cmd.args, opt_progress);
/* Options passed to git-fetch */
if (opt_all)
- strvec_push(&args, opt_all);
+ strvec_push(&cmd.args, opt_all);
if (opt_append)
- strvec_push(&args, opt_append);
+ strvec_push(&cmd.args, opt_append);
if (opt_upload_pack)
- strvec_push(&args, opt_upload_pack);
- argv_push_force(&args);
+ strvec_push(&cmd.args, opt_upload_pack);
+ argv_push_force(&cmd.args);
if (opt_tags)
- strvec_push(&args, opt_tags);
+ strvec_push(&cmd.args, opt_tags);
if (opt_prune)
- strvec_push(&args, opt_prune);
+ strvec_push(&cmd.args, opt_prune);
if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
switch (recurse_submodules_cli) {
case RECURSE_SUBMODULES_ON:
- strvec_push(&args, "--recurse-submodules=on");
+ strvec_push(&cmd.args, "--recurse-submodules=on");
break;
case RECURSE_SUBMODULES_OFF:
- strvec_push(&args, "--recurse-submodules=no");
+ strvec_push(&cmd.args, "--recurse-submodules=no");
break;
case RECURSE_SUBMODULES_ON_DEMAND:
- strvec_push(&args, "--recurse-submodules=on-demand");
+ strvec_push(&cmd.args, "--recurse-submodules=on-demand");
break;
default:
BUG("submodule recursion option not understood");
}
if (max_children)
- strvec_push(&args, max_children);
+ strvec_push(&cmd.args, max_children);
if (opt_dry_run)
- strvec_push(&args, "--dry-run");
+ strvec_push(&cmd.args, "--dry-run");
if (opt_keep)
- strvec_push(&args, opt_keep);
+ strvec_push(&cmd.args, opt_keep);
if (opt_depth)
- strvec_push(&args, opt_depth);
+ strvec_push(&cmd.args, opt_depth);
if (opt_unshallow)
- strvec_push(&args, opt_unshallow);
+ strvec_push(&cmd.args, opt_unshallow);
if (opt_update_shallow)
- strvec_push(&args, opt_update_shallow);
+ strvec_push(&cmd.args, opt_update_shallow);
if (opt_refmap)
- strvec_push(&args, opt_refmap);
+ strvec_push(&cmd.args, opt_refmap);
if (opt_ipv4)
- strvec_push(&args, opt_ipv4);
+ strvec_push(&cmd.args, opt_ipv4);
if (opt_ipv6)
- strvec_push(&args, opt_ipv6);
+ strvec_push(&cmd.args, opt_ipv6);
if (opt_show_forced_updates > 0)
- strvec_push(&args, "--show-forced-updates");
+ strvec_push(&cmd.args, "--show-forced-updates");
else if (opt_show_forced_updates == 0)
- strvec_push(&args, "--no-show-forced-updates");
+ strvec_push(&cmd.args, "--no-show-forced-updates");
if (set_upstream)
- strvec_push(&args, set_upstream);
- strvec_pushv(&args, opt_fetch.v);
+ strvec_push(&cmd.args, set_upstream);
+ strvec_pushv(&cmd.args, opt_fetch.v);
if (repo) {
- strvec_push(&args, repo);
- strvec_pushv(&args, refspecs);
+ strvec_push(&cmd.args, repo);
+ strvec_pushv(&cmd.args, refspecs);
} else if (*refspecs)
BUG("refspecs without repo?");
- ret = run_command_v_opt(args.v, RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE);
- strvec_clear(&args);
- return ret;
+ cmd.git_cmd = 1;
+ cmd.close_object_store = 1;
+ return run_command(&cmd);
}
/**
@@ -653,52 +652,50 @@ static int update_submodules(void)
*/
static int run_merge(void)
{
- int ret;
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&args, "merge", NULL);
+ strvec_pushl(&cmd.args, "merge", NULL);
/* Shared options */
- argv_push_verbosity(&args);
+ argv_push_verbosity(&cmd.args);
if (opt_progress)
- strvec_push(&args, opt_progress);
+ strvec_push(&cmd.args, opt_progress);
/* Options passed to git-merge */
if (opt_diffstat)
- strvec_push(&args, opt_diffstat);
+ strvec_push(&cmd.args, opt_diffstat);
if (opt_log)
- strvec_push(&args, opt_log);
+ strvec_push(&cmd.args, opt_log);
if (opt_signoff)
- strvec_push(&args, opt_signoff);
+ strvec_push(&cmd.args, opt_signoff);
if (opt_squash)
- strvec_push(&args, opt_squash);
+ strvec_push(&cmd.args, opt_squash);
if (opt_commit)
- strvec_push(&args, opt_commit);
+ strvec_push(&cmd.args, opt_commit);
if (opt_edit)
- strvec_push(&args, opt_edit);
+ strvec_push(&cmd.args, opt_edit);
if (cleanup_arg)
- strvec_pushf(&args, "--cleanup=%s", cleanup_arg);
+ strvec_pushf(&cmd.args, "--cleanup=%s", cleanup_arg);
if (opt_ff)
- strvec_push(&args, opt_ff);
+ strvec_push(&cmd.args, opt_ff);
if (opt_verify)
- strvec_push(&args, opt_verify);
+ strvec_push(&cmd.args, opt_verify);
if (opt_verify_signatures)
- strvec_push(&args, opt_verify_signatures);
- strvec_pushv(&args, opt_strategies.v);
- strvec_pushv(&args, opt_strategy_opts.v);
+ strvec_push(&cmd.args, opt_verify_signatures);
+ strvec_pushv(&cmd.args, opt_strategies.v);
+ strvec_pushv(&cmd.args, opt_strategy_opts.v);
if (opt_gpg_sign)
- strvec_push(&args, opt_gpg_sign);
+ strvec_push(&cmd.args, opt_gpg_sign);
if (opt_autostash == 0)
- strvec_push(&args, "--no-autostash");
+ strvec_push(&cmd.args, "--no-autostash");
else if (opt_autostash == 1)
- strvec_push(&args, "--autostash");
+ strvec_push(&cmd.args, "--autostash");
if (opt_allow_unrelated_histories > 0)
- strvec_push(&args, "--allow-unrelated-histories");
+ strvec_push(&cmd.args, "--allow-unrelated-histories");
- strvec_push(&args, "FETCH_HEAD");
- ret = run_command_v_opt(args.v, RUN_GIT_CMD);
- strvec_clear(&args);
- return ret;
+ strvec_push(&cmd.args, "FETCH_HEAD");
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
/**
@@ -879,43 +876,41 @@ static int get_rebase_newbase_and_upstream(struct object_id *newbase,
static int run_rebase(const struct object_id *newbase,
const struct object_id *upstream)
{
- int ret;
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_push(&args, "rebase");
+ strvec_push(&cmd.args, "rebase");
/* Shared options */
- argv_push_verbosity(&args);
+ argv_push_verbosity(&cmd.args);
/* Options passed to git-rebase */
if (opt_rebase == REBASE_MERGES)
- strvec_push(&args, "--rebase-merges");
+ strvec_push(&cmd.args, "--rebase-merges");
else if (opt_rebase == REBASE_INTERACTIVE)
- strvec_push(&args, "--interactive");
+ strvec_push(&cmd.args, "--interactive");
if (opt_diffstat)
- strvec_push(&args, opt_diffstat);
- strvec_pushv(&args, opt_strategies.v);
- strvec_pushv(&args, opt_strategy_opts.v);
+ strvec_push(&cmd.args, opt_diffstat);
+ strvec_pushv(&cmd.args, opt_strategies.v);
+ strvec_pushv(&cmd.args, opt_strategy_opts.v);
if (opt_gpg_sign)
- strvec_push(&args, opt_gpg_sign);
+ strvec_push(&cmd.args, opt_gpg_sign);
if (opt_signoff)
- strvec_push(&args, opt_signoff);
+ strvec_push(&cmd.args, opt_signoff);
if (opt_autostash == 0)
- strvec_push(&args, "--no-autostash");
+ strvec_push(&cmd.args, "--no-autostash");
else if (opt_autostash == 1)
- strvec_push(&args, "--autostash");
+ strvec_push(&cmd.args, "--autostash");
if (opt_verify_signatures &&
!strcmp(opt_verify_signatures, "--verify-signatures"))
warning(_("ignoring --verify-signatures for rebase"));
- strvec_push(&args, "--onto");
- strvec_push(&args, oid_to_hex(newbase));
+ strvec_push(&cmd.args, "--onto");
+ strvec_push(&cmd.args, oid_to_hex(newbase));
- strvec_push(&args, oid_to_hex(upstream));
+ strvec_push(&cmd.args, oid_to_hex(upstream));
- ret = run_command_v_opt(args.v, RUN_GIT_CMD);
- strvec_clear(&args);
- return ret;
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
static int get_can_ff(struct object_id *orig_head,
diff --git a/builtin/push.c b/builtin/push.c
index df0d68e5998..f0329c62a2d 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -169,8 +169,8 @@ static NORETURN void die_push_simple(struct branch *branch,
if (git_branch_track != BRANCH_TRACK_SIMPLE)
advice_automergesimple_maybe = _("\n"
"To avoid automatically configuring "
- "upstream branches when their name\n"
- "doesn't match the local branch, see option "
+ "an upstream branch when its name\n"
+ "won't match the local branch, see option "
"'simple' of branch.autoSetupMerge\n"
"in 'git help config'.\n");
die(_("The upstream branch of your current branch does not match\n"
diff --git a/builtin/range-diff.c b/builtin/range-diff.c
index 50318849d65..e2a74efb42a 100644
--- a/builtin/range-diff.c
+++ b/builtin/range-diff.c
@@ -38,8 +38,10 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
OPT_END()
};
struct option *options;
- int res = 0;
+ int i, dash_dash = -1, res = 0;
struct strbuf range1 = STRBUF_INIT, range2 = STRBUF_INIT;
+ struct object_id oid;
+ const char *three_dots = NULL;
git_config(git_diff_ui_config, NULL);
@@ -47,7 +49,7 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
options = parse_options_concat(range_diff_options, diffopt.parseopts);
argc = parse_options(argc, argv, prefix, options,
- builtin_range_diff_usage, 0);
+ builtin_range_diff_usage, PARSE_OPT_KEEP_DASHDASH);
diff_setup_done(&diffopt);
@@ -55,40 +57,91 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
if (!simple_color)
diffopt.use_color = 1;
- if (argc == 2) {
- if (!is_range_diff_range(argv[0]))
- die(_("not a commit range: '%s'"), argv[0]);
- strbuf_addstr(&range1, argv[0]);
+ for (i = 0; i < argc; i++)
+ if (!strcmp(argv[i], "--")) {
+ dash_dash = i;
+ break;
+ }
+
+ if (dash_dash == 3 ||
+ (dash_dash < 0 && argc > 2 &&
+ !get_oid_committish(argv[0], &oid) &&
+ !get_oid_committish(argv[1], &oid) &&
+ !get_oid_committish(argv[2], &oid))) {
+ if (dash_dash < 0)
+ ; /* already validated arguments */
+ else if (get_oid_committish(argv[0], &oid))
+ usage_msg_optf(_("not a revision: '%s'"),
+ builtin_range_diff_usage, options,
+ argv[0]);
+ else if (get_oid_committish(argv[1], &oid))
+ usage_msg_optf(_("not a revision: '%s'"),
+ builtin_range_diff_usage, options,
+ argv[1]);
+ else if (get_oid_committish(argv[2], &oid))
+ usage_msg_optf(_("not a revision: '%s'"),
+ builtin_range_diff_usage, options,
+ argv[2]);
- if (!is_range_diff_range(argv[1]))
- die(_("not a commit range: '%s'"), argv[1]);
- strbuf_addstr(&range2, argv[1]);
- } else if (argc == 3) {
strbuf_addf(&range1, "%s..%s", argv[0], argv[1]);
strbuf_addf(&range2, "%s..%s", argv[0], argv[2]);
- } else if (argc == 1) {
- const char *b = strstr(argv[0], "..."), *a = argv[0];
+
+ strvec_pushv(&other_arg, argv +
+ (dash_dash < 0 ? 3 : dash_dash));
+ } else if (dash_dash == 2 ||
+ (dash_dash < 0 && argc > 1 &&
+ is_range_diff_range(argv[0]) &&
+ is_range_diff_range(argv[1]))) {
+ if (dash_dash < 0)
+ ; /* already validated arguments */
+ else if (!is_range_diff_range(argv[0]))
+ usage_msg_optf(_("not a commit range: '%s'"),
+ builtin_range_diff_usage, options,
+ argv[0]);
+ else if (!is_range_diff_range(argv[1]))
+ usage_msg_optf(_("not a commit range: '%s'"),
+ builtin_range_diff_usage, options,
+ argv[1]);
+
+ strbuf_addstr(&range1, argv[0]);
+ strbuf_addstr(&range2, argv[1]);
+
+ strvec_pushv(&other_arg, argv +
+ (dash_dash < 0 ? 2 : dash_dash));
+ } else if (dash_dash == 1 ||
+ (dash_dash < 0 && argc > 0 &&
+ (three_dots = strstr(argv[0], "...")))) {
+ const char *a, *b;
int a_len;
- if (!b) {
- error(_("single arg format must be symmetric range"));
- usage_with_options(builtin_range_diff_usage, options);
- }
+ if (dash_dash < 0)
+ ; /* already validated arguments */
+ else if (!(three_dots = strstr(argv[0], "...")))
+ usage_msg_optf(_("not a symmetric range: '%s'"),
+ builtin_range_diff_usage, options,
+ argv[0]);
- a_len = (int)(b - a);
- if (!a_len) {
+ if (three_dots == argv[0]) {
a = "HEAD";
a_len = strlen(a);
+ } else {
+ a = argv[0];
+ a_len = (int)(three_dots - a);
}
- b += 3;
- if (!*b)
+
+ if (three_dots[3])
+ b = three_dots + 3;
+ else
b = "HEAD";
+
strbuf_addf(&range1, "%s..%.*s", b, a_len, a);
strbuf_addf(&range2, "%.*s..%s", a_len, a, b);
- } else {
- error(_("need two commit ranges"));
- usage_with_options(builtin_range_diff_usage, options);
- }
+
+ strvec_pushv(&other_arg, argv +
+ (dash_dash < 0 ? 1 : dash_dash));
+ } else
+ usage_msg_opt(_("need two commit ranges"),
+ builtin_range_diff_usage, options);
FREE_AND_NULL(options);
range_diff_opts.dual_color = simple_color < 1;
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 9f1f33e9546..f4cbe460b97 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -38,7 +38,9 @@ static int list_tree(struct object_id *oid)
}
static const char * const read_tree_usage[] = {
- N_("git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) [-u | -i]] [--no-sparse-checkout] [--index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"),
+ N_("git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>)\n"
+ " [-u | -i]] [--index-output=<file>] [--no-sparse-checkout]\n"
+ " (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"),
NULL
};
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 56e4214b441..5d855fd8f51 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -59,6 +59,26 @@ enum empty_type {
EMPTY_ASK
};
+enum action {
+ ACTION_NONE = 0,
+ ACTION_CONTINUE,
+ ACTION_SKIP,
+ ACTION_ABORT,
+ ACTION_QUIT,
+ ACTION_EDIT_TODO,
+ ACTION_SHOW_CURRENT_PATCH
+};
+
+static const char *action_names[] = {
+ "undefined",
+ "continue",
+ "skip",
+ "abort",
+ "quit",
+ "edit_todo",
+ "show_current_patch"
+};
+
struct rebase_options {
enum rebase_type type;
enum empty_type empty;
@@ -68,7 +88,7 @@ struct rebase_options {
const char *upstream_name;
const char *upstream_arg;
char *head_name;
- struct object_id orig_head;
+ struct commit *orig_head;
struct commit *onto;
const char *onto_name;
const char *revisions;
@@ -85,7 +105,7 @@ struct rebase_options {
REBASE_INTERACTIVE_EXPLICIT = 1<<4,
} flags;
struct strvec git_am_opts;
- const char *action;
+ enum action action;
int signoff;
int allow_rerere_autoupdate;
int keep_empty;
@@ -157,24 +177,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
return replay;
}
-enum action {
- ACTION_NONE = 0,
- ACTION_CONTINUE,
- ACTION_SKIP,
- ACTION_ABORT,
- ACTION_QUIT,
- ACTION_EDIT_TODO,
- ACTION_SHOW_CURRENT_PATCH
-};
-
-static const char *action_names[] = { "undefined",
- "continue",
- "skip",
- "abort",
- "quit",
- "edit_todo",
- "show_current_patch" };
-
static int edit_todo_file(unsigned flags)
{
const char *todo_file = rebase_path_todo();
@@ -261,13 +263,13 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
struct replay_opts replay = get_replay_opts(opts);
struct string_list commands = STRING_LIST_INIT_DUP;
- if (get_revision_ranges(opts->upstream, opts->onto, &opts->orig_head,
+ if (get_revision_ranges(opts->upstream, opts->onto, &opts->orig_head->object.oid,
&revisions, &shortrevisions))
return -1;
if (init_basic_state(&replay,
opts->head_name ? opts->head_name : "detached HEAD",
- opts->onto, &opts->orig_head)) {
+ opts->onto, &opts->orig_head->object.oid)) {
free(revisions);
free(shortrevisions);
@@ -298,9 +300,8 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
split_exec_commands(opts->cmd, &commands);
ret = complete_action(the_repository, &replay, flags,
shortrevisions, opts->onto_name, opts->onto,
- &opts->orig_head, &commands, opts->autosquash,
- opts->update_refs,
- &todo_list);
+ &opts->orig_head->object.oid, &commands,
+ opts->autosquash, opts->update_refs, &todo_list);
}
string_list_clear(&commands, 0);
@@ -312,8 +313,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
return ret;
}
-static int run_sequencer_rebase(struct rebase_options *opts,
- enum action command)
+static int run_sequencer_rebase(struct rebase_options *opts)
{
unsigned flags = 0;
int abbreviate_commands = 0, ret = 0;
@@ -328,7 +328,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
flags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;
flags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;
- switch (command) {
+ switch (opts->action) {
case ACTION_NONE: {
if (!opts->onto && !opts->upstream)
die(_("a base commit must be provided with --upstream or --onto"));
@@ -361,7 +361,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
break;
}
default:
- BUG("invalid command '%d'", command);
+ BUG("invalid command '%d'", opts->action);
}
return ret;
@@ -431,9 +431,9 @@ static int read_basic_state(struct rebase_options *opts)
opts->head_name = starts_with(head_name.buf, "refs/") ?
xstrdup(head_name.buf) : NULL;
strbuf_release(&head_name);
- if (get_oid(buf.buf, &oid))
- return error(_("could not get 'onto': '%s'"), buf.buf);
- opts->onto = lookup_commit_or_die(&oid, buf.buf);
+ if (get_oid_hex(buf.buf, &oid) ||
+ !(opts->onto = lookup_commit_object(the_repository, &oid)))
+ return error(_("invalid onto: '%s'"), buf.buf);
/*
* We always write to orig-head, but interactive rebase used to write to
@@ -448,7 +448,8 @@ static int read_basic_state(struct rebase_options *opts)
} else if (!read_oneliner(&buf, state_dir_path("head", opts),
READ_ONELINER_WARN_MISSING))
return -1;
- if (get_oid(buf.buf, &opts->orig_head))
+ if (get_oid_hex(buf.buf, &oid) ||
+ !(opts->orig_head = lookup_commit_object(the_repository, &oid)))
return error(_("invalid orig-head: '%s'"), buf.buf);
if (file_exists(state_dir_path("quiet", opts)))
@@ -517,7 +518,7 @@ static int rebase_write_basic_state(struct rebase_options *opts)
write_file(state_dir_path("onto", opts), "%s",
opts->onto ? oid_to_hex(&opts->onto->object.oid) : "");
write_file(state_dir_path("orig-head", opts), "%s",
- oid_to_hex(&opts->orig_head));
+ oid_to_hex(&opts->orig_head->object.oid));
if (!(opts->flags & REBASE_NO_QUIET))
write_file(state_dir_path("quiet", opts), "%s", "");
if (opts->flags & REBASE_VERBOSE)
@@ -583,10 +584,11 @@ static int move_to_original_branch(struct rebase_options *opts)
if (!opts->onto)
BUG("move_to_original_branch without onto");
- strbuf_addf(&branch_reflog, "rebase finished: %s onto %s",
+ strbuf_addf(&branch_reflog, "%s (finish): %s onto %s",
+ getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
opts->head_name, oid_to_hex(&opts->onto->object.oid));
- strbuf_addf(&head_reflog, "rebase finished: returning to %s",
- opts->head_name);
+ strbuf_addf(&head_reflog, "%s (finish): returning to %s",
+ getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name);
ropts.branch = opts->head_name;
ropts.flags = RESET_HEAD_REFS_ONLY;
ropts.branch_msg = branch_reflog.buf;
@@ -615,8 +617,9 @@ static int run_am(struct rebase_options *opts)
am.git_cmd = 1;
strvec_push(&am.args, "am");
-
- if (opts->action && !strcmp("continue", opts->action)) {
+ strvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT "=%s (pick)",
+ getenv(GIT_REFLOG_ACTION_ENVIRONMENT));
+ if (opts->action == ACTION_CONTINUE) {
strvec_push(&am.args, "--resolved");
strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
if (opts->gpg_sign_opt)
@@ -627,7 +630,7 @@ static int run_am(struct rebase_options *opts)
return move_to_original_branch(opts);
}
- if (opts->action && !strcmp("skip", opts->action)) {
+ if (opts->action == ACTION_SKIP) {
strvec_push(&am.args, "--skip");
strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
status = run_command(&am);
@@ -636,7 +639,7 @@ static int run_am(struct rebase_options *opts)
return move_to_original_branch(opts);
}
- if (opts->action && !strcmp("show-current-patch", opts->action)) {
+ if (opts->action == ACTION_SHOW_CURRENT_PATCH) {
strvec_push(&am.args, "--show-current-patch");
return run_command(&am);
}
@@ -646,7 +649,7 @@ static int run_am(struct rebase_options *opts)
/* this is now equivalent to !opts->upstream */
&opts->onto->object.oid :
&opts->upstream->object.oid),
- oid_to_hex(&opts->orig_head));
+ oid_to_hex(&opts->orig_head->object.oid));
rebased_patches = xstrdup(git_path("rebased-patches"));
format_patch.out = open(rebased_patches,
@@ -680,7 +683,7 @@ static int run_am(struct rebase_options *opts)
free(rebased_patches);
strvec_clear(&am.args);
- ropts.oid = &opts->orig_head;
+ ropts.oid = &opts->orig_head->object.oid;
ropts.branch = opts->head_name;
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
reset_head(the_repository, &ropts);
@@ -729,7 +732,7 @@ static int run_am(struct rebase_options *opts)
return status;
}
-static int run_specific_rebase(struct rebase_options *opts, enum action action)
+static int run_specific_rebase(struct rebase_options *opts)
{
int status;
@@ -747,7 +750,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
opts->gpg_sign_opt = tmp;
}
- status = run_sequencer_rebase(opts, action);
+ status = run_sequencer_rebase(opts);
} else if (opts->type == REBASE_APPLY)
status = run_am(opts);
else
@@ -833,7 +836,7 @@ static int checkout_up_to_date(struct rebase_options *options)
strbuf_addf(&buf, "%s: checkout %s",
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
options->switch_to);
- ropts.oid = &options->orig_head;
+ ropts.oid = &options->orig_head->object.oid;
ropts.branch = options->head_name;
ropts.flags = RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
if (!ropts.branch)
@@ -866,32 +869,23 @@ static int is_linear_history(struct commit *from, struct commit *to)
static int can_fast_forward(struct commit *onto, struct commit *upstream,
struct commit *restrict_revision,
- struct object_id *head_oid, struct object_id *merge_base)
+ struct commit *head, struct object_id *branch_base)
{
- struct commit *head = lookup_commit(the_repository, head_oid);
struct commit_list *merge_bases = NULL;
int res = 0;
- if (!head)
- goto done;
+ if (is_null_oid(branch_base))
+ goto done; /* fill_branch_base() found multiple merge bases */
- merge_bases = get_merge_bases(onto, head);
- if (!merge_bases || merge_bases->next) {
- oidcpy(merge_base, null_oid());
+ if (!oideq(branch_base, &onto->object.oid))
goto done;
- }
- oidcpy(merge_base, &merge_bases->item->object.oid);
- if (!oideq(merge_base, &onto->object.oid))
- goto done;
-
- if (restrict_revision && !oideq(&restrict_revision->object.oid, merge_base))
+ if (restrict_revision && !oideq(&restrict_revision->object.oid, branch_base))
goto done;
if (!upstream)
goto done;
- free_commit_list(merge_bases);
merge_bases = get_merge_bases(upstream, head);
if (!merge_bases || merge_bases->next)
goto done;
@@ -906,6 +900,20 @@ done:
return res && is_linear_history(onto, head);
}
+static void fill_branch_base(struct rebase_options *options,
+ struct object_id *branch_base)
+{
+ struct commit_list *merge_bases = NULL;
+
+ merge_bases = get_merge_bases(options->onto, options->orig_head);
+ if (!merge_bases || merge_bases->next)
+ oidcpy(branch_base, null_oid());
+ else
+ oidcpy(branch_base, &merge_bases->item->object.oid);
+
+ free_commit_list(merge_bases);
+}
+
static int parse_opt_am(const struct option *opt, const char *arg, int unset)
{
struct rebase_options *opts = opt->value;
@@ -1000,23 +1008,6 @@ static void NORETURN error_on_missing_default_upstream(void)
exit(1);
}
-static void set_reflog_action(struct rebase_options *options)
-{
- const char *env;
- struct strbuf buf = STRBUF_INIT;
-
- if (!is_merge(options))
- return;
-
- env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
- if (env && strcmp("rebase", env))
- return; /* only override it if it is "rebase" */
-
- strbuf_addf(&buf, "rebase (%s)", options->action);
- setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
- strbuf_release(&buf);
-}
-
static int check_exec_cmd(const char *cmd)
{
if (strchr(cmd, '\n'))
@@ -1039,9 +1030,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
struct strbuf msg = STRBUF_INIT;
struct strbuf revisions = STRBUF_INIT;
struct strbuf buf = STRBUF_INIT;
- struct object_id merge_base;
+ struct object_id branch_base;
int ignore_whitespace = 0;
- enum action action = ACTION_NONE;
const char *gpg_sign = NULL;
struct string_list exec = STRING_LIST_INIT_NODUP;
const char *rebase_merges = NULL;
@@ -1090,18 +1080,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
OPT_BIT(0, "no-ff", &options.flags,
N_("cherry-pick all commits, even if unchanged"),
REBASE_FORCE),
- OPT_CMDMODE(0, "continue", &action, N_("continue"),
+ OPT_CMDMODE(0, "continue", &options.action, N_("continue"),
ACTION_CONTINUE),
- OPT_CMDMODE(0, "skip", &action,
+ OPT_CMDMODE(0, "skip", &options.action,
N_("skip current patch and continue"), ACTION_SKIP),
- OPT_CMDMODE(0, "abort", &action,
+ OPT_CMDMODE(0, "abort", &options.action,
N_("abort and check out the original branch"),
ACTION_ABORT),
- OPT_CMDMODE(0, "quit", &action,
+ OPT_CMDMODE(0, "quit", &options.action,
N_("abort but keep HEAD where it is"), ACTION_QUIT),
- OPT_CMDMODE(0, "edit-todo", &action, N_("edit the todo list "
+ OPT_CMDMODE(0, "edit-todo", &options.action, N_("edit the todo list "
"during an interactive rebase"), ACTION_EDIT_TODO),
- OPT_CMDMODE(0, "show-current-patch", &action,
+ OPT_CMDMODE(0, "show-current-patch", &options.action,
N_("show the patch file being applied or merged"),
ACTION_SHOW_CURRENT_PATCH),
OPT_CALLBACK_F(0, "apply", &options, NULL,
@@ -1175,6 +1165,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
+ options.reapply_cherry_picks = -1;
options.allow_empty_message = 1;
git_config(rebase_config, &options);
/* options.gpg_sign_opt will be either "-S" or NULL */
@@ -1192,7 +1183,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
} else if (is_directory(merge_dir())) {
strbuf_reset(&buf);
strbuf_addf(&buf, "%s/rewritten", merge_dir());
- if (!(action == ACTION_ABORT) && is_directory(buf.buf)) {
+ if (!(options.action == ACTION_ABORT) && is_directory(buf.buf)) {
die(_("`rebase --preserve-merges` (-p) is no longer supported.\n"
"Use `git rebase --abort` to terminate current rebase.\n"
"Or downgrade to v2.33, or earlier, to complete the rebase."));
@@ -1219,7 +1210,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
"Note: Your `pull.rebase` configuration may also be set to 'preserve',\n"
"which is no longer supported; use 'merges' instead"));
- if (action != ACTION_NONE && total_argc != 2) {
+ if (options.action != ACTION_NONE && total_argc != 2) {
usage_with_options(builtin_rebase_usage,
builtin_rebase_options);
}
@@ -1233,16 +1224,28 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("options '%s' and '%s' cannot be used together"), "--keep-base", "--onto");
if (options.root)
die(_("options '%s' and '%s' cannot be used together"), "--keep-base", "--root");
+ /*
+ * --keep-base defaults to --no-fork-point to keep the
+ * base the same.
+ */
+ if (options.fork_point < 0)
+ options.fork_point = 0;
}
+ /*
+ * --keep-base defaults to --reapply-cherry-picks to avoid losing
+ * commits when using this option.
+ */
+ if (options.reapply_cherry_picks < 0)
+ options.reapply_cherry_picks = keep_base;
if (options.root && options.fork_point > 0)
die(_("options '%s' and '%s' cannot be used together"), "--root", "--fork-point");
- if (action != ACTION_NONE && !in_progress)
+ if (options.action != ACTION_NONE && !in_progress)
die(_("No rebase in progress?"));
setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
- if (action == ACTION_EDIT_TODO && !is_merge(&options))
+ if (options.action == ACTION_EDIT_TODO && !is_merge(&options))
die(_("The --edit-todo action can only be used during "
"interactive rebase."));
@@ -1252,18 +1255,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
else if (exec.nr)
trace2_cmd_mode("interactive-exec");
else
- trace2_cmd_mode(action_names[action]);
+ trace2_cmd_mode(action_names[options.action]);
}
- switch (action) {
+ switch (options.action) {
case ACTION_CONTINUE: {
struct object_id head;
struct lock_file lock_file = LOCK_INIT;
int fd;
- options.action = "continue";
- set_reflog_action(&options);
-
/* Sanity check */
if (get_oid("HEAD", &head))
die(_("Cannot read HEAD"));
@@ -1289,9 +1289,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
case ACTION_SKIP: {
struct string_list merge_rr = STRING_LIST_INIT_DUP;
- options.action = "skip";
- set_reflog_action(&options);
-
rerere_clear(the_repository, &merge_rr);
string_list_clear(&merge_rr, 1);
ropts.flags = RESET_HEAD_HARD;
@@ -1304,21 +1301,25 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
}
case ACTION_ABORT: {
struct string_list merge_rr = STRING_LIST_INIT_DUP;
- options.action = "abort";
- set_reflog_action(&options);
+ struct strbuf head_msg = STRBUF_INIT;
rerere_clear(the_repository, &merge_rr);
string_list_clear(&merge_rr, 1);
if (read_basic_state(&options))
exit(1);
- ropts.oid = &options.orig_head;
+
+ strbuf_addf(&head_msg, "%s (abort): returning to %s",
+ getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
+ options.head_name ? options.head_name
+ : oid_to_hex(&options.orig_head->object.oid));
+ ropts.oid = &options.orig_head->object.oid;
+ ropts.head_msg = head_msg.buf;
ropts.branch = options.head_name;
ropts.flags = RESET_HEAD_HARD;
- ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
if (reset_head(the_repository, &ropts) < 0)
die(_("could not move back to %s"),
- oid_to_hex(&options.orig_head));
+ oid_to_hex(&options.orig_head->object.oid));
remove_branch_state(the_repository, 0);
ret = finish_rebase(&options);
goto cleanup;
@@ -1341,17 +1342,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
goto cleanup;
}
case ACTION_EDIT_TODO:
- options.action = "edit-todo";
options.dont_finish_rebase = 1;
goto run_rebase;
case ACTION_SHOW_CURRENT_PATCH:
- options.action = "show-current-patch";
options.dont_finish_rebase = 1;
goto run_rebase;
case ACTION_NONE:
break;
default:
- BUG("action: %d", action);
+ BUG("action: %d", options.action);
}
/* Make sure no rebase is in progress */
@@ -1375,7 +1374,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
}
if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
- (action != ACTION_NONE) ||
+ (options.action != ACTION_NONE) ||
(exec.nr > 0) ||
options.autosquash) {
allow_preemptive_ff = 0;
@@ -1410,7 +1409,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if (options.empty != EMPTY_UNSPECIFIED)
imply_merge(&options, "--empty");
- if (options.reapply_cherry_picks)
+ /*
+ * --keep-base implements --reapply-cherry-picks by altering upstream so
+ * it works with both backends.
+ */
+ if (options.reapply_cherry_picks && !keep_base)
imply_merge(&options, "--reapply-cherry-picks");
if (gpg_sign)
@@ -1604,25 +1607,27 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
*/
if (argc == 1) {
/* Is it "rebase other branchname" or "rebase other commit"? */
+ struct object_id branch_oid;
branch_name = argv[0];
options.switch_to = argv[0];
/* Is it a local branch? */
strbuf_reset(&buf);
strbuf_addf(&buf, "refs/heads/%s", branch_name);
- if (!read_ref(buf.buf, &options.orig_head)) {
+ if (!read_ref(buf.buf, &branch_oid)) {
die_if_checked_out(buf.buf, 1);
options.head_name = xstrdup(buf.buf);
+ options.orig_head =
+ lookup_commit_object(the_repository,
+ &branch_oid);
/* If not is it a valid ref (branch or commit)? */
} else {
- struct commit *commit =
+ options.orig_head =
lookup_commit_reference_by_name(branch_name);
- if (!commit)
- die(_("no such branch/commit '%s'"),
- branch_name);
- oidcpy(&options.orig_head, &commit->object.oid);
options.head_name = NULL;
}
+ if (!options.orig_head)
+ die(_("no such branch/commit '%s'"), branch_name);
} else if (argc == 0) {
/* Do not need to switch branches, we are already on it. */
options.head_name =
@@ -1639,8 +1644,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
FREE_AND_NULL(options.head_name);
branch_name = "HEAD";
}
- if (get_oid("HEAD", &options.orig_head))
- die(_("Could not resolve HEAD to a revision"));
+ options.orig_head = lookup_commit_reference_by_name("HEAD");
+ if (!options.orig_head)
+ die(_("Could not resolve HEAD to a commit"));
} else
BUG("unexpected number of arguments left to parse");
@@ -1654,7 +1660,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
} else if (!options.onto_name)
options.onto_name = options.upstream_name;
if (strstr(options.onto_name, "...")) {
- if (get_oid_mb(options.onto_name, &merge_base) < 0) {
+ if (get_oid_mb(options.onto_name, &branch_base) < 0) {
if (keep_base)
die(_("'%s': need exactly one merge base with branch"),
options.upstream_name);
@@ -1662,7 +1668,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("'%s': need exactly one merge base"),
options.onto_name);
}
- options.onto = lookup_commit_or_die(&merge_base,
+ options.onto = lookup_commit_or_die(&branch_base,
options.onto_name);
} else {
options.onto =
@@ -1670,15 +1676,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if (!options.onto)
die(_("Does not point to a valid commit '%s'"),
options.onto_name);
+ fill_branch_base(&options, &branch_base);
}
- if (options.fork_point > 0) {
- struct commit *head =
- lookup_commit_reference(the_repository,
- &options.orig_head);
+ if (keep_base && options.reapply_cherry_picks)
+ options.upstream = options.onto;
+
+ if (options.fork_point > 0)
options.restrict_revision =
- get_fork_point(options.upstream_name, head);
- }
+ get_fork_point(options.upstream_name, options.orig_head);
if (repo_read_index(the_repository) < 0)
die(_("could not read index"));
@@ -1703,13 +1709,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
* Check if we are already based on onto with linear history,
* in which case we could fast-forward without replacing the commits
* with new commits recreated by replaying their changes.
- *
- * Note that can_fast_forward() initializes merge_base, so we have to
- * call it before checking allow_preemptive_ff.
*/
- if (can_fast_forward(options.onto, options.upstream, options.restrict_revision,
- &options.orig_head, &merge_base) &&
- allow_preemptive_ff) {
+ if (allow_preemptive_ff &&
+ can_fast_forward(options.onto, options.upstream, options.restrict_revision,
+ options.orig_head, &branch_base)) {
int flag;
if (!(options.flags & REBASE_FORCE)) {
@@ -1750,12 +1753,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
struct diff_options opts;
if (options.flags & REBASE_VERBOSE) {
- if (is_null_oid(&merge_base))
+ if (is_null_oid(&branch_base))
printf(_("Changes to %s:\n"),
oid_to_hex(&options.onto->object.oid));
else
printf(_("Changes from %s to %s:\n"),
- oid_to_hex(&merge_base),
+ oid_to_hex(&branch_base),
oid_to_hex(&options.onto->object.oid));
}
@@ -1767,8 +1770,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
opts.detect_rename = DIFF_DETECT_RENAME;
diff_setup_done(&opts);
- diff_tree_oid(is_null_oid(&merge_base) ?
- the_hash_algo->empty_tree : &merge_base,
+ diff_tree_oid(is_null_oid(&branch_base) ?
+ the_hash_algo->empty_tree : &branch_base,
&options.onto->object.oid, "", &opts);
diffcore_std(&opts);
diff_flush(&opts);
@@ -1782,10 +1785,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
printf(_("First, rewinding head to replay your work on top of "
"it...\n"));
- strbuf_addf(&msg, "%s: checkout %s",
+ strbuf_addf(&msg, "%s (start): checkout %s",
getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
ropts.oid = &options.onto->object.oid;
- ropts.orig_head = &options.orig_head,
+ ropts.orig_head = &options.orig_head->object.oid,
ropts.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |
RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
ropts.head_msg = msg.buf;
@@ -1798,19 +1801,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
* If the onto is a proper descendant of the tip of the branch, then
* we just fast-forwarded.
*/
- strbuf_reset(&msg);
- if (oideq(&merge_base, &options.orig_head)) {
+ if (oideq(&branch_base, &options.orig_head->object.oid)) {
printf(_("Fast-forwarded %s to %s.\n"),
branch_name, options.onto_name);
- strbuf_addf(&msg, "rebase finished: %s onto %s",
- options.head_name ? options.head_name : "detached HEAD",
- oid_to_hex(&options.onto->object.oid));
- memset(&ropts, 0, sizeof(ropts));
- ropts.branch = options.head_name;
- ropts.flags = RESET_HEAD_REFS_ONLY;
- ropts.head_msg = msg.buf;
- reset_head(the_repository, &ropts);
- strbuf_release(&msg);
+ move_to_original_branch(&options);
ret = finish_rebase(&options);
goto cleanup;
}
@@ -1820,12 +1814,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
(options.restrict_revision ?
oid_to_hex(&options.restrict_revision->object.oid) :
oid_to_hex(&options.upstream->object.oid)),
- oid_to_hex(&options.orig_head));
+ oid_to_hex(&options.orig_head->object.oid));
options.revisions = revisions.buf;
run_rebase:
- ret = run_specific_rebase(&options, action);
+ ret = run_specific_rebase(&options);
cleanup:
strbuf_release(&buf);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 31b48e728be..44bcea3a5b3 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -291,7 +291,7 @@ static void show_ref(const char *path, const struct object_id *oid)
}
static int show_ref_cb(const char *path_full, const struct object_id *oid,
- int flag, void *data)
+ int flag UNUSED, void *data)
{
struct oidset *seen = data;
const char *path = strip_namespace(path_full);
@@ -465,7 +465,7 @@ static void rp_error(const char *err, ...)
va_end(params);
}
-static int copy_to_sideband(int in, int out, void *arg)
+static int copy_to_sideband(int in, int out UNUSED, void *arg UNUSED)
{
char data[128];
int keepalive_active = 0;
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 81239568478..270681dcdf4 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -56,7 +56,8 @@ struct worktree_reflogs {
struct string_list reflogs;
};
-static int collect_reflog(const char *ref, const struct object_id *oid, int unused, void *cb_data)
+static int collect_reflog(const char *ref, const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data)
{
struct worktree_reflogs *cb = cb_data;
struct worktree *worktree = cb->worktree;
@@ -66,7 +67,8 @@ static int collect_reflog(const char *ref, const struct object_id *oid, int unus
* Avoid collecting the same shared ref multiple times because
* they are available via all worktrees.
*/
- if (!worktree->is_current && ref_type(ref) == REF_TYPE_NORMAL)
+ if (!worktree->is_current &&
+ parse_worktree_ref(ref, NULL, NULL, NULL) == REF_WORKTREE_SHARED)
return 0;
strbuf_worktree_ref(worktree, &newref, ref);
@@ -227,7 +229,7 @@ static int cmd_reflog_show(int argc, const char **argv, const char *prefix)
parse_options(argc, argv, prefix, options, reflog_show_usage,
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
return cmd_log_reflog(argc, argv, prefix);
}
@@ -408,40 +410,21 @@ static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)
int cmd_reflog(int argc, const char **argv, const char *prefix)
{
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
+ OPT_SUBCOMMAND("show", &fn, cmd_reflog_show),
+ OPT_SUBCOMMAND("expire", &fn, cmd_reflog_expire),
+ OPT_SUBCOMMAND("delete", &fn, cmd_reflog_delete),
+ OPT_SUBCOMMAND("exists", &fn, cmd_reflog_exists),
OPT_END()
};
argc = parse_options(argc, argv, prefix, options, reflog_usage,
+ PARSE_OPT_SUBCOMMAND_OPTIONAL |
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |
- PARSE_OPT_KEEP_UNKNOWN |
- PARSE_OPT_NO_INTERNAL_HELP);
-
- /*
- * With "git reflog" we default to showing it. !argc is
- * impossible with PARSE_OPT_KEEP_ARGV0.
- */
- if (argc == 1)
- goto log_reflog;
-
- if (!strcmp(argv[1], "-h"))
- usage_with_options(reflog_usage, options);
- else if (*argv[1] == '-')
- goto log_reflog;
-
- if (!strcmp(argv[1], "show"))
- return cmd_reflog_show(argc - 1, argv + 1, prefix);
- else if (!strcmp(argv[1], "expire"))
- return cmd_reflog_expire(argc - 1, argv + 1, prefix);
- else if (!strcmp(argv[1], "delete"))
- return cmd_reflog_delete(argc - 1, argv + 1, prefix);
- else if (!strcmp(argv[1], "exists"))
- return cmd_reflog_exists(argc - 1, argv + 1, prefix);
-
- /*
- * Fall-through for e.g. "git reflog -1", "git reflog master",
- * as well as the plain "git reflog" above goto above.
- */
-log_reflog:
- return cmd_log_reflog(argc, argv, prefix);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
+ if (fn)
+ return fn(argc - 1, argv + 1, prefix);
+ else
+ return cmd_log_reflog(argc, argv, prefix);
}
diff --git a/builtin/remote.c b/builtin/remote.c
index c713463d89d..729f6f3643a 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -92,13 +92,15 @@ static int verbose;
static int fetch_remote(const char *name)
{
- const char *argv[] = { "fetch", name, NULL, NULL };
- if (verbose) {
- argv[1] = "-v";
- argv[2] = name;
- }
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_push(&cmd.args, "fetch");
+ if (verbose)
+ strvec_push(&cmd.args, "-v");
+ strvec_push(&cmd.args, name);
+ cmd.git_cmd = 1;
printf_ln(_("Updating %s"), name);
- if (run_command_v_opt(argv, RUN_GIT_CMD))
+ if (run_command(&cmd))
return error(_("Could not fetch %s"), name);
return 0;
}
@@ -150,7 +152,7 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)
return 0;
}
-static int add(int argc, const char **argv)
+static int add(int argc, const char **argv, const char *prefix)
{
int fetch = 0, fetch_tags = TAGS_DEFAULT;
unsigned mirror = MIRROR_NONE;
@@ -177,8 +179,8 @@ static int add(int argc, const char **argv)
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_add_usage,
- 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_add_usage, 0);
if (argc != 2)
usage_with_options(builtin_remote_add_usage, options);
@@ -264,7 +266,8 @@ static const char *abbrev_ref(const char *name, const char *prefix)
}
#define abbrev_branch(name) abbrev_ref((name), "refs/heads/")
-static int config_read_branches(const char *key, const char *value, void *cb)
+static int config_read_branches(const char *key, const char *value,
+ void *data UNUSED)
{
const char *orig_key = key;
char *name;
@@ -538,7 +541,8 @@ struct branches_for_remote {
};
static int add_branch_for_removal(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data)
{
struct branches_for_remote *branches = cb_data;
struct refspec_item refspec;
@@ -580,7 +584,8 @@ struct rename_info {
};
static int read_remote_branches(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data)
{
struct rename_info *rename = cb_data;
struct strbuf buf = STRBUF_INIT;
@@ -680,7 +685,7 @@ static void handle_push_default(const char* old_name, const char* new_name)
}
-static int mv(int argc, const char **argv)
+static int mv(int argc, const char **argv, const char *prefix)
{
int show_progress = isatty(2);
struct option options[] = {
@@ -695,7 +700,7 @@ static int mv(int argc, const char **argv)
int i, refs_renamed_nr = 0, refspec_updated = 0;
struct progress *progress = NULL;
- argc = parse_options(argc, argv, NULL, options,
+ argc = parse_options(argc, argv, prefix, options,
builtin_remote_rename_usage, 0);
if (argc != 2)
@@ -730,29 +735,31 @@ static int mv(int argc, const char **argv)
return error(_("Could not rename config section '%s' to '%s'"),
buf.buf, buf2.buf);
- strbuf_reset(&buf);
- strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
- git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
- strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
- for (i = 0; i < oldremote->fetch.raw_nr; i++) {
- char *ptr;
-
- strbuf_reset(&buf2);
- strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
- ptr = strstr(buf2.buf, old_remote_context.buf);
- if (ptr) {
- refspec_updated = 1;
- strbuf_splice(&buf2,
- ptr-buf2.buf + strlen(":refs/remotes/"),
- strlen(rename.old_name), rename.new_name,
- strlen(rename.new_name));
- } else
- warning(_("Not updating non-default fetch refspec\n"
- "\t%s\n"
- "\tPlease update the configuration manually if necessary."),
- buf2.buf);
-
- git_config_set_multivar(buf.buf, buf2.buf, "^$", 0);
+ if (oldremote->fetch.raw_nr) {
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
+ git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
+ strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
+ for (i = 0; i < oldremote->fetch.raw_nr; i++) {
+ char *ptr;
+
+ strbuf_reset(&buf2);
+ strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
+ ptr = strstr(buf2.buf, old_remote_context.buf);
+ if (ptr) {
+ refspec_updated = 1;
+ strbuf_splice(&buf2,
+ ptr-buf2.buf + strlen(":refs/remotes/"),
+ strlen(rename.old_name), rename.new_name,
+ strlen(rename.new_name));
+ } else
+ warning(_("Not updating non-default fetch refspec\n"
+ "\t%s\n"
+ "\tPlease update the configuration manually if necessary."),
+ buf2.buf);
+
+ git_config_set_multivar(buf.buf, buf2.buf, "^$", 0);
+ }
}
read_branches();
@@ -844,7 +851,7 @@ static int mv(int argc, const char **argv)
return 0;
}
-static int rm(int argc, const char **argv)
+static int rm(int argc, const char **argv, const char *prefix)
{
struct option options[] = {
OPT_END()
@@ -862,12 +869,14 @@ static int rm(int argc, const char **argv)
cb_data.skipped = &skipped;
cb_data.keep = &known_remotes;
- if (argc != 2)
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_rm_usage, 0);
+ if (argc != 1)
usage_with_options(builtin_remote_rm_usage, options);
- remote = remote_get(argv[1]);
+ remote = remote_get(argv[0]);
if (!remote_is_configured(remote, 1)) {
- error(_("No such remote: '%s'"), argv[1]);
+ error(_("No such remote: '%s'"), argv[0]);
exit(2);
}
@@ -935,7 +944,7 @@ static int rm(int argc, const char **argv)
return result;
}
-static void clear_push_info(void *util, const char *string)
+static void clear_push_info(void *util, const char *string UNUSED)
{
struct push_info *info = util;
free(info->dest);
@@ -953,7 +962,8 @@ static void free_remote_ref_states(struct ref_states *states)
}
static int append_ref_to_tracked_list(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags, void *cb_data)
{
struct ref_states *states = cb_data;
struct refspec_item refspec;
@@ -1254,7 +1264,7 @@ static int show_all(void)
return result;
}
-static int show(int argc, const char **argv)
+static int show(int argc, const char **argv, const char *prefix)
{
int no_query = 0, result = 0, query_flag = 0;
struct option options[] = {
@@ -1263,7 +1273,8 @@ static int show(int argc, const char **argv)
};
struct show_info info = SHOW_INFO_INIT;
- argc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_show_usage,
0);
if (argc < 1)
@@ -1357,7 +1368,7 @@ static int show(int argc, const char **argv)
return result;
}
-static int set_head(int argc, const char **argv)
+static int set_head(int argc, const char **argv, const char *prefix)
{
int i, opt_a = 0, opt_d = 0, result = 0;
struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
@@ -1370,8 +1381,8 @@ static int set_head(int argc, const char **argv)
N_("delete refs/remotes/<name>/HEAD")),
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_sethead_usage,
- 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_sethead_usage, 0);
if (argc)
strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]);
@@ -1462,7 +1473,7 @@ static int prune_remote(const char *remote, int dry_run)
return result;
}
-static int prune(int argc, const char **argv)
+static int prune(int argc, const char **argv, const char *prefix)
{
int dry_run = 0, result = 0;
struct option options[] = {
@@ -1470,8 +1481,8 @@ static int prune(int argc, const char **argv)
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_prune_usage,
- 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_prune_usage, 0);
if (argc < 1)
usage_with_options(builtin_remote_prune_usage, options);
@@ -1482,7 +1493,7 @@ static int prune(int argc, const char **argv)
return result;
}
-static int get_remote_default(const char *key, const char *value, void *priv)
+static int get_remote_default(const char *key, const char *value UNUSED, void *priv)
{
if (strcmp(key, "remotes.default") == 0) {
int *found = priv;
@@ -1491,7 +1502,7 @@ static int get_remote_default(const char *key, const char *value, void *priv)
return 0;
}
-static int update(int argc, const char **argv)
+static int update(int argc, const char **argv, const char *prefix)
{
int i, prune = -1;
struct option options[] = {
@@ -1499,36 +1510,35 @@ static int update(int argc, const char **argv)
N_("prune remotes after fetching")),
OPT_END()
};
- struct strvec fetch_argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int default_defined = 0;
- int retval;
- argc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage,
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_update_usage,
PARSE_OPT_KEEP_ARGV0);
- strvec_push(&fetch_argv, "fetch");
+ strvec_push(&cmd.args, "fetch");
if (prune != -1)
- strvec_push(&fetch_argv, prune ? "--prune" : "--no-prune");
+ strvec_push(&cmd.args, prune ? "--prune" : "--no-prune");
if (verbose)
- strvec_push(&fetch_argv, "-v");
- strvec_push(&fetch_argv, "--multiple");
+ strvec_push(&cmd.args, "-v");
+ strvec_push(&cmd.args, "--multiple");
if (argc < 2)
- strvec_push(&fetch_argv, "default");
+ strvec_push(&cmd.args, "default");
for (i = 1; i < argc; i++)
- strvec_push(&fetch_argv, argv[i]);
+ strvec_push(&cmd.args, argv[i]);
- if (strcmp(fetch_argv.v[fetch_argv.nr-1], "default") == 0) {
+ if (strcmp(cmd.args.v[cmd.args.nr-1], "default") == 0) {
git_config(get_remote_default, &default_defined);
if (!default_defined) {
- strvec_pop(&fetch_argv);
- strvec_push(&fetch_argv, "--all");
+ strvec_pop(&cmd.args);
+ strvec_push(&cmd.args, "--all");
}
}
- retval = run_command_v_opt(fetch_argv.v, RUN_GIT_CMD);
- strvec_clear(&fetch_argv);
- return retval;
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
static int remove_all_fetch_refspecs(const char *key)
@@ -1574,7 +1584,7 @@ static int set_remote_branches(const char *remotename, const char **branches,
return 0;
}
-static int set_branches(int argc, const char **argv)
+static int set_branches(int argc, const char **argv, const char *prefix)
{
int add_mode = 0;
struct option options[] = {
@@ -1582,7 +1592,7 @@ static int set_branches(int argc, const char **argv)
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options,
+ argc = parse_options(argc, argv, prefix, options,
builtin_remote_setbranches_usage, 0);
if (argc == 0) {
error(_("no remote specified"));
@@ -1593,7 +1603,7 @@ static int set_branches(int argc, const char **argv)
return set_remote_branches(argv[0], argv + 1, add_mode);
}
-static int get_url(int argc, const char **argv)
+static int get_url(int argc, const char **argv, const char *prefix)
{
int i, push_mode = 0, all_mode = 0;
const char *remotename = NULL;
@@ -1607,7 +1617,8 @@ static int get_url(int argc, const char **argv)
N_("return all URLs")),
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_geturl_usage, 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_geturl_usage, 0);
if (argc != 1)
usage_with_options(builtin_remote_geturl_usage, options);
@@ -1646,7 +1657,7 @@ static int get_url(int argc, const char **argv)
return 0;
}
-static int set_url(int argc, const char **argv)
+static int set_url(int argc, const char **argv, const char *prefix)
{
int i, push_mode = 0, add_mode = 0, delete_mode = 0;
int matches = 0, negative_matches = 0;
@@ -1667,7 +1678,8 @@ static int set_url(int argc, const char **argv)
N_("delete URLs")),
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_seturl_usage,
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_seturl_usage,
PARSE_OPT_KEEP_ARGV0);
if (add_mode && delete_mode)
@@ -1738,41 +1750,33 @@ out:
int cmd_remote(int argc, const char **argv, const char *prefix)
{
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")),
+ OPT_SUBCOMMAND("add", &fn, add),
+ OPT_SUBCOMMAND("rename", &fn, mv),
+ OPT_SUBCOMMAND_F("rm", &fn, rm, PARSE_OPT_NOCOMPLETE),
+ OPT_SUBCOMMAND("remove", &fn, rm),
+ OPT_SUBCOMMAND("set-head", &fn, set_head),
+ OPT_SUBCOMMAND("set-branches", &fn, set_branches),
+ OPT_SUBCOMMAND("get-url", &fn, get_url),
+ OPT_SUBCOMMAND("set-url", &fn, set_url),
+ OPT_SUBCOMMAND("show", &fn, show),
+ OPT_SUBCOMMAND("prune", &fn, prune),
+ OPT_SUBCOMMAND("update", &fn, update),
OPT_END()
};
- int result;
argc = parse_options(argc, argv, prefix, options, builtin_remote_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ PARSE_OPT_SUBCOMMAND_OPTIONAL);
- if (argc < 1)
- result = show_all();
- else if (!strcmp(argv[0], "add"))
- result = add(argc, argv);
- else if (!strcmp(argv[0], "rename"))
- result = mv(argc, argv);
- else if (!strcmp(argv[0], "rm") || !strcmp(argv[0], "remove"))
- result = rm(argc, argv);
- else if (!strcmp(argv[0], "set-head"))
- result = set_head(argc, argv);
- else if (!strcmp(argv[0], "set-branches"))
- result = set_branches(argc, argv);
- else if (!strcmp(argv[0], "get-url"))
- result = get_url(argc, argv);
- else if (!strcmp(argv[0], "set-url"))
- result = set_url(argc, argv);
- else if (!strcmp(argv[0], "show"))
- result = show(argc, argv);
- else if (!strcmp(argv[0], "prune"))
- result = prune(argc, argv);
- else if (!strcmp(argv[0], "update"))
- result = update(argc, argv);
- else {
- error(_("Unknown subcommand: %s"), argv[0]);
- usage_with_options(builtin_remote_usage, options);
+ if (fn) {
+ return !!fn(argc, argv, prefix);
+ } else {
+ if (argc) {
+ error(_("unknown subcommand: `%s'"), argv[0]);
+ usage_with_options(builtin_remote_usage, options);
+ }
+ return !!show_all();
}
-
- return result ? 1 : 0;
}
diff --git a/builtin/repack.c b/builtin/repack.c
index 482b66f57d6..65eb1b8bd22 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -32,7 +32,6 @@ static int write_bitmaps = -1;
static int use_delta_islands;
static int run_update_server_info = 1;
static char *packdir, *packtmp_name, *packtmp;
-static char *cruft_expiration;
static const char *const git_repack_usage[] = {
N_("git repack [<options>]"),
@@ -92,44 +91,6 @@ static int repack_config(const char *var, const char *value, void *cb)
}
/*
- * Remove temporary $GIT_OBJECT_DIRECTORY/pack/.tmp-$$-pack-* files.
- */
-static void remove_temporary_files(void)
-{
- struct strbuf buf = STRBUF_INIT;
- size_t dirlen, prefixlen;
- DIR *dir;
- struct dirent *e;
-
- dir = opendir(packdir);
- if (!dir)
- return;
-
- /* Point at the slash at the end of ".../objects/pack/" */
- dirlen = strlen(packdir) + 1;
- strbuf_addstr(&buf, packtmp);
- /* Hold the length of ".tmp-%d-pack-" */
- prefixlen = buf.len - dirlen;
-
- while ((e = readdir(dir))) {
- if (strncmp(e->d_name, buf.buf + dirlen, prefixlen))
- continue;
- strbuf_setlen(&buf, dirlen);
- strbuf_addstr(&buf, e->d_name);
- unlink(buf.buf);
- }
- closedir(dir);
- strbuf_release(&buf);
-}
-
-static void remove_pack_on_signal(int signo)
-{
- remove_temporary_files();
- sigchain_pop(signo);
- raise(signo);
-}
-
-/*
* Adds all packs hex strings to either fname_nonkept_list or
* fname_kept_list based on whether each pack has a corresponding
* .keep file or not. Packs without a .keep file are not to be kept
@@ -188,7 +149,8 @@ static void remove_redundant_pack(const char *dir_name, const char *base_name)
}
static void prepare_pack_objects(struct child_process *cmd,
- const struct pack_objects_args *args)
+ const struct pack_objects_args *args,
+ const char *out)
{
strvec_push(&cmd->args, "pack-objects");
if (args->window)
@@ -211,7 +173,7 @@ static void prepare_pack_objects(struct child_process *cmd,
strvec_push(&cmd->args, "--quiet");
if (delta_base_offset)
strvec_push(&cmd->args, "--delta-base-offset");
- strvec_push(&cmd->args, packtmp);
+ strvec_push(&cmd->args, out);
cmd->git_cmd = 1;
cmd->out = -1;
}
@@ -247,11 +209,15 @@ static struct {
{".idx"},
};
-static unsigned populate_pack_exts(char *name)
+struct generated_pack_data {
+ struct tempfile *tempfiles[ARRAY_SIZE(exts)];
+};
+
+static struct generated_pack_data *populate_pack_exts(const char *name)
{
struct stat statbuf;
struct strbuf path = STRBUF_INIT;
- unsigned ret = 0;
+ struct generated_pack_data *data = xcalloc(1, sizeof(*data));
int i;
for (i = 0; i < ARRAY_SIZE(exts); i++) {
@@ -261,11 +227,11 @@ static unsigned populate_pack_exts(char *name)
if (stat(path.buf, &statbuf))
continue;
- ret |= (1 << i);
+ data->tempfiles[i] = register_tempfile(path.buf);
}
strbuf_release(&path);
- return ret;
+ return data;
}
static void repack_promisor_objects(const struct pack_objects_args *args,
@@ -275,7 +241,7 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
FILE *out;
struct strbuf line = STRBUF_INIT;
- prepare_pack_objects(&cmd, args);
+ prepare_pack_objects(&cmd, args, packtmp);
cmd.in = -1;
/*
@@ -320,7 +286,7 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
line.buf);
write_promisor_file(promisor_name, NULL, 0);
- item->util = (void *)(uintptr_t)populate_pack_exts(item->string);
+ item->util = populate_pack_exts(item->string);
free(promisor_name);
}
@@ -514,9 +480,9 @@ struct midx_snapshot_ref_data {
int preferred;
};
-static int midx_snapshot_ref_one(const char *refname,
+static int midx_snapshot_ref_one(const char *refname UNUSED,
const struct object_id *oid,
- int flag, void *_data)
+ int flag UNUSED, void *_data)
{
struct midx_snapshot_ref_data *data = _data;
struct object_id peeled;
@@ -661,8 +627,39 @@ static int write_midx_included_packs(struct string_list *include,
return finish_command(&cmd);
}
+static void remove_redundant_bitmaps(struct string_list *include,
+ const char *packdir)
+{
+ struct strbuf path = STRBUF_INIT;
+ struct string_list_item *item;
+ size_t packdir_len;
+
+ strbuf_addstr(&path, packdir);
+ strbuf_addch(&path, '/');
+ packdir_len = path.len;
+
+ /*
+ * Remove any pack bitmaps corresponding to packs which are now
+ * included in the MIDX.
+ */
+ for_each_string_list_item(item, include) {
+ strbuf_addstr(&path, item->string);
+ strbuf_strip_suffix(&path, ".idx");
+ strbuf_addstr(&path, ".bitmap");
+
+ if (unlink(path.buf) && errno != ENOENT)
+ warning_errno(_("could not remove stale bitmap: %s"),
+ path.buf);
+
+ strbuf_setlen(&path, packdir_len);
+ }
+ strbuf_release(&path);
+}
+
static int write_cruft_pack(const struct pack_objects_args *args,
+ const char *destination,
const char *pack_prefix,
+ const char *cruft_expiration,
struct string_list *names,
struct string_list *existing_packs,
struct string_list *existing_kept_packs)
@@ -672,8 +669,10 @@ static int write_cruft_pack(const struct pack_objects_args *args,
struct string_list_item *item;
FILE *in, *out;
int ret;
+ const char *scratch;
+ int local = skip_prefix(destination, packdir, &scratch);
- prepare_pack_objects(&cmd, args);
+ prepare_pack_objects(&cmd, args, destination);
strvec_push(&cmd.args, "--cruft");
if (cruft_expiration)
@@ -698,6 +697,10 @@ static int write_cruft_pack(const struct pack_objects_args *args,
* By the time it is read here, it contains only the pack(s)
* that were just written, which is exactly the set of packs we
* want to consider kept.
+ *
+ * If `--expire-to` is given, the double-use served by `names`
+ * ensures that the pack written to `--expire-to` excludes any
+ * objects contained in the cruft pack.
*/
in = xfdopen(cmd.in, "w");
for_each_string_list_item(item, names)
@@ -710,10 +713,19 @@ static int write_cruft_pack(const struct pack_objects_args *args,
out = xfdopen(cmd.out, "r");
while (strbuf_getline_lf(&line, out) != EOF) {
+ struct string_list_item *item;
+
if (line.len != the_hash_algo->hexsz)
die(_("repack: Expecting full hex object ID lines only "
"from pack-objects."));
- string_list_append(names, line.buf);
+ /*
+ * avoid putting packs written outside of the repository in the
+ * list of names
+ */
+ if (local) {
+ item = string_list_append(names, line.buf);
+ item->util = populate_pack_exts(line.buf);
+ }
}
fclose(out);
@@ -745,6 +757,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
struct pack_objects_args cruft_po_args = {NULL};
int geometric_factor = 0;
int write_midx = 0;
+ const char *cruft_expiration = NULL;
+ const char *expire_to = NULL;
struct option builtin_repack_options[] = {
OPT_BIT('a', NULL, &pack_everything,
@@ -794,6 +808,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
N_("find a geometric progression with factor <N>")),
OPT_BOOL('m', "write-midx", &write_midx,
N_("write a multi-pack index of the resulting packs")),
+ OPT_STRING(0, "expire-to", &expire_to, N_("dir"),
+ N_("pack prefix to store a pack containing pruned objects")),
OPT_END()
};
@@ -859,9 +875,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
split_pack_geometry(geometry, geometric_factor);
}
- sigchain_push_common(remove_pack_on_signal);
-
- prepare_pack_objects(&cmd, &po_args);
+ prepare_pack_objects(&cmd, &po_args, packtmp);
show_progress = !po_args.quiet && isatty(2);
@@ -952,9 +966,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
out = xfdopen(cmd.out, "r");
while (strbuf_getline_lf(&line, out) != EOF) {
+ struct string_list_item *item;
+
if (line.len != the_hash_algo->hexsz)
die(_("repack: Expecting full hex object ID lines only from pack-objects."));
- string_list_append(&names, line.buf);
+ item = string_list_append(&names, line.buf);
+ item->util = populate_pack_exts(item->string);
}
fclose(out);
ret = finish_command(&cmd);
@@ -984,49 +1001,81 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
cruft_po_args.local = po_args.local;
cruft_po_args.quiet = po_args.quiet;
- ret = write_cruft_pack(&cruft_po_args, pack_prefix, &names,
+ ret = write_cruft_pack(&cruft_po_args, packtmp, pack_prefix,
+ cruft_expiration, &names,
&existing_nonkept_packs,
&existing_kept_packs);
if (ret)
return ret;
+
+ if (delete_redundant && expire_to) {
+ /*
+ * If `--expire-to` is given with `-d`, it's possible
+ * that we're about to prune some objects. With cruft
+ * packs, pruning is implicit: any objects from existing
+ * packs that weren't picked up by new packs are removed
+ * when their packs are deleted.
+ *
+ * Generate an additional cruft pack, with one twist:
+ * `names` now includes the name of the cruft pack
+ * written in the previous step. So the contents of
+ * _this_ cruft pack exclude everything contained in the
+ * existing cruft pack (that is, all of the unreachable
+ * objects which are no older than
+ * `--cruft-expiration`).
+ *
+ * To make this work, cruft_expiration must become NULL
+ * so that this cruft pack doesn't actually prune any
+ * objects. If it were non-NULL, this call would always
+ * generate an empty pack (since every object not in the
+ * cruft pack generated above will have an mtime older
+ * than the expiration).
+ */
+ ret = write_cruft_pack(&cruft_po_args, expire_to,
+ pack_prefix,
+ NULL,
+ &names,
+ &existing_nonkept_packs,
+ &existing_kept_packs);
+ if (ret)
+ return ret;
+ }
}
string_list_sort(&names);
- for_each_string_list_item(item, &names) {
- item->util = (void *)(uintptr_t)populate_pack_exts(item->string);
- }
-
close_object_store(the_repository->objects);
/*
* Ok we have prepared all new packfiles.
*/
for_each_string_list_item(item, &names) {
+ struct generated_pack_data *data = item->util;
+
for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
- char *fname, *fname_old;
+ char *fname;
fname = mkpathdup("%s/pack-%s%s",
packdir, item->string, exts[ext].name);
- fname_old = mkpathdup("%s-%s%s",
- packtmp, item->string, exts[ext].name);
- if (((uintptr_t)item->util) & ((uintptr_t)1 << ext)) {
+ if (data->tempfiles[ext]) {
+ const char *fname_old = get_tempfile_path(data->tempfiles[ext]);
struct stat statbuffer;
+
if (!stat(fname_old, &statbuffer)) {
statbuffer.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
chmod(fname_old, statbuffer.st_mode);
}
- if (rename(fname_old, fname))
- die_errno(_("renaming '%s' failed"), fname_old);
+ if (rename_tempfile(&data->tempfiles[ext], fname))
+ die_errno(_("renaming pack to '%s' failed"), fname);
} else if (!exts[ext].optional)
- die(_("missing required file: %s"), fname_old);
+ die(_("pack-objects did not write a '%s' file for pack %s-%s"),
+ exts[ext].name, packtmp, item->string);
else if (unlink(fname) < 0 && errno != ENOENT)
die_errno(_("could not unlink: %s"), fname);
free(fname);
- free(fname_old);
}
}
/* End of pack replacement. */
@@ -1059,6 +1108,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
refs_snapshot ? get_tempfile_path(refs_snapshot) : NULL,
show_progress, write_bitmaps > 0);
+ if (!ret && write_bitmaps)
+ remove_redundant_bitmaps(&include, packdir);
+
string_list_clear(&include, 0);
if (ret)
@@ -1089,6 +1141,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
strbuf_addstr(&buf, pack_basename(p));
strbuf_strip_suffix(&buf, ".pack");
+ if ((p->pack_keep) ||
+ (string_list_has_string(&existing_kept_packs,
+ buf.buf)))
+ continue;
+
remove_redundant_pack(packdir, buf.buf);
}
strbuf_release(&buf);
@@ -1106,7 +1163,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (run_update_server_info)
update_server_info(0);
- remove_temporary_files();
if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) {
unsigned flags = 0;
@@ -1115,7 +1171,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
write_midx_file(get_object_directory(), NULL, NULL, flags);
}
- string_list_clear(&names, 0);
+ string_list_clear(&names, 1);
string_list_clear(&existing_nonkept_packs, 0);
string_list_clear(&existing_kept_packs, 0);
clear_pack_geometry(geometry);
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 83d7a778e37..8b7392d5b44 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -10,7 +10,7 @@
#include "pathspec.h"
static const char * const rerere_usage[] = {
- N_("git rerere [clear | forget <path>... | status | remaining | diff | gc]"),
+ N_("git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"),
NULL,
};
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index fba6f5d51f3..3acd93f71e1 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -20,7 +20,8 @@
#include "packfile.h"
static const char rev_list_usage[] =
-"git rev-list [<options>] <commit-id>... [-- <path>...]\n"
+"git rev-list [<options>] <commit>... [--] [<path>...]\n"
+"\n"
" limiting output:\n"
" --max-count=<n>\n"
" --max-age=<epoch>\n"
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index b259d8990a6..8f61050bde8 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -195,7 +195,8 @@ static int show_default(void)
return 0;
}
-static int show_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data)
+static int show_reference(const char *refname, const struct object_id *oid,
+ int flag UNUSED, void *cb_data UNUSED)
{
if (ref_excluded(ref_excludes, refname))
return 0;
@@ -203,7 +204,8 @@ static int show_reference(const char *refname, const struct object_id *oid, int
return 0;
}
-static int anti_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data)
+static int anti_reference(const char *refname, const struct object_id *oid,
+ int flag UNUSED, void *cb_data UNUSED)
{
show_rev(REVERSED, oid, refname);
return 0;
@@ -479,6 +481,9 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
if (!s)
s = help;
+ if (s == sb.buf)
+ die(_("missing opt-spec before option flags"));
+
if (s - sb.buf == 1) /* short option only */
o->short_name = *sb.buf;
else if (sb.buf[1] != ',') /* long option only */
diff --git a/builtin/revert.c b/builtin/revert.c
index 2554f9099cc..ee32c714a76 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -21,14 +21,15 @@
*/
static const char * const revert_usage[] = {
- N_("git revert [<options>] <commit-ish>..."),
- N_("git revert <subcommand>"),
+ N_("git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>..."),
+ N_("git revert (--continue | --skip | --abort | --quit)"),
NULL
};
static const char * const cherry_pick_usage[] = {
- N_("git cherry-pick [<options>] <commit-ish>..."),
- N_("git cherry-pick <subcommand>"),
+ N_("git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n"
+ " [-S[<keyid>]] <commit>..."),
+ N_("git cherry-pick (--continue | --skip | --abort | --quit)"),
NULL
};
@@ -141,7 +142,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
argc = parse_options(argc, argv, NULL, options, usage_str,
PARSE_OPT_KEEP_ARGV0 |
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
diff --git a/builtin/rm.c b/builtin/rm.c
index b6ba859fe42..05bfe20a469 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -17,7 +17,9 @@
#include "pathspec.h"
static const char * const builtin_rm_usage[] = {
- N_("git rm [<options>] [--] <file>..."),
+ N_("git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]\n"
+ " [--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
+ " [--] [<pathspec>...]"),
NULL
};
@@ -84,8 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void)
continue;
if (!submodule_uses_gitfile(name))
- absorb_git_dir_into_superproject(name,
- ABSORB_GITDIR_RECURSE_SUBMODULES);
+ absorb_git_dir_into_superproject(name);
}
}
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 64962be0168..4c5d125fa0a 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -20,6 +20,7 @@ static const char * const send_pack_usage[] = {
N_("git send-pack [--mirror] [--dry-run] [--force]\n"
" [--receive-pack=<git-receive-pack>]\n"
" [--verbose] [--thin] [--atomic]\n"
+ " [--[no-]signed | --signed=(true|false|if-asked)]\n"
" [<host>:]<directory> (--all | <ref>...)"),
NULL,
};
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 086dfee45aa..27a87167e19 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -132,7 +132,9 @@ static void read_from_stdin(struct shortlog *log)
match = committer_match;
break;
case SHORTLOG_GROUP_TRAILER:
- die(_("using --group=trailer with stdin is not supported"));
+ die(_("using %s with stdin is not supported"), "--group=trailer");
+ case SHORTLOG_GROUP_FORMAT:
+ die(_("using %s with stdin is not supported"), "--group=format");
default:
BUG("unhandled shortlog group");
}
@@ -170,6 +172,9 @@ static void insert_records_from_trailers(struct shortlog *log,
const char *commit_buffer, *body;
struct strbuf ident = STRBUF_INIT;
+ if (!log->trailers.nr)
+ return;
+
/*
* Using format_commit_message("%B") would be simpler here, but
* this saves us copying the message.
@@ -200,9 +205,34 @@ static void insert_records_from_trailers(struct shortlog *log,
unuse_commit_buffer(commit, commit_buffer);
}
+static int shortlog_needs_dedup(const struct shortlog *log)
+{
+ return HAS_MULTI_BITS(log->groups) || log->format.nr > 1 || log->trailers.nr;
+}
+
+static void insert_records_from_format(struct shortlog *log,
+ struct strset *dups,
+ struct commit *commit,
+ struct pretty_print_context *ctx,
+ const char *oneline)
+{
+ struct strbuf buf = STRBUF_INIT;
+ struct string_list_item *item;
+
+ for_each_string_list_item(item, &log->format) {
+ strbuf_reset(&buf);
+
+ format_commit_message(commit, item->string, &buf, ctx);
+
+ if (!shortlog_needs_dedup(log) || strset_add(dups, buf.buf))
+ insert_one_record(log, buf.buf, oneline);
+ }
+
+ strbuf_release(&buf);
+}
+
void shortlog_add_commit(struct shortlog *log, struct commit *commit)
{
- struct strbuf ident = STRBUF_INIT;
struct strbuf oneline = STRBUF_INIT;
struct strset dups = STRSET_INIT;
struct pretty_print_context ctx = {0};
@@ -211,7 +241,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
ctx.fmt = CMIT_FMT_USERFORMAT;
ctx.abbrev = log->abbrev;
ctx.print_email_subject = 1;
- ctx.date_mode.type = DATE_NORMAL;
+ ctx.date_mode = log->date_mode;
ctx.output_encoding = get_log_output_encoding();
if (!log->summary) {
@@ -222,30 +252,10 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
}
oneline_str = oneline.len ? oneline.buf : "<none>";
- if (log->groups & SHORTLOG_GROUP_AUTHOR) {
- strbuf_reset(&ident);
- format_commit_message(commit,
- log->email ? "%aN <%aE>" : "%aN",
- &ident, &ctx);
- if (!HAS_MULTI_BITS(log->groups) ||
- strset_add(&dups, ident.buf))
- insert_one_record(log, ident.buf, oneline_str);
- }
- if (log->groups & SHORTLOG_GROUP_COMMITTER) {
- strbuf_reset(&ident);
- format_commit_message(commit,
- log->email ? "%cN <%cE>" : "%cN",
- &ident, &ctx);
- if (!HAS_MULTI_BITS(log->groups) ||
- strset_add(&dups, ident.buf))
- insert_one_record(log, ident.buf, oneline_str);
- }
- if (log->groups & SHORTLOG_GROUP_TRAILER) {
- insert_records_from_trailers(log, &dups, commit, &ctx, oneline_str);
- }
+ insert_records_from_trailers(log, &dups, commit, &ctx, oneline_str);
+ insert_records_from_format(log, &dups, commit, &ctx, oneline_str);
strset_clear(&dups);
- strbuf_release(&ident);
strbuf_release(&oneline);
}
@@ -314,6 +324,7 @@ static int parse_group_option(const struct option *opt, const char *arg, int uns
if (unset) {
log->groups = 0;
string_list_clear(&log->trailers, 0);
+ string_list_clear(&log->format, 0);
} else if (!strcasecmp(arg, "author"))
log->groups |= SHORTLOG_GROUP_AUTHOR;
else if (!strcasecmp(arg, "committer"))
@@ -321,8 +332,15 @@ static int parse_group_option(const struct option *opt, const char *arg, int uns
else if (skip_prefix(arg, "trailer:", &field)) {
log->groups |= SHORTLOG_GROUP_TRAILER;
string_list_append(&log->trailers, field);
- } else
+ } else if (skip_prefix(arg, "format:", &field)) {
+ log->groups |= SHORTLOG_GROUP_FORMAT;
+ string_list_append(&log->format, field);
+ } else if (strchr(arg, '%')) {
+ log->groups |= SHORTLOG_GROUP_FORMAT;
+ string_list_append(&log->format, arg);
+ } else {
return error(_("unknown group type: %s"), arg);
+ }
return 0;
}
@@ -340,6 +358,19 @@ void shortlog_init(struct shortlog *log)
log->in2 = DEFAULT_INDENT2;
log->trailers.strdup_strings = 1;
log->trailers.cmp = strcasecmp;
+ log->format.strdup_strings = 1;
+}
+
+void shortlog_finish_setup(struct shortlog *log)
+{
+ if (log->groups & SHORTLOG_GROUP_AUTHOR)
+ string_list_append(&log->format,
+ log->email ? "%aN <%aE>" : "%aN");
+ if (log->groups & SHORTLOG_GROUP_COMMITTER)
+ string_list_append(&log->format,
+ log->email ? "%cN <%cE>" : "%cN");
+
+ string_list_sort(&log->trailers);
}
int cmd_shortlog(int argc, const char **argv, const char *prefix)
@@ -381,6 +412,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
break;
case PARSE_OPT_HELP:
case PARSE_OPT_ERROR:
+ case PARSE_OPT_SUBCOMMAND:
exit(129);
case PARSE_OPT_COMPLETE:
exit(0);
@@ -406,10 +438,11 @@ parse_done:
log.user_format = rev.commit_format == CMIT_FMT_USERFORMAT;
log.abbrev = rev.abbrev;
log.file = rev.diffopt.file;
+ log.date_mode = rev.date_mode;
if (!log.groups)
log.groups = SHORTLOG_GROUP_AUTHOR;
- string_list_sort(&log.trailers);
+ shortlog_finish_setup(&log);
/* assume HEAD if from a tty */
if (!nongit && !rev.pending.nr && isatty(0))
@@ -478,4 +511,5 @@ void shortlog_output(struct shortlog *log)
log->list.strdup_strings = 1;
string_list_clear(&log->list, 1);
clear_mailmap(&log->mailmap);
+ string_list_clear(&log->format, 0);
}
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 64c649c6a23..c013abaf942 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -14,7 +14,8 @@ static const char* show_branch_usage[] = {
N_("git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
" [--current] [--color[=<when>] | --no-color] [--sparse]\n"
" [--more=<n> | --list | --independent | --merge-base]\n"
- " [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]"),
+ " [--no-name | --sha1-name] [--topics]\n"
+ " [(<rev> | <glob>)...]"),
N_("git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]"),
NULL
};
@@ -404,7 +405,7 @@ static int append_ref(const char *refname, const struct object_id *oid,
}
static int append_head_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data UNUSED)
{
struct object_id tmp;
int ofs = 11;
@@ -419,7 +420,7 @@ static int append_head_ref(const char *refname, const struct object_id *oid,
}
static int append_remote_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data UNUSED)
{
struct object_id tmp;
int ofs = 13;
@@ -434,7 +435,7 @@ static int append_remote_ref(const char *refname, const struct object_id *oid,
}
static int append_tag_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data UNUSED)
{
if (!starts_with(refname, "refs/tags/"))
return 0;
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 5fa207a044e..3af6a53ee97 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -9,7 +9,9 @@
#include "parse-options.h"
static const char * const show_ref_usage[] = {
- N_("git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]"),
+ N_("git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n"
+ " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
+ " [--heads] [--] [<pattern>...]"),
N_("git show-ref --exclude-existing[=<pattern>]"),
NULL
};
@@ -47,7 +49,7 @@ static void show_one(const char *refname, const struct object_id *oid)
}
static int show_ref(const char *refname, const struct object_id *oid,
- int flag, void *cbdata)
+ int flag UNUSED, void *cbdata UNUSED)
{
if (show_head && !strcmp(refname, "HEAD"))
goto match;
@@ -77,8 +79,9 @@ match:
return 0;
}
-static int add_existing(const char *refname, const struct object_id *oid,
- int flag, void *cbdata)
+static int add_existing(const char *refname,
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cbdata)
{
struct string_list *list = (struct string_list *)cbdata;
string_list_insert(list, refname);
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index f91e29b56a9..58a22503f04 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -20,7 +20,7 @@
static const char *empty_base = "";
static char const * const builtin_sparse_checkout_usage[] = {
- N_("git sparse-checkout (init|list|set|add|reapply|disable) <options>"),
+ N_("git sparse-checkout (init | list | set | add | reapply | disable) [<options>]"),
NULL
};
@@ -48,7 +48,7 @@ static char const * const builtin_sparse_checkout_list_usage[] = {
NULL
};
-static int sparse_checkout_list(int argc, const char **argv)
+static int sparse_checkout_list(int argc, const char **argv, const char *prefix)
{
static struct option builtin_sparse_checkout_list_options[] = {
OPT_END(),
@@ -60,7 +60,7 @@ static int sparse_checkout_list(int argc, const char **argv)
if (!core_apply_sparse_checkout)
die(_("this worktree is not sparse"));
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_list_options,
builtin_sparse_checkout_list_usage, 0);
@@ -431,7 +431,7 @@ static struct sparse_checkout_init_opts {
int sparse_index;
} init_opts;
-static int sparse_checkout_init(int argc, const char **argv)
+static int sparse_checkout_init(int argc, const char **argv, const char *prefix)
{
struct pattern_list pl;
char *sparse_filename;
@@ -452,7 +452,7 @@ static int sparse_checkout_init(int argc, const char **argv)
init_opts.cone_mode = -1;
init_opts.sparse_index = -1;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_init_options,
builtin_sparse_checkout_init_usage, 0);
@@ -767,7 +767,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_add_options,
builtin_sparse_checkout_add_usage,
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
sanitize_paths(argc, argv, prefix, add_opts.skip_checks);
@@ -813,7 +813,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_set_options,
builtin_sparse_checkout_set_usage,
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
if (update_modes(&set_opts.cone_mode, &set_opts.sparse_index))
return 1;
@@ -843,7 +843,8 @@ static struct sparse_checkout_reapply_opts {
int sparse_index;
} reapply_opts;
-static int sparse_checkout_reapply(int argc, const char **argv)
+static int sparse_checkout_reapply(int argc, const char **argv,
+ const char *prefix)
{
static struct option builtin_sparse_checkout_reapply_options[] = {
OPT_BOOL(0, "cone", &reapply_opts.cone_mode,
@@ -859,7 +860,7 @@ static int sparse_checkout_reapply(int argc, const char **argv)
reapply_opts.cone_mode = -1;
reapply_opts.sparse_index = -1;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_reapply_options,
builtin_sparse_checkout_reapply_usage, 0);
@@ -876,7 +877,8 @@ static char const * const builtin_sparse_checkout_disable_usage[] = {
NULL
};
-static int sparse_checkout_disable(int argc, const char **argv)
+static int sparse_checkout_disable(int argc, const char **argv,
+ const char *prefix)
{
static struct option builtin_sparse_checkout_disable_options[] = {
OPT_END(),
@@ -895,7 +897,7 @@ static int sparse_checkout_disable(int argc, const char **argv)
* forcibly return to a dense checkout regardless of initial state.
*/
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_disable_options,
builtin_sparse_checkout_disable_usage, 0);
@@ -922,39 +924,25 @@ static int sparse_checkout_disable(int argc, const char **argv)
int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
{
- static struct option builtin_sparse_checkout_options[] = {
+ parse_opt_subcommand_fn *fn = NULL;
+ struct option builtin_sparse_checkout_options[] = {
+ OPT_SUBCOMMAND("list", &fn, sparse_checkout_list),
+ OPT_SUBCOMMAND("init", &fn, sparse_checkout_init),
+ OPT_SUBCOMMAND("set", &fn, sparse_checkout_set),
+ OPT_SUBCOMMAND("add", &fn, sparse_checkout_add),
+ OPT_SUBCOMMAND("reapply", &fn, sparse_checkout_reapply),
+ OPT_SUBCOMMAND("disable", &fn, sparse_checkout_disable),
OPT_END(),
};
- if (argc == 2 && !strcmp(argv[1], "-h"))
- usage_with_options(builtin_sparse_checkout_usage,
- builtin_sparse_checkout_options);
-
argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_options,
- builtin_sparse_checkout_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ builtin_sparse_checkout_usage, 0);
git_config(git_default_config, NULL);
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
- if (argc > 0) {
- if (!strcmp(argv[0], "list"))
- return sparse_checkout_list(argc, argv);
- if (!strcmp(argv[0], "init"))
- return sparse_checkout_init(argc, argv);
- if (!strcmp(argv[0], "set"))
- return sparse_checkout_set(argc, argv, prefix);
- if (!strcmp(argv[0], "add"))
- return sparse_checkout_add(argc, argv, prefix);
- if (!strcmp(argv[0], "reapply"))
- return sparse_checkout_reapply(argc, argv);
- if (!strcmp(argv[0], "disable"))
- return sparse_checkout_disable(argc, argv);
- }
-
- usage_with_options(builtin_sparse_checkout_usage,
- builtin_sparse_checkout_options);
+ return fn(argc, argv, prefix);
}
diff --git a/builtin/stash.c b/builtin/stash.c
index 30fa1014605..bb5485b4095 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -21,72 +21,95 @@
#define INCLUDE_ALL_FILES 2
+#define BUILTIN_STASH_LIST_USAGE \
+ N_("git stash list [<log-options>]")
+#define BUILTIN_STASH_SHOW_USAGE \
+ N_("git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]")
+#define BUILTIN_STASH_DROP_USAGE \
+ N_("git stash drop [-q | --quiet] [<stash>]")
+#define BUILTIN_STASH_POP_USAGE \
+ N_("git stash pop [--index] [-q | --quiet] [<stash>]")
+#define BUILTIN_STASH_APPLY_USAGE \
+ N_("git stash apply [--index] [-q | --quiet] [<stash>]")
+#define BUILTIN_STASH_BRANCH_USAGE \
+ N_("git stash branch <branchname> [<stash>]")
+#define BUILTIN_STASH_STORE_USAGE \
+ N_("git stash store [(-m | --message) <message>] [-q | --quiet] <commit>")
+#define BUILTIN_STASH_PUSH_USAGE \
+ N_("git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \
+ " [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]\n" \
+ " [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" \
+ " [--] [<pathspec>...]]")
+#define BUILTIN_STASH_SAVE_USAGE \
+ N_("git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \
+ " [-u | --include-untracked] [-a | --all] [<message>]")
+#define BUILTIN_STASH_CREATE_USAGE \
+ N_("git stash create [<message>]")
+#define BUILTIN_STASH_CLEAR_USAGE \
+ "git stash clear"
+
static const char * const git_stash_usage[] = {
- N_("git stash list [<options>]"),
- N_("git stash show [<options>] [<stash>]"),
- N_("git stash drop [-q|--quiet] [<stash>]"),
- N_("git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]"),
- N_("git stash branch <branchname> [<stash>]"),
- "git stash clear",
- N_("git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet]\n"
- " [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
- " [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
- " [--] [<pathspec>...]]"),
- N_("git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet]\n"
- " [-u|--include-untracked] [-a|--all] [<message>]"),
+ BUILTIN_STASH_LIST_USAGE,
+ BUILTIN_STASH_SHOW_USAGE,
+ BUILTIN_STASH_DROP_USAGE,
+ BUILTIN_STASH_POP_USAGE,
+ BUILTIN_STASH_APPLY_USAGE,
+ BUILTIN_STASH_BRANCH_USAGE,
+ BUILTIN_STASH_PUSH_USAGE,
+ BUILTIN_STASH_SAVE_USAGE,
+ BUILTIN_STASH_CLEAR_USAGE,
+ BUILTIN_STASH_CREATE_USAGE,
+ BUILTIN_STASH_STORE_USAGE,
NULL
};
static const char * const git_stash_list_usage[] = {
- N_("git stash list [<options>]"),
+ BUILTIN_STASH_LIST_USAGE,
NULL
};
static const char * const git_stash_show_usage[] = {
- N_("git stash show [<options>] [<stash>]"),
+ BUILTIN_STASH_SHOW_USAGE,
NULL
};
static const char * const git_stash_drop_usage[] = {
- N_("git stash drop [-q|--quiet] [<stash>]"),
+ BUILTIN_STASH_DROP_USAGE,
NULL
};
static const char * const git_stash_pop_usage[] = {
- N_("git stash pop [--index] [-q|--quiet] [<stash>]"),
+ BUILTIN_STASH_POP_USAGE,
NULL
};
static const char * const git_stash_apply_usage[] = {
- N_("git stash apply [--index] [-q|--quiet] [<stash>]"),
+ BUILTIN_STASH_APPLY_USAGE,
NULL
};
static const char * const git_stash_branch_usage[] = {
- N_("git stash branch <branchname> [<stash>]"),
+ BUILTIN_STASH_BRANCH_USAGE,
NULL
};
static const char * const git_stash_clear_usage[] = {
- "git stash clear",
+ BUILTIN_STASH_CLEAR_USAGE,
NULL
};
static const char * const git_stash_store_usage[] = {
- N_("git stash store [-m|--message <message>] [-q|--quiet] <commit>"),
+ BUILTIN_STASH_STORE_USAGE,
NULL
};
static const char * const git_stash_push_usage[] = {
- N_("git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
- " [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
- " [--] [<pathspec>...]]"),
+ BUILTIN_STASH_PUSH_USAGE,
NULL
};
static const char * const git_stash_save_usage[] = {
- N_("git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
- " [-u|--include-untracked] [-a|--all] [<message>]"),
+ BUILTIN_STASH_SAVE_USAGE,
NULL
};
@@ -638,9 +661,12 @@ cleanup:
return ret;
}
-static int reject_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+static int reject_reflog_ent(struct object_id *ooid UNUSED,
+ struct object_id *noid UNUSED,
+ const char *email UNUSED,
+ timestamp_t timestamp UNUSED,
+ int tz UNUSED, const char *message UNUSED,
+ void *cb_data UNUSED)
{
return 1;
}
@@ -782,7 +808,7 @@ static int list_stash(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options,
git_stash_list_usage,
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
if (!ref_exists(ref_stash))
return 0;
@@ -873,7 +899,7 @@ static int show_stash(int argc, const char **argv, const char *prefix)
init_revisions(&rev, prefix);
argc = parse_options(argc, argv, prefix, options, git_stash_show_usage,
- PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |
PARSE_OPT_KEEP_DASHDASH);
strvec_push(&revision_args, argv[0]);
@@ -979,7 +1005,7 @@ static int store_stash(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options,
git_stash_store_usage,
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
if (argc != 1) {
if (!quiet)
@@ -1739,6 +1765,11 @@ static int push_stash(int argc, const char **argv, const char *prefix,
include_untracked, only_staged);
}
+static int push_stash_unassumed(int argc, const char **argv, const char *prefix)
+{
+ return push_stash(argc, argv, prefix, 0);
+}
+
static int save_stash(int argc, const char **argv, const char *prefix)
{
int keep_index = -1;
@@ -1787,15 +1818,28 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
pid_t pid = getpid();
const char *index_file;
struct strvec args = STRVEC_INIT;
-
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
+ OPT_SUBCOMMAND("apply", &fn, apply_stash),
+ OPT_SUBCOMMAND("clear", &fn, clear_stash),
+ OPT_SUBCOMMAND("drop", &fn, drop_stash),
+ OPT_SUBCOMMAND("pop", &fn, pop_stash),
+ OPT_SUBCOMMAND("branch", &fn, branch_stash),
+ OPT_SUBCOMMAND("list", &fn, list_stash),
+ OPT_SUBCOMMAND("show", &fn, show_stash),
+ OPT_SUBCOMMAND("store", &fn, store_stash),
+ OPT_SUBCOMMAND("create", &fn, create_stash),
+ OPT_SUBCOMMAND("push", &fn, push_stash_unassumed),
+ OPT_SUBCOMMAND_F("save", &fn, save_stash, PARSE_OPT_NOCOMPLETE),
OPT_END()
};
git_config(git_stash_config, NULL);
argc = parse_options(argc, argv, prefix, options, git_stash_usage,
- PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH);
+ PARSE_OPT_SUBCOMMAND_OPTIONAL |
+ PARSE_OPT_KEEP_UNKNOWN_OPT |
+ PARSE_OPT_KEEP_DASHDASH);
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
@@ -1804,33 +1848,10 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
(uintmax_t)pid);
- if (!argc)
- return !!push_stash(0, NULL, prefix, 0);
- else if (!strcmp(argv[0], "apply"))
- return !!apply_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "clear"))
- return !!clear_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "drop"))
- return !!drop_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "pop"))
- return !!pop_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "branch"))
- return !!branch_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "list"))
- return !!list_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "show"))
- return !!show_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "store"))
- return !!store_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "create"))
- return !!create_stash(argc, argv, prefix);
- else if (!strcmp(argv[0], "push"))
- return !!push_stash(argc, argv, prefix, 0);
- else if (!strcmp(argv[0], "save"))
- return !!save_stash(argc, argv, prefix);
- else if (*argv[0] != '-')
- usage_msg_optf(_("unknown subcommand: %s"),
- git_stash_usage, options, argv[0]);
+ if (fn)
+ return !!fn(argc, argv, prefix);
+ else if (!argc)
+ return !!push_stash_unassumed(0, NULL, prefix);
/* Assume 'stash push' */
strvec_push(&args, "push");
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b63f420ecef..c75e9e86b06 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -31,45 +31,61 @@
typedef void (*each_submodule_fn)(const struct cache_entry *list_item,
void *cb_data);
-static char *repo_get_default_remote(struct repository *repo)
+static int repo_get_default_remote(struct repository *repo, char **default_remote)
{
- char *dest = NULL, *ret;
+ char *dest = NULL;
struct strbuf sb = STRBUF_INIT;
struct ref_store *store = get_main_ref_store(repo);
const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL,
NULL);
if (!refname)
- die(_("No such ref: %s"), "HEAD");
+ return die_message(_("No such ref: %s"), "HEAD");
/* detached HEAD */
- if (!strcmp(refname, "HEAD"))
- return xstrdup("origin");
+ if (!strcmp(refname, "HEAD")) {
+ *default_remote = xstrdup("origin");
+ return 0;
+ }
if (!skip_prefix(refname, "refs/heads/", &refname))
- die(_("Expecting a full ref name, got %s"), refname);
+ return die_message(_("Expecting a full ref name, got %s"),
+ refname);
strbuf_addf(&sb, "branch.%s.remote", refname);
if (repo_config_get_string(repo, sb.buf, &dest))
- ret = xstrdup("origin");
+ *default_remote = xstrdup("origin");
else
- ret = dest;
+ *default_remote = dest;
strbuf_release(&sb);
- return ret;
+ return 0;
}
-static char *get_default_remote_submodule(const char *module_path)
+static int get_default_remote_submodule(const char *module_path, char **default_remote)
{
struct repository subrepo;
+ int ret;
- repo_submodule_init(&subrepo, the_repository, module_path, null_oid());
- return repo_get_default_remote(&subrepo);
+ if (repo_submodule_init(&subrepo, the_repository, module_path,
+ null_oid()) < 0)
+ return die_message(_("could not get a repository handle for submodule '%s'"),
+ module_path);
+ ret = repo_get_default_remote(&subrepo, default_remote);
+ repo_clear(&subrepo);
+
+ return ret;
}
static char *get_default_remote(void)
{
- return repo_get_default_remote(the_repository);
+ char *default_remote;
+ int code = repo_get_default_remote(the_repository, &default_remote);
+
+ if (code)
+ exit(code);
+
+ return default_remote;
}
static char *resolve_relative_url(const char *rel_url, const char *up_path, int quiet)
@@ -96,28 +112,6 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int
return resolved_url;
}
-static int resolve_relative_url_test(int argc, const char **argv, const char *prefix)
-{
- char *remoteurl, *res;
- const char *up_path, *url;
-
- if (argc != 4)
- die("resolve-relative-url-test only accepts three arguments: <up_path> <remoteurl> <url>");
-
- up_path = argv[1];
- remoteurl = xstrdup(argv[2]);
- url = argv[3];
-
- if (!strcmp(up_path, "(null)"))
- up_path = NULL;
-
- res = relative_url(remoteurl, url, up_path);
- puts(res);
- free(res);
- free(remoteurl);
- return 0;
-}
-
/* the result should be freed by the caller. */
static char *get_submodule_displaypath(const char *path, const char *prefix)
{
@@ -182,13 +176,19 @@ struct module_list {
};
#define MODULE_LIST_INIT { 0 }
-static int module_list_compute(int argc, const char **argv,
+static void module_list_release(struct module_list *ml)
+{
+ free(ml->entries);
+}
+
+static int module_list_compute(const char **argv,
const char *prefix,
struct pathspec *pathspec,
struct module_list *list)
{
int i, result = 0;
char *ps_matched = NULL;
+
parse_pathspec(pathspec, 0,
PATHSPEC_PREFER_FULL,
prefix, argv);
@@ -243,7 +243,7 @@ static void module_list_active(struct module_list *list)
active_modules.entries[active_modules.nr++] = ce;
}
- free(list->entries);
+ module_list_release(list);
*list = active_modules;
}
@@ -266,49 +266,11 @@ static char *get_up_path(const char *path)
return strbuf_detach(&sb, NULL);
}
-static int module_list(int argc, const char **argv, const char *prefix)
-{
- int i;
- struct pathspec pathspec;
- struct module_list list = MODULE_LIST_INIT;
-
- struct option module_list_options[] = {
- OPT_STRING(0, "prefix", &prefix,
- N_("path"),
- N_("alternative anchor for relative paths")),
- OPT_END()
- };
-
- const char *const git_submodule_helper_usage[] = {
- N_("git submodule--helper list [--prefix=<path>] [<path>...]"),
- NULL
- };
-
- argc = parse_options(argc, argv, prefix, module_list_options,
- git_submodule_helper_usage, 0);
-
- if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
- return 1;
-
- for (i = 0; i < list.nr; i++) {
- const struct cache_entry *ce = list.entries[i];
-
- if (ce_stage(ce))
- printf("%06o %s U\t", ce->ce_mode,
- oid_to_hex(null_oid()));
- else
- printf("%06o %s %d\t", ce->ce_mode,
- oid_to_hex(&ce->oid), ce_stage(ce));
-
- fprintf(stdout, "%s\n", ce->name);
- }
- return 0;
-}
-
static void for_each_listed_submodule(const struct module_list *list,
each_submodule_fn fn, void *cb_data)
{
int i;
+
for (i = 0; i < list->nr; i++)
fn(list->entries[i], cb_data);
}
@@ -328,7 +290,6 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
struct foreach_cb *info = cb_data;
const char *path = list_item->name;
const struct object_id *ce_oid = &list_item->oid;
-
const struct submodule *sub;
struct child_process cp = CHILD_PROCESS_INIT;
char *displaypath;
@@ -427,26 +388,25 @@ cleanup:
static int module_foreach(int argc, const char **argv, const char *prefix)
{
struct foreach_cb info = FOREACH_CB_INIT;
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
-
struct option module_foreach_options[] = {
OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
OPT_BOOL(0, "recursive", &info.recursive,
N_("recurse into nested submodules")),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule foreach [--quiet] [--recursive] [--] <command>"),
NULL
};
+ int ret = 1;
argc = parse_options(argc, argv, prefix, module_foreach_options,
git_submodule_helper_usage, 0);
- if (module_list_compute(0, NULL, prefix, &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(NULL, prefix, &pathspec, &list) < 0)
+ goto cleanup;
info.argc = argc;
info.argv = argv;
@@ -454,7 +414,11 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
for_each_listed_submodule(&list, runcommand_in_submodule_cb, &info);
- return 0;
+ ret = 0;
+cleanup:
+ module_list_release(&list);
+ clear_pathspec(&pathspec);
+ return ret;
}
static int starts_with_dot_slash(const char *const path)
@@ -480,7 +444,8 @@ static void init_submodule(const char *path, const char *prefix,
{
const struct submodule *sub;
struct strbuf sb = STRBUF_INIT;
- char *upd = NULL, *url = NULL, *displaypath;
+ const char *upd;
+ char *url = NULL, *displaypath;
displaypath = get_submodule_displaypath(path, prefix);
@@ -519,6 +484,7 @@ static void init_submodule(const char *path, const char *prefix,
if (starts_with_dot_dot_slash(url) ||
starts_with_dot_slash(url)) {
char *oldurl = url;
+
url = resolve_relative_url(oldurl, NULL, 0);
free(oldurl);
}
@@ -535,14 +501,15 @@ static void init_submodule(const char *path, const char *prefix,
/* Copy "update" setting when it is not set yet */
strbuf_addf(&sb, "submodule.%s.update", sub->name);
- if (git_config_get_string(sb.buf, &upd) &&
+ if (git_config_get_string_tmp(sb.buf, &upd) &&
sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
if (sub->update_strategy.type == SM_UPDATE_COMMAND) {
fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"),
sub->name);
- upd = xstrdup("none");
- } else
- upd = xstrdup(submodule_strategy_to_string(&sub->update_strategy));
+ upd = "none";
+ } else {
+ upd = submodule_update_type_to_string(sub->update_strategy.type);
+ }
if (git_config_set_gently(sb.buf, upd))
die(_("Failed to register update mode for submodule path '%s'"), displaypath);
@@ -550,37 +517,36 @@ static void init_submodule(const char *path, const char *prefix,
strbuf_release(&sb);
free(displaypath);
free(url);
- free(upd);
}
static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)
{
struct init_cb *info = cb_data;
+
init_submodule(list_item->name, info->prefix, info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
{
struct init_cb info = INIT_CB_INIT;
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
-
struct option module_init_options[] = {
OPT__QUIET(&quiet, N_("suppress output for initializing a submodule")),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule init [<options>] [<path>]"),
NULL
};
+ int ret = 1;
argc = parse_options(argc, argv, prefix, module_init_options,
git_submodule_helper_usage, 0);
- if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
+ goto cleanup;
/*
* If there are no path args and submodule.active is set then,
@@ -595,7 +561,11 @@ static int module_init(int argc, const char **argv, const char *prefix)
for_each_listed_submodule(&list, init_submodule_cb, &info);
- return 0;
+ ret = 0;
+cleanup:
+ module_list_release(&list);
+ clear_pathspec(&pathspec);
+ return ret;
}
struct status_cb {
@@ -613,20 +583,23 @@ static void print_status(unsigned int flags, char state, const char *path,
printf("%c%s %s", state, oid_to_hex(oid), displaypath);
if (state == ' ' || state == '+') {
- const char *name = compute_rev_name(path, oid_to_hex(oid));
+ char *name = compute_rev_name(path, oid_to_hex(oid));
if (name)
printf(" (%s)", name);
+ free(name);
}
printf("\n");
}
-static int handle_submodule_head_ref(const char *refname,
- const struct object_id *oid, int flags,
+static int handle_submodule_head_ref(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flags UNUSED,
void *cb_data)
{
struct object_id *output = cb_data;
+
if (oid)
oidcpy(output, oid);
@@ -643,6 +616,9 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
int diff_files_result;
struct strbuf buf = STRBUF_INIT;
const char *git_dir;
+ struct setup_revision_opt opt = {
+ .free_removed_argv_elements = 1,
+ };
if (!submodule_from_path(the_repository, null_oid(), path))
die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -676,9 +652,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
repo_init_revisions(the_repository, &rev, NULL);
rev.abbrev = 0;
- diff_files_args.nr = setup_revisions(diff_files_args.nr,
- diff_files_args.v,
- &rev, NULL);
+ setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt);
diff_files_result = run_diff_files(&rev, 0);
if (!diff_result_code(&rev.diffopt, diff_files_result)) {
@@ -733,6 +707,7 @@ static void status_submodule_cb(const struct cache_entry *list_item,
void *cb_data)
{
struct status_cb *info = cb_data;
+
status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
info->prefix, info->flags);
}
@@ -740,27 +715,26 @@ static void status_submodule_cb(const struct cache_entry *list_item,
static int module_status(int argc, const char **argv, const char *prefix)
{
struct status_cb info = STATUS_CB_INIT;
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
-
struct option module_status_options[] = {
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule status [--quiet] [--cached] [--recursive] [<path>...]"),
NULL
};
+ int ret = 1;
argc = parse_options(argc, argv, prefix, module_status_options,
git_submodule_helper_usage, 0);
- if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
+ goto cleanup;
info.prefix = prefix;
if (quiet)
@@ -768,25 +742,11 @@ static int module_status(int argc, const char **argv, const char *prefix)
for_each_listed_submodule(&list, status_submodule_cb, &info);
- return 0;
-}
-
-static int module_name(int argc, const char **argv, const char *prefix)
-{
- const struct submodule *sub;
-
- if (argc != 2)
- usage(_("git submodule--helper name <path>"));
-
- sub = submodule_from_path(the_repository, null_oid(), argv[1]);
-
- if (!sub)
- die(_("no submodule mapping found in .gitmodules for path '%s'"),
- argv[1]);
-
- printf("%s\n", sub->name);
-
- return 0;
+ ret = 0;
+cleanup:
+ module_list_release(&list);
+ clear_pathspec(&pathspec);
+ return ret;
}
struct module_cb {
@@ -795,16 +755,34 @@ struct module_cb {
struct object_id oid_src;
struct object_id oid_dst;
char status;
- const char *sm_path;
+ char *sm_path;
};
#define MODULE_CB_INIT { 0 }
+static void module_cb_release(struct module_cb *mcb)
+{
+ free(mcb->sm_path);
+}
+
struct module_cb_list {
struct module_cb **entries;
int alloc, nr;
};
#define MODULE_CB_LIST_INIT { 0 }
+static void module_cb_list_release(struct module_cb_list *mcbl)
+{
+ int i;
+
+ for (i = 0; i < mcbl->nr; i++) {
+ struct module_cb *mcb = mcbl->entries[i];
+
+ module_cb_release(mcb);
+ free(mcb);
+ }
+ free(mcbl->entries);
+}
+
struct summary_cb {
int argc;
const char **argv;
@@ -841,7 +819,7 @@ static char *verify_submodule_committish(const char *sm_path,
return strbuf_detach(&result, NULL);
}
-static void print_submodule_summary(struct summary_cb *info, char *errmsg,
+static void print_submodule_summary(struct summary_cb *info, const char *errmsg,
int total_commits, const char *displaypath,
const char *src_abbrev, const char *dst_abbrev,
struct module_cb *p)
@@ -899,12 +877,13 @@ static void generate_submodule_summary(struct summary_cb *info,
{
char *displaypath, *src_abbrev = NULL, *dst_abbrev;
int missing_src = 0, missing_dst = 0;
- char *errmsg = NULL;
+ struct strbuf errmsg = STRBUF_INIT;
int total_commits = -1;
if (!info->cached && oideq(&p->oid_dst, null_oid())) {
if (S_ISGITLINK(p->mod_dst)) {
struct ref_store *refs = get_submodule_ref_store(p->sm_path);
+
if (refs)
refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
@@ -999,28 +978,27 @@ static void generate_submodule_summary(struct summary_cb *info,
* submodule, i.e., deleted or changed to blob
*/
if (S_ISGITLINK(p->mod_dst)) {
- struct strbuf errmsg_str = STRBUF_INIT;
if (missing_src && missing_dst) {
- strbuf_addf(&errmsg_str, " Warn: %s doesn't contain commits %s and %s\n",
+ strbuf_addf(&errmsg, " Warn: %s doesn't contain commits %s and %s\n",
displaypath, oid_to_hex(&p->oid_src),
oid_to_hex(&p->oid_dst));
} else {
- strbuf_addf(&errmsg_str, " Warn: %s doesn't contain commit %s\n",
+ strbuf_addf(&errmsg, " Warn: %s doesn't contain commit %s\n",
displaypath, missing_src ?
oid_to_hex(&p->oid_src) :
oid_to_hex(&p->oid_dst));
}
- errmsg = strbuf_detach(&errmsg_str, NULL);
}
}
- print_submodule_summary(info, errmsg, total_commits,
- displaypath, src_abbrev,
+ print_submodule_summary(info, errmsg.len ? errmsg.buf : NULL,
+ total_commits, displaypath, src_abbrev,
dst_abbrev, p);
free(displaypath);
free(src_abbrev);
free(dst_abbrev);
+ strbuf_release(&errmsg);
}
static void prepare_submodule_summary(struct summary_cb *info,
@@ -1151,6 +1129,7 @@ static int compute_summary_module_list(struct object_id *head_oid,
cleanup:
strvec_clear(&diff_args);
release_revisions(&rev);
+ module_cb_list_release(&list);
return ret;
}
@@ -1164,7 +1143,6 @@ static int module_summary(int argc, const char **argv, const char *prefix)
enum diff_cmd diff_cmd = DIFF_INDEX;
struct object_id head_oid;
int ret;
-
struct option module_summary_options[] = {
OPT_BOOL(0, "cached", &cached,
N_("use the commit stored in the index instead of the submodule HEAD")),
@@ -1176,7 +1154,6 @@ static int module_summary(int argc, const char **argv, const char *prefix)
N_("limit the summary size")),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule summary [<options>] [<commit>] [--] [<path>]"),
NULL
@@ -1238,6 +1215,7 @@ static void sync_submodule(const char *path, const char *prefix,
char *sub_origin_url, *super_config_url, *displaypath, *default_remote;
struct strbuf sb = STRBUF_INIT;
char *sub_config_path = NULL;
+ int code;
if (!is_submodule_active(the_repository, path))
return;
@@ -1248,6 +1226,7 @@ static void sync_submodule(const char *path, const char *prefix,
if (starts_with_dot_dot_slash(sub->url) ||
starts_with_dot_slash(sub->url)) {
char *up_path = get_up_path(path);
+
sub_origin_url = resolve_relative_url(sub->url, up_path, 1);
super_config_url = resolve_relative_url(sub->url, NULL, 1);
free(up_path);
@@ -1276,10 +1255,9 @@ static void sync_submodule(const char *path, const char *prefix,
goto cleanup;
strbuf_reset(&sb);
- default_remote = get_default_remote_submodule(path);
- if (!default_remote)
- die(_("failed to get the default remote for submodule '%s'"),
- path);
+ code = get_default_remote_submodule(path, &default_remote);
+ if (code)
+ exit(code);
remote_key = xstrfmt("remote.%s.url", default_remote);
free(default_remote);
@@ -1323,34 +1301,34 @@ cleanup:
static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data)
{
struct sync_cb *info = cb_data;
+
sync_submodule(list_item->name, info->prefix, info->flags);
}
static int module_sync(int argc, const char **argv, const char *prefix)
{
struct sync_cb info = SYNC_CB_INIT;
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
int recursive = 0;
-
struct option module_sync_options[] = {
OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
OPT_BOOL(0, "recursive", &recursive,
N_("recurse into nested submodules")),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule sync [--quiet] [--recursive] [<path>]"),
NULL
};
+ int ret = 1;
argc = parse_options(argc, argv, prefix, module_sync_options,
git_submodule_helper_usage, 0);
- if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
+ goto cleanup;
info.prefix = prefix;
if (quiet)
@@ -1360,7 +1338,11 @@ static int module_sync(int argc, const char **argv, const char *prefix)
for_each_listed_submodule(&list, sync_submodule_cb, &info);
- return 0;
+ ret = 0;
+cleanup:
+ module_list_release(&list);
+ clear_pathspec(&pathspec);
+ return ret;
}
struct deinit_cb {
@@ -1397,13 +1379,13 @@ static void deinit_submodule(const char *path, const char *prefix,
".git file by using absorbgitdirs."),
displaypath);
- absorb_git_dir_into_superproject(path,
- ABSORB_GITDIR_RECURSE_SUBMODULES);
+ absorb_git_dir_into_superproject(path);
}
if (!(flags & OPT_FORCE)) {
struct child_process cp_rm = CHILD_PROCESS_INIT;
+
cp_rm.git_cmd = 1;
strvec_pushl(&cp_rm.args, "rm", "-qn",
path, NULL);
@@ -1440,6 +1422,7 @@ static void deinit_submodule(const char *path, const char *prefix,
/* remove the .git/config entries (unless the user already did it) */
if (!capture_command(&cp_config, &sb_config, 0) && sb_config.len) {
char *sub_key = xstrfmt("submodule.%s", sub->name);
+
/*
* remove the whole section so we have a clean state when
* the user later decides to init this submodule again
@@ -1467,23 +1450,22 @@ static void deinit_submodule_cb(const struct cache_entry *list_item,
static int module_deinit(int argc, const char **argv, const char *prefix)
{
struct deinit_cb info = DEINIT_CB_INIT;
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
int force = 0;
int all = 0;
-
struct option module_deinit_options[] = {
OPT__QUIET(&quiet, N_("suppress submodule status output")),
OPT__FORCE(&force, N_("remove submodule working trees even if they contain local changes"), 0),
OPT_BOOL(0, "all", &all, N_("unregister all submodules")),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"),
NULL
};
+ int ret = 1;
argc = parse_options(argc, argv, prefix, module_deinit_options,
git_submodule_helper_usage, 0);
@@ -1497,8 +1479,8 @@ static int module_deinit(int argc, const char **argv, const char *prefix)
if (!argc && !all)
die(_("Use '--all' if you really want to deinitialize all submodules"));
- if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
+ goto cleanup;
info.prefix = prefix;
if (quiet)
@@ -1508,7 +1490,11 @@ static int module_deinit(int argc, const char **argv, const char *prefix)
for_each_listed_submodule(&list, deinit_submodule_cb, &info);
- return 0;
+ ret = 0;
+cleanup:
+ module_list_release(&list);
+ clear_pathspec(&pathspec);
+ return ret;
}
struct module_clone_data {
@@ -1518,7 +1504,6 @@ struct module_clone_data {
const char *url;
const char *depth;
struct list_objects_filter_options *filter_options;
- struct string_list reference;
unsigned int quiet: 1;
unsigned int progress: 1;
unsigned int dissociate: 1;
@@ -1526,7 +1511,6 @@ struct module_clone_data {
int single_branch;
};
#define MODULE_CLONE_DATA_INIT { \
- .reference = STRING_LIST_INIT_NODUP, \
.single_branch = -1, \
}
@@ -1567,7 +1551,9 @@ static int add_possible_reference_from_superproject(
struct strbuf err = STRBUF_INIT;
strbuf_add(&sb, odb->path, len);
- repo_init(&alternate, sb.buf, NULL);
+ if (repo_init(&alternate, sb.buf, NULL) < 0)
+ die(_("could not get a repository handle for gitdir '%s'"),
+ sb.buf);
/*
* We need to end the new path with '/' to mark it as a dir,
@@ -1582,7 +1568,9 @@ static int add_possible_reference_from_superproject(
sm_alternate = compute_alternate_path(sb.buf, &err);
if (sm_alternate) {
- string_list_append(sas->reference, xstrdup(sb.buf));
+ char *p = strbuf_detach(&sb, NULL);
+
+ string_list_append(sas->reference, p)->util = p;
free(sm_alternate);
} else {
switch (sas->error_mode) {
@@ -1641,23 +1629,31 @@ static void prepare_possible_alternates(const char *sm_name,
free(error_strategy);
}
-static int clone_submodule(struct module_clone_data *clone_data)
+static char *clone_submodule_sm_gitdir(const char *name)
{
- char *p, *sm_gitdir;
- char *sm_alternate = NULL, *error_strategy = NULL;
struct strbuf sb = STRBUF_INIT;
- struct child_process cp = CHILD_PROCESS_INIT;
+ char *sm_gitdir;
- submodule_name_to_gitdir(&sb, the_repository, clone_data->name);
+ submodule_name_to_gitdir(&sb, the_repository, name);
sm_gitdir = absolute_pathdup(sb.buf);
- strbuf_reset(&sb);
+ strbuf_release(&sb);
- if (!is_absolute_path(clone_data->path)) {
- strbuf_addf(&sb, "%s/%s", get_git_work_tree(), clone_data->path);
- clone_data->path = strbuf_detach(&sb, NULL);
- } else {
- clone_data->path = xstrdup(clone_data->path);
- }
+ return sm_gitdir;
+}
+
+static int clone_submodule(const struct module_clone_data *clone_data,
+ struct string_list *reference)
+{
+ char *p;
+ char *sm_gitdir = clone_submodule_sm_gitdir(clone_data->name);
+ char *sm_alternate = NULL, *error_strategy = NULL;
+ struct child_process cp = CHILD_PROCESS_INIT;
+ const char *clone_data_path = clone_data->path;
+ char *to_free = NULL;
+
+ if (!is_absolute_path(clone_data->path))
+ clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(),
+ clone_data->path);
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
die(_("refusing to create/use '%s' in another submodule's "
@@ -1667,7 +1663,7 @@ static int clone_submodule(struct module_clone_data *clone_data)
if (safe_create_leading_directories_const(sm_gitdir) < 0)
die(_("could not create directory '%s'"), sm_gitdir);
- prepare_possible_alternates(clone_data->name, &clone_data->reference);
+ prepare_possible_alternates(clone_data->name, reference);
strvec_push(&cp.args, "clone");
strvec_push(&cp.args, "--no-checkout");
@@ -1677,9 +1673,10 @@ static int clone_submodule(struct module_clone_data *clone_data)
strvec_push(&cp.args, "--progress");
if (clone_data->depth && *(clone_data->depth))
strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
- if (clone_data->reference.nr) {
+ if (reference->nr) {
struct string_list_item *item;
- for_each_string_list_item(item, &clone_data->reference)
+
+ for_each_string_list_item(item, reference)
strvec_pushl(&cp.args, "--reference",
item->string, NULL);
}
@@ -1698,7 +1695,7 @@ static int clone_submodule(struct module_clone_data *clone_data)
strvec_push(&cp.args, "--");
strvec_push(&cp.args, clone_data->url);
- strvec_push(&cp.args, clone_data->path);
+ strvec_push(&cp.args, clone_data_path);
cp.git_cmd = 1;
prepare_submodule_repo_env(&cp.env);
@@ -1706,23 +1703,25 @@ static int clone_submodule(struct module_clone_data *clone_data)
if(run_command(&cp))
die(_("clone of '%s' into submodule path '%s' failed"),
- clone_data->url, clone_data->path);
+ clone_data->url, clone_data_path);
} else {
- if (clone_data->require_init && !access(clone_data->path, X_OK) &&
- !is_empty_dir(clone_data->path))
- die(_("directory not empty: '%s'"), clone_data->path);
- if (safe_create_leading_directories_const(clone_data->path) < 0)
- die(_("could not create directory '%s'"), clone_data->path);
- strbuf_addf(&sb, "%s/index", sm_gitdir);
- unlink_or_warn(sb.buf);
- strbuf_reset(&sb);
+ char *path;
+
+ if (clone_data->require_init && !access(clone_data_path, X_OK) &&
+ !is_empty_dir(clone_data_path))
+ die(_("directory not empty: '%s'"), clone_data_path);
+ if (safe_create_leading_directories_const(clone_data_path) < 0)
+ die(_("could not create directory '%s'"), clone_data_path);
+ path = xstrfmt("%s/index", sm_gitdir);
+ unlink_or_warn(path);
+ free(path);
}
- connect_work_tree_and_git_dir(clone_data->path, sm_gitdir, 0);
+ connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
- p = git_pathdup_submodule(clone_data->path, "config");
+ p = git_pathdup_submodule(clone_data_path, "config");
if (!p)
- die(_("could not get submodule directory for '%s'"), clone_data->path);
+ die(_("could not get submodule directory for '%s'"), clone_data_path);
/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
git_config_get_string("submodule.alternateLocation", &sm_alternate);
@@ -1737,9 +1736,9 @@ static int clone_submodule(struct module_clone_data *clone_data)
free(sm_alternate);
free(error_strategy);
- strbuf_release(&sb);
free(sm_gitdir);
free(p);
+ free(to_free);
return 0;
}
@@ -1747,7 +1746,9 @@ static int module_clone(int argc, const char **argv, const char *prefix)
{
int dissociate = 0, quiet = 0, progress = 0, require_init = 0;
struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
- struct list_objects_filter_options filter_options;
+ struct string_list reference = STRING_LIST_INIT_NODUP;
+ struct list_objects_filter_options filter_options =
+ LIST_OBJECTS_FILTER_INIT;
struct option module_clone_options[] = {
OPT_STRING(0, "prefix", &clone_data.prefix,
@@ -1762,7 +1763,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
OPT_STRING(0, "url", &clone_data.url,
N_("string"),
N_("url where to clone the submodule from")),
- OPT_STRING_LIST(0, "reference", &clone_data.reference,
+ OPT_STRING_LIST(0, "reference", &reference,
N_("repo"),
N_("reference repository")),
OPT_BOOL(0, "dissociate", &dissociate,
@@ -1780,7 +1781,6 @@ static int module_clone(int argc, const char **argv, const char *prefix)
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
"[--reference <repository>] [--name <name>] [--depth <depth>] "
@@ -1789,7 +1789,6 @@ static int module_clone(int argc, const char **argv, const char *prefix)
NULL
};
- memset(&filter_options, 0, sizeof(filter_options));
argc = parse_options(argc, argv, prefix, module_clone_options,
git_submodule_helper_usage, 0);
@@ -1803,29 +1802,33 @@ static int module_clone(int argc, const char **argv, const char *prefix)
usage_with_options(git_submodule_helper_usage,
module_clone_options);
- clone_submodule(&clone_data);
+ clone_submodule(&clone_data, &reference);
list_objects_filter_release(&filter_options);
+ string_list_clear(&reference, 1);
return 0;
}
-static void determine_submodule_update_strategy(struct repository *r,
- int just_cloned,
- const char *path,
- enum submodule_update_type update,
- struct submodule_update_strategy *out)
+static int determine_submodule_update_strategy(struct repository *r,
+ int just_cloned,
+ const char *path,
+ enum submodule_update_type update,
+ struct submodule_update_strategy *out)
{
const struct submodule *sub = submodule_from_path(r, null_oid(), path);
char *key;
const char *val;
+ int ret;
key = xstrfmt("submodule.%s.update", sub->name);
if (update) {
out->type = update;
} else if (!repo_config_get_string_tmp(r, key, &val)) {
- if (parse_submodule_update_strategy(val, out) < 0)
- die(_("Invalid update mode '%s' configured for submodule path '%s'"),
- val, path);
+ if (parse_submodule_update_strategy(val, out) < 0) {
+ ret = die_message(_("Invalid update mode '%s' configured for submodule path '%s'"),
+ val, path);
+ goto cleanup;
+ }
} else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
if (sub->update_strategy.type == SM_UPDATE_COMMAND)
BUG("how did we read update = !command from .gitmodules?");
@@ -1840,7 +1843,10 @@ static void determine_submodule_update_strategy(struct repository *r,
out->type == SM_UPDATE_NONE))
out->type = SM_UPDATE_CHECKOUT;
+ ret = 0;
+cleanup:
free(key);
+ return ret;
}
struct update_clone_data {
@@ -1854,7 +1860,7 @@ struct submodule_update_clone {
int current;
/* configuration parameters which are passed on to the children */
- struct update_data *update_data;
+ const struct update_data *update_data;
/* to be consumed by update_submodule() */
struct update_clone_data *update_clone;
@@ -1869,9 +1875,15 @@ struct submodule_update_clone {
};
#define SUBMODULE_UPDATE_CLONE_INIT { 0 }
+static void submodule_update_clone_release(struct submodule_update_clone *suc)
+{
+ free(suc->update_clone);
+ free(suc->failed_clones);
+}
+
struct update_data {
const char *prefix;
- const char *displaypath;
+ char *displaypath;
enum submodule_update_type update_default;
struct object_id suboid;
struct string_list references;
@@ -1907,6 +1919,12 @@ struct update_data {
.max_jobs = 1, \
}
+static void update_data_release(struct update_data *ud)
+{
+ free(ud->displaypath);
+ module_list_release(&ud->list);
+}
+
static void next_submodule_warn_missing(struct submodule_update_clone *suc,
struct strbuf *out, const char *displaypath)
{
@@ -1939,7 +1957,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
const char *update_string;
enum submodule_update_type update_type;
char *key;
- struct update_data *ud = suc->update_data;
+ const struct update_data *ud = suc->update_data;
char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
struct strbuf sb = STRBUF_INIT;
int needs_cloning = 0;
@@ -2031,6 +2049,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
strvec_pushl(&child->args, "--url", url, NULL);
if (suc->update_data->references.nr) {
struct string_list_item *item;
+
for_each_string_list_item(item, &suc->update_data->references)
strvec_pushl(&child->args, "--reference", item->string, NULL);
}
@@ -2063,6 +2082,7 @@ static int update_clone_get_next_task(struct child_process *child,
ce = suc->update_data->list.entries[suc->current];
if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
int *p = xmalloc(sizeof(*p));
+
*p = suc->current;
*idx_task_cb = p;
suc->current++;
@@ -2078,6 +2098,7 @@ static int update_clone_get_next_task(struct child_process *child,
index = suc->current - suc->update_data->list.nr;
if (index < suc->failed_clones_nr) {
int *p;
+
ce = suc->failed_clones[index];
if (!prepare_to_clone_next_submodule(ce, child, suc, err)) {
suc->current ++;
@@ -2101,6 +2122,7 @@ static int update_clone_start_failure(struct strbuf *err,
void *idx_task_cb)
{
struct submodule_update_clone *suc = suc_cb;
+
suc->quickstop = 1;
return 1;
}
@@ -2112,9 +2134,9 @@ static int update_clone_task_finished(int result,
{
const struct cache_entry *ce;
struct submodule_update_clone *suc = suc_cb;
-
int *idxP = idx_task_cb;
int idx = *idxP;
+
free(idxP);
if (!result)
@@ -2147,19 +2169,20 @@ static int git_update_clone_config(const char *var, const char *value,
void *cb)
{
int *max_jobs = cb;
+
if (!strcmp(var, "submodule.fetchjobs"))
*max_jobs = parse_submodule_fetchjobs(var, value);
return 0;
}
-static int is_tip_reachable(const char *path, struct object_id *oid)
+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);
cp.git_cmd = 1;
- cp.dir = xstrdup(path);
+ cp.dir = path;
cp.no_stderr = 1;
strvec_pushl(&cp.args, "rev-list", "-n", "1", hex, "--not", "--all", NULL);
@@ -2171,13 +2194,14 @@ static int is_tip_reachable(const char *path, struct object_id *oid)
return 1;
}
-static int fetch_in_submodule(const char *module_path, int depth, int quiet, struct object_id *oid)
+static int fetch_in_submodule(const char *module_path, int depth, int quiet,
+ const struct object_id *oid)
{
struct child_process cp = CHILD_PROCESS_INIT;
prepare_submodule_repo_env(&cp.env);
cp.git_cmd = 1;
- cp.dir = xstrdup(module_path);
+ cp.dir = module_path;
strvec_push(&cp.args, "fetch");
if (quiet)
@@ -2187,6 +2211,7 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str
if (oid) {
char *hex = oid_to_hex(oid);
char *remote = get_default_remote();
+
strvec_pushl(&cp.args, remote, hex, NULL);
free(remote);
}
@@ -2194,11 +2219,11 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str
return run_command(&cp);
}
-static int run_update_command(struct update_data *ud, int subforce)
+static int run_update_command(const struct update_data *ud, int subforce)
{
struct child_process cp = CHILD_PROCESS_INIT;
char *oid = oid_to_hex(&ud->oid);
- int must_die_on_failure = 0;
+ int ret;
switch (ud->update_strategy.type) {
case SM_UPDATE_CHECKOUT:
@@ -2212,55 +2237,50 @@ static int run_update_command(struct update_data *ud, int subforce)
strvec_push(&cp.args, "rebase");
if (ud->quiet)
strvec_push(&cp.args, "--quiet");
- must_die_on_failure = 1;
break;
case SM_UPDATE_MERGE:
cp.git_cmd = 1;
strvec_push(&cp.args, "merge");
if (ud->quiet)
strvec_push(&cp.args, "--quiet");
- must_die_on_failure = 1;
break;
case SM_UPDATE_COMMAND:
cp.use_shell = 1;
strvec_push(&cp.args, ud->update_strategy.command);
- must_die_on_failure = 1;
break;
default:
- BUG("unexpected update strategy type: %s",
- submodule_strategy_to_string(&ud->update_strategy));
+ BUG("unexpected update strategy type: %d",
+ ud->update_strategy.type);
}
strvec_push(&cp.args, oid);
- cp.dir = xstrdup(ud->sm_path);
+ cp.dir = ud->sm_path;
prepare_submodule_repo_env(&cp.env);
- if (run_command(&cp)) {
+ if ((ret = run_command(&cp))) {
switch (ud->update_strategy.type) {
case SM_UPDATE_CHECKOUT:
die_message(_("Unable to checkout '%s' in submodule path '%s'"),
oid, ud->displaypath);
+ /* No "ret" assignment, use "git checkout"'s */
break;
case SM_UPDATE_REBASE:
- die_message(_("Unable to rebase '%s' in submodule path '%s'"),
- oid, ud->displaypath);
+ ret = die_message(_("Unable to rebase '%s' in submodule path '%s'"),
+ oid, ud->displaypath);
break;
case SM_UPDATE_MERGE:
- die_message(_("Unable to merge '%s' in submodule path '%s'"),
- oid, ud->displaypath);
+ ret = die_message(_("Unable to merge '%s' in submodule path '%s'"),
+ oid, ud->displaypath);
break;
case SM_UPDATE_COMMAND:
- die_message(_("Execution of '%s %s' failed in submodule path '%s'"),
- ud->update_strategy.command, oid, ud->displaypath);
+ ret = die_message(_("Execution of '%s %s' failed in submodule path '%s'"),
+ ud->update_strategy.command, oid, ud->displaypath);
break;
default:
- BUG("unexpected update strategy type: %s",
- submodule_strategy_to_string(&ud->update_strategy));
+ BUG("unexpected update strategy type: %d",
+ ud->update_strategy.type);
}
- if (must_die_on_failure)
- exit(128);
- /* the command failed, but update must continue */
- return 1;
+ return ret;
}
if (ud->quiet)
@@ -2284,14 +2304,14 @@ static int run_update_command(struct update_data *ud, int subforce)
ud->displaypath, ud->update_strategy.command, oid);
break;
default:
- BUG("unexpected update strategy type: %s",
- submodule_strategy_to_string(&ud->update_strategy));
+ BUG("unexpected update strategy type: %d",
+ ud->update_strategy.type);
}
return 0;
}
-static int run_update_procedure(struct update_data *ud)
+static int run_update_procedure(const struct update_data *ud)
{
int subforce = is_null_oid(&ud->suboid) || ud->force;
@@ -2313,59 +2333,67 @@ static int run_update_procedure(struct update_data *ud)
*/
if (!is_tip_reachable(ud->sm_path, &ud->oid) &&
fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, &ud->oid))
- die(_("Fetched in submodule path '%s', but it did not "
- "contain %s. Direct fetching of that commit failed."),
- ud->displaypath, oid_to_hex(&ud->oid));
+ return die_message(_("Fetched in submodule path '%s', but it did not "
+ "contain %s. Direct fetching of that commit failed."),
+ ud->displaypath, oid_to_hex(&ud->oid));
}
return run_update_command(ud, subforce);
}
-static const char *remote_submodule_branch(const char *path)
+static int remote_submodule_branch(const char *path, const char **branch)
{
const struct submodule *sub;
- const char *branch = NULL;
char *key;
+ *branch = NULL;
sub = submodule_from_path(the_repository, null_oid(), path);
if (!sub)
- return NULL;
+ return die_message(_("could not initialize submodule at path '%s'"),
+ path);
key = xstrfmt("submodule.%s.branch", sub->name);
- if (repo_config_get_string_tmp(the_repository, key, &branch))
- branch = sub->branch;
+ if (repo_config_get_string_tmp(the_repository, key, branch))
+ *branch = sub->branch;
free(key);
- if (!branch)
- return "HEAD";
+ if (!*branch) {
+ *branch = "HEAD";
+ return 0;
+ }
- if (!strcmp(branch, ".")) {
+ if (!strcmp(*branch, ".")) {
const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
if (!refname)
- die(_("No such ref: %s"), "HEAD");
+ return die_message(_("No such ref: %s"), "HEAD");
/* detached HEAD */
if (!strcmp(refname, "HEAD"))
- die(_("Submodule (%s) branch configured to inherit "
- "branch from superproject, but the superproject "
- "is not on any branch"), sub->name);
+ return die_message(_("Submodule (%s) branch configured to inherit "
+ "branch from superproject, but the superproject "
+ "is not on any branch"), sub->name);
if (!skip_prefix(refname, "refs/heads/", &refname))
- die(_("Expecting a full ref name, got %s"), refname);
- return refname;
+ return die_message(_("Expecting a full ref name, got %s"),
+ refname);
+
+ *branch = refname;
+ return 0;
}
- return branch;
+ /* Our "branch" is coming from repo_config_get_string_tmp() */
+ return 0;
}
-static void ensure_core_worktree(const char *path)
+static int ensure_core_worktree(const char *path)
{
const char *cw;
struct repository subrepo;
if (repo_submodule_init(&subrepo, the_repository, path, null_oid()))
- die(_("could not get a repository handle for submodule '%s'"), path);
+ return die_message(_("could not get a repository handle for submodule '%s'"),
+ path);
if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) {
char *cfg_file, *abs_path;
@@ -2383,6 +2411,9 @@ static void ensure_core_worktree(const char *path)
free(abs_path);
strbuf_release(&sb);
}
+
+ repo_clear(&subrepo);
+ return 0;
}
static const char *submodule_update_type_to_label(enum submodule_update_type type)
@@ -2402,7 +2433,8 @@ static const char *submodule_update_type_to_label(enum submodule_update_type typ
BUG("unreachable with type %d", type);
}
-static void update_data_to_args(struct update_data *update_data, struct strvec *args)
+static void update_data_to_args(const struct update_data *update_data,
+ struct strvec *args)
{
enum submodule_update_type update_type = update_data->update_default;
@@ -2436,6 +2468,7 @@ static void update_data_to_args(struct update_data *update_data, struct strvec *
if (update_data->references.nr) {
struct string_list_item *item;
+
for_each_string_list_item(item, &update_data->references)
strvec_pushl(args, "--reference", item->string, NULL);
}
@@ -2455,48 +2488,61 @@ static void update_data_to_args(struct update_data *update_data, struct strvec *
static int update_submodule(struct update_data *update_data)
{
- ensure_core_worktree(update_data->sm_path);
-
- update_data->displaypath = get_submodule_displaypath(
- update_data->sm_path, update_data->prefix);
+ int ret;
- determine_submodule_update_strategy(the_repository, update_data->just_cloned,
- update_data->sm_path, update_data->update_default,
- &update_data->update_strategy);
+ ret = determine_submodule_update_strategy(the_repository,
+ update_data->just_cloned,
+ update_data->sm_path,
+ update_data->update_default,
+ &update_data->update_strategy);
+ if (ret)
+ return ret;
if (update_data->just_cloned)
oidcpy(&update_data->suboid, null_oid());
else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid))
- die(_("Unable to find current revision in submodule path '%s'"),
- update_data->displaypath);
+ return die_message(_("Unable to find current revision in submodule path '%s'"),
+ update_data->displaypath);
if (update_data->remote) {
- char *remote_name = get_default_remote_submodule(update_data->sm_path);
- const char *branch = remote_submodule_branch(update_data->sm_path);
- char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch);
+ char *remote_name;
+ const char *branch;
+ char *remote_ref;
+ int code;
+
+ code = get_default_remote_submodule(update_data->sm_path, &remote_name);
+ if (code)
+ return code;
+ code = remote_submodule_branch(update_data->sm_path, &branch);
+ if (code)
+ return code;
+ remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch);
+
+ free(remote_name);
if (!update_data->nofetch) {
if (fetch_in_submodule(update_data->sm_path, update_data->depth,
0, NULL))
- die(_("Unable to fetch in submodule path '%s'"),
- update_data->sm_path);
+ return die_message(_("Unable to fetch in submodule path '%s'"),
+ update_data->sm_path);
}
if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))
- die(_("Unable to find %s revision in submodule path '%s'"),
- remote_ref, update_data->sm_path);
+ return die_message(_("Unable to find %s revision in submodule path '%s'"),
+ remote_ref, update_data->sm_path);
free(remote_ref);
}
- if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)
- if (run_update_procedure(update_data))
- return 1;
+ if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) {
+ ret = run_update_procedure(update_data);
+ if (ret)
+ return ret;
+ }
if (update_data->recursive) {
struct child_process cp = CHILD_PROCESS_INIT;
struct update_data next = *update_data;
- int res;
next.prefix = NULL;
oidcpy(&next.oid, null_oid());
@@ -2507,16 +2553,11 @@ static int update_submodule(struct update_data *update_data)
prepare_submodule_repo_env(&cp.env);
update_data_to_args(&next, &cp.args);
- /* die() if child process die()'d */
- res = run_command(&cp);
- if (!res)
- return 0;
- die_message(_("Failed to recurse into submodule path '%s'"),
- update_data->displaypath);
- if (res == 128)
- exit(res);
- else if (res)
- return 1;
+ ret = run_command(&cp);
+ if (ret)
+ die_message(_("Failed to recurse into submodule path '%s'"),
+ update_data->displaypath);
+ return ret;
}
return 0;
@@ -2524,14 +2565,22 @@ static int update_submodule(struct update_data *update_data)
static int update_submodules(struct update_data *update_data)
{
- int i, res = 0;
+ int i, ret = 0;
struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
+ const struct run_process_parallel_opts opts = {
+ .tr2_category = "submodule",
+ .tr2_label = "parallel/update",
+
+ .processes = update_data->max_jobs,
+
+ .get_next_task = update_clone_get_next_task,
+ .start_failure = update_clone_start_failure,
+ .task_finished = update_clone_task_finished,
+ .data = &suc,
+ };
suc.update_data = update_data;
- run_processes_parallel_tr2(suc.update_data->max_jobs, update_clone_get_next_task,
- update_clone_start_failure,
- update_clone_task_finished, &suc, "submodule",
- "parallel/update");
+ run_processes_parallel(&opts);
/*
* We saved the output and put it out all at once now.
@@ -2542,33 +2591,48 @@ static int update_submodules(struct update_data *update_data)
* - the listener can avoid doing any work if fetching failed.
*/
if (suc.quickstop) {
- res = 1;
+ ret = 1;
goto cleanup;
}
for (i = 0; i < suc.update_clone_nr; i++) {
struct update_clone_data ucd = suc.update_clone[i];
+ int code;
oidcpy(&update_data->oid, &ucd.oid);
update_data->just_cloned = ucd.just_cloned;
update_data->sm_path = ucd.sub->path;
- if (update_submodule(update_data))
- res = 1;
+ code = ensure_core_worktree(update_data->sm_path);
+ if (code)
+ goto fail;
+
+ update_data->displaypath = get_submodule_displaypath(
+ update_data->sm_path, update_data->prefix);
+ code = update_submodule(update_data);
+ FREE_AND_NULL(update_data->displaypath);
+fail:
+ if (!code)
+ continue;
+ ret = code;
+ if (ret == 128)
+ goto cleanup;
}
cleanup:
+ submodule_update_clone_release(&suc);
string_list_clear(&update_data->references, 0);
- return res;
+ return ret;
}
static int module_update(int argc, const char **argv, const char *prefix)
{
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
+ struct pathspec pathspec2 = { 0 };
struct update_data opt = UPDATE_DATA_INIT;
- struct list_objects_filter_options filter_options;
+ struct list_objects_filter_options filter_options =
+ LIST_OBJECTS_FILTER_INIT;
int ret;
-
struct option module_update_options[] = {
OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
OPT_BOOL(0, "init", &opt.init,
@@ -2579,9 +2643,6 @@ static int module_update(int argc, const char **argv, const char *prefix)
N_("traverse submodules recursively")),
OPT_BOOL('N', "no-fetch", &opt.nofetch,
N_("don't fetch new objects from the remote site")),
- OPT_STRING(0, "prefix", &opt.prefix,
- N_("path"),
- N_("path into the working tree")),
OPT_SET_INT(0, "checkout", &opt.update_default,
N_("use the 'checkout' update strategy (default)"),
SM_UPDATE_CHECKOUT),
@@ -2612,7 +2673,6 @@ static int module_update(int argc, const char **argv, const char *prefix)
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule [--quiet] update"
" [--init [--filter=<filter-spec>]] [--remote]"
@@ -2626,7 +2686,6 @@ static int module_update(int argc, const char **argv, const char *prefix)
update_clone_config_from_gitmodules(&opt.max_jobs);
git_config(git_update_clone_config, &opt.max_jobs);
- memset(&filter_options, 0, sizeof(filter_options));
argc = parse_options(argc, argv, prefix, module_update_options,
git_submodule_helper_usage, 0);
@@ -2639,13 +2698,14 @@ static int module_update(int argc, const char **argv, const char *prefix)
}
opt.filter_options = &filter_options;
+ opt.prefix = prefix;
if (opt.update_default)
opt.update_strategy.type = opt.update_default;
- if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) {
- list_objects_filter_release(&filter_options);
- return 1;
+ if (module_list_compute(argv, prefix, &pathspec, &opt.list) < 0) {
+ ret = 1;
+ goto cleanup;
}
if (pathspec.nr)
@@ -2655,9 +2715,12 @@ static int module_update(int argc, const char **argv, const char *prefix)
struct module_list list = MODULE_LIST_INIT;
struct init_cb info = INIT_CB_INIT;
- if (module_list_compute(argc, argv, opt.prefix,
- &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(argv, opt.prefix,
+ &pathspec2, &list) < 0) {
+ module_list_release(&list);
+ ret = 1;
+ goto cleanup;
+ }
/*
* If there are no path args and submodule.active is set then,
@@ -2671,10 +2734,15 @@ static int module_update(int argc, const char **argv, const char *prefix)
info.flags |= OPT_QUIET;
for_each_listed_submodule(&list, init_submodule_cb, &info);
+ module_list_release(&list);
}
ret = update_submodules(&opt);
+cleanup:
+ update_data_release(&opt);
list_objects_filter_release(&filter_options);
+ clear_pathspec(&pathspec);
+ clear_pathspec(&pathspec2);
return ret;
}
@@ -2758,111 +2826,31 @@ static int push_check(int argc, const char **argv, const char *prefix)
static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
{
int i;
- struct pathspec pathspec;
+ struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
- unsigned flags = ABSORB_GITDIR_RECURSE_SUBMODULES;
-
struct option embed_gitdir_options[] = {
- OPT_STRING(0, "prefix", &prefix,
- N_("path"),
- N_("path into the working tree")),
- OPT_BIT(0, "--recursive", &flags, N_("recurse into submodules"),
- ABSORB_GITDIR_RECURSE_SUBMODULES),
OPT_END()
};
-
const char *const git_submodule_helper_usage[] = {
N_("git submodule absorbgitdirs [<options>] [<path>...]"),
NULL
};
+ int ret = 1;
argc = parse_options(argc, argv, prefix, embed_gitdir_options,
git_submodule_helper_usage, 0);
- if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
- return 1;
+ if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
+ goto cleanup;
for (i = 0; i < list.nr; i++)
- absorb_git_dir_into_superproject(list.entries[i]->name, flags);
-
- return 0;
-}
-
-static int is_active(int argc, const char **argv, const char *prefix)
-{
- if (argc != 2)
- die("submodule--helper is-active takes exactly 1 argument");
-
- return !is_submodule_active(the_repository, argv[1]);
-}
-
-/*
- * Exit non-zero if any of the submodule names given on the command line is
- * invalid. If no names are given, filter stdin to print only valid names
- * (which is primarily intended for testing).
- */
-static int check_name(int argc, const char **argv, const char *prefix)
-{
- if (argc > 1) {
- while (*++argv) {
- if (check_submodule_name(*argv) < 0)
- return 1;
- }
- } else {
- struct strbuf buf = STRBUF_INIT;
- while (strbuf_getline(&buf, stdin) != EOF) {
- if (!check_submodule_name(buf.buf))
- printf("%s\n", buf.buf);
- }
- strbuf_release(&buf);
- }
- return 0;
-}
-
-static int module_config(int argc, const char **argv, const char *prefix)
-{
- enum {
- CHECK_WRITEABLE = 1,
- DO_UNSET = 2
- } command = 0;
+ absorb_git_dir_into_superproject(list.entries[i]->name);
- struct option module_config_options[] = {
- OPT_CMDMODE(0, "check-writeable", &command,
- N_("check if it is safe to write to the .gitmodules file"),
- CHECK_WRITEABLE),
- OPT_CMDMODE(0, "unset", &command,
- N_("unset the config in the .gitmodules file"),
- DO_UNSET),
- OPT_END()
- };
- const char *const git_submodule_helper_usage[] = {
- N_("git submodule--helper config <name> [<value>]"),
- N_("git submodule--helper config --unset <name>"),
- "git submodule--helper config --check-writeable",
- NULL
- };
-
- argc = parse_options(argc, argv, prefix, module_config_options,
- git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);
-
- if (argc == 1 && command == CHECK_WRITEABLE)
- return is_writing_gitmodules_ok() ? 0 : -1;
-
- /* Equivalent to ACTION_GET in builtin/config.c */
- if (argc == 2 && command != DO_UNSET)
- return print_config_from_gitmodules(the_repository, argv[1]);
-
- /* Equivalent to ACTION_SET in builtin/config.c */
- if (argc == 3 || (argc == 2 && command == DO_UNSET)) {
- const char *value = (argc == 3) ? argv[2] : NULL;
-
- if (!is_writing_gitmodules_ok())
- die(_("please make sure that the .gitmodules file is in the working tree"));
-
- return config_set_in_gitmodules_file_gently(argv[1], value);
- }
-
- usage_with_options(git_submodule_helper_usage, module_config_options);
+ ret = 0;
+cleanup:
+ clear_pathspec(&pathspec);
+ module_list_release(&list);
+ return ret;
}
static int module_set_url(int argc, const char **argv, const char *prefix)
@@ -2871,7 +2859,6 @@ static int module_set_url(int argc, const char **argv, const char *prefix)
const char *newurl;
const char *path;
char *config_name;
-
struct option options[] = {
OPT__QUIET(&quiet, N_("suppress output for setting url of a submodule")),
OPT_END()
@@ -2902,13 +2889,13 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)
const char *opt_branch = NULL;
const char *path;
char *config_name;
-
- /*
- * We accept the `quiet` option for uniformity across subcommands,
- * though there is nothing to make less verbose in this subcommand.
- */
struct option options[] = {
+ /*
+ * We accept the `quiet` option for uniformity across subcommands,
+ * though there is nothing to make less verbose in this subcommand.
+ */
OPT_NOOP_NOARG('q', "quiet"),
+
OPT_BOOL('d', "default", &opt_default,
N_("set the default tracking branch to master")),
OPT_STRING('b', "branch", &opt_branch, N_("branch"),
@@ -2943,7 +2930,6 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)
{
enum branch_track track;
int quiet = 0, force = 0, reflog = 0, dry_run = 0;
-
struct option options[] = {
OPT__QUIET(&quiet, N_("print only error messages")),
OPT__FORCE(&force, N_("force creation"), 0),
@@ -3006,8 +2992,10 @@ static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
if (!capture_command(&cp_remote, &sb_remote_out, 0)) {
char *next_line;
char *line = sb_remote_out.buf;
+
while ((next_line = strchr(line, '\n')) != NULL) {
size_t len = next_line - line;
+
if (strip_suffix_mem(line, &len, " (fetch)"))
strbuf_addf(msg, " %.*s\n", (int)len, line);
line = next_line + 1;
@@ -3021,6 +3009,8 @@ static int add_submodule(const struct add_data *add_data)
{
char *submod_gitdir_path;
struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
+ struct string_list reference = STRING_LIST_INIT_NODUP;
+ int ret = -1;
/* perhaps the path already exists and is already a git repo, else clone it */
if (is_directory(add_data->sm_path)) {
@@ -3037,6 +3027,7 @@ static int add_submodule(const struct add_data *add_data)
free(submod_gitdir_path);
} else {
struct child_process cp = CHILD_PROCESS_INIT;
+
submod_gitdir_path = xstrfmt(".git/modules/%s", add_data->sm_name);
if (is_directory(submod_gitdir_path)) {
@@ -3075,15 +3066,17 @@ static int add_submodule(const struct add_data *add_data)
clone_data.url = add_data->realrepo;
clone_data.quiet = add_data->quiet;
clone_data.progress = add_data->progress;
- if (add_data->reference_path)
- string_list_append(&clone_data.reference,
- xstrdup(add_data->reference_path));
+ if (add_data->reference_path) {
+ char *p = xstrdup(add_data->reference_path);
+
+ string_list_append(&reference, p)->util = p;
+ }
clone_data.dissociate = add_data->dissociate;
if (add_data->depth >= 0)
clone_data.depth = xstrfmt("%d", add_data->depth);
- if (clone_submodule(&clone_data))
- return -1;
+ if (clone_submodule(&clone_data, &reference))
+ goto cleanup;
prepare_submodule_repo_env(&cp.env);
cp.git_cmd = 1;
@@ -3102,7 +3095,10 @@ static int add_submodule(const struct add_data *add_data)
if (run_command(&cp))
die(_("unable to checkout submodule '%s'"), add_data->sm_path);
}
- return 0;
+ ret = 0;
+cleanup:
+ string_list_clear(&reference, 1);
+ return ret;
}
static int config_submodule_in_gitmodules(const char *name, const char *var, const char *value)
@@ -3123,7 +3119,7 @@ static int config_submodule_in_gitmodules(const char *name, const char *var, con
static void configure_added_submodule(struct add_data *add_data)
{
char *key;
- char *val = NULL;
+ const char *val;
struct child_process add_submod = CHILD_PROCESS_INIT;
struct child_process add_gitmodules = CHILD_PROCESS_INIT;
@@ -3168,7 +3164,7 @@ static void configure_added_submodule(struct add_data *add_data)
* is_submodule_active(), since that function needs to find
* out the value of "submodule.active" again anyway.
*/
- if (!git_config_get_string("submodule.active", &val) && val) {
+ if (!git_config_get_string_tmp("submodule.active", &val)) {
/*
* If the submodule being added isn't already covered by the
* current configured pathspec, set the submodule's active flag
@@ -3242,7 +3238,6 @@ static int module_add(int argc, const char **argv, const char *prefix)
int force = 0, quiet = 0, progress = 0, dissociate = 0;
struct add_data add_data = ADD_DATA_INIT;
char *to_free = NULL;
-
struct option options[] = {
OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
N_("branch of repository to add as submodule")),
@@ -3259,11 +3254,12 @@ static int module_add(int argc, const char **argv, const char *prefix)
OPT_INTEGER(0, "depth", &add_data.depth, N_("depth for shallow clones")),
OPT_END()
};
-
const char *const usage[] = {
N_("git submodule add [<options>] [--] <repository> [<path>]"),
NULL
};
+ struct strbuf sb = STRBUF_INIT;
+ int ret = 1;
argc = parse_options(argc, argv, prefix, options, usage, 0);
@@ -3283,8 +3279,12 @@ static int module_add(int argc, const char **argv, const char *prefix)
else
add_data.sm_path = xstrdup(argv[1]);
- if (prefix && *prefix && !is_absolute_path(add_data.sm_path))
- add_data.sm_path = xstrfmt("%s%s", prefix, add_data.sm_path);
+ if (prefix && *prefix && !is_absolute_path(add_data.sm_path)) {
+ char *sm_path = add_data.sm_path;
+
+ add_data.sm_path = xstrfmt("%s%s", prefix, sm_path);
+ free(sm_path);
+ }
if (starts_with_dot_dot_slash(add_data.repo) ||
starts_with_dot_slash(add_data.repo)) {
@@ -3313,20 +3313,17 @@ static int module_add(int argc, const char **argv, const char *prefix)
die_on_repo_without_commits(add_data.sm_path);
if (!force) {
- int exit_code = -1;
- struct strbuf sb = STRBUF_INIT;
struct child_process cp = CHILD_PROCESS_INIT;
+
cp.git_cmd = 1;
cp.no_stdout = 1;
strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing",
"--no-warn-embedded-repo", add_data.sm_path, NULL);
- if ((exit_code = pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0))) {
+ if ((ret = pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0))) {
strbuf_complete_line(&sb);
fputs(sb.buf, stderr);
- free(add_data.sm_path);
- return exit_code;
+ goto cleanup;
}
- strbuf_release(&sb);
}
if(!add_data.sm_name)
@@ -3341,64 +3338,58 @@ static int module_add(int argc, const char **argv, const char *prefix)
add_data.progress = !!progress;
add_data.dissociate = !!dissociate;
- if (add_submodule(&add_data)) {
- free(add_data.sm_path);
- return 1;
- }
+ if (add_submodule(&add_data))
+ goto cleanup;
configure_added_submodule(&add_data);
+
+ ret = 0;
+cleanup:
free(add_data.sm_path);
free(to_free);
+ strbuf_release(&sb);
- return 0;
+ return ret;
}
-#define SUPPORT_SUPER_PREFIX (1<<0)
-
-struct cmd_struct {
- const char *cmd;
- int (*fn)(int, const char **, const char *);
- unsigned option;
-};
-
-static struct cmd_struct commands[] = {
- {"list", module_list, 0},
- {"name", module_name, 0},
- {"clone", module_clone, SUPPORT_SUPER_PREFIX},
- {"add", module_add, 0},
- {"update", module_update, SUPPORT_SUPER_PREFIX},
- {"resolve-relative-url-test", resolve_relative_url_test, 0},
- {"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
- {"init", module_init, 0},
- {"status", module_status, SUPPORT_SUPER_PREFIX},
- {"sync", module_sync, SUPPORT_SUPER_PREFIX},
- {"deinit", module_deinit, 0},
- {"summary", module_summary, 0},
- {"push-check", push_check, 0},
- {"absorbgitdirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
- {"is-active", is_active, 0},
- {"check-name", check_name, 0},
- {"config", module_config, 0},
- {"set-url", module_set_url, 0},
- {"set-branch", module_set_branch, 0},
- {"create-branch", module_create_branch, 0},
-};
-
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
{
- int i;
- if (argc < 2 || !strcmp(argv[1], "-h"))
- usage("git submodule--helper <command>");
-
- for (i = 0; i < ARRAY_SIZE(commands); i++) {
- if (!strcmp(argv[1], commands[i].cmd)) {
- if (get_super_prefix() &&
- !(commands[i].option & SUPPORT_SUPER_PREFIX))
- die(_("%s doesn't support --super-prefix"),
- commands[i].cmd);
- return commands[i].fn(argc - 1, argv + 1, prefix);
- }
- }
+ const char *cmd = argv[0];
+ const char *subcmd;
+ parse_opt_subcommand_fn *fn = NULL;
+ const char *const usage[] = {
+ N_("git submodule--helper <command>"),
+ NULL
+ };
+ struct option options[] = {
+ OPT_SUBCOMMAND("clone", &fn, module_clone),
+ OPT_SUBCOMMAND("add", &fn, module_add),
+ OPT_SUBCOMMAND("update", &fn, module_update),
+ OPT_SUBCOMMAND("foreach", &fn, module_foreach),
+ OPT_SUBCOMMAND("init", &fn, module_init),
+ OPT_SUBCOMMAND("status", &fn, module_status),
+ OPT_SUBCOMMAND("sync", &fn, module_sync),
+ OPT_SUBCOMMAND("deinit", &fn, module_deinit),
+ OPT_SUBCOMMAND("summary", &fn, module_summary),
+ OPT_SUBCOMMAND("push-check", &fn, push_check),
+ OPT_SUBCOMMAND("absorbgitdirs", &fn, absorb_git_dirs),
+ OPT_SUBCOMMAND("set-url", &fn, module_set_url),
+ OPT_SUBCOMMAND("set-branch", &fn, module_set_branch),
+ OPT_SUBCOMMAND("create-branch", &fn, module_create_branch),
+ OPT_END()
+ };
+ argc = parse_options(argc, argv, prefix, options, usage, 0);
+ subcmd = argv[0];
+
+ if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
+ strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
+ strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
+ get_super_prefix())
+ /*
+ * xstrfmt() rather than "%s %s" to keep the translated
+ * string identical to git.c's.
+ */
+ die(_("%s doesn't support --super-prefix"),
+ xstrfmt("'%s %s'", cmd, subcmd));
- die(_("'%s' is not a valid submodule--helper "
- "subcommand"), argv[1]);
+ return fn(argc, argv, prefix);
}
diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c
index 1b0f10225f0..e00768a8b7e 100644
--- a/builtin/symbolic-ref.c
+++ b/builtin/symbolic-ref.c
@@ -5,15 +5,19 @@
#include "parse-options.h"
static const char * const git_symbolic_ref_usage[] = {
- N_("git symbolic-ref [<options>] <name> [<ref>]"),
- N_("git symbolic-ref -d [-q] <name>"),
+ N_("git symbolic-ref [-m <reason>] <name> <ref>"),
+ N_("git symbolic-ref [-q] [--short] [--no-recurse] <name>"),
+ N_("git symbolic-ref --delete [-q] <name>"),
NULL
};
-static int check_symref(const char *HEAD, int quiet, int shorten, int print)
+static int check_symref(const char *HEAD, int quiet, int shorten, int recurse, int print)
{
- int flag;
- const char *refname = resolve_ref_unsafe(HEAD, 0, NULL, &flag);
+ int resolve_flags, flag;
+ const char *refname;
+
+ resolve_flags = (recurse ? 0 : RESOLVE_REF_NO_RECURSE);
+ refname = resolve_ref_unsafe(HEAD, resolve_flags, NULL, &flag);
if (!refname)
die("No such ref: %s", HEAD);
@@ -35,13 +39,14 @@ static int check_symref(const char *HEAD, int quiet, int shorten, int print)
int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
{
- int quiet = 0, delete = 0, shorten = 0, ret = 0;
+ int quiet = 0, delete = 0, shorten = 0, recurse = 1, ret = 0;
const char *msg = NULL;
struct option options[] = {
OPT__QUIET(&quiet,
N_("suppress error message for non-symbolic (detached) refs")),
OPT_BOOL('d', "delete", &delete, N_("delete symbolic ref")),
OPT_BOOL(0, "short", &shorten, N_("shorten ref output")),
+ OPT_BOOL(0, "recurse", &recurse, N_("recursively dereference (default)")),
OPT_STRING('m', NULL, &msg, N_("reason"), N_("reason of the update")),
OPT_END(),
};
@@ -55,7 +60,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
if (delete) {
if (argc != 1)
usage_with_options(git_symbolic_ref_usage, options);
- ret = check_symref(argv[0], 1, 0, 0);
+ ret = check_symref(argv[0], 1, 0, 0, 0);
if (ret)
die("Cannot delete %s, not a symbolic ref", argv[0]);
if (!strcmp(argv[0], "HEAD"))
@@ -65,7 +70,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
switch (argc) {
case 1:
- ret = check_symref(argv[0], quiet, shorten, 1);
+ ret = check_symref(argv[0], quiet, shorten, recurse, 1);
break;
case 2:
if (!strcmp(argv[0], "HEAD") &&
diff --git a/builtin/tag.c b/builtin/tag.c
index 75dece0e4f1..d428c45dc8d 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -23,11 +23,13 @@
#include "date.h"
static const char * const git_tag_usage[] = {
- N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n"
- " <tagname> [<head>]"),
+ N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+ " <tagname> [<commit> | <object>]"),
N_("git tag -d <tagname>..."),
- N_("git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at <object>]\n"
- " [--format=<format>] [--merged <commit>] [--no-merged <commit>] [<pattern>...]"),
+ N_("git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n"
+ " [--points-at <object>] [--column[=<options>] | --no-column]\n"
+ " [--create-reflog] [--sort=<key>] [--format=<format>]\n"
+ " [--merged <commit>] [--no-merged <commit>] [<pattern>...]"),
N_("git tag -v [--format=<format>] <tagname>..."),
NULL
};
diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c
index 58652229f27..9e8119dd354 100644
--- a/builtin/unpack-file.c
+++ b/builtin/unpack-file.c
@@ -27,7 +27,7 @@ int cmd_unpack_file(int argc, const char **argv, const char *prefix)
struct object_id oid;
if (argc != 2 || !strcmp(argv[1], "-h"))
- usage("git unpack-file <sha1>");
+ usage("git unpack-file <blob>");
if (get_oid(argv[1], &oid))
die("Not a valid object name %s", argv[1]);
diff --git a/builtin/update-index.c b/builtin/update-index.c
index b62249905f1..7b0c924d7d4 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -732,7 +732,7 @@ static int do_unresolve(int ac, const char **av,
return err;
}
-static int do_reupdate(int ac, const char **av,
+static int do_reupdate(const char **paths,
const char *prefix)
{
/* Read HEAD and run update-index on paths that are
@@ -744,7 +744,7 @@ static int do_reupdate(int ac, const char **av,
parse_pathspec(&pathspec, 0,
PATHSPEC_PREFER_CWD,
- prefix, av + 1);
+ prefix, paths);
if (read_ref("HEAD", &head_oid))
/* If there is no HEAD, that means it is an initial
@@ -970,7 +970,7 @@ static enum parse_opt_result reupdate_callback(
/* consume remaining arguments. */
setup_work_tree();
- *has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);
+ *has_errors = do_reupdate(ctx->argv + 1, prefix);
if (*has_errors)
active_cache_changed = 0;
diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c
index 880fffec587..d2239c9ef4d 100644
--- a/builtin/update-server-info.c
+++ b/builtin/update-server-info.c
@@ -4,7 +4,7 @@
#include "parse-options.h"
static const char * const update_server_info_usage[] = {
- "git update-server-info [--force]",
+ "git update-server-info [-f | --force]",
NULL
};
diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c
index 98d028dae67..945ee2b4126 100644
--- a/builtin/upload-archive.c
+++ b/builtin/upload-archive.c
@@ -10,7 +10,7 @@
#include "strvec.h"
static const char upload_archive_usage[] =
- "git upload-archive <repo>";
+ "git upload-archive <repository>";
static const char deadchild[] =
"git upload-archive: archiver died with error";
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
index 125af53885f..25b69da2bf2 100644
--- a/builtin/upload-pack.c
+++ b/builtin/upload-pack.c
@@ -8,7 +8,8 @@
#include "serve.h"
static const char * const upload_pack_usage[] = {
- N_("git upload-pack [<options>] <dir>"),
+ N_("git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n"
+ " [--advertise-refs] <directory>"),
NULL
};
diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c
index 40c69a0bedd..3ebad32b0f1 100644
--- a/builtin/verify-commit.c
+++ b/builtin/verify-commit.c
@@ -16,7 +16,7 @@
#include "gpg-interface.h"
static const char * const verify_commit_usage[] = {
- N_("git verify-commit [-v | --verbose] <commit>..."),
+ N_("git verify-commit [-v | --verbose] [--raw] <commit>..."),
NULL
};
diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c
index 05c52135946..27d6f75fd8a 100644
--- a/builtin/verify-pack.c
+++ b/builtin/verify-pack.c
@@ -56,7 +56,7 @@ static int verify_one_pack(const char *path, unsigned int flags, const char *has
}
static const char * const verify_pack_usage[] = {
- N_("git verify-pack [-v | --verbose] [-s | --stat-only] <pack>..."),
+ N_("git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idx..."),
NULL
};
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index f45136a06ba..217566952d8 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -15,7 +15,7 @@
#include "ref-filter.h"
static const char * const verify_tag_usage[] = {
- N_("git verify-tag [-v | --verbose] [--format=<format>] <tag>..."),
+ N_("git verify-tag [-v | --verbose] [--format=<format>] [--raw] <tag>..."),
NULL
};
diff --git a/builtin/worktree.c b/builtin/worktree.c
index cd62eef240e..4a24d53be15 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -15,15 +15,73 @@
#include "worktree.h"
#include "quote.h"
-static const char * const worktree_usage[] = {
- N_("git worktree add [<options>] <path> [<commit-ish>]"),
- N_("git worktree list [<options>]"),
- N_("git worktree lock [<options>] <path>"),
- N_("git worktree move <worktree> <new-path>"),
- N_("git worktree prune [<options>]"),
- N_("git worktree remove [<options>] <worktree>"),
- N_("git worktree repair [<path>...]"),
- N_("git worktree unlock <path>"),
+#define BUILTIN_WORKTREE_ADD_USAGE \
+ N_("git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]\n" \
+ " [-b <new-branch>] <path> [<commit-ish>]")
+#define BUILTIN_WORKTREE_LIST_USAGE \
+ N_("git worktree list [-v | --porcelain [-z]]")
+#define BUILTIN_WORKTREE_LOCK_USAGE \
+ N_("git worktree lock [--reason <string>] <worktree>")
+#define BUILTIN_WORKTREE_MOVE_USAGE \
+ N_("git worktree move <worktree> <new-path>")
+#define BUILTIN_WORKTREE_PRUNE_USAGE \
+ N_("git worktree prune [-n] [-v] [--expire <expire>]")
+#define BUILTIN_WORKTREE_REMOVE_USAGE \
+ N_("git worktree remove [-f] <worktree>")
+#define BUILTIN_WORKTREE_REPAIR_USAGE \
+ N_("git worktree repair [<path>...]")
+#define BUILTIN_WORKTREE_UNLOCK_USAGE \
+ N_("git worktree unlock <worktree>")
+
+static const char * const git_worktree_usage[] = {
+ BUILTIN_WORKTREE_ADD_USAGE,
+ BUILTIN_WORKTREE_LIST_USAGE,
+ BUILTIN_WORKTREE_LOCK_USAGE,
+ BUILTIN_WORKTREE_MOVE_USAGE,
+ BUILTIN_WORKTREE_PRUNE_USAGE,
+ BUILTIN_WORKTREE_REMOVE_USAGE,
+ BUILTIN_WORKTREE_REPAIR_USAGE,
+ BUILTIN_WORKTREE_UNLOCK_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_add_usage[] = {
+ BUILTIN_WORKTREE_ADD_USAGE,
+ NULL,
+};
+
+static const char * const git_worktree_list_usage[] = {
+ BUILTIN_WORKTREE_LIST_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_lock_usage[] = {
+ BUILTIN_WORKTREE_LOCK_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_move_usage[] = {
+ BUILTIN_WORKTREE_MOVE_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_prune_usage[] = {
+ BUILTIN_WORKTREE_PRUNE_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_remove_usage[] = {
+ BUILTIN_WORKTREE_REMOVE_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_repair_usage[] = {
+ BUILTIN_WORKTREE_REPAIR_USAGE,
+ NULL
+};
+
+static const char * const git_worktree_unlock_usage[] = {
+ BUILTIN_WORKTREE_UNLOCK_USAGE,
NULL
};
@@ -153,9 +211,10 @@ static int prune(int ac, const char **av, const char *prefix)
};
expire = TIME_MAX;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_prune_usage,
+ 0);
if (ac)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_prune_usage, options);
prune_worktrees();
return 0;
}
@@ -573,7 +632,7 @@ static int add(int ac, const char **av, const char *prefix)
memset(&opts, 0, sizeof(opts));
opts.checkout = 1;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_add_usage, 0);
if (!!opts.detach + !!new_branch + !!new_branch_force > 1)
die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach");
if (lock_reason && !keep_locked)
@@ -584,7 +643,7 @@ static int add(int ac, const char **av, const char *prefix)
opts.keep_locked = _("added with --lock");
if (ac < 1 || ac > 2)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_add_usage, options);
path = prefix_filename(prefix, av[0]);
branch = ac < 2 ? "HEAD" : av[1];
@@ -772,9 +831,9 @@ static int list(int ac, const char **av, const char *prefix)
};
expire = TIME_MAX;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_list_usage, 0);
if (ac)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_list_usage, options);
else if (verbose && porcelain)
die(_("options '%s' and '%s' cannot be used together"), "--verbose", "--porcelain");
else if (!line_terminator && !porcelain)
@@ -811,9 +870,9 @@ static int lock_worktree(int ac, const char **av, const char *prefix)
};
struct worktree **worktrees, *wt;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_lock_usage, 0);
if (ac != 1)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_lock_usage, options);
worktrees = get_worktrees();
wt = find_worktree(worktrees, prefix, av[0]);
@@ -844,9 +903,9 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
struct worktree **worktrees, *wt;
int ret;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_unlock_usage, 0);
if (ac != 1)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_unlock_usage, options);
worktrees = get_worktrees();
wt = find_worktree(worktrees, prefix, av[0]);
@@ -914,9 +973,10 @@ static int move_worktree(int ac, const char **av, const char *prefix)
const char *reason = NULL;
char *path;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_move_usage,
+ 0);
if (ac != 2)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_move_usage, options);
path = prefix_filename(prefix, av[1]);
strbuf_addstr(&dst, path);
@@ -1042,9 +1102,9 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
const char *reason = NULL;
int ret = 0;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_remove_usage, 0);
if (ac != 1)
- usage_with_options(worktree_usage, options);
+ usage_with_options(git_worktree_remove_usage, options);
worktrees = get_worktrees();
wt = find_worktree(worktrees, prefix, av[0]);
@@ -1102,7 +1162,7 @@ static int repair(int ac, const char **av, const char *prefix)
};
int rc = 0;
- ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ ac = parse_options(ac, av, prefix, options, git_worktree_repair_usage, 0);
p = ac > 0 ? av : self;
for (; *p; p++)
repair_worktree_at_path(*p, report_repair, &rc);
@@ -1112,31 +1172,24 @@ static int repair(int ac, const char **av, const char *prefix)
int cmd_worktree(int ac, const char **av, const char *prefix)
{
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
+ OPT_SUBCOMMAND("add", &fn, add),
+ OPT_SUBCOMMAND("prune", &fn, prune),
+ OPT_SUBCOMMAND("list", &fn, list),
+ OPT_SUBCOMMAND("lock", &fn, lock_worktree),
+ OPT_SUBCOMMAND("unlock", &fn, unlock_worktree),
+ OPT_SUBCOMMAND("move", &fn, move_worktree),
+ OPT_SUBCOMMAND("remove", &fn, remove_worktree),
+ OPT_SUBCOMMAND("repair", &fn, repair),
OPT_END()
};
git_config(git_worktree_config, NULL);
- if (ac < 2)
- usage_with_options(worktree_usage, options);
if (!prefix)
prefix = "";
- if (!strcmp(av[1], "add"))
- return add(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "prune"))
- return prune(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "list"))
- return list(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "lock"))
- return lock_worktree(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "unlock"))
- return unlock_worktree(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "move"))
- return move_worktree(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "remove"))
- return remove_worktree(ac - 1, av + 1, prefix);
- if (!strcmp(av[1], "repair"))
- return repair(ac - 1, av + 1, prefix);
- usage_with_options(worktree_usage, options);
+
+ ac = parse_options(ac, av, prefix, options, git_worktree_usage, 0);
+ return fn(ac, av, prefix);
}
diff --git a/bundle-uri.c b/bundle-uri.c
new file mode 100644
index 00000000000..79a914f961b
--- /dev/null
+++ b/bundle-uri.c
@@ -0,0 +1,590 @@
+#include "cache.h"
+#include "bundle-uri.h"
+#include "bundle.h"
+#include "object-store.h"
+#include "refs.h"
+#include "run-command.h"
+#include "hashmap.h"
+#include "pkt-line.h"
+#include "config.h"
+
+static int compare_bundles(const void *hashmap_cmp_fn_data,
+ const struct hashmap_entry *he1,
+ const struct hashmap_entry *he2,
+ const void *id)
+{
+ const struct remote_bundle_info *e1 =
+ container_of(he1, const struct remote_bundle_info, ent);
+ const struct remote_bundle_info *e2 =
+ container_of(he2, const struct remote_bundle_info, ent);
+
+ return strcmp(e1->id, id ? (const char *)id : e2->id);
+}
+
+void init_bundle_list(struct bundle_list *list)
+{
+ memset(list, 0, sizeof(*list));
+
+ /* Implied defaults. */
+ list->mode = BUNDLE_MODE_ALL;
+ list->version = 1;
+
+ hashmap_init(&list->bundles, compare_bundles, NULL, 0);
+}
+
+static int clear_remote_bundle_info(struct remote_bundle_info *bundle,
+ void *data)
+{
+ FREE_AND_NULL(bundle->id);
+ FREE_AND_NULL(bundle->uri);
+ FREE_AND_NULL(bundle->file);
+ bundle->unbundled = 0;
+ return 0;
+}
+
+void clear_bundle_list(struct bundle_list *list)
+{
+ if (!list)
+ return;
+
+ for_all_bundles_in_list(list, clear_remote_bundle_info, NULL);
+ hashmap_clear_and_free(&list->bundles, struct remote_bundle_info, ent);
+}
+
+int for_all_bundles_in_list(struct bundle_list *list,
+ bundle_iterator iter,
+ void *data)
+{
+ struct remote_bundle_info *info;
+ struct hashmap_iter i;
+
+ hashmap_for_each_entry(&list->bundles, &i, info, ent) {
+ int result = iter(info, data);
+
+ if (result)
+ return result;
+ }
+
+ return 0;
+}
+
+static int summarize_bundle(struct remote_bundle_info *info, void *data)
+{
+ FILE *fp = data;
+ fprintf(fp, "[bundle \"%s\"]\n", info->id);
+ fprintf(fp, "\turi = %s\n", info->uri);
+ return 0;
+}
+
+void print_bundle_list(FILE *fp, struct bundle_list *list)
+{
+ const char *mode;
+
+ switch (list->mode) {
+ case BUNDLE_MODE_ALL:
+ mode = "all";
+ break;
+
+ case BUNDLE_MODE_ANY:
+ mode = "any";
+ break;
+
+ case BUNDLE_MODE_NONE:
+ default:
+ mode = "<unknown>";
+ }
+
+ fprintf(fp, "[bundle]\n");
+ fprintf(fp, "\tversion = %d\n", list->version);
+ fprintf(fp, "\tmode = %s\n", mode);
+
+ for_all_bundles_in_list(list, summarize_bundle, fp);
+}
+
+/**
+ * Given a key-value pair, update the state of the given bundle list.
+ * Returns 0 if the key-value pair is understood. Returns -1 if the key
+ * is not understood or the value is malformed.
+ */
+static int bundle_list_update(const char *key, const char *value,
+ struct bundle_list *list)
+{
+ struct strbuf id = STRBUF_INIT;
+ struct remote_bundle_info lookup = REMOTE_BUNDLE_INFO_INIT;
+ struct remote_bundle_info *bundle;
+ const char *subsection, *subkey;
+ size_t subsection_len;
+
+ if (parse_config_key(key, "bundle", &subsection, &subsection_len, &subkey))
+ return -1;
+
+ if (!subsection_len) {
+ if (!strcmp(subkey, "version")) {
+ int version;
+ if (!git_parse_int(value, &version))
+ return -1;
+ if (version != 1)
+ return -1;
+
+ list->version = version;
+ return 0;
+ }
+
+ if (!strcmp(subkey, "mode")) {
+ if (!strcmp(value, "all"))
+ list->mode = BUNDLE_MODE_ALL;
+ else if (!strcmp(value, "any"))
+ list->mode = BUNDLE_MODE_ANY;
+ else
+ return -1;
+ return 0;
+ }
+
+ /* Ignore other unknown global keys. */
+ return 0;
+ }
+
+ strbuf_add(&id, subsection, subsection_len);
+
+ /*
+ * Check for an existing bundle with this <id>, or create one
+ * if necessary.
+ */
+ lookup.id = id.buf;
+ hashmap_entry_init(&lookup.ent, strhash(lookup.id));
+ if (!(bundle = hashmap_get_entry(&list->bundles, &lookup, ent, NULL))) {
+ CALLOC_ARRAY(bundle, 1);
+ bundle->id = strbuf_detach(&id, NULL);
+ hashmap_entry_init(&bundle->ent, strhash(bundle->id));
+ hashmap_add(&list->bundles, &bundle->ent);
+ }
+ strbuf_release(&id);
+
+ if (!strcmp(subkey, "uri")) {
+ if (bundle->uri)
+ return -1;
+ bundle->uri = xstrdup(value);
+ return 0;
+ }
+
+ /*
+ * At this point, we ignore any information that we don't
+ * understand, assuming it to be hints for a heuristic the client
+ * does not currently understand.
+ */
+ return 0;
+}
+
+static int config_to_bundle_list(const char *key, const char *value, void *data)
+{
+ struct bundle_list *list = data;
+ return bundle_list_update(key, value, list);
+}
+
+int bundle_uri_parse_config_format(const char *uri,
+ const char *filename,
+ struct bundle_list *list)
+{
+ int result;
+ struct config_options opts = {
+ .error_action = CONFIG_ERROR_ERROR,
+ };
+
+ result = git_config_from_file_with_options(config_to_bundle_list,
+ filename, list,
+ &opts);
+
+ if (!result && list->mode == BUNDLE_MODE_NONE) {
+ warning(_("bundle list at '%s' has no mode"), uri);
+ result = 1;
+ }
+
+ return result;
+}
+
+static char *find_temp_filename(void)
+{
+ int fd;
+ struct strbuf name = STRBUF_INIT;
+ /*
+ * Find a temporary filename that is available. This is briefly
+ * racy, but unlikely to collide.
+ */
+ fd = odb_mkstemp(&name, "bundles/tmp_uri_XXXXXX");
+ if (fd < 0) {
+ warning(_("failed to create temporary file"));
+ return NULL;
+ }
+
+ close(fd);
+ unlink(name.buf);
+ return strbuf_detach(&name, NULL);
+}
+
+static int download_https_uri_to_file(const char *file, const char *uri)
+{
+ int result = 0;
+ struct child_process cp = CHILD_PROCESS_INIT;
+ FILE *child_in = NULL, *child_out = NULL;
+ struct strbuf line = STRBUF_INIT;
+ int found_get = 0;
+
+ strvec_pushl(&cp.args, "git-remote-https", uri, NULL);
+ cp.err = -1;
+ cp.in = -1;
+ cp.out = -1;
+
+ if (start_command(&cp))
+ return 1;
+
+ child_in = fdopen(cp.in, "w");
+ if (!child_in) {
+ result = 1;
+ goto cleanup;
+ }
+
+ child_out = fdopen(cp.out, "r");
+ if (!child_out) {
+ result = 1;
+ goto cleanup;
+ }
+
+ fprintf(child_in, "capabilities\n");
+ fflush(child_in);
+
+ while (!strbuf_getline(&line, child_out)) {
+ if (!line.len)
+ break;
+ if (!strcmp(line.buf, "get"))
+ found_get = 1;
+ }
+ strbuf_release(&line);
+
+ if (!found_get) {
+ result = error(_("insufficient capabilities"));
+ goto cleanup;
+ }
+
+ fprintf(child_in, "get %s %s\n\n", uri, file);
+
+cleanup:
+ if (child_in)
+ fclose(child_in);
+ if (finish_command(&cp))
+ return 1;
+ if (child_out)
+ fclose(child_out);
+ return result;
+}
+
+static int copy_uri_to_file(const char *filename, const char *uri)
+{
+ const char *out;
+
+ if (starts_with(uri, "https:") ||
+ starts_with(uri, "http:"))
+ return download_https_uri_to_file(filename, uri);
+
+ if (skip_prefix(uri, "file://", &out))
+ uri = out;
+
+ /* Copy as a file */
+ return copy_file(filename, uri, 0);
+}
+
+static int unbundle_from_file(struct repository *r, const char *file)
+{
+ int result = 0;
+ int bundle_fd;
+ struct bundle_header header = BUNDLE_HEADER_INIT;
+ struct string_list_item *refname;
+ struct strbuf bundle_ref = STRBUF_INIT;
+ size_t bundle_prefix_len;
+
+ if ((bundle_fd = read_bundle_header(file, &header)) < 0)
+ return 1;
+
+ /*
+ * Skip the reachability walk here, since we will be adding
+ * a reachable ref pointing to the new tips, which will reach
+ * the prerequisite commits.
+ */
+ if ((result = unbundle(r, &header, bundle_fd, NULL,
+ VERIFY_BUNDLE_QUIET)))
+ return 1;
+
+ /*
+ * Convert all refs/heads/ from the bundle into refs/bundles/
+ * in the local repository.
+ */
+ strbuf_addstr(&bundle_ref, "refs/bundles/");
+ bundle_prefix_len = bundle_ref.len;
+
+ for_each_string_list_item(refname, &header.references) {
+ struct object_id *oid = refname->util;
+ struct object_id old_oid;
+ const char *branch_name;
+ int has_old;
+
+ if (!skip_prefix(refname->string, "refs/heads/", &branch_name))
+ continue;
+
+ strbuf_setlen(&bundle_ref, bundle_prefix_len);
+ strbuf_addstr(&bundle_ref, branch_name);
+
+ has_old = !read_ref(bundle_ref.buf, &old_oid);
+ update_ref("fetched bundle", bundle_ref.buf, oid,
+ has_old ? &old_oid : NULL,
+ REF_SKIP_OID_VERIFICATION,
+ UPDATE_REFS_MSG_ON_ERR);
+ }
+
+ bundle_header_release(&header);
+ return result;
+}
+
+struct bundle_list_context {
+ struct repository *r;
+ struct bundle_list *list;
+ enum bundle_list_mode mode;
+ int count;
+ int depth;
+};
+
+/*
+ * This early definition is necessary because we use indirect recursion:
+ *
+ * While iterating through a bundle list that was downloaded as part
+ * of fetch_bundle_uri_internal(), iterator methods eventually call it
+ * again, but with depth + 1.
+ */
+static int fetch_bundle_uri_internal(struct repository *r,
+ struct remote_bundle_info *bundle,
+ int depth,
+ struct bundle_list *list);
+
+static int download_bundle_to_file(struct remote_bundle_info *bundle, void *data)
+{
+ int res;
+ struct bundle_list_context *ctx = data;
+
+ if (ctx->mode == BUNDLE_MODE_ANY && ctx->count)
+ return 0;
+
+ res = fetch_bundle_uri_internal(ctx->r, bundle, ctx->depth + 1, ctx->list);
+
+ /*
+ * Only increment count if the download succeeded. If our mode is
+ * BUNDLE_MODE_ANY, then we will want to try other URIs in the
+ * list in case they work instead.
+ */
+ if (!res)
+ ctx->count++;
+
+ /*
+ * To be opportunistic as possible, we continue iterating and
+ * download as many bundles as we can, so we can apply the ones
+ * that work, even in BUNDLE_MODE_ALL mode.
+ */
+ return 0;
+}
+
+static int download_bundle_list(struct repository *r,
+ struct bundle_list *local_list,
+ struct bundle_list *global_list,
+ int depth)
+{
+ struct bundle_list_context ctx = {
+ .r = r,
+ .list = global_list,
+ .depth = depth + 1,
+ .mode = local_list->mode,
+ };
+
+ return for_all_bundles_in_list(local_list, download_bundle_to_file, &ctx);
+}
+
+static int fetch_bundle_list_in_config_format(struct repository *r,
+ struct bundle_list *global_list,
+ struct remote_bundle_info *bundle,
+ int depth)
+{
+ int result;
+ struct bundle_list list_from_bundle;
+
+ init_bundle_list(&list_from_bundle);
+
+ if ((result = bundle_uri_parse_config_format(bundle->uri,
+ bundle->file,
+ &list_from_bundle)))
+ goto cleanup;
+
+ if (list_from_bundle.mode == BUNDLE_MODE_NONE) {
+ warning(_("unrecognized bundle mode from URI '%s'"),
+ bundle->uri);
+ result = -1;
+ goto cleanup;
+ }
+
+ if ((result = download_bundle_list(r, &list_from_bundle,
+ global_list, depth)))
+ goto cleanup;
+
+cleanup:
+ clear_bundle_list(&list_from_bundle);
+ return result;
+}
+
+/**
+ * This limits the recursion on fetch_bundle_uri_internal() when following
+ * bundle lists.
+ */
+static int max_bundle_uri_depth = 4;
+
+/**
+ * Recursively download all bundles advertised at the given URI
+ * to files. If the file is a bundle, then add it to the given
+ * 'list'. Otherwise, expect a bundle list and recurse on the
+ * URIs in that list according to the list mode (ANY or ALL).
+ */
+static int fetch_bundle_uri_internal(struct repository *r,
+ struct remote_bundle_info *bundle,
+ int depth,
+ struct bundle_list *list)
+{
+ int result = 0;
+ struct remote_bundle_info *bcopy;
+
+ if (depth >= max_bundle_uri_depth) {
+ warning(_("exceeded bundle URI recursion limit (%d)"),
+ max_bundle_uri_depth);
+ return -1;
+ }
+
+ if (!bundle->file &&
+ !(bundle->file = find_temp_filename())) {
+ result = -1;
+ goto cleanup;
+ }
+
+ if ((result = copy_uri_to_file(bundle->file, bundle->uri))) {
+ warning(_("failed to download bundle from URI '%s'"), bundle->uri);
+ goto cleanup;
+ }
+
+ if ((result = !is_bundle(bundle->file, 1))) {
+ result = fetch_bundle_list_in_config_format(
+ r, list, bundle, depth);
+ if (result)
+ warning(_("file at URI '%s' is not a bundle or bundle list"),
+ bundle->uri);
+ goto cleanup;
+ }
+
+ /* Copy the bundle and insert it into the global list. */
+ CALLOC_ARRAY(bcopy, 1);
+ bcopy->id = xstrdup(bundle->id);
+ bcopy->file = xstrdup(bundle->file);
+ hashmap_entry_init(&bcopy->ent, strhash(bcopy->id));
+ hashmap_add(&list->bundles, &bcopy->ent);
+
+cleanup:
+ if (result && bundle->file)
+ unlink(bundle->file);
+ return result;
+}
+
+/**
+ * This loop iterator breaks the loop with nonzero return code on the
+ * first successful unbundling of a bundle.
+ */
+static int attempt_unbundle(struct remote_bundle_info *info, void *data)
+{
+ struct repository *r = data;
+
+ if (!info->file || info->unbundled)
+ return 0;
+
+ if (!unbundle_from_file(r, info->file)) {
+ info->unbundled = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int unbundle_all_bundles(struct repository *r,
+ struct bundle_list *list)
+{
+ /*
+ * Iterate through all bundles looking for ones that can
+ * successfully unbundle. If any succeed, then perhaps another
+ * will succeed in the next attempt.
+ *
+ * Keep in mind that a non-zero result for the loop here means
+ * the loop terminated early on a successful unbundling, which
+ * signals that we can try again.
+ */
+ while (for_all_bundles_in_list(list, attempt_unbundle, r)) ;
+
+ return 0;
+}
+
+static int unlink_bundle(struct remote_bundle_info *info, void *data)
+{
+ if (info->file)
+ unlink_or_warn(info->file);
+ return 0;
+}
+
+int fetch_bundle_uri(struct repository *r, const char *uri)
+{
+ int result;
+ struct bundle_list list;
+ struct remote_bundle_info bundle = {
+ .uri = xstrdup(uri),
+ .id = xstrdup(""),
+ };
+
+ init_bundle_list(&list);
+
+ /* If a bundle is added to this global list, then it is required. */
+ list.mode = BUNDLE_MODE_ALL;
+
+ if ((result = fetch_bundle_uri_internal(r, &bundle, 0, &list)))
+ goto cleanup;
+
+ result = unbundle_all_bundles(r, &list);
+
+cleanup:
+ for_all_bundles_in_list(&list, unlink_bundle, NULL);
+ clear_bundle_list(&list);
+ clear_remote_bundle_info(&bundle, NULL);
+ return result;
+}
+
+/**
+ * General API for {transport,connect}.c etc.
+ */
+int bundle_uri_parse_line(struct bundle_list *list, const char *line)
+{
+ int result;
+ const char *equals;
+ struct strbuf key = STRBUF_INIT;
+
+ if (!strlen(line))
+ return error(_("bundle-uri: got an empty line"));
+
+ equals = strchr(line, '=');
+
+ if (!equals)
+ return error(_("bundle-uri: line is not of the form 'key=value'"));
+ if (line == equals || !*(equals + 1))
+ return error(_("bundle-uri: line has empty key or value"));
+
+ strbuf_add(&key, line, equals - line);
+ result = bundle_list_update(key.buf, equals + 1, list);
+ strbuf_release(&key);
+
+ return result;
+}
diff --git a/bundle-uri.h b/bundle-uri.h
new file mode 100644
index 00000000000..4dbc269823c
--- /dev/null
+++ b/bundle-uri.h
@@ -0,0 +1,107 @@
+#ifndef BUNDLE_URI_H
+#define BUNDLE_URI_H
+
+#include "hashmap.h"
+#include "strbuf.h"
+
+struct repository;
+struct string_list;
+
+/**
+ * The remote_bundle_info struct contains information for a single bundle
+ * URI. This may be initialized simply by a given URI or might have
+ * additional metadata associated with it if the bundle was advertised by
+ * a bundle list.
+ */
+struct remote_bundle_info {
+ struct hashmap_entry ent;
+
+ /**
+ * The 'id' is a name given to the bundle for reference
+ * by other bundle infos.
+ */
+ char *id;
+
+ /**
+ * The 'uri' is the location of the remote bundle so
+ * it can be downloaded on-demand. This will be NULL
+ * if there was no table of contents.
+ */
+ char *uri;
+
+ /**
+ * If the bundle has been downloaded, then 'file' is a
+ * filename storing its contents. Otherwise, 'file' is
+ * NULL.
+ */
+ char *file;
+
+ /**
+ * If the bundle has been unbundled successfully, then
+ * this boolean is true.
+ */
+ unsigned unbundled:1;
+};
+
+#define REMOTE_BUNDLE_INFO_INIT { 0 }
+
+enum bundle_list_mode {
+ BUNDLE_MODE_NONE = 0,
+ BUNDLE_MODE_ALL,
+ BUNDLE_MODE_ANY
+};
+
+/**
+ * A bundle_list contains an unordered set of remote_bundle_info structs,
+ * as well as information about the bundle listing, such as version and
+ * mode.
+ */
+struct bundle_list {
+ int version;
+ enum bundle_list_mode mode;
+ struct hashmap bundles;
+};
+
+void init_bundle_list(struct bundle_list *list);
+void clear_bundle_list(struct bundle_list *list);
+
+typedef int (*bundle_iterator)(struct remote_bundle_info *bundle,
+ void *data);
+
+int for_all_bundles_in_list(struct bundle_list *list,
+ bundle_iterator iter,
+ void *data);
+
+struct FILE;
+void print_bundle_list(FILE *fp, struct bundle_list *list);
+
+/**
+ * A bundle URI may point to a bundle list where the key=value
+ * pairs are provided in config file format. This method is
+ * exposed publicly for testing purposes.
+ */
+int bundle_uri_parse_config_format(const char *uri,
+ const char *filename,
+ struct bundle_list *list);
+
+/**
+ * Fetch data from the given 'uri' and unbundle the bundle data found
+ * based on that information.
+ *
+ * Returns non-zero if no bundle information is found at the given 'uri'.
+ */
+int fetch_bundle_uri(struct repository *r, const char *uri);
+
+/**
+ * General API for {transport,connect}.c etc.
+ */
+
+/**
+ * Parse a "key=value" packet line from the bundle-uri verb.
+ *
+ * Returns 0 on success and non-zero on error.
+ */
+int bundle_uri_parse_line(struct bundle_list *list,
+ const char *line);
+
+#endif
diff --git a/bundle.c b/bundle.c
index 0208e6d90d3..4ef7256aa11 100644
--- a/bundle.c
+++ b/bundle.c
@@ -189,7 +189,7 @@ static int list_refs(struct string_list *r, int argc, const char **argv)
int verify_bundle(struct repository *r,
struct bundle_header *header,
- int verbose)
+ enum verify_bundle_flags flags)
{
/*
* Do fast check, then if any prereqs are missing then go line by line
@@ -202,10 +202,8 @@ int verify_bundle(struct repository *r,
int i, ret = 0, req_nr;
const char *message = _("Repository lacks these prerequisite commits:");
- if (!r || !r->objects || !r->objects->odb) {
- ret = error(_("need a repository to verify a bundle"));
- goto cleanup;
- }
+ if (!r || !r->objects || !r->objects->odb)
+ return error(_("need a repository to verify a bundle"));
repo_init_revisions(r, &revs, NULL);
for (i = 0; i < p->nr; i++) {
@@ -218,7 +216,10 @@ int verify_bundle(struct repository *r,
add_pending_object(&revs, o, name);
continue;
}
- if (++ret == 1)
+ ret++;
+ if (flags & VERIFY_BUNDLE_QUIET)
+ continue;
+ if (ret == 1)
error("%s", message);
error("%s %s", oid_to_hex(oid), name);
}
@@ -245,21 +246,15 @@ int verify_bundle(struct repository *r,
assert(o); /* otherwise we'd have returned early */
if (o->flags & SHOWN)
continue;
- if (++ret == 1)
+ ret++;
+ if (flags & VERIFY_BUNDLE_QUIET)
+ continue;
+ if (ret == 1)
error("%s", message);
error("%s %s", oid_to_hex(oid), name);
}
- /* Clean up objects used, as they will be reused. */
- for (i = 0; i < p->nr; i++) {
- struct string_list_item *e = p->items + i;
- struct object_id *oid = e->util;
- commit = lookup_commit_reference_gently(r, oid, 1);
- if (commit)
- clear_commit_marks(commit, ALL_REV_FLAGS);
- }
-
- if (verbose) {
+ if (flags & VERIFY_BUNDLE_VERBOSE) {
struct string_list *r;
r = &header->references;
@@ -287,6 +282,14 @@ int verify_bundle(struct repository *r,
list_objects_filter_spec(&header->filter));
}
cleanup:
+ /* Clean up objects used, as they will be reused. */
+ for (i = 0; i < p->nr; i++) {
+ struct string_list_item *e = p->items + i;
+ struct object_id *oid = e->util;
+ commit = lookup_commit_reference_gently(r, oid, 1);
+ if (commit)
+ clear_commit_marks(commit, ALL_REV_FLAGS | PREREQ_MARK);
+ }
release_revisions(&revs);
return ret;
}
@@ -620,7 +623,8 @@ err:
}
int unbundle(struct repository *r, struct bundle_header *header,
- int bundle_fd, struct strvec *extra_index_pack_args)
+ int bundle_fd, struct strvec *extra_index_pack_args,
+ enum verify_bundle_flags flags)
{
struct child_process ip = CHILD_PROCESS_INIT;
strvec_pushl(&ip.args, "index-pack", "--fix-thin", "--stdin", NULL);
@@ -634,7 +638,7 @@ int unbundle(struct repository *r, struct bundle_header *header,
strvec_clear(extra_index_pack_args);
}
- if (verify_bundle(r, header, 0))
+ if (verify_bundle(r, header, flags))
return -1;
ip.in = bundle_fd;
ip.no_stdout = 1;
diff --git a/bundle.h b/bundle.h
index 0c052f54964..9f2bd733a6a 100644
--- a/bundle.h
+++ b/bundle.h
@@ -18,6 +18,7 @@ struct bundle_header {
{ \
.prerequisites = STRING_LIST_INIT_DUP, \
.references = STRING_LIST_INIT_DUP, \
+ .filter = LIST_OBJECTS_FILTER_INIT, \
}
void bundle_header_init(struct bundle_header *header);
void bundle_header_release(struct bundle_header *header);
@@ -29,7 +30,14 @@ int read_bundle_header_fd(int fd, struct bundle_header *header,
int create_bundle(struct repository *r, const char *path,
int argc, const char **argv, struct strvec *pack_options,
int version);
-int verify_bundle(struct repository *r, struct bundle_header *header, int verbose);
+
+enum verify_bundle_flags {
+ VERIFY_BUNDLE_VERBOSE = (1 << 0),
+ VERIFY_BUNDLE_QUIET = (1 << 1),
+};
+
+int verify_bundle(struct repository *r, struct bundle_header *header,
+ enum verify_bundle_flags flags);
/**
* Unbundle after reading the header with read_bundle_header().
@@ -40,9 +48,13 @@ int verify_bundle(struct repository *r, struct bundle_header *header, int verbos
* Provide "extra_index_pack_args" to pass any extra arguments
* (e.g. "-v" for verbose/progress), NULL otherwise. The provided
* "extra_index_pack_args" (if any) will be strvec_clear()'d for you.
+ *
+ * Before unbundling, this method will call verify_bundle() with the
+ * given 'flags'.
*/
int unbundle(struct repository *r, struct bundle_header *header,
- int bundle_fd, struct strvec *extra_index_pack_args);
+ int bundle_fd, struct strvec *extra_index_pack_args,
+ enum verify_bundle_flags flags);
int list_bundle_refs(struct bundle_header *header,
int argc, const char **argv);
diff --git a/ci/lib.sh b/ci/lib.sh
index 1b0cc2b57db..24d20a5d648 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -259,6 +259,8 @@ macos-latest)
MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python3)"
else
MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python2)"
+ MAKEFLAGS="$MAKEFLAGS NO_APPLE_COMMON_CRYPTO=NoThanks"
+ MAKEFLAGS="$MAKEFLAGS NO_OPENSSL=NoThanks"
fi
;;
esac
@@ -278,6 +280,12 @@ linux-leaks)
export GIT_TEST_PASSING_SANITIZE_LEAK=true
export GIT_TEST_SANITIZE_LEAK_LOG=true
;;
+linux-asan)
+ export SANITIZE=address
+ ;;
+linux-ubsan)
+ export SANITIZE=undefined
+ ;;
esac
MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}"
diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
index 8ebff425967..a3ae5ff3972 100755
--- a/ci/run-build-and-tests.sh
+++ b/ci/run-build-and-tests.sh
@@ -45,10 +45,19 @@ pedantic)
;;
esac
-group Build make
+mc=
+if test "$jobname" = "linux-cmake-ctest"
+then
+ cb=contrib/buildsystems
+ group CMake cmake -S "$cb" -B "$cb/out"
+ mc="-C $cb/out"
+fi
+
+group Build make $mc
+
if test -n "$run_tests"
then
- group "Run tests" make test ||
+ group "Run tests" make $mc test ||
handle_failed_tests
fi
check_unignored_build_artifacts
diff --git a/color.c b/color.c
index 4f884c6b3dc..f05d8a81d72 100644
--- a/color.c
+++ b/color.c
@@ -415,7 +415,7 @@ int want_color_fd(int fd, int var)
return var;
}
-int git_color_config(const char *var, const char *value, void *cb)
+int git_color_config(const char *var, const char *value, void *cb UNUSED)
{
if (!strcmp(var, "color.ui")) {
git_use_color_default = git_config_colorbool(var, value);
diff --git a/command-list.txt b/command-list.txt
index f96bdabd7d9..54b2a50f5f1 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -91,6 +91,7 @@ git-cvsimport foreignscminterface
git-cvsserver foreignscminterface
git-daemon synchingrepositories
git-describe mainporcelain
+git-diagnose ancillaryinterrogators
git-diff mainporcelain info
git-diff-files plumbinginterrogators
git-diff-index plumbinginterrogators
@@ -198,6 +199,7 @@ git-var plumbinginterrogators
git-verify-commit ancillaryinterrogators
git-verify-pack plumbinginterrogators
git-verify-tag ancillaryinterrogators
+git-version ancillaryinterrogators
git-whatchanged ancillaryinterrogators complete
git-worktree mainporcelain
git-write-tree plumbingmanipulators
@@ -235,3 +237,4 @@ gittutorial guide
gittutorial-2 guide
gitweb ancillaryinterrogators
gitworkflows guide
+scalar mainporcelain
diff --git a/commit-graph.c b/commit-graph.c
index f2a36032f84..a7d87559328 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -901,7 +901,7 @@ struct commit *lookup_commit_in_graph(struct repository *repo, const struct obje
struct commit *commit;
uint32_t pos;
- if (!repo->objects->commit_graph)
+ if (!prepare_commit_graph(repo))
return NULL;
if (!search_commit_pos_in_graph(id, repo->objects->commit_graph, &pos))
return NULL;
@@ -1639,9 +1639,9 @@ struct refs_cb_data {
struct progress *progress;
};
-static int add_ref_to_set(const char *refname,
+static int add_ref_to_set(const char *refname UNUSED,
const struct object_id *oid,
- int flags, void *cb_data)
+ int flags UNUSED, void *cb_data)
{
struct object_id peeled;
struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
@@ -2265,6 +2265,8 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
}
out:
+ if(dir)
+ closedir(dir);
strbuf_release(&path);
}
diff --git a/commit.c b/commit.c
index 0db461f9735..572301b80a2 100644
--- a/commit.c
+++ b/commit.c
@@ -59,6 +59,14 @@ struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref
return c;
}
+struct commit *lookup_commit_object(struct repository *r,
+ const struct object_id *oid)
+{
+ struct object *obj = parse_object(r, oid);
+ return obj ? object_as_type(obj, OBJ_COMMIT, 0) : NULL;
+
+}
+
struct commit *lookup_commit(struct repository *r, const struct object_id *oid)
{
struct object *obj = lookup_object(r, oid);
@@ -951,8 +959,9 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs)
}
static int collect_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *ident, timestamp_t timestamp,
- int tz, const char *message, void *cbdata)
+ const char *ident UNUSED,
+ timestamp_t timestamp UNUSED, int tz UNUSED,
+ const char *message UNUSED, void *cbdata)
{
struct rev_collect *revs = cbdata;
diff --git a/commit.h b/commit.h
index 21e4d25ce78..fa39202fa6b 100644
--- a/commit.h
+++ b/commit.h
@@ -64,6 +64,19 @@ enum decoration_type {
void add_name_decoration(enum decoration_type type, const char *name, struct object *obj);
const struct name_decoration *get_name_decoration(const struct object *obj);
+/*
+ * Look up commit named by "oid" respecting replacement objects.
+ * Returns NULL if "oid" is not a commit or does not exist.
+ */
+struct commit *lookup_commit_object(struct repository *r, const struct object_id *oid);
+
+/*
+ * Look up commit named by "oid" without replacement objects or
+ * checking for object existence. Returns the requested commit if it
+ * is found in the object cache, NULL if "oid" is in the object cache
+ * but is not a commit and a newly allocated unparsed commit object if
+ * "oid" is not in the object cache.
+ */
struct commit *lookup_commit(struct repository *r, const struct object_id *oid);
struct commit *lookup_commit_reference(struct repository *r,
const struct object_id *oid);
diff --git a/common-main.c b/common-main.c
index c531372f3ff..0a22861f1ce 100644
--- a/common-main.c
+++ b/common-main.c
@@ -40,6 +40,7 @@ int main(int argc, const char **argv)
git_resolve_executable_dir(argv[0]);
+ setlocale(LC_CTYPE, "");
git_setup_gettext();
initialize_the_repository();
diff --git a/compat/fsmonitor/fsm-ipc-darwin.c b/compat/fsmonitor/fsm-ipc-darwin.c
new file mode 100644
index 00000000000..d67b0ee50d3
--- /dev/null
+++ b/compat/fsmonitor/fsm-ipc-darwin.c
@@ -0,0 +1,52 @@
+#include "cache.h"
+#include "config.h"
+#include "strbuf.h"
+#include "fsmonitor.h"
+#include "fsmonitor-ipc.h"
+#include "fsmonitor-path-utils.h"
+
+static GIT_PATH_FUNC(fsmonitor_ipc__get_default_path, "fsmonitor--daemon.ipc")
+
+const char *fsmonitor_ipc__get_path(struct repository *r)
+{
+ static const char *ipc_path = NULL;
+ git_SHA_CTX sha1ctx;
+ char *sock_dir = NULL;
+ struct strbuf ipc_file = STRBUF_INIT;
+ unsigned char hash[GIT_MAX_RAWSZ];
+
+ if (!r)
+ BUG("No repository passed into fsmonitor_ipc__get_path");
+
+ if (ipc_path)
+ return ipc_path;
+
+
+ /* By default the socket file is created in the .git directory */
+ if (fsmonitor__is_fs_remote(r->gitdir) < 1) {
+ ipc_path = fsmonitor_ipc__get_default_path();
+ return ipc_path;
+ }
+
+ git_SHA1_Init(&sha1ctx);
+ git_SHA1_Update(&sha1ctx, r->worktree, strlen(r->worktree));
+ git_SHA1_Final(hash, &sha1ctx);
+
+ repo_config_get_string(r, "fsmonitor.socketdir", &sock_dir);
+
+ /* Create the socket file in either socketDir or $HOME */
+ if (sock_dir && *sock_dir) {
+ strbuf_addf(&ipc_file, "%s/.git-fsmonitor-%s",
+ sock_dir, hash_to_hex(hash));
+ } else {
+ strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash));
+ }
+ free(sock_dir);
+
+ ipc_path = interpolate_path(ipc_file.buf, 1);
+ if (!ipc_path)
+ die(_("Invalid path: %s"), ipc_file.buf);
+
+ strbuf_release(&ipc_file);
+ return ipc_path;
+}
diff --git a/compat/fsmonitor/fsm-ipc-win32.c b/compat/fsmonitor/fsm-ipc-win32.c
new file mode 100644
index 00000000000..e08c505c148
--- /dev/null
+++ b/compat/fsmonitor/fsm-ipc-win32.c
@@ -0,0 +1,9 @@
+#include "config.h"
+#include "fsmonitor-ipc.h"
+
+const char *fsmonitor_ipc__get_path(struct repository *r) {
+ static char *ret;
+ if (!ret)
+ ret = git_pathdup("fsmonitor--daemon.ipc");
+ return ret;
+}
diff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c
index 8e208e8289e..daeee4e465c 100644
--- a/compat/fsmonitor/fsm-listen-darwin.c
+++ b/compat/fsmonitor/fsm-listen-darwin.c
@@ -26,6 +26,7 @@
#include "fsmonitor.h"
#include "fsm-listen.h"
#include "fsmonitor--daemon.h"
+#include "fsmonitor-path-utils.h"
struct fsm_listen_data
{
@@ -198,8 +199,9 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef,
struct string_list cookie_list = STRING_LIST_INIT_DUP;
const char *path_k;
const char *slash;
- int k;
+ char *resolved = NULL;
struct strbuf tmp = STRBUF_INIT;
+ int k;
/*
* Build a list of all filesystem changes into a private/local
@@ -209,7 +211,12 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef,
/*
* On Mac, we receive an array of absolute paths.
*/
- path_k = paths[k];
+ free(resolved);
+ resolved = fsmonitor__resolve_alias(paths[k], &state->alias);
+ if (resolved)
+ path_k = resolved;
+ else
+ path_k = paths[k];
/*
* If you want to debug FSEvents, log them to GIT_TRACE_FSMONITOR.
@@ -238,6 +245,7 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef,
fsmonitor_force_resync(state);
fsmonitor_batch__free_list(batch);
string_list_clear(&cookie_list, 0);
+ batch = NULL;
/*
* We assume that any events that we received
@@ -360,12 +368,14 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef,
}
}
+ free(resolved);
fsmonitor_publish(state, batch, &cookie_list);
string_list_clear(&cookie_list, 0);
strbuf_release(&tmp);
return;
force_shutdown:
+ free(resolved);
fsmonitor_batch__free_list(batch);
string_list_clear(&cookie_list, 0);
diff --git a/compat/fsmonitor/fsm-path-utils-darwin.c b/compat/fsmonitor/fsm-path-utils-darwin.c
new file mode 100644
index 00000000000..ce5a8febe09
--- /dev/null
+++ b/compat/fsmonitor/fsm-path-utils-darwin.c
@@ -0,0 +1,135 @@
+#include "fsmonitor.h"
+#include "fsmonitor-path-utils.h"
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
+{
+ struct statfs fs;
+ if (statfs(path, &fs) == -1) {
+ int saved_errno = errno;
+ trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s",
+ path, strerror(saved_errno));
+ errno = saved_errno;
+ return -1;
+ }
+
+ trace_printf_key(&trace_fsmonitor,
+ "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'",
+ path, fs.f_type, fs.f_flags, fs.f_fstypename);
+
+ if (!(fs.f_flags & MNT_LOCAL))
+ fs_info->is_remote = 1;
+ else
+ fs_info->is_remote = 0;
+
+ fs_info->typename = xstrdup(fs.f_fstypename);
+
+ trace_printf_key(&trace_fsmonitor,
+ "'%s' is_remote: %d",
+ path, fs_info->is_remote);
+ return 0;
+}
+
+int fsmonitor__is_fs_remote(const char *path)
+{
+ struct fs_info fs;
+ if (fsmonitor__get_fs_info(path, &fs))
+ return -1;
+
+ free(fs.typename);
+
+ return fs.is_remote;
+}
+
+/*
+ * Scan the root directory for synthetic firmlinks that when resolved
+ * are a prefix of the path, stopping at the first one found.
+ *
+ * Some information about firmlinks and synthetic firmlinks:
+ * https://eclecticlight.co/2020/01/23/catalina-boot-volumes/
+ *
+ * macOS no longer allows symlinks in the root directory; any link found
+ * there is therefore a synthetic firmlink.
+ *
+ * If this function gets called often, will want to cache all the firmlink
+ * information, but for now there is only one caller of this function.
+ *
+ * If there is more than one alias for the path, that is another
+ * matter altogether.
+ */
+int fsmonitor__get_alias(const char *path, struct alias_info *info)
+{
+ DIR *dir;
+ int retval = -1;
+ const char *const root = "/";
+ struct stat st;
+ struct dirent *de;
+ struct strbuf alias;
+ struct strbuf points_to = STRBUF_INIT;
+
+ dir = opendir(root);
+ if (!dir)
+ return error_errno(_("opendir('%s') failed"), root);
+
+ strbuf_init(&alias, 256);
+
+ while ((de = readdir(dir)) != NULL) {
+ strbuf_reset(&alias);
+ strbuf_addf(&alias, "%s%s", root, de->d_name);
+
+ if (lstat(alias.buf, &st) < 0) {
+ error_errno(_("lstat('%s') failed"), alias.buf);
+ goto done;
+ }
+
+ if (!S_ISLNK(st.st_mode))
+ continue;
+
+ if (strbuf_readlink(&points_to, alias.buf, st.st_size) < 0) {
+ error_errno(_("strbuf_readlink('%s') failed"), alias.buf);
+ goto done;
+ }
+
+ if (!strncmp(points_to.buf, path, points_to.len) &&
+ (path[points_to.len] == '/')) {
+ strbuf_addbuf(&info->alias, &alias);
+ strbuf_addbuf(&info->points_to, &points_to);
+ trace_printf_key(&trace_fsmonitor,
+ "Found alias for '%s' : '%s' -> '%s'",
+ path, info->alias.buf, info->points_to.buf);
+ retval = 0;
+ goto done;
+ }
+ }
+ retval = 0; /* no alias */
+
+done:
+ strbuf_release(&alias);
+ strbuf_release(&points_to);
+ if (closedir(dir) < 0)
+ return error_errno(_("closedir('%s') failed"), root);
+ return retval;
+}
+
+char *fsmonitor__resolve_alias(const char *path,
+ const struct alias_info *info)
+{
+ if (!info->alias.len)
+ return NULL;
+
+ if ((!strncmp(info->alias.buf, path, info->alias.len))
+ && path[info->alias.len] == '/') {
+ struct strbuf tmp = STRBUF_INIT;
+ const char *remainder = path + info->alias.len;
+
+ strbuf_addbuf(&tmp, &info->points_to);
+ strbuf_add(&tmp, remainder, strlen(remainder));
+ return strbuf_detach(&tmp, NULL);
+ }
+
+ return NULL;
+}
diff --git a/compat/fsmonitor/fsm-path-utils-win32.c b/compat/fsmonitor/fsm-path-utils-win32.c
new file mode 100644
index 00000000000..0d95bbb416f
--- /dev/null
+++ b/compat/fsmonitor/fsm-path-utils-win32.c
@@ -0,0 +1,145 @@
+#include "cache.h"
+#include "fsmonitor.h"
+#include "fsmonitor-path-utils.h"
+
+/*
+ * Check remote working directory protocol.
+ *
+ * Return -1 if client machine cannot get remote protocol information.
+ */
+static int check_remote_protocol(wchar_t *wpath)
+{
+ HANDLE h;
+ FILE_REMOTE_PROTOCOL_INFO proto_info;
+
+ h = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+ if (h == INVALID_HANDLE_VALUE) {
+ error(_("[GLE %ld] unable to open for read '%ls'"),
+ GetLastError(), wpath);
+ return -1;
+ }
+
+ if (!GetFileInformationByHandleEx(h, FileRemoteProtocolInfo,
+ &proto_info, sizeof(proto_info))) {
+ error(_("[GLE %ld] unable to get protocol information for '%ls'"),
+ GetLastError(), wpath);
+ CloseHandle(h);
+ return -1;
+ }
+
+ CloseHandle(h);
+
+ trace_printf_key(&trace_fsmonitor,
+ "check_remote_protocol('%ls') remote protocol %#8.8lx",
+ wpath, proto_info.Protocol);
+
+ return 0;
+}
+
+/*
+ * Notes for testing:
+ *
+ * (a) Windows allows a network share to be mapped to a drive letter.
+ * (This is the normal method to access it.)
+ *
+ * $ NET USE Z: \\server\share
+ * $ git -C Z:/repo status
+ *
+ * (b) Windows allows a network share to be referenced WITHOUT mapping
+ * it to drive letter.
+ *
+ * $ NET USE \\server\share\dir
+ * $ git -C //server/share/repo status
+ *
+ * (c) Windows allows "SUBST" to create a fake drive mapping to an
+ * arbitrary path (which may be remote)
+ *
+ * $ SUBST Q: Z:\repo
+ * $ git -C Q:/ status
+ *
+ * (d) Windows allows a directory symlink to be created on a local
+ * file system that points to a remote repo.
+ *
+ * $ mklink /d ./link //server/share/repo
+ * $ git -C ./link status
+ */
+int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
+{
+ wchar_t wpath[MAX_PATH];
+ wchar_t wfullpath[MAX_PATH];
+ size_t wlen;
+ UINT driveType;
+
+ /*
+ * Do everything in wide chars because the drive letter might be
+ * a multi-byte sequence. See win32_has_dos_drive_prefix().
+ */
+ if (xutftowcs_path(wpath, path) < 0) {
+ return -1;
+ }
+
+ /*
+ * GetDriveTypeW() requires a final slash. We assume that the
+ * worktree pathname points to an actual directory.
+ */
+ wlen = wcslen(wpath);
+ if (wpath[wlen - 1] != L'\\' && wpath[wlen - 1] != L'/') {
+ wpath[wlen++] = L'\\';
+ wpath[wlen] = 0;
+ }
+
+ /*
+ * Normalize the path. If nothing else, this converts forward
+ * slashes to backslashes. This is essential to get GetDriveTypeW()
+ * correctly handle some UNC "\\server\share\..." paths.
+ */
+ if (!GetFullPathNameW(wpath, MAX_PATH, wfullpath, NULL)) {
+ return -1;
+ }
+
+ driveType = GetDriveTypeW(wfullpath);
+ trace_printf_key(&trace_fsmonitor,
+ "DriveType '%s' L'%ls' (%u)",
+ path, wfullpath, driveType);
+
+ if (driveType == DRIVE_REMOTE) {
+ fs_info->is_remote = 1;
+ if (check_remote_protocol(wfullpath) < 0)
+ return -1;
+ } else {
+ fs_info->is_remote = 0;
+ }
+
+ trace_printf_key(&trace_fsmonitor,
+ "'%s' is_remote: %d",
+ path, fs_info->is_remote);
+
+ return 0;
+}
+
+int fsmonitor__is_fs_remote(const char *path)
+{
+ struct fs_info fs;
+ if (fsmonitor__get_fs_info(path, &fs))
+ return -1;
+ return fs.is_remote;
+}
+
+/*
+ * No-op for now.
+ */
+int fsmonitor__get_alias(const char *path, struct alias_info *info)
+{
+ return 0;
+}
+
+/*
+ * No-op for now.
+ */
+char *fsmonitor__resolve_alias(const char *path,
+ const struct alias_info *info)
+{
+ return NULL;
+}
diff --git a/compat/fsmonitor/fsm-settings-darwin.c b/compat/fsmonitor/fsm-settings-darwin.c
index efc732c0f31..6abbc7af3ab 100644
--- a/compat/fsmonitor/fsm-settings-darwin.c
+++ b/compat/fsmonitor/fsm-settings-darwin.c
@@ -1,32 +1,10 @@
-#include "cache.h"
#include "config.h"
-#include "repository.h"
-#include "fsmonitor-settings.h"
#include "fsmonitor.h"
-#include <sys/param.h>
-#include <sys/mount.h>
+#include "fsmonitor-ipc.h"
+#include "fsmonitor-settings.h"
+#include "fsmonitor-path-utils.h"
-/*
- * [1] Remote working directories are problematic for FSMonitor.
- *
- * The underlying file system on the server machine and/or the remote
- * mount type (NFS, SAMBA, etc.) dictates whether notification events
- * are available at all to remote client machines.
- *
- * Kernel differences between the server and client machines also
- * dictate the how (buffering, frequency, de-dup) the events are
- * delivered to client machine processes.
- *
- * A client machine (such as a laptop) may choose to suspend/resume
- * and it is unclear (without lots of testing) whether the watcher can
- * resync after a resume. We might be able to treat this as a normal
- * "events were dropped by the kernel" event and do our normal "flush
- * and resync" --or-- we might need to close the existing (zombie?)
- * notification fd and create a new one.
- *
- * In theory, the above issues need to be addressed whether we are
- * using the Hook or IPC API.
- *
+ /*
* For the builtin FSMonitor, we create the Unix domain socket for the
* IPC in the .git directory. If the working directory is remote,
* then the socket will be created on the remote file system. This
@@ -38,52 +16,47 @@
* be taken to ensure that $HOME is actually local and not a managed
* file share.)
*
- * So (for now at least), mark remote working directories as
- * incompatible.
- *
- *
- * [2] FAT32 and NTFS working directories are problematic too.
+ * FAT32 and NTFS working directories are problematic too.
*
* The builtin FSMonitor uses a Unix domain socket in the .git
* directory for IPC. These Windows drive formats do not support
* Unix domain sockets, so mark them as incompatible for the daemon.
*
*/
-static enum fsmonitor_reason check_volume(struct repository *r)
+static enum fsmonitor_reason check_uds_volume(struct repository *r)
{
- struct statfs fs;
+ struct fs_info fs;
+ const char *ipc_path = fsmonitor_ipc__get_path(r);
+ struct strbuf path = STRBUF_INIT;
+ strbuf_add(&path, ipc_path, strlen(ipc_path));
- if (statfs(r->worktree, &fs) == -1) {
- int saved_errno = errno;
- trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s",
- r->worktree, strerror(saved_errno));
- errno = saved_errno;
+ if (fsmonitor__get_fs_info(dirname(path.buf), &fs) == -1) {
+ strbuf_release(&path);
return FSMONITOR_REASON_ERROR;
}
- trace_printf_key(&trace_fsmonitor,
- "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'",
- r->worktree, fs.f_type, fs.f_flags, fs.f_fstypename);
+ strbuf_release(&path);
- if (!(fs.f_flags & MNT_LOCAL))
- return FSMONITOR_REASON_REMOTE;
-
- if (!strcmp(fs.f_fstypename, "msdos")) /* aka FAT32 */
- return FSMONITOR_REASON_NOSOCKETS;
-
- if (!strcmp(fs.f_fstypename, "ntfs"))
+ if (fs.is_remote ||
+ !strcmp(fs.typename, "msdos") ||
+ !strcmp(fs.typename, "ntfs")) {
+ free(fs.typename);
return FSMONITOR_REASON_NOSOCKETS;
+ }
+ free(fs.typename);
return FSMONITOR_REASON_OK;
}
-enum fsmonitor_reason fsm_os__incompatible(struct repository *r)
+enum fsmonitor_reason fsm_os__incompatible(struct repository *r, int ipc)
{
enum fsmonitor_reason reason;
- reason = check_volume(r);
- if (reason != FSMONITOR_REASON_OK)
- return reason;
+ if (ipc) {
+ reason = check_uds_volume(r);
+ if (reason != FSMONITOR_REASON_OK)
+ return reason;
+ }
return FSMONITOR_REASON_OK;
}
diff --git a/compat/fsmonitor/fsm-settings-win32.c b/compat/fsmonitor/fsm-settings-win32.c
index 907655720bb..a8af31b71de 100644
--- a/compat/fsmonitor/fsm-settings-win32.c
+++ b/compat/fsmonitor/fsm-settings-win32.c
@@ -1,8 +1,9 @@
#include "cache.h"
#include "config.h"
#include "repository.h"
-#include "fsmonitor-settings.h"
#include "fsmonitor.h"
+#include "fsmonitor-settings.h"
+#include "fsmonitor-path-utils.h"
/*
* VFS for Git is incompatible with FSMonitor.
@@ -24,104 +25,7 @@ static enum fsmonitor_reason check_vfs4git(struct repository *r)
return FSMONITOR_REASON_OK;
}
-/*
- * Remote working directories are problematic for FSMonitor.
- *
- * The underlying file system on the server machine and/or the remote
- * mount type dictates whether notification events are available at
- * all to remote client machines.
- *
- * Kernel differences between the server and client machines also
- * dictate the how (buffering, frequency, de-dup) the events are
- * delivered to client machine processes.
- *
- * A client machine (such as a laptop) may choose to suspend/resume
- * and it is unclear (without lots of testing) whether the watcher can
- * resync after a resume. We might be able to treat this as a normal
- * "events were dropped by the kernel" event and do our normal "flush
- * and resync" --or-- we might need to close the existing (zombie?)
- * notification fd and create a new one.
- *
- * In theory, the above issues need to be addressed whether we are
- * using the Hook or IPC API.
- *
- * So (for now at least), mark remote working directories as
- * incompatible.
- *
- * Notes for testing:
- *
- * (a) Windows allows a network share to be mapped to a drive letter.
- * (This is the normal method to access it.)
- *
- * $ NET USE Z: \\server\share
- * $ git -C Z:/repo status
- *
- * (b) Windows allows a network share to be referenced WITHOUT mapping
- * it to drive letter.
- *
- * $ NET USE \\server\share\dir
- * $ git -C //server/share/repo status
- *
- * (c) Windows allows "SUBST" to create a fake drive mapping to an
- * arbitrary path (which may be remote)
- *
- * $ SUBST Q: Z:\repo
- * $ git -C Q:/ status
- *
- * (d) Windows allows a directory symlink to be created on a local
- * file system that points to a remote repo.
- *
- * $ mklink /d ./link //server/share/repo
- * $ git -C ./link status
- */
-static enum fsmonitor_reason check_remote(struct repository *r)
-{
- wchar_t wpath[MAX_PATH];
- wchar_t wfullpath[MAX_PATH];
- size_t wlen;
- UINT driveType;
-
- /*
- * Do everything in wide chars because the drive letter might be
- * a multi-byte sequence. See win32_has_dos_drive_prefix().
- */
- if (xutftowcs_path(wpath, r->worktree) < 0)
- return FSMONITOR_REASON_ERROR;
-
- /*
- * GetDriveTypeW() requires a final slash. We assume that the
- * worktree pathname points to an actual directory.
- */
- wlen = wcslen(wpath);
- if (wpath[wlen - 1] != L'\\' && wpath[wlen - 1] != L'/') {
- wpath[wlen++] = L'\\';
- wpath[wlen] = 0;
- }
-
- /*
- * Normalize the path. If nothing else, this converts forward
- * slashes to backslashes. This is essential to get GetDriveTypeW()
- * correctly handle some UNC "\\server\share\..." paths.
- */
- if (!GetFullPathNameW(wpath, MAX_PATH, wfullpath, NULL))
- return FSMONITOR_REASON_ERROR;
-
- driveType = GetDriveTypeW(wfullpath);
- trace_printf_key(&trace_fsmonitor,
- "DriveType '%s' L'%ls' (%u)",
- r->worktree, wfullpath, driveType);
-
- if (driveType == DRIVE_REMOTE) {
- trace_printf_key(&trace_fsmonitor,
- "check_remote('%s') true",
- r->worktree);
- return FSMONITOR_REASON_REMOTE;
- }
-
- return FSMONITOR_REASON_OK;
-}
-
-enum fsmonitor_reason fsm_os__incompatible(struct repository *r)
+enum fsmonitor_reason fsm_os__incompatible(struct repository *r, int ipc)
{
enum fsmonitor_reason reason;
@@ -129,9 +33,5 @@ enum fsmonitor_reason fsm_os__incompatible(struct repository *r)
if (reason != FSMONITOR_REASON_OK)
return reason;
- reason = check_remote(r);
- if (reason != FSMONITOR_REASON_OK)
- return reason;
-
return FSMONITOR_REASON_OK;
}
diff --git a/compat/mingw.c b/compat/mingw.c
index 901375d5841..d614f156df1 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -196,16 +196,19 @@ static int read_yes_no_answer(void)
static int ask_yes_no_if_possible(const char *format, ...)
{
char question[4096];
- const char *retry_hook[] = { NULL, NULL, NULL };
+ const char *retry_hook;
va_list args;
va_start(args, format);
vsnprintf(question, sizeof(question), format, args);
va_end(args);
- if ((retry_hook[0] = mingw_getenv("GIT_ASK_YESNO"))) {
- retry_hook[1] = question;
- return !run_command_v_opt(retry_hook, 0);
+ retry_hook = mingw_getenv("GIT_ASK_YESNO");
+ if (retry_hook) {
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&cmd.args, retry_hook, question, NULL);
+ return !run_command(&cmd);
}
if (!isatty(_fileno(stdin)) || !isatty(_fileno(stderr)))
diff --git a/compat/nonblock.c b/compat/nonblock.c
index 9694ebdb1d7..5b51195c32f 100644
--- a/compat/nonblock.c
+++ b/compat/nonblock.c
@@ -41,7 +41,7 @@ int enable_pipe_nonblock(int fd)
#else
-int enable_pipe_nonblock(int fd)
+int enable_pipe_nonblock(int fd UNUSED)
{
errno = ENOSYS;
return -1;
diff --git a/compat/terminal.c b/compat/terminal.c
index 7db330c52dc..ea490a7ced4 100644
--- a/compat/terminal.c
+++ b/compat/terminal.c
@@ -477,7 +477,7 @@ struct escape_sequence_entry {
char sequence[FLEX_ARRAY];
};
-static int sequence_entry_cmp(const void *hashmap_cmp_fn_data,
+static int sequence_entry_cmp(const void *hashmap_cmp_fn_data UNUSED,
const struct escape_sequence_entry *e1,
const struct escape_sequence_entry *e2,
const void *keydata)
diff --git a/config.c b/config.c
index e8ebef77d5c..c058b2c70c3 100644
--- a/config.c
+++ b/config.c
@@ -362,7 +362,8 @@ static void populate_remote_urls(struct config_include_data *inc)
current_parsing_scope = store_scope;
}
-static int forbid_remote_url(const char *var, const char *value, void *data)
+static int forbid_remote_url(const char *var, const char *value UNUSED,
+ void *data UNUSED)
{
const char *remote_name;
size_t remote_name_len;
@@ -1214,7 +1215,7 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
return 0;
}
-static int git_parse_int(const char *value, int *ret)
+int git_parse_int(const char *value, int *ret)
{
intmax_t tmp;
if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))
@@ -2337,10 +2338,10 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
return 0;
}
-static int config_set_element_cmp(const void *unused_cmp_data,
+static int config_set_element_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct config_set_element *e1, *e2;
@@ -2391,11 +2392,6 @@ int git_configset_add_file(struct config_set *cs, const char *filename)
return git_config_from_file(config_set_callback, filename, cs);
}
-int git_configset_add_parameters(struct config_set *cs)
-{
- return git_config_from_parameters(config_set_callback, cs);
-}
-
int git_configset_get_value(struct config_set *cs, const char *key, const char **value)
{
const struct string_list *values = NULL;
@@ -2640,24 +2636,15 @@ int repo_config_get_pathname(struct repository *repo,
/* Read values into protected_config. */
static void read_protected_config(void)
{
- char *xdg_config = NULL, *user_config = NULL, *system_config = NULL;
-
+ struct config_options opts = {
+ .respect_includes = 1,
+ .ignore_repo = 1,
+ .ignore_worktree = 1,
+ .system_gently = 1,
+ };
git_configset_init(&protected_config);
-
- system_config = git_system_config();
- git_global_config(&user_config, &xdg_config);
-
- if (system_config)
- git_configset_add_file(&protected_config, system_config);
- if (xdg_config)
- git_configset_add_file(&protected_config, xdg_config);
- if (user_config)
- git_configset_add_file(&protected_config, user_config);
- git_configset_add_parameters(&protected_config);
-
- free(system_config);
- free(xdg_config);
- free(user_config);
+ config_with_options(config_set_callback, &protected_config,
+ NULL, &opts);
}
void git_protected_config(config_fn_t fn, void *data)
diff --git a/config.h b/config.h
index ca994d77147..ef9eade6414 100644
--- a/config.h
+++ b/config.h
@@ -206,6 +206,7 @@ int config_with_options(config_fn_t fn, void *,
int git_parse_ssize_t(const char *, ssize_t *);
int git_parse_ulong(const char *, unsigned long *);
+int git_parse_int(const char *value, int *ret);
/**
* Same as `git_config_bool`, except that it returns -1 on error rather
diff --git a/config.mak.dev b/config.mak.dev
index 4fa19d361b7..981304727c5 100644
--- a/config.mak.dev
+++ b/config.mak.dev
@@ -69,6 +69,31 @@ DEVELOPER_CFLAGS += -Wno-missing-braces
endif
endif
+# Old versions of clang complain about initializaing a
+# struct-within-a-struct using just "{0}" rather than "{{0}}". This
+# error is considered a false-positive and not worth fixing, because
+# new clang versions do not, so just disable it.
+#
+# The "bug" was fixed in upstream clang 9.
+#
+# Complicating this is that versions of clang released by Apple have
+# their own version numbers (associated with the corresponding version
+# of XCode) unrelated to the official clang version numbers.
+#
+# The bug was fixed in Apple clang 12.
+#
+ifneq ($(filter clang1,$(COMPILER_FEATURES)),) # if we are using clang
+ifeq ($(uname_S),Darwin) # if we are on darwin
+ifeq ($(filter clang12,$(COMPILER_FEATURES)),) # if version < 12
+DEVELOPER_CFLAGS += -Wno-missing-braces
+endif
+else # not darwin
+ifeq ($(filter clang9,$(COMPILER_FEATURES)),) # if version < 9
+DEVELOPER_CFLAGS += -Wno-missing-braces
+endif
+endif
+endif
+
# https://bugzilla.redhat.com/show_bug.cgi?id=2075786
ifneq ($(filter gcc12,$(COMPILER_FEATURES)),)
DEVELOPER_CFLAGS += -Wno-error=stringop-overread
diff --git a/configure.ac b/configure.ac
index 7dcd0482042..38ff86678a0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -237,9 +237,6 @@ AC_MSG_NOTICE([CHECKS for site configuration])
# tests. These tests take up a significant amount of the total test time
# but are not needed unless you plan to talk to SVN repos.
#
-# Define PPC_SHA1 environment variable when running make to make use of
-# a bundled SHA1 routine optimized for PowerPC.
-#
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
#
# Define OPENSSLDIR=/foo/bar if your openssl header and library files are in
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 2237109b57f..ea1bd9602e2 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -4,25 +4,67 @@
#[[
-Instructions how to use this in Visual Studio:
+== Overview ==
+
+The top-level Makefile is Git's primary build environment, and a lot
+of things are missing (and probably always will be) from this CMake
+alternative.
+
+The primary use-case for maintaining this CMake build recipe is to
+have nicer IDE integration on Windows.
+
+== Creating a build recipe ==
+
+The "cmake" command creates a build file from this recipe:
+
+ cmake -S contrib/buildsystems -B contrib/buildsystems/out -DCMAKE_BUILD_TYPE=Release
+
+Running this will create files in the contrib/buildsystems/out
+directory (our top-level .gitignore file knows to ignore contents of
+this directory).
+
+See "cmake options" below for a discussion of
+"-DCMAKE_BUILD_TYPE=Release" and other options to "cmake".
+
+== Building with Visual Visual Studio ==
+
+To use this in Visual Studio:
Open the worktree as a folder. Visual Studio 2019 and later will detect
the CMake configuration automatically and set everything up for you,
-ready to build. You can then run the tests in `t/` via a regular Git Bash.
+ready to build. See "== Running the tests ==" below for running the tests.
Note: Visual Studio also has the option of opening `CMakeLists.txt`
directly; Using this option, Visual Studio will not find the source code,
though, therefore the `File>Open>Folder...` option is preferred.
-Instructions to run CMake manually:
+By default CMake will install vcpkg locally to your source tree on configuration,
+to avoid this, add `-DNO_VCPKG=TRUE` to the command line when configuring.
+
+== Building on Windows without Visual Studio ==
- mkdir -p contrib/buildsystems/out
- cd contrib/buildsystems/out
- cmake ../ -DCMAKE_BUILD_TYPE=Release
+Open contrib/buildsystems/git.sln and build Git. Or use the "msbuild"
+command-line tool (see our own ".github/workflows/main.yml" for a real
+example):
-This will build the git binaries in contrib/buildsystems/out
-directory (our top-level .gitignore file knows to ignore contents of
-this directory).
+ msbuild git.sln
+
+== Building on *nix ==
+
+On all other platforms running "cmake" will generate a Makefile; to
+build with it run:
+
+ make -C contrib/buildsystems/out
+
+It's also possible to use other generators, e.g. Ninja has arguably
+slightly better output. Add "-G Ninja" to the cmake command above,
+then:
+
+ ninja -C contrib/buildsystems/out
+
+== cmake options ==
+
+=== -DCMAKE_BUILD_TYPE=<type> ===
Possible build configurations(-DCMAKE_BUILD_TYPE) with corresponding
compiler flags
@@ -35,17 +77,36 @@ empty(default) :
NOTE: -DCMAKE_BUILD_TYPE is optional. For multi-config generators like Visual Studio
this option is ignored
-This process generates a Makefile(Linux/*BSD/MacOS) , Visual Studio solution(Windows) by default.
-Run `make` to build Git on Linux/*BSD/MacOS.
-Open git.sln on Windows and build Git.
+== Running the tests ==
-NOTE: By default CMake uses Makefile as the build tool on Linux and Visual Studio in Windows,
-to use another tool say `ninja` add this to the command line when configuring.
-`-G Ninja`
+Once we've built in "contrib/buildsystems/out" the tests can be run at
+the top-level (note: not the generated "contrib/buildsystems/out/t/"
+drectory). If no top-level build is found (as created with the
+Makefile) the t/test-lib.sh will discover the git in
+"contrib/buildsystems/out" on e.g.:
-NOTE: By default CMake will install vcpkg locally to your source tree on configuration,
-to avoid this, add `-DNO_VCPKG=TRUE` to the command line when configuring.
+ (cd t && ./t0001-init.sh)
+ setup: had no ../git, but found & used cmake built git in ../contrib/buildsystems/out/git
+ [...]
+
+The tests can also be run with ctest, e.g. after building with "cmake"
+and "make" or "msbuild" run, from the top-level e.g.:
+ # "--test-dir" is new in cmake v3.20, so "(cd
+ # contrib/buildsystems/out && ctest ...)" on older versions.
+ ctest --test-dir contrib/buildsystems/out --jobs="$(nproc)"--output-on-failure
+
+Options can be passed by setting GIT_TEST_OPTIONS before invoking
+cmake. E.g. on a Linux system with systemd the tests can be sped up by
+using a ramdisk for the scratch files:
+
+ GIT_TEST_OPTS="--root=/dev/shm/$(id -u)/ctest" cmake -S contrib/buildsystems -B contrib/buildsystems/out
+ [...]
+ -- Using user-selected test options: --root=/dev/shm/<uid>/ctest
+
+Then running the tests with "ctest" (here with --jobs="$(nproc)"):
+
+ ctest --jobs=$(nproc) --test-dir contrib/buildsystems/out
]]
cmake_minimum_required(VERSION 3.14)
@@ -77,10 +138,17 @@ if(USE_VCPKG)
set(CMAKE_TOOLCHAIN_FILE ${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file")
endif()
-find_program(SH_EXE sh PATHS "C:/Program Files/Git/bin" "$ENV{LOCALAPPDATA}/Programs/Git/bin")
-if(NOT SH_EXE)
- message(FATAL_ERROR "sh: shell interpreter was not found in your path, please install one."
- "On Windows, you can get it as part of 'Git for Windows' install at https://gitforwindows.org/")
+if(WIN32)
+ find_program(SH_EXE sh PATHS "C:/Program Files/Git/bin" "$ENV{LOCALAPPDATA}/Programs/Git/bin")
+ if(NOT SH_EXE)
+ message(FATAL_ERROR "sh: shell interpreter was not found in your path, please install one."
+ "You can get it as part of 'Git for Windows' install at https://gitforwindows.org/")
+ endif()
+else()
+ find_program(SH_EXE sh)
+ if(NOT SH_EXE)
+ message(FATAL_ERROR "cannot find 'sh' in '$PATH'")
+ endif()
endif()
#Create GIT-VERSION-FILE using GIT-VERSION-GEN
@@ -308,6 +376,8 @@ if(SUPPORTS_SIMPLE_IPC)
add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND)
list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-win32.c)
list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-win32.c)
+ list(APPEND compat_SOURCES compat/fsmonitor/fsm-ipc-win32.c)
+ list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-win32.c)
add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS)
list(APPEND compat_SOURCES compat/fsmonitor/fsm-settings-win32.c)
@@ -315,6 +385,8 @@ if(SUPPORTS_SIMPLE_IPC)
add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND)
list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-darwin.c)
list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-darwin.c)
+ list(APPEND compat_SOURCES compat/fsmonitor/fsm-ipc-darwin.c)
+ list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-darwin.c)
add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS)
list(APPEND compat_SOURCES compat/fsmonitor/fsm-settings-darwin.c)
@@ -610,7 +682,7 @@ unset(CMAKE_REQUIRED_INCLUDES)
#programs
set(PROGRAMS_BUILT
git git-daemon git-http-backend git-sh-i18n--envsubst
- git-shell)
+ git-shell scalar)
if(NOT CURL_FOUND)
list(APPEND excluded_progs git-http-fetch git-http-push)
@@ -757,6 +829,9 @@ target_link_libraries(git-sh-i18n--envsubst common-main)
add_executable(git-shell ${CMAKE_SOURCE_DIR}/shell.c)
target_link_libraries(git-shell common-main)
+add_executable(scalar ${CMAKE_SOURCE_DIR}/scalar.c)
+target_link_libraries(scalar common-main)
+
if(CURL_FOUND)
add_library(http_obj OBJECT ${CMAKE_SOURCE_DIR}/http.c)
@@ -803,6 +878,19 @@ add_custom_command(OUTPUT ${git_links} ${git_http_links}
DEPENDS git git-remote-http)
add_custom_target(git-links ALL DEPENDS ${git_links} ${git_http_links})
+function(write_script path content)
+ file(WRITE ${path} ${content})
+
+ if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER_EQUAL "3.19")
+ file(CHMOD ${path} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+ else()
+ execute_process(COMMAND chmod +x ${path}
+ RESULT_VARIABLE CHILD_ERROR)
+ if(CHILD_ERROR)
+ message(FATAL_ERROR "failed to chmod +x '${path}': '${CHILD_ERROR}'")
+ endif()
+ endif()
+endfunction()
#creating required scripts
set(SHELL_PATH /bin/sh)
@@ -828,7 +916,7 @@ foreach(script ${git_shell_scripts})
string(REPLACE "# @@BROKEN_PATH_FIX@@" "" content "${content}")
string(REPLACE "@@PERL@@" "${PERL_PATH}" content "${content}")
string(REPLACE "@@PAGER_ENV@@" "LESS=FRX LV=-c" content "${content}")
- file(WRITE ${CMAKE_BINARY_DIR}/${script} ${content})
+ write_script(${CMAKE_BINARY_DIR}/${script} "${content}")
endforeach()
#perl scripts
@@ -843,13 +931,14 @@ foreach(script ${git_perl_scripts})
file(STRINGS ${CMAKE_SOURCE_DIR}/${script}.perl content NEWLINE_CONSUME)
string(REPLACE "#!/usr/bin/perl" "#!/usr/bin/perl\n${perl_header}\n" content "${content}")
string(REPLACE "@@GIT_VERSION@@" "${PROJECT_VERSION}" content "${content}")
- file(WRITE ${CMAKE_BINARY_DIR}/${script} ${content})
+ write_script(${CMAKE_BINARY_DIR}/${script} "${content}")
endforeach()
#python script
file(STRINGS ${CMAKE_SOURCE_DIR}/git-p4.py content NEWLINE_CONSUME)
string(REPLACE "#!/usr/bin/env python" "#!/usr/bin/python" content "${content}")
-file(WRITE ${CMAKE_BINARY_DIR}/git-p4 ${content})
+write_script(${CMAKE_BINARY_DIR}/git-p4 "${content}")
+file(COPY ${CMAKE_SOURCE_DIR}/git-p4.py DESTINATION ${CMAKE_BINARY_DIR}/)
#perl modules
file(GLOB_RECURSE perl_modules "${CMAKE_SOURCE_DIR}/perl/*.pm")
@@ -890,7 +979,7 @@ if(MSGFMT_EXE)
foreach(po ${po_files})
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo
- COMMAND ${MSGFMT_EXE} --check --statistics -o ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo ${CMAKE_SOURCE_DIR}/po/${po}.po)
+ COMMAND ${MSGFMT_EXE} --check -o ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo ${CMAKE_SOURCE_DIR}/po/${po}.po)
list(APPEND po_gen ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo)
endforeach()
add_custom_target(po-gen ALL DEPENDS ${po_gen})
@@ -903,7 +992,7 @@ list(TRANSFORM git_perl_scripts PREPEND "${CMAKE_BINARY_DIR}/")
#install
foreach(program ${PROGRAMS_BUILT})
-if(program STREQUAL "git" OR program STREQUAL "git-shell")
+if(program MATCHES "^(git|git-shell|scalar)$")
install(TARGETS ${program}
RUNTIME DESTINATION bin)
else()
@@ -977,7 +1066,7 @@ endif()
#wrapper scripts
set(wrapper_scripts
- git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext)
+ git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext scalar)
set(wrapper_test_scripts
test-fake-ssh test-tool)
@@ -987,20 +1076,20 @@ foreach(script ${wrapper_scripts})
file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
string(REPLACE "@@PROG@@" "${script}${EXE_EXTENSION}" content "${content}")
- file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content})
+ write_script(${CMAKE_BINARY_DIR}/bin-wrappers/${script} "${content}")
endforeach()
foreach(script ${wrapper_test_scripts})
file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
string(REPLACE "@@PROG@@" "t/helper/${script}${EXE_EXTENSION}" content "${content}")
- file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content})
+ write_script(${CMAKE_BINARY_DIR}/bin-wrappers/${script} "${content}")
endforeach()
file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
string(REPLACE "@@PROG@@" "git-cvsserver" content "${content}")
-file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/git-cvsserver ${content})
+write_script(${CMAKE_BINARY_DIR}/bin-wrappers/git-cvsserver "${content}")
#options for configuring test options
option(PERL_TESTS "Perform tests that use perl" ON)
@@ -1018,7 +1107,6 @@ set(NO_PERL )
set(NO_PTHREADS )
set(NO_PYTHON )
set(PAGER_ENV "LESS=FRX LV=-c")
-set(DC_SHA1 YesPlease)
set(RUNTIME_PREFIX true)
set(NO_GETTEXT )
@@ -1050,11 +1138,13 @@ file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PYTHON_PATH='${PYTHON_PATH}'\
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "TAR='${TAR}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_CURL='${NO_CURL}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_EXPAT='${NO_EXPAT}'\n")
+if(PCRE2_FOUND)
+ file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "USE_LIBPCRE2='YesPlease'\n")
+endif()
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PERL='${NO_PERL}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PTHREADS='${NO_PTHREADS}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_UNIX_SOCKETS='${NO_UNIX_SOCKETS}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PAGER_ENV='${PAGER_ENV}'\n")
-file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "DC_SHA1='${DC_SHA1}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "X='${EXE_EXTENSION}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_GETTEXT='${NO_GETTEXT}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "RUNTIME_PREFIX='${RUNTIME_PREFIX}'\n")
@@ -1064,32 +1154,36 @@ if(USE_VCPKG)
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n")
endif()
-#Make the tests work when building out of the source tree
-get_filename_component(CACHE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../CMakeCache.txt ABSOLUTE)
-if(NOT ${CMAKE_BINARY_DIR}/CMakeCache.txt STREQUAL ${CACHE_PATH})
- file(RELATIVE_PATH BUILD_DIR_RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/CMakeCache.txt)
- string(REPLACE "/CMakeCache.txt" "" BUILD_DIR_RELATIVE ${BUILD_DIR_RELATIVE})
- #Setting the build directory in test-lib.sh before running tests
- file(WRITE ${CMAKE_BINARY_DIR}/CTestCustom.cmake
- "file(STRINGS ${CMAKE_SOURCE_DIR}/t/test-lib.sh GIT_BUILD_DIR_REPL REGEX \"GIT_BUILD_DIR=(.*)\")\n"
- "file(STRINGS ${CMAKE_SOURCE_DIR}/t/test-lib.sh content NEWLINE_CONSUME)\n"
- "string(REPLACE \"\${GIT_BUILD_DIR_REPL}\" \"GIT_BUILD_DIR=\\\"$TEST_DIRECTORY/../${BUILD_DIR_RELATIVE}\\\"\" content \"\${content}\")\n"
- "file(WRITE ${CMAKE_SOURCE_DIR}/t/test-lib.sh \${content})")
- #misc copies
- file(COPY ${CMAKE_SOURCE_DIR}/t/chainlint.sed DESTINATION ${CMAKE_BINARY_DIR}/t/)
- file(COPY ${CMAKE_SOURCE_DIR}/po/is.po DESTINATION ${CMAKE_BINARY_DIR}/po/)
- file(COPY ${CMAKE_SOURCE_DIR}/mergetools/tkdiff DESTINATION ${CMAKE_BINARY_DIR}/mergetools/)
- file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-prompt.sh DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
- file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-completion.bash DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
-endif()
-
file(GLOB test_scipts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh")
+if(DEFINED ENV{GIT_TEST_OPTS})
+ set(GIT_TEST_OPTS "$ENV{GIT_TEST_OPTS}"
+ CACHE STRING "test options, see t/README")
+ message(STATUS "Using user-selected test options: ${GIT_TEST_OPTS}")
+elseif(WIN32)
+ set(GIT_TEST_OPTS "--no-bin-wrappers --no-chain-lint -vx"
+ CACHE STRING "test options, see t/README")
+ message(STATUS "Using Windowns-specific default test options: ${GIT_TEST_OPTS}")
+else()
+ set(GIT_TEST_OPTS ""
+ CACHE STRING "test options, see t/README")
+ message(STATUS "No custom test options selected, set e.g. GIT_TEST_OPTS=\"-vixd\"")
+endif()
+separate_arguments(GIT_TEST_OPTS)
+
#test
foreach(tsh ${test_scipts})
add_test(NAME ${tsh}
- COMMAND ${SH_EXE} ${tsh}
+ COMMAND ${SH_EXE} ${tsh} ${GIT_TEST_OPTS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/t)
+ set_property(TEST ${tsh} APPEND PROPERTY ENVIRONMENT
+ GIT_TEST_BUILD_DIR=${CMAKE_BINARY_DIR})
endforeach()
+if(WIN32)
+ # This test script takes an extremely long time and is known to time out even
+ # on fast machines because it requires in excess of one hour to run
+ set_tests_properties("${CMAKE_SOURCE_DIR}/t/t7112-reset-submodule.sh" PROPERTIES TIMEOUT 4000)
+endif()
+
endif()#BUILD_TESTING
diff --git a/contrib/credential/netrc/git-credential-netrc.perl b/contrib/credential/netrc/git-credential-netrc.perl
index bc57cc65884..9fb998ae090 100755
--- a/contrib/credential/netrc/git-credential-netrc.perl
+++ b/contrib/credential/netrc/git-credential-netrc.perl
@@ -356,7 +356,10 @@ sub read_credential_data_from_stdin {
next unless m/^([^=]+)=(.+)/;
my ($token, $value) = ($1, $2);
- die "Unknown search token $token" unless exists $q{$token};
+
+ # skip any unknown tokens
+ next unless exists $q{$token};
+
$q{$token} = $value;
log_debug("We were given search token $token and value $value");
}
diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
index bf77748d602..e29cc28779d 100644
--- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c
+++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
@@ -159,6 +159,11 @@ static void read_credential(void)
username = xstrdup(v);
else if (!strcmp(buf, "password"))
password = xstrdup(v);
+ /*
+ * Ignore other lines; we don't know what they mean, but
+ * this future-proofs us when later versions of git do
+ * learn new lines, and the helpers are updated to match.
+ */
}
}
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
index 5091048f9c6..ead6e267c78 100644
--- a/contrib/credential/wincred/git-credential-wincred.c
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -278,8 +278,11 @@ static void read_credential(void)
wusername = utf8_to_utf16_dup(v);
} else if (!strcmp(buf, "password"))
password = utf8_to_utf16_dup(v);
- else
- die("unrecognized input");
+ /*
+ * Ignore other lines; we don't know what they mean, but
+ * this future-proofs us when later versions of git do
+ * learn new lines, and the helpers are updated to match.
+ */
}
}
diff --git a/contrib/scalar/.gitignore b/contrib/scalar/.gitignore
deleted file mode 100644
index ff3d47e84d0..00000000000
--- a/contrib/scalar/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/*.exe
-/scalar
diff --git a/contrib/scalar/Makefile b/contrib/scalar/Makefile
deleted file mode 100644
index 37f283f35d7..00000000000
--- a/contrib/scalar/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# The default target of this Makefile is...
-all::
-
-# Import tree-wide shared Makefile behavior and libraries
-include ../../shared.mak
-
-include ../../config.mak.uname
--include ../../config.mak.autogen
--include ../../config.mak
-
-TARGETS = scalar$(X) scalar.o
-GITLIBS = ../../common-main.o ../../libgit.a ../../xdiff/lib.a
-
-all:: scalar$(X) ../../bin-wrappers/scalar
-
-$(GITLIBS):
- $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(subst ../../,,$@)
-
-$(TARGETS): $(GITLIBS) scalar.c
- $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(patsubst %,contrib/scalar/%,$@)
-
-clean:
- $(RM) $(TARGETS) ../../bin-wrappers/scalar
-
-../../bin-wrappers/scalar: ../../wrap-for-bin.sh Makefile
- @mkdir -p ../../bin-wrappers
- $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
- -e 's|@@BUILD_DIR@@|$(shell cd ../.. && pwd)|' \
- -e 's|@@PROG@@|contrib/scalar/scalar$(X)|' < $< > $@ && \
- chmod +x $@
-
-test: all
- $(MAKE) -C t
-
-.PHONY: $(GITLIBS) all clean test FORCE
diff --git a/contrib/scalar/t/Makefile b/contrib/scalar/t/Makefile
deleted file mode 100644
index 1ed174a8cf3..00000000000
--- a/contrib/scalar/t/Makefile
+++ /dev/null
@@ -1,81 +0,0 @@
-# Import tree-wide shared Makefile behavior and libraries
-include ../../../shared.mak
-
-# Run scalar tests
-#
-# Copyright (c) 2005,2021 Junio C Hamano, Johannes Schindelin
-#
-
--include ../../../config.mak.autogen
--include ../../../config.mak
-
-SHELL_PATH ?= $(SHELL)
-PERL_PATH ?= /usr/bin/perl
-RM ?= rm -f
-PROVE ?= prove
-DEFAULT_TEST_TARGET ?= test
-TEST_LINT ?= test-lint
-
-ifdef TEST_OUTPUT_DIRECTORY
-TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results
-else
-TEST_RESULTS_DIRECTORY = ../../../t/test-results
-endif
-
-# Shell quote;
-SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
-PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
-TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))
-
-T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
-
-all: $(DEFAULT_TEST_TARGET)
-
-test: $(TEST_LINT)
- $(MAKE) aggregate-results-and-cleanup
-
-prove: $(TEST_LINT)
- @echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
- $(MAKE) clean-except-prove-cache
-
-$(T):
- @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
-
-clean-except-prove-cache:
- $(RM) -r 'trash directory'.*
- $(RM) -r valgrind/bin
-
-clean: clean-except-prove-cache
- $(RM) .prove
-
-test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax
-
-test-lint-duplicates:
- @dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
- test -z "$$dups" || { \
- echo >&2 "duplicate test numbers:" $$dups; exit 1; }
-
-test-lint-executable:
- @bad=`for i in $(T); do test -x "$$i" || echo $$i; done` && \
- test -z "$$bad" || { \
- echo >&2 "non-executable tests:" $$bad; exit 1; }
-
-test-lint-shell-syntax:
- @'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T)
-
-aggregate-results-and-cleanup: $(T)
- $(MAKE) aggregate-results
- $(MAKE) clean
-
-aggregate-results:
- for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \
- echo "$$f"; \
- done | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh
-
-valgrind:
- $(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
-
-test-results:
- mkdir -p test-results
-
-.PHONY: $(T) aggregate-results clean valgrind
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 7562a395c24..10c9c87839a 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -98,10 +98,18 @@ progress () {
assert () {
if ! "$@"
then
- die "assertion failed: $*"
+ die "fatal: assertion failed: $*"
fi
}
+# Usage: die_incompatible_opt OPTION COMMAND
+die_incompatible_opt () {
+ assert test "$#" = 2
+ opt="$1"
+ arg_command="$2"
+ die "fatal: the '$opt' flag does not make sense with 'git subtree $arg_command'."
+}
+
main () {
if test $# -eq 0
then
@@ -147,7 +155,7 @@ main () {
allow_addmerge=$arg_split_rejoin
;;
*)
- die "Unknown command '$arg_command'"
+ die "fatal: unknown command '$arg_command'"
;;
esac
# Reset the arguments array for "real" flag parsing.
@@ -176,16 +184,16 @@ main () {
arg_debug=1
;;
--annotate)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_annotate="$1"
shift
;;
--no-annotate)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_annotate=
;;
-b)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_branch="$1"
shift
;;
@@ -194,7 +202,7 @@ main () {
shift
;;
-m)
- test -n "$allow_addmerge" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
arg_addmerge_message="$1"
shift
;;
@@ -202,41 +210,41 @@ main () {
arg_prefix=
;;
--onto)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_onto="$1"
shift
;;
--no-onto)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_onto=
;;
--rejoin)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
;;
--no-rejoin)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
;;
--ignore-joins)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_ignore_joins=1
;;
--no-ignore-joins)
- test -n "$allow_split" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
arg_split_ignore_joins=
;;
--squash)
- test -n "$allow_addmerge" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
arg_addmerge_squash=1
;;
--no-squash)
- test -n "$allow_addmerge" || die "The '$opt' flag does not make sense with 'git subtree $arg_command'."
+ test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
arg_addmerge_squash=
;;
--)
break
;;
*)
- die "Unexpected option: $opt"
+ die "fatal: unexpected option: $opt"
;;
esac
done
@@ -244,17 +252,17 @@ main () {
if test -z "$arg_prefix"
then
- die "You must provide the --prefix option."
+ die "fatal: you must provide the --prefix option."
fi
case "$arg_command" in
add)
test -e "$arg_prefix" &&
- die "prefix '$arg_prefix' already exists."
+ die "fatal: prefix '$arg_prefix' already exists."
;;
*)
test -e "$arg_prefix" ||
- die "'$arg_prefix' does not exist; use 'git subtree add'"
+ die "fatal: '$arg_prefix' does not exist; use 'git subtree add'"
;;
esac
@@ -274,11 +282,11 @@ cache_setup () {
assert test $# = 0
cachedir="$GIT_DIR/subtree-cache/$$"
rm -rf "$cachedir" ||
- die "Can't delete old cachedir: $cachedir"
+ die "fatal: can't delete old cachedir: $cachedir"
mkdir -p "$cachedir" ||
- die "Can't create new cachedir: $cachedir"
+ die "fatal: can't create new cachedir: $cachedir"
mkdir -p "$cachedir/notree" ||
- die "Can't create new cachedir: $cachedir/notree"
+ die "fatal: can't create new cachedir: $cachedir/notree"
debug "Using cachedir: $cachedir" >&2
}
@@ -334,7 +342,7 @@ cache_set () {
test "$oldrev" != "latest_new" &&
test -e "$cachedir/$oldrev"
then
- die "cache for $oldrev already exists!"
+ die "fatal: cache for $oldrev already exists!"
fi
echo "$newrev" >"$cachedir/$oldrev"
}
@@ -363,13 +371,47 @@ try_remove_previous () {
fi
}
-# Usage: find_latest_squash DIR
+# Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY]
+process_subtree_split_trailer () {
+ assert test $# = 2 -o $# = 3
+ b="$1"
+ sq="$2"
+ repository=""
+ if test "$#" = 3
+ then
+ repository="$3"
+ fi
+ fail_msg="fatal: could not rev-parse split hash $b from commit $sq"
+ if ! sub="$(git rev-parse --verify --quiet "$b^{commit}")"
+ then
+ # if 'repository' was given, try to fetch the 'git-subtree-split' hash
+ # before 'rev-parse'-ing it again, as it might be a tag that we do not have locally
+ if test -n "${repository}"
+ then
+ git fetch "$repository" "$b"
+ sub="$(git rev-parse --verify --quiet "$b^{commit}")" ||
+ die "$fail_msg"
+ else
+ hint1=$(printf "hint: hash might be a tag, try fetching it from the subtree repository:")
+ hint2=$(printf "hint: git fetch <subtree-repository> $b")
+ fail_msg=$(printf "$fail_msg\n$hint1\n$hint2")
+ die "$fail_msg"
+ fi
+ fi
+}
+
+# Usage: find_latest_squash DIR [REPOSITORY]
find_latest_squash () {
- assert test $# = 1
- debug "Looking for latest squash ($dir)..."
+ assert test $# = 1 -o $# = 2
+ dir="$1"
+ repository=""
+ if test "$#" = 2
+ then
+ repository="$2"
+ fi
+ debug "Looking for latest squash (dir=$dir, repository=$repository)..."
local indent=$(($indent + 1))
- dir="$1"
sq=
main=
sub=
@@ -387,8 +429,7 @@ find_latest_squash () {
main="$b"
;;
git-subtree-split:)
- sub="$(git rev-parse "$b^{commit}")" ||
- die "could not rev-parse split hash $b from commit $sq"
+ process_subtree_split_trailer "$b" "$sq" "$repository"
;;
END)
if test -n "$sub"
@@ -412,14 +453,19 @@ find_latest_squash () {
done || exit $?
}
-# Usage: find_existing_splits DIR REV
+# Usage: find_existing_splits DIR REV [REPOSITORY]
find_existing_splits () {
- assert test $# = 2
+ assert test $# = 2 -o $# = 3
debug "Looking for prior splits..."
local indent=$(($indent + 1))
dir="$1"
rev="$2"
+ repository=""
+ if test "$#" = 3
+ then
+ repository="$3"
+ fi
main=
sub=
local grep_format="^git-subtree-dir: $dir/*\$"
@@ -439,8 +485,7 @@ find_existing_splits () {
main="$b"
;;
git-subtree-split:)
- sub="$(git rev-parse "$b^{commit}")" ||
- die "could not rev-parse split hash $b from commit $sq"
+ process_subtree_split_trailer "$b" "$sq" "$repository"
;;
END)
debug "Main is: '$main'"
@@ -490,7 +535,7 @@ copy_commit () {
cat
) |
git commit-tree "$2" $3 # reads the rest of stdin
- ) || die "Can't copy commit $1"
+ ) || die "fatal: can't copy commit $1"
}
# Usage: add_msg DIR LATEST_OLD LATEST_NEW
@@ -718,11 +763,11 @@ ensure_clean () {
assert test $# = 0
if ! git diff-index HEAD --exit-code --quiet 2>&1
then
- die "Working tree has modifications. Cannot add."
+ die "fatal: working tree has modifications. Cannot add."
fi
if ! git diff-index --cached HEAD --exit-code --quiet 2>&1
then
- die "Index has modifications. Cannot add."
+ die "fatal: index has modifications. Cannot add."
fi
}
@@ -730,7 +775,7 @@ ensure_clean () {
ensure_valid_ref_format () {
assert test $# = 1
git check-ref-format "refs/heads/$1" ||
- die "'$1' does not look like a ref"
+ die "fatal: '$1' does not look like a ref"
}
# Usage: process_split_commit REV PARENTS
@@ -796,7 +841,7 @@ cmd_add () {
if test $# -eq 1
then
git rev-parse -q --verify "$1^{commit}" >/dev/null ||
- die "'$1' does not refer to a commit"
+ die "fatal: '$1' does not refer to a commit"
cmd_add_commit "$@"
@@ -811,7 +856,7 @@ cmd_add () {
cmd_add_repository "$@"
else
- say >&2 "error: parameters were '$*'"
+ say >&2 "fatal: parameters were '$*'"
die "Provide either a commit or a repository and commit."
fi
}
@@ -843,7 +888,7 @@ cmd_add_commit () {
git checkout -- "$dir" || exit $?
tree=$(git write-tree) || exit $?
- headrev=$(git rev-parse HEAD) || exit $?
+ headrev=$(git rev-parse --verify HEAD) || exit $?
if test -n "$headrev" && test "$headrev" != "$rev"
then
headp="-p $headrev"
@@ -866,17 +911,22 @@ cmd_add_commit () {
say >&2 "Added dir '$dir'"
}
-# Usage: cmd_split [REV]
+# Usage: cmd_split [REV] [REPOSITORY]
cmd_split () {
if test $# -eq 0
then
rev=$(git rev-parse HEAD)
- elif test $# -eq 1
+ elif test $# -eq 1 -o $# -eq 2
then
rev=$(git rev-parse -q --verify "$1^{commit}") ||
- die "'$1' does not refer to a commit"
+ die "fatal: '$1' does not refer to a commit"
else
- die "You must provide exactly one revision. Got: '$*'"
+ die "fatal: you must provide exactly one revision, and optionnally a repository. Got: '$*'"
+ fi
+ repository=""
+ if test "$#" = 2
+ then
+ repository="$2"
fi
if test -n "$arg_split_rejoin"
@@ -900,7 +950,7 @@ cmd_split () {
done || exit $?
fi
- unrevs="$(find_existing_splits "$dir" "$rev")" || exit $?
+ unrevs="$(find_existing_splits "$dir" "$rev" "$repository")" || exit $?
# We can't restrict rev-list to only $dir here, because some of our
# parents have the $dir contents the root, and those won't match.
@@ -919,7 +969,7 @@ cmd_split () {
latest_new=$(cache_get latest_new) || exit $?
if test -z "$latest_new"
then
- die "No new revisions were found"
+ die "fatal: no new revisions were found"
fi
if test -n "$arg_split_rejoin"
@@ -940,7 +990,7 @@ cmd_split () {
then
if ! git merge-base --is-ancestor "$arg_split_branch" "$latest_new"
then
- die "Branch '$arg_split_branch' is not an ancestor of commit '$latest_new'."
+ die "fatal: branch '$arg_split_branch' is not an ancestor of commit '$latest_new'."
fi
action='Updated'
else
@@ -954,20 +1004,25 @@ cmd_split () {
exit 0
}
-# Usage: cmd_merge REV
+# Usage: cmd_merge REV [REPOSITORY]
cmd_merge () {
- test $# -eq 1 ||
- die "You must provide exactly one revision. Got: '$*'"
+ test $# -eq 1 -o $# -eq 2 ||
+ die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'"
rev=$(git rev-parse -q --verify "$1^{commit}") ||
- die "'$1' does not refer to a commit"
+ die "fatal: '$1' does not refer to a commit"
+ repository=""
+ if test "$#" = 2
+ then
+ repository="$2"
+ fi
ensure_clean
if test -n "$arg_addmerge_squash"
then
- first_split="$(find_latest_squash "$dir")" || exit $?
+ first_split="$(find_latest_squash "$dir" "$repository")" || exit $?
if test -z "$first_split"
then
- die "Can't squash-merge: '$dir' was never added."
+ die "fatal: can't squash-merge: '$dir' was never added."
fi
set $first_split
old=$1
@@ -995,19 +1050,21 @@ cmd_merge () {
cmd_pull () {
if test $# -ne 2
then
- die "You must provide <repository> <ref>"
+ die "fatal: you must provide <repository> <ref>"
fi
+ repository="$1"
+ ref="$2"
ensure_clean
- ensure_valid_ref_format "$2"
- git fetch "$@" || exit $?
- cmd_merge FETCH_HEAD
+ ensure_valid_ref_format "$ref"
+ git fetch "$repository" "$ref" || exit $?
+ cmd_merge FETCH_HEAD "$repository"
}
# Usage: cmd_push REPOSITORY [+][LOCALREV:]REMOTEREF
cmd_push () {
if test $# -ne 2
then
- die "You must provide <repository> <refspec>"
+ die "fatal: you must provide <repository> <refspec>"
fi
if test -e "$dir"
then
@@ -1022,13 +1079,13 @@ cmd_push () {
fi
ensure_valid_ref_format "$remoteref"
localrev_presplit=$(git rev-parse -q --verify "$localrevname_presplit^{commit}") ||
- die "'$localrevname_presplit' does not refer to a commit"
+ die "fatal: '$localrevname_presplit' does not refer to a commit"
echo "git push using: " "$repository" "$refspec"
- localrev=$(cmd_split "$localrev_presplit") || die
+ localrev=$(cmd_split "$localrev_presplit" "$repository") || die
git push "$repository" "$localrev":"refs/heads/$remoteref"
else
- die "'$dir' must already exist. Try 'git subtree add'."
+ die "fatal: '$dir' must already exist. Try 'git subtree add'."
fi
}
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index 9cddfa26540..004abf415b8 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git subtree' [<options>] -P <prefix> add <local-commit>
'git subtree' [<options>] -P <prefix> add <repository> <remote-ref>
-'git subtree' [<options>] -P <prefix> merge <local-commit>
+'git subtree' [<options>] -P <prefix> merge <local-commit> [<repository>]
'git subtree' [<options>] -P <prefix> split [<local-commit>]
[verse]
@@ -76,7 +76,7 @@ add <repository> <remote-ref>::
only a single commit from the subproject, rather than its
entire history.
-merge <local-commit>::
+merge <local-commit> [<repository>]::
Merge recent changes up to <local-commit> into the <prefix>
subtree. As with normal 'git merge', this doesn't
remove your own local changes; it just merges those
@@ -88,8 +88,13 @@ If you use '--squash', the merge direction doesn't always have to be
forward; you can use this command to go back in time from v2.5 to v2.4,
for example. If your merge introduces a conflict, you can resolve it in
the usual ways.
++
+When using '--squash', and the previous merge with '--squash' merged an
+annotated tag of the subtree repository, that tag needs to be available locally.
+If <repository> is given, a missing tag will automatically be fetched from that
+repository.
-split [<local-commit>]::
+split [<local-commit>] [<repository>]::
Extract a new, synthetic project history from the
history of the <prefix> subtree of <local-commit>, or of
HEAD if no <local-commit> is given. The new history
@@ -109,6 +114,11 @@ settings passed to 'split' (such as '--annotate') are the same.
Because of this, if you add new commits and then re-split, the new
commits will be attached as commits on top of the history you
generated last time, so 'git merge' and friends will work as expected.
++
+When a previous merge with '--squash' merged an annotated tag of the
+subtree repository, that tag needs to be available locally.
+If <repository> is given, a missing tag will automatically be fetched from that
+repository.
pull <repository> <remote-ref>::
Exactly like 'merge', but parallels 'git pull' in that
diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile
index 3d278bb0edb..4655e0987b3 100644
--- a/contrib/subtree/t/Makefile
+++ b/contrib/subtree/t/Makefile
@@ -51,6 +51,7 @@ clean-except-prove-cache:
$(RM) -r valgrind/bin
clean: clean-except-prove-cache
+ $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
$(RM) .prove
test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index 1c1f76f04aa..341c169eca7 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -43,6 +43,30 @@ last_commit_subject () {
git log --pretty=format:%s -1
}
+# Upon 'git subtree add|merge --squash' of an annotated tag,
+# pre-2.32.0 versions of 'git subtree' would write the hash of the tag
+# (sub1 below), instead of the commit (sub1^{commit}) in the
+# "git-subtree-split" trailer.
+# We immitate this behaviour below using a replace ref.
+# This function creates 3 repositories:
+# - $1
+# - $1-sub (added as subtree "sub" in $1)
+# - $1-clone (clone of $1)
+test_create_pre2_32_repo () {
+ subtree_test_create_repo "$1" &&
+ subtree_test_create_repo "$1-sub" &&
+ test_commit -C "$1" main1 &&
+ test_commit -C "$1-sub" --annotate sub1 &&
+ git -C "$1" subtree add --prefix="sub" --squash "../$1-sub" sub1 &&
+ tag=$(git -C "$1" rev-parse FETCH_HEAD) &&
+ commit=$(git -C "$1" rev-parse FETCH_HEAD^{commit}) &&
+ git -C "$1" log -1 --format=%B HEAD^2 >msg &&
+ test_commit -C "$1-sub" --annotate sub2 &&
+ git clone --no-local "$1" "$1-clone" &&
+ new_commit=$(cat msg | sed -e "s/$commit/$tag/" | git -C "$1-clone" commit-tree HEAD^2^{tree}) &&
+ git -C "$1-clone" replace HEAD^2 $new_commit
+}
+
test_expect_success 'shows short help text for -h' '
test_expect_code 129 git subtree -h >out 2>err &&
test_must_be_empty err &&
@@ -264,6 +288,13 @@ test_expect_success 'merge new subproj history into subdir/ with a slash appende
)
'
+test_expect_success 'merge with --squash after annotated tag was added/merged with --squash pre-v2.32.0 ' '
+ test_create_pre2_32_repo "$test_count" &&
+ git -C "$test_count-clone" fetch "../$test_count-sub" sub2 &&
+ test_must_fail git -C "$test_count-clone" subtree merge --prefix="sub" --squash FETCH_HEAD &&
+ git -C "$test_count-clone" subtree merge --prefix="sub" --squash FETCH_HEAD "../$test_count-sub"
+'
+
#
# Tests for 'git subtree split'
#
@@ -277,7 +308,7 @@ test_expect_success 'split requires option --prefix' '
cd "$test_count" &&
git fetch ./"sub proj" HEAD &&
git subtree add --prefix="sub dir" FETCH_HEAD &&
- echo "You must provide the --prefix option." >expected &&
+ echo "fatal: you must provide the --prefix option." >expected &&
test_must_fail git subtree split >actual 2>&1 &&
test_debug "printf '"expected: "'" &&
test_debug "cat expected" &&
@@ -296,7 +327,7 @@ test_expect_success 'split requires path given by option --prefix must exist' '
cd "$test_count" &&
git fetch ./"sub proj" HEAD &&
git subtree add --prefix="sub dir" FETCH_HEAD &&
- echo "'\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" >expected &&
+ echo "fatal: '\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" >expected &&
test_must_fail git subtree split --prefix=non-existent-directory >actual 2>&1 &&
test_debug "printf '"expected: "'" &&
test_debug "cat expected" &&
@@ -551,6 +582,12 @@ test_expect_success 'split "sub dir"/ with --branch for an incompatible branch'
)
'
+test_expect_success 'split after annotated tag was added/merged with --squash pre-v2.32.0' '
+ test_create_pre2_32_repo "$test_count" &&
+ test_must_fail git -C "$test_count-clone" subtree split --prefix="sub" HEAD &&
+ git -C "$test_count-clone" subtree split --prefix="sub" HEAD "../$test_count-sub"
+'
+
#
# Tests for 'git subtree pull'
#
@@ -570,7 +607,7 @@ test_expect_success 'pull requires option --prefix' '
cd "$test_count" &&
test_must_fail git subtree pull ./"sub proj" HEAD >out 2>err &&
- echo "You must provide the --prefix option." >expected &&
+ echo "fatal: you must provide the --prefix option." >expected &&
test_must_be_empty out &&
test_cmp expected err
)
@@ -584,7 +621,7 @@ test_expect_success 'pull requires path given by option --prefix must exist' '
(
test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" HEAD >out 2>err &&
- echo "'\''sub dir'\'' does not exist; use '\''git subtree add'\''" >expected &&
+ echo "fatal: '\''sub dir'\'' does not exist; use '\''git subtree add'\''" >expected &&
test_must_be_empty out &&
test_cmp expected err
)
@@ -630,6 +667,11 @@ test_expect_success 'pull rejects flags for split' '
)
'
+test_expect_success 'pull with --squash after annotated tag was added/merged with --squash pre-v2.32.0 ' '
+ test_create_pre2_32_repo "$test_count" &&
+ git -C "$test_count-clone" subtree -d pull --prefix="sub" --squash "../$test_count-sub" sub2
+'
+
#
# Tests for 'git subtree push'
#
@@ -643,7 +685,7 @@ test_expect_success 'push requires option --prefix' '
cd "$test_count" &&
git fetch ./"sub proj" HEAD &&
git subtree add --prefix="sub dir" FETCH_HEAD &&
- echo "You must provide the --prefix option." >expected &&
+ echo "fatal: you must provide the --prefix option." >expected &&
test_must_fail git subtree push "./sub proj" from-mainline >actual 2>&1 &&
test_debug "printf '"expected: "'" &&
test_debug "cat expected" &&
@@ -662,7 +704,7 @@ test_expect_success 'push requires path given by option --prefix must exist' '
cd "$test_count" &&
git fetch ./"sub proj" HEAD &&
git subtree add --prefix="sub dir" FETCH_HEAD &&
- echo "'\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" >expected &&
+ echo "fatal: '\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" >expected &&
test_must_fail git subtree push --prefix=non-existent-directory "./sub proj" from-mainline >actual 2>&1 &&
test_debug "printf '"expected: "'" &&
test_debug "cat expected" &&
@@ -953,6 +995,12 @@ test_expect_success 'push "sub dir"/ with a local rev' '
)
'
+test_expect_success 'push after annotated tag was added/merged with --squash pre-v2.32.0' '
+ test_create_pre2_32_repo "$test_count" &&
+ test_create_commit "$test_count-clone" sub/main-sub1 &&
+ git -C "$test_count-clone" subtree push --prefix="sub" "../$test_count-sub" from-mainline
+'
+
#
# Validity checking
#
diff --git a/convert.c b/convert.c
index 4d153729da0..9b676490320 100644
--- a/convert.c
+++ b/convert.c
@@ -619,7 +619,7 @@ struct filter_params {
const char *path;
};
-static int filter_buffer_or_fd(int in, int out, void *data)
+static int filter_buffer_or_fd(int in UNUSED, int out, void *data)
{
/*
* Spawn cmd and feed the buffer contents through its stdin.
@@ -1008,7 +1008,7 @@ static int apply_filter(const char *path, const char *src, size_t len,
return 0;
}
-static int read_convert_config(const char *var, const char *value, void *cb)
+static int read_convert_config(const char *var, const char *value, void *cb UNUSED)
{
const char *key, *name;
size_t namelen;
@@ -1549,7 +1549,7 @@ struct stream_filter {
struct stream_filter_vtbl *vtbl;
};
-static int null_filter_fn(struct stream_filter *filter,
+static int null_filter_fn(struct stream_filter *filter UNUSED,
const char *input, size_t *isize_p,
char *output, size_t *osize_p)
{
@@ -1568,7 +1568,7 @@ static int null_filter_fn(struct stream_filter *filter,
return 0;
}
-static void null_free_fn(struct stream_filter *filter)
+static void null_free_fn(struct stream_filter *filter UNUSED)
{
; /* nothing -- null instances are shared */
}
diff --git a/date.c b/date.c
index 68a260c214d..53bd6a7932e 100644
--- a/date.c
+++ b/date.c
@@ -1101,7 +1101,7 @@ static void date_tea(struct tm *tm, struct tm *now, int *num)
date_time(tm, now, 17);
}
-static void date_pm(struct tm *tm, struct tm *now, int *num)
+static void date_pm(struct tm *tm, struct tm *now UNUSED, int *num)
{
int hour, n = *num;
*num = 0;
@@ -1115,7 +1115,7 @@ static void date_pm(struct tm *tm, struct tm *now, int *num)
tm->tm_hour = (hour % 12) + 12;
}
-static void date_am(struct tm *tm, struct tm *now, int *num)
+static void date_am(struct tm *tm, struct tm *now UNUSED, int *num)
{
int hour, n = *num;
*num = 0;
@@ -1129,7 +1129,7 @@ static void date_am(struct tm *tm, struct tm *now, int *num)
tm->tm_hour = (hour % 12);
}
-static void date_never(struct tm *tm, struct tm *now, int *num)
+static void date_never(struct tm *tm, struct tm *now UNUSED, int *num)
{
time_t n = 0;
localtime_r(&n, tm);
diff --git a/delta-islands.c b/delta-islands.c
index aa98b2e5414..26f9e99e1a9 100644
--- a/delta-islands.c
+++ b/delta-islands.c
@@ -316,7 +316,7 @@ static regex_t *island_regexes;
static unsigned int island_regexes_alloc, island_regexes_nr;
static const char *core_island_name;
-static int island_config_callback(const char *k, const char *v, void *cb)
+static int island_config_callback(const char *k, const char *v, void *cb UNUSED)
{
if (!strcmp(k, "pack.island")) {
struct strbuf re = STRBUF_INIT;
@@ -365,7 +365,7 @@ static void add_ref_to_island(const char *island_name, const struct object_id *o
}
static int find_island_for_ref(const char *refname, const struct object_id *oid,
- int flags, void *data)
+ int flags UNUSED, void *data UNUSED)
{
/*
* We should advertise 'ARRAY_SIZE(matches) - 2' as the max,
diff --git a/diagnose.c b/diagnose.c
index beb0a8741ba..8f265698966 100644
--- a/diagnose.c
+++ b/diagnose.c
@@ -66,17 +66,53 @@ static int dir_file_stats(struct object_directory *object_dir, void *data)
return 0;
}
-static int count_files(char *path)
+/*
+ * Get the d_type of a dirent. If the d_type is unknown, derive it from
+ * stat.st_mode.
+ *
+ * Note that 'path' is assumed to have a trailing slash. It is also modified
+ * in-place during the execution of the function, but is then reverted to its
+ * original value before returning.
+ */
+static unsigned char get_dtype(struct dirent *e, struct strbuf *path)
{
- DIR *dir = opendir(path);
+ struct stat st;
+ unsigned char dtype = DTYPE(e);
+ size_t base_path_len;
+
+ if (dtype != DT_UNKNOWN)
+ return dtype;
+
+ /* d_type unknown in dirent, try to fall back on lstat results */
+ base_path_len = path->len;
+ strbuf_addstr(path, e->d_name);
+ if (lstat(path->buf, &st))
+ goto cleanup;
+
+ /* determine d_type from st_mode */
+ if (S_ISREG(st.st_mode))
+ dtype = DT_REG;
+ else if (S_ISDIR(st.st_mode))
+ dtype = DT_DIR;
+ else if (S_ISLNK(st.st_mode))
+ dtype = DT_LNK;
+
+cleanup:
+ strbuf_setlen(path, base_path_len);
+ return dtype;
+}
+
+static int count_files(struct strbuf *path)
+{
+ DIR *dir = opendir(path->buf);
struct dirent *e;
int count = 0;
if (!dir)
return 0;
- while ((e = readdir(dir)) != NULL)
- if (!is_dot_or_dotdot(e->d_name) && e->d_type == DT_REG)
+ while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL)
+ if (get_dtype(e, path) == DT_REG)
count++;
closedir(dir);
@@ -104,13 +140,13 @@ static void loose_objs_stats(struct strbuf *buf, const char *path)
strbuf_addch(&count_path, '/');
base_path_len = count_path.len;
- while ((e = readdir(dir)) != NULL)
- if (!is_dot_or_dotdot(e->d_name) &&
- e->d_type == DT_DIR && strlen(e->d_name) == 2 &&
+ while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL)
+ if (get_dtype(e, &count_path) == DT_DIR &&
+ strlen(e->d_name) == 2 &&
!hex_to_bytes(&c, e->d_name, 1)) {
strbuf_setlen(&count_path, base_path_len);
- strbuf_addstr(&count_path, e->d_name);
- total += (count = count_files(count_path.buf));
+ strbuf_addf(&count_path, "%s/", e->d_name);
+ total += (count = count_files(&count_path));
strbuf_addf(buf, "%s : %7d files\n", e->d_name, count);
}
@@ -144,22 +180,28 @@ static int add_directory_to_archiver(struct strvec *archiver_args,
len = buf.len;
strvec_pushf(archiver_args, "--prefix=%s", buf.buf);
- while (!res && (e = readdir(dir))) {
- if (!strcmp(".", e->d_name) || !strcmp("..", e->d_name))
- continue;
+ while (!res && (e = readdir_skip_dot_and_dotdot(dir))) {
+ struct strbuf abspath = STRBUF_INIT;
+ unsigned char dtype;
+
+ strbuf_add_absolute_path(&abspath, at_root ? "." : path);
+ strbuf_addch(&abspath, '/');
+ dtype = get_dtype(e, &abspath);
strbuf_setlen(&buf, len);
strbuf_addstr(&buf, e->d_name);
- if (e->d_type == DT_REG)
+ if (dtype == DT_REG)
strvec_pushf(archiver_args, "--add-file=%s", buf.buf);
- else if (e->d_type != DT_DIR)
+ else if (dtype != DT_DIR)
warning(_("skipping '%s', which is neither file nor "
"directory"), buf.buf);
else if (recurse &&
add_directory_to_archiver(archiver_args,
buf.buf, recurse) < 0)
res = -1;
+
+ strbuf_release(&abspath);
}
closedir(dir);
diff --git a/diff-merges.c b/diff-merges.c
index 7f64156b8bf..85cbefa5afd 100644
--- a/diff-merges.c
+++ b/diff-merges.c
@@ -20,9 +20,20 @@ static void suppress(struct rev_info *revs)
revs->remerge_diff = 0;
}
-static void set_separate(struct rev_info *revs)
+static void common_setup(struct rev_info *revs)
{
suppress(revs);
+ revs->merges_need_diff = 1;
+}
+
+static void set_none(struct rev_info *revs)
+{
+ suppress(revs);
+}
+
+static void set_separate(struct rev_info *revs)
+{
+ common_setup(revs);
revs->separate_merges = 1;
revs->simplify_history = 0;
}
@@ -35,21 +46,21 @@ static void set_first_parent(struct rev_info *revs)
static void set_combined(struct rev_info *revs)
{
- suppress(revs);
+ common_setup(revs);
revs->combine_merges = 1;
revs->dense_combined_merges = 0;
}
static void set_dense_combined(struct rev_info *revs)
{
- suppress(revs);
+ common_setup(revs);
revs->combine_merges = 1;
revs->dense_combined_merges = 1;
}
static void set_remerge_diff(struct rev_info *revs)
{
- suppress(revs);
+ common_setup(revs);
revs->remerge_diff = 1;
revs->simplify_history = 0;
}
@@ -57,18 +68,18 @@ static void set_remerge_diff(struct rev_info *revs)
static diff_merges_setup_func_t func_by_opt(const char *optarg)
{
if (!strcmp(optarg, "off") || !strcmp(optarg, "none"))
- return suppress;
+ return set_none;
if (!strcmp(optarg, "1") || !strcmp(optarg, "first-parent"))
return set_first_parent;
- else if (!strcmp(optarg, "separate"))
+ if (!strcmp(optarg, "separate"))
return set_separate;
- else if (!strcmp(optarg, "c") || !strcmp(optarg, "combined"))
+ if (!strcmp(optarg, "c") || !strcmp(optarg, "combined"))
return set_combined;
- else if (!strcmp(optarg, "cc") || !strcmp(optarg, "dense-combined"))
+ if (!strcmp(optarg, "cc") || !strcmp(optarg, "dense-combined"))
return set_dense_combined;
- else if (!strcmp(optarg, "r") || !strcmp(optarg, "remerge"))
+ if (!strcmp(optarg, "r") || !strcmp(optarg, "remerge"))
return set_remerge_diff;
- else if (!strcmp(optarg, "m") || !strcmp(optarg, "on"))
+ if (!strcmp(optarg, "m") || !strcmp(optarg, "on"))
return set_to_default;
return NULL;
}
@@ -81,10 +92,6 @@ static void set_diff_merges(struct rev_info *revs, const char *optarg)
die(_("invalid value for '%s': '%s'"), "--diff-merges", optarg);
func(revs);
-
- /* NOTE: the merges_need_diff flag is cleared by func() call */
- if (func != suppress)
- revs->merges_need_diff = 1;
}
/*
@@ -115,6 +122,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
if (!suppress_m_parsing && !strcmp(arg, "-m")) {
set_to_default(revs);
+ revs->merges_need_diff = 0;
} else if (!strcmp(arg, "-c")) {
set_combined(revs);
revs->merges_imply_patch = 1;
@@ -125,7 +133,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
set_remerge_diff(revs);
revs->merges_imply_patch = 1;
} else if (!strcmp(arg, "--no-diff-merges")) {
- suppress(revs);
+ set_none(revs);
} else if (!strcmp(arg, "--combined-all-paths")) {
revs->combined_all_paths = 1;
} else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) {
@@ -139,7 +147,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
void diff_merges_suppress(struct rev_info *revs)
{
- suppress(revs);
+ set_none(revs);
}
void diff_merges_default_to_first_parent(struct rev_info *revs)
diff --git a/diff-no-index.c b/diff-no-index.c
index 9a8b09346bd..18edbdf4b59 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -243,7 +243,9 @@ int diff_no_index(struct rev_info *revs,
int argc, const char **argv)
{
int i, no_index;
+ int ret = 1;
const char *paths[2];
+ char *to_free[ARRAY_SIZE(paths)] = { 0 };
struct strbuf replacement = STRBUF_INIT;
const char *prefix = revs->prefix;
struct option no_index_options[] = {
@@ -265,7 +267,7 @@ int diff_no_index(struct rev_info *revs,
}
FREE_AND_NULL(options);
for (i = 0; i < 2; i++) {
- const char *p = argv[argc - 2 + i];
+ const char *p = argv[i];
if (!strcmp(p, "-"))
/*
* stdin should be spelled as "-"; if you have
@@ -273,7 +275,7 @@ int diff_no_index(struct rev_info *revs,
*/
p = file_from_standard_input;
else if (prefix)
- p = prefix_filename(prefix, p);
+ p = to_free[i] = prefix_filename(prefix, p);
paths[i] = p;
}
@@ -295,16 +297,20 @@ int diff_no_index(struct rev_info *revs,
revs->diffopt.flags.exit_with_status = 1;
if (queue_diff(&revs->diffopt, paths[0], paths[1]))
- return 1;
+ goto out;
diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/");
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
- strbuf_release(&replacement);
-
/*
* The return code for --no-index imitates diff(1):
* 0 = no changes, 1 = changes, else error
*/
- return diff_result_code(&revs->diffopt, 0);
+ ret = diff_result_code(&revs->diffopt, 0);
+
+out:
+ for (i = 0; i < ARRAY_SIZE(to_free); i++)
+ free(to_free[i]);
+ strbuf_release(&replacement);
+ return ret;
}
diff --git a/diff.c b/diff.c
index 974626a6211..9f9a92ec9d2 100644
--- a/diff.c
+++ b/diff.c
@@ -264,7 +264,8 @@ void init_diff_ui_defaults(void)
diff_detect_rename_default = DIFF_DETECT_RENAME;
}
-int git_diff_heuristic_config(const char *var, const char *value, void *cb)
+int git_diff_heuristic_config(const char *var, const char *value,
+ void *cb UNUSED)
{
if (!strcmp(var, "diff.indentheuristic"))
diff_indent_heuristic = git_config_bool(var, value);
@@ -916,7 +917,7 @@ struct interned_diff_symbol {
static int interned_diff_symbol_cmp(const void *hashmap_cmp_fn_data,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *keydata)
+ const void *keydata UNUSED)
{
const struct diff_options *diffopt = hashmap_cmp_fn_data;
const struct emitted_diff_symbol *a, *b;
@@ -2487,6 +2488,9 @@ static int diffstat_consume(void *priv, char *line, unsigned long len)
struct diffstat_t *diffstat = priv;
struct diffstat_file *x = diffstat->files[diffstat->nr - 1];
+ if (!len)
+ BUG("xdiff fed us an empty line");
+
if (line[0] == '+')
x->added++;
else if (line[0] == '-')
@@ -2620,7 +2624,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
continue;
}
fill_print_name(file);
- len = strlen(file->print_name);
+ len = utf8_strwidth(file->print_name);
if (max_len < len)
max_len = len;
@@ -2673,6 +2677,11 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
* making the line longer than the maximum width.
*/
+ /*
+ * NEEDSWORK: line_prefix is often used for "log --graph" output
+ * and contains ANSI-colored string. utf8_strnwidth() should be
+ * used to correctly count the display width instead of strlen().
+ */
if (options->stat_width == -1)
width = term_columns() - strlen(line_prefix);
else
@@ -2734,7 +2743,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
char *name = file->print_name;
uintmax_t added = file->added;
uintmax_t deleted = file->deleted;
- int name_len;
+ int name_len, padding;
if (!file->is_interesting && (added + deleted == 0))
continue;
@@ -2743,20 +2752,34 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
* "scale" the filename
*/
len = name_width;
- name_len = strlen(name);
+ name_len = utf8_strwidth(name);
if (name_width < name_len) {
char *slash;
prefix = "...";
len -= 3;
+ /*
+ * NEEDSWORK: (name_len - len) counts the display
+ * width, which would be shorter than the byte
+ * length of the corresponding substring.
+ * Advancing "name" by that number of bytes does
+ * *NOT* skip over that many columns, so it is
+ * very likely that chomping the pathname at the
+ * slash we will find starting from "name" will
+ * leave the resulting string still too long.
+ */
name += name_len - len;
slash = strchr(name, '/');
if (slash)
name = slash;
}
+ padding = len - utf8_strwidth(name);
+ if (padding < 0)
+ padding = 0;
if (file->is_binary) {
- strbuf_addf(&out, " %s%-*s |", prefix, len, name);
- strbuf_addf(&out, " %*s", number_width, "Bin");
+ strbuf_addf(&out, " %s%s%*s | %*s",
+ prefix, name, padding, "",
+ number_width, "Bin");
if (!added && !deleted) {
strbuf_addch(&out, '\n');
emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,
@@ -2776,8 +2799,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
continue;
}
else if (file->is_unmerged) {
- strbuf_addf(&out, " %s%-*s |", prefix, len, name);
- strbuf_addstr(&out, " Unmerged\n");
+ strbuf_addf(&out, " %s%s%*s | %*s",
+ prefix, name, padding, "",
+ number_width, "Unmerged");
emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,
out.buf, out.len, 0);
strbuf_reset(&out);
@@ -2803,10 +2827,10 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
add = total - del;
}
}
- strbuf_addf(&out, " %s%-*s |", prefix, len, name);
- strbuf_addf(&out, " %*"PRIuMAX"%s",
- number_width, added + deleted,
- added + deleted ? " " : "");
+ strbuf_addf(&out, " %s%s%*s | %*"PRIuMAX"%s",
+ prefix, name, padding, "",
+ number_width, added + deleted,
+ added + deleted ? " " : "");
show_graph(&out, '+', add, add_c, reset);
show_graph(&out, '-', del, del_c, reset);
strbuf_addch(&out, '\n');
@@ -3398,6 +3422,21 @@ static void add_formatted_headers(struct strbuf *msg,
line_prefix, meta, reset);
}
+static int diff_filepair_is_phoney(struct diff_filespec *one,
+ struct diff_filespec *two)
+{
+ /*
+ * This function specifically looks for pairs injected by
+ * create_filepairs_for_header_only_notifications(). Such
+ * pairs are "phoney" in that they do not represent any
+ * content or even mode difference, but were inserted because
+ * diff_queued_diff previously had no pair associated with
+ * that path but we needed some pair to avoid losing the
+ * "remerge CONFLICT" header associated with the path.
+ */
+ return !DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two);
+}
+
static void builtin_diff(const char *name_a,
const char *name_b,
struct diff_filespec *one,
@@ -3429,14 +3468,16 @@ static void builtin_diff(const char *name_a,
if (o->submodule_format == DIFF_SUBMODULE_LOG &&
(!one->mode || S_ISGITLINK(one->mode)) &&
- (!two->mode || S_ISGITLINK(two->mode))) {
+ (!two->mode || S_ISGITLINK(two->mode)) &&
+ (!diff_filepair_is_phoney(one, two))) {
show_submodule_diff_summary(o, one->path ? one->path : two->path,
&one->oid, &two->oid,
two->dirty_submodule);
return;
} else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF &&
(!one->mode || S_ISGITLINK(one->mode)) &&
- (!two->mode || S_ISGITLINK(two->mode))) {
+ (!two->mode || S_ISGITLINK(two->mode)) &&
+ (!diff_filepair_is_phoney(one, two))) {
show_submodule_inline_diff(o, one->path ? one->path : two->path,
&one->oid, &two->oid,
two->dirty_submodule);
@@ -3456,12 +3497,12 @@ static void builtin_diff(const char *name_a,
b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
- if (!DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two)) {
+ if (diff_filepair_is_phoney(one, two)) {
/*
- * We should only reach this point for pairs from
+ * We should only reach this point for pairs generated from
* create_filepairs_for_header_only_notifications(). For
- * these, we should avoid the "/dev/null" special casing
- * above, meaning we avoid showing such pairs as either
+ * these, we want to avoid the "/dev/null" special casing
+ * above, because we do not want such pairs shown as either
* "new file" or "deleted file" below.
*/
lbl[0] = a_one;
@@ -4260,35 +4301,34 @@ static void run_external_diff(const char *pgm,
const char *xfrm_msg,
struct diff_options *o)
{
- struct strvec argv = STRVEC_INIT;
- struct strvec env = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
struct diff_queue_struct *q = &diff_queued_diff;
- strvec_push(&argv, pgm);
- strvec_push(&argv, name);
+ strvec_push(&cmd.args, pgm);
+ strvec_push(&cmd.args, name);
if (one && two) {
- add_external_diff_name(o->repo, &argv, name, one);
+ add_external_diff_name(o->repo, &cmd.args, name, one);
if (!other)
- add_external_diff_name(o->repo, &argv, name, two);
+ add_external_diff_name(o->repo, &cmd.args, name, two);
else {
- add_external_diff_name(o->repo, &argv, other, two);
- strvec_push(&argv, other);
- strvec_push(&argv, xfrm_msg);
+ add_external_diff_name(o->repo, &cmd.args, other, two);
+ strvec_push(&cmd.args, other);
+ strvec_push(&cmd.args, xfrm_msg);
}
}
- strvec_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter);
- strvec_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
+ strvec_pushf(&cmd.env, "GIT_DIFF_PATH_COUNTER=%d",
+ ++o->diff_path_counter);
+ strvec_pushf(&cmd.env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
diff_free_filespec_data(one);
diff_free_filespec_data(two);
- if (run_command_v_opt_cd_env(argv.v, RUN_USING_SHELL, NULL, env.v))
+ cmd.use_shell = 1;
+ if (run_command(&cmd))
die(_("external diff died, stopping at %s"), name);
remove_tempfile();
- strvec_clear(&argv);
- strvec_clear(&env);
}
static int similarity_index(struct diff_filepair *p)
@@ -5661,7 +5701,7 @@ int diff_opt_parse(struct diff_options *options,
ac = parse_options(ac, av, prefix, options->parseopts, NULL,
PARSE_OPT_KEEP_DASHDASH |
- PARSE_OPT_KEEP_UNKNOWN |
+ PARSE_OPT_KEEP_UNKNOWN_OPT |
PARSE_OPT_NO_INTERNAL_HELP |
PARSE_OPT_ONE_SHOT |
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -5852,6 +5892,7 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
{
int include_conflict_headers =
(additional_headers(o, p->one->path) &&
+ !o->pickaxe_opts &&
(!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o)));
/*
@@ -5907,6 +5948,8 @@ int diff_queue_is_empty(struct diff_options *o)
int i;
int include_conflict_headers =
(o->additional_path_headers &&
+ strmap_get_size(o->additional_path_headers) &&
+ !o->pickaxe_opts &&
(!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o)));
if (include_conflict_headers)
@@ -6185,7 +6228,7 @@ static void patch_id_add_mode(git_hash_ctx *ctx, unsigned mode)
}
/* returns 0 upon success, and writes result into oid */
-static int diff_get_patch_id(struct diff_options *options, struct object_id *oid, int diff_header_only, int stable)
+static int diff_get_patch_id(struct diff_options *options, struct object_id *oid, int diff_header_only)
{
struct diff_queue_struct *q = &diff_queued_diff;
int i;
@@ -6232,61 +6275,62 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
if (p->one->mode == 0) {
patch_id_add_string(&ctx, "newfilemode");
patch_id_add_mode(&ctx, p->two->mode);
- patch_id_add_string(&ctx, "---/dev/null");
- patch_id_add_string(&ctx, "+++b/");
- the_hash_algo->update_fn(&ctx, p->two->path, len2);
} else if (p->two->mode == 0) {
patch_id_add_string(&ctx, "deletedfilemode");
patch_id_add_mode(&ctx, p->one->mode);
- patch_id_add_string(&ctx, "---a/");
- the_hash_algo->update_fn(&ctx, p->one->path, len1);
- patch_id_add_string(&ctx, "+++/dev/null");
- } else {
- patch_id_add_string(&ctx, "---a/");
- the_hash_algo->update_fn(&ctx, p->one->path, len1);
- patch_id_add_string(&ctx, "+++b/");
- the_hash_algo->update_fn(&ctx, p->two->path, len2);
+ } else if (p->one->mode != p->two->mode) {
+ patch_id_add_string(&ctx, "oldmode");
+ patch_id_add_mode(&ctx, p->one->mode);
+ patch_id_add_string(&ctx, "newmode");
+ patch_id_add_mode(&ctx, p->two->mode);
}
- if (diff_header_only)
- continue;
-
- if (fill_mmfile(options->repo, &mf1, p->one) < 0 ||
- fill_mmfile(options->repo, &mf2, p->two) < 0)
- return error("unable to read files to diff");
-
- if (diff_filespec_is_binary(options->repo, p->one) ||
+ if (diff_header_only) {
+ /* don't do anything since we're only populating header info */
+ } else if (diff_filespec_is_binary(options->repo, p->one) ||
diff_filespec_is_binary(options->repo, p->two)) {
the_hash_algo->update_fn(&ctx, oid_to_hex(&p->one->oid),
the_hash_algo->hexsz);
the_hash_algo->update_fn(&ctx, oid_to_hex(&p->two->oid),
the_hash_algo->hexsz);
- continue;
- }
-
- xpp.flags = 0;
- xecfg.ctxlen = 3;
- xecfg.flags = XDL_EMIT_NO_HUNK_HDR;
- if (xdi_diff_outf(&mf1, &mf2, NULL,
- patch_id_consume, &data, &xpp, &xecfg))
- return error("unable to generate patch-id diff for %s",
- p->one->path);
+ } else {
+ if (p->one->mode == 0) {
+ patch_id_add_string(&ctx, "---/dev/null");
+ patch_id_add_string(&ctx, "+++b/");
+ the_hash_algo->update_fn(&ctx, p->two->path, len2);
+ } else if (p->two->mode == 0) {
+ patch_id_add_string(&ctx, "---a/");
+ the_hash_algo->update_fn(&ctx, p->one->path, len1);
+ patch_id_add_string(&ctx, "+++/dev/null");
+ } else {
+ patch_id_add_string(&ctx, "---a/");
+ the_hash_algo->update_fn(&ctx, p->one->path, len1);
+ patch_id_add_string(&ctx, "+++b/");
+ the_hash_algo->update_fn(&ctx, p->two->path, len2);
+ }
- if (stable)
- flush_one_hunk(oid, &ctx);
+ if (fill_mmfile(options->repo, &mf1, p->one) < 0 ||
+ fill_mmfile(options->repo, &mf2, p->two) < 0)
+ return error("unable to read files to diff");
+ xpp.flags = 0;
+ xecfg.ctxlen = 3;
+ xecfg.flags = XDL_EMIT_NO_HUNK_HDR;
+ if (xdi_diff_outf(&mf1, &mf2, NULL,
+ patch_id_consume, &data, &xpp, &xecfg))
+ return error("unable to generate patch-id diff for %s",
+ p->one->path);
+ }
+ flush_one_hunk(oid, &ctx);
}
- if (!stable)
- the_hash_algo->final_oid_fn(oid, &ctx);
-
return 0;
}
-int diff_flush_patch_id(struct diff_options *options, struct object_id *oid, int diff_header_only, int stable)
+int diff_flush_patch_id(struct diff_options *options, struct object_id *oid, int diff_header_only)
{
struct diff_queue_struct *q = &diff_queued_diff;
int i;
- int result = diff_get_patch_id(options, oid, diff_header_only, stable);
+ int result = diff_get_patch_id(options, oid, diff_header_only);
for (i = 0; i < q->nr; i++)
diff_free_filepair(q->queue[i]);
diff --git a/diff.h b/diff.h
index 8ae18e5ab1e..fd33caeb25d 100644
--- a/diff.h
+++ b/diff.h
@@ -634,7 +634,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option);
int run_diff_index(struct rev_info *revs, unsigned int option);
int do_diff_cache(const struct object_id *, struct diff_options *);
-int diff_flush_patch_id(struct diff_options *, struct object_id *, int, int);
+int diff_flush_patch_id(struct diff_options *, struct object_id *, int);
void flush_one_hunk(struct object_id *result, git_hash_ctx *ctx);
int diff_result_code(struct diff_options *, int);
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index c88e50c6329..03fcbcb40ba 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -38,7 +38,7 @@ static int diffgrep_consume(void *priv, char *line, unsigned long len)
static int diff_grep(mmfile_t *one, mmfile_t *two,
struct diff_options *o,
- regex_t *regexp, kwset_t kws)
+ regex_t *regexp, kwset_t kws UNUSED)
{
struct diffgrep_cb ecbdata;
xpparam_t xpp;
@@ -114,7 +114,7 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws,
}
static int has_changes(mmfile_t *one, mmfile_t *two,
- struct diff_options *o,
+ struct diff_options *o UNUSED,
regex_t *regexp, kwset_t kws)
{
unsigned int c1 = one ? contains(one, regexp, kws, 0) : 0;
diff --git a/dir.c b/dir.c
index 50eeb8b11eb..d604d1bab98 100644
--- a/dir.c
+++ b/dir.c
@@ -655,10 +655,10 @@ void parse_path_pattern(const char **pattern,
*patternlen = len;
}
-int pl_hashmap_cmp(const void *unused_cmp_data,
+int pl_hashmap_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *a,
const struct hashmap_entry *b,
- const void *key)
+ const void *key UNUSED)
{
const struct pattern_entry *ee1 =
container_of(a, struct pattern_entry, ent);
@@ -669,9 +669,7 @@ int pl_hashmap_cmp(const void *unused_cmp_data,
? ee1->patternlen
: ee2->patternlen;
- if (ignore_case)
- return strncasecmp(ee1->pattern, ee2->pattern, min_len);
- return strncmp(ee1->pattern, ee2->pattern, min_len);
+ return fspathncmp(ee1->pattern, ee2->pattern, min_len);
}
static char *dup_and_filter_pattern(const char *pattern)
diff --git a/environment.c b/environment.c
index b2004437dce..18d042b467d 100644
--- a/environment.c
+++ b/environment.c
@@ -334,10 +334,10 @@ static void set_git_dir_1(const char *path)
setup_git_env(path);
}
-static void update_relative_gitdir(const char *name,
+static void update_relative_gitdir(const char *name UNUSED,
const char *old_cwd,
const char *new_cwd,
- void *data)
+ void *data UNUSED)
{
char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir());
struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb();
diff --git a/exec-cmd.c b/exec-cmd.c
index eeb2ee52b83..0232bbc9905 100644
--- a/exec-cmd.c
+++ b/exec-cmd.c
@@ -252,7 +252,7 @@ static const char *system_prefix(void)
* This is called during initialization, but No work needs to be done here when
* runtime prefix is not being used.
*/
-void git_resolve_executable_dir(const char *argv0)
+void git_resolve_executable_dir(const char *argv0 UNUSED)
{
}
diff --git a/fetch-pack.c b/fetch-pack.c
index a1a508ee72e..998fc2fa1ed 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -176,8 +176,10 @@ static int rev_list_insert_ref(struct fetch_negotiator *negotiator,
return 0;
}
-static int rev_list_insert_ref_oid(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int rev_list_insert_ref_oid(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flag UNUSED,
+ void *cb_data)
{
return rev_list_insert_ref(cb_data, oid);
}
@@ -600,8 +602,10 @@ static int mark_complete(const struct object_id *oid)
return 0;
}
-static int mark_complete_oid(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int mark_complete_oid(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flag UNUSED,
+ void *cb_data UNUSED)
{
return mark_complete(oid);
}
@@ -839,7 +843,7 @@ static int everything_local(struct fetch_pack_args *args,
return retval;
}
-static int sideband_demux(int in, int out, void *data)
+static int sideband_demux(int in UNUSED, int out, void *data)
{
int *xd = data;
int ret;
diff --git a/fsck.h b/fsck.h
index 6f801e53b1d..6fbce68ad67 100644
--- a/fsck.h
+++ b/fsck.h
@@ -13,6 +13,12 @@ enum fsck_msg_type {
FSCK_WARN,
};
+/*
+ * Documentation/fsck-msgids.txt documents these; when
+ * modifying this list in any way, make sure to keep the
+ * two in sync.
+ */
+
#define FOREACH_FSCK_MSG_ID(FUNC) \
/* fatal errors */ \
FUNC(NUL_IN_HEADER, FATAL) \
@@ -24,7 +30,6 @@ enum fsck_msg_type {
FUNC(BAD_NAME, ERROR) \
FUNC(BAD_OBJECT_SHA1, ERROR) \
FUNC(BAD_PARENT_SHA1, ERROR) \
- FUNC(BAD_TAG_OBJECT, ERROR) \
FUNC(BAD_TIMEZONE, ERROR) \
FUNC(BAD_TREE, ERROR) \
FUNC(BAD_TREE_SHA1, ERROR) \
@@ -40,7 +45,6 @@ enum fsck_msg_type {
FUNC(MISSING_TAG, ERROR) \
FUNC(MISSING_TAG_ENTRY, ERROR) \
FUNC(MISSING_TREE, ERROR) \
- FUNC(MISSING_TREE_OBJECT, ERROR) \
FUNC(MISSING_TYPE, ERROR) \
FUNC(MISSING_TYPE_ENTRY, ERROR) \
FUNC(MULTIPLE_AUTHORS, ERROR) \
diff --git a/fsmonitor--daemon.h b/fsmonitor--daemon.h
index 2102a5c9ff5..e24838f9a86 100644
--- a/fsmonitor--daemon.h
+++ b/fsmonitor--daemon.h
@@ -8,6 +8,7 @@
#include "run-command.h"
#include "simple-ipc.h"
#include "thread-utils.h"
+#include "fsmonitor-path-utils.h"
struct fsmonitor_batch;
struct fsmonitor_token_data;
@@ -43,6 +44,7 @@ struct fsmonitor_daemon_state {
struct strbuf path_worktree_watch;
struct strbuf path_gitdir_watch;
+ struct alias_info alias;
int nr_paths_watching;
struct fsmonitor_token_data *current_token_data;
@@ -59,6 +61,7 @@ struct fsmonitor_daemon_state {
struct ipc_server_data *ipc_server_data;
struct strbuf path_ipc;
+
};
/*
diff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c
index 789e7397baa..19d772f0f3a 100644
--- a/fsmonitor-ipc.c
+++ b/fsmonitor-ipc.c
@@ -18,7 +18,7 @@ int fsmonitor_ipc__is_supported(void)
return 0;
}
-const char *fsmonitor_ipc__get_path(void)
+const char *fsmonitor_ipc__get_path(struct repository *r)
{
return NULL;
}
@@ -47,19 +47,21 @@ int fsmonitor_ipc__is_supported(void)
return 1;
}
-GIT_PATH_FUNC(fsmonitor_ipc__get_path, "fsmonitor--daemon.ipc")
-
enum ipc_active_state fsmonitor_ipc__get_state(void)
{
- return ipc_get_active_state(fsmonitor_ipc__get_path());
+ return ipc_get_active_state(fsmonitor_ipc__get_path(the_repository));
}
static int spawn_daemon(void)
{
- const char *args[] = { "fsmonitor--daemon", "start", NULL };
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ cmd.git_cmd = 1;
+ cmd.no_stdin = 1;
+ cmd.trace2_child_class = "fsmonitor";
+ strvec_pushl(&cmd.args, "fsmonitor--daemon", "start", NULL);
- return run_command_v_opt_tr2(args, RUN_COMMAND_NO_STDIN | RUN_GIT_CMD,
- "fsmonitor");
+ return run_command(&cmd);
}
int fsmonitor_ipc__send_query(const char *since_token,
@@ -81,8 +83,8 @@ int fsmonitor_ipc__send_query(const char *since_token,
trace2_data_string("fsm_client", NULL, "query/command", tok);
try_again:
- state = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options,
- &connection);
+ state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository),
+ &options, &connection);
switch (state) {
case IPC_STATE__LISTENING:
@@ -117,13 +119,13 @@ try_again:
case IPC_STATE__INVALID_PATH:
ret = error(_("fsmonitor_ipc__send_query: invalid path '%s'"),
- fsmonitor_ipc__get_path());
+ fsmonitor_ipc__get_path(the_repository));
goto done;
case IPC_STATE__OTHER_ERROR:
default:
ret = error(_("fsmonitor_ipc__send_query: unspecified error on '%s'"),
- fsmonitor_ipc__get_path());
+ fsmonitor_ipc__get_path(the_repository));
goto done;
}
@@ -149,8 +151,8 @@ int fsmonitor_ipc__send_command(const char *command,
options.wait_if_busy = 1;
options.wait_if_not_found = 0;
- state = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options,
- &connection);
+ state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository),
+ &options, &connection);
if (state != IPC_STATE__LISTENING) {
die(_("fsmonitor--daemon is not running"));
return -1;
diff --git a/fsmonitor-ipc.h b/fsmonitor-ipc.h
index b6a7067c3af..8b489da762b 100644
--- a/fsmonitor-ipc.h
+++ b/fsmonitor-ipc.h
@@ -3,6 +3,8 @@
#include "simple-ipc.h"
+struct repository;
+
/*
* Returns true if built-in file system monitor daemon is defined
* for this platform.
@@ -16,7 +18,7 @@ int fsmonitor_ipc__is_supported(void);
*
* Returns NULL if the daemon is not supported on this platform.
*/
-const char *fsmonitor_ipc__get_path(void);
+const char *fsmonitor_ipc__get_path(struct repository *r);
/*
* Try to determine whether there is a `git-fsmonitor--daemon` process
diff --git a/fsmonitor-path-utils.h b/fsmonitor-path-utils.h
new file mode 100644
index 00000000000..5bfdfb81c14
--- /dev/null
+++ b/fsmonitor-path-utils.h
@@ -0,0 +1,60 @@
+#ifndef FSM_PATH_UTILS_H
+#define FSM_PATH_UTILS_H
+
+#include "strbuf.h"
+
+struct alias_info
+{
+ struct strbuf alias;
+ struct strbuf points_to;
+};
+
+struct fs_info {
+ int is_remote;
+ char *typename;
+};
+
+/*
+ * Get some basic filesystem information for the given path
+ *
+ * The caller owns the storage that is occupied by fs_info and
+ * is responsible for releasing it.
+ *
+ * Returns -1 on error, zero otherwise.
+ */
+int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info);
+
+/*
+ * Determines if the filesystem that path resides on is remote.
+ *
+ * Returns -1 on error, 0 if not remote, 1 if remote.
+ */
+int fsmonitor__is_fs_remote(const char *path);
+
+/*
+ * Get the alias in given path, if any.
+ *
+ * Sets alias to the first alias that matches any part of the path.
+ *
+ * If an alias is found, info.alias and info.points_to are set to the
+ * found mapping.
+ *
+ * Returns -1 on error, 0 otherwise.
+ *
+ * The caller owns the storage that is occupied by info.alias and
+ * info.points_to and is responsible for releasing it.
+ */
+int fsmonitor__get_alias(const char *path, struct alias_info *info);
+
+/*
+ * Resolve the path against the given alias.
+ *
+ * Returns the resolved path if there is one, NULL otherwise.
+ *
+ * The caller owns the storage that the returned string occupies and
+ * is responsible for releasing it.
+ */
+char *fsmonitor__resolve_alias(const char *path,
+ const struct alias_info *info);
+
+#endif
diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c
index 464424a1e92..ee63a97dc51 100644
--- a/fsmonitor-settings.c
+++ b/fsmonitor-settings.c
@@ -1,7 +1,9 @@
#include "cache.h"
#include "config.h"
#include "repository.h"
+#include "fsmonitor-ipc.h"
#include "fsmonitor-settings.h"
+#include "fsmonitor-path-utils.h"
/*
* We keep this structure defintion private and have getters
@@ -13,7 +15,53 @@ struct fsmonitor_settings {
char *hook_path;
};
-static enum fsmonitor_reason check_for_incompatible(struct repository *r)
+/*
+ * Remote working directories are problematic for FSMonitor.
+ *
+ * The underlying file system on the server machine and/or the remote
+ * mount type dictates whether notification events are available at
+ * all to remote client machines.
+ *
+ * Kernel differences between the server and client machines also
+ * dictate the how (buffering, frequency, de-dup) the events are
+ * delivered to client machine processes.
+ *
+ * A client machine (such as a laptop) may choose to suspend/resume
+ * and it is unclear (without lots of testing) whether the watcher can
+ * resync after a resume. We might be able to treat this as a normal
+ * "events were dropped by the kernel" event and do our normal "flush
+ * and resync" --or-- we might need to close the existing (zombie?)
+ * notification fd and create a new one.
+ *
+ * In theory, the above issues need to be addressed whether we are
+ * using the Hook or IPC API.
+ *
+ * So (for now at least), mark remote working directories as
+ * incompatible unless 'fsmonitor.allowRemote' is true.
+ *
+ */
+#ifdef HAVE_FSMONITOR_OS_SETTINGS
+static enum fsmonitor_reason check_remote(struct repository *r)
+{
+ int allow_remote = -1; /* -1 unset, 0 not allowed, 1 allowed */
+ int is_remote = fsmonitor__is_fs_remote(r->worktree);
+
+ switch (is_remote) {
+ case 0:
+ return FSMONITOR_REASON_OK;
+ case 1:
+ repo_config_get_bool(r, "fsmonitor.allowremote", &allow_remote);
+ if (allow_remote < 1)
+ return FSMONITOR_REASON_REMOTE;
+ else
+ return FSMONITOR_REASON_OK;
+ default:
+ return FSMONITOR_REASON_ERROR;
+ }
+}
+#endif
+
+static enum fsmonitor_reason check_for_incompatible(struct repository *r, int ipc)
{
if (!r->worktree) {
/*
@@ -27,7 +75,10 @@ static enum fsmonitor_reason check_for_incompatible(struct repository *r)
{
enum fsmonitor_reason reason;
- reason = fsm_os__incompatible(r);
+ reason = check_remote(r);
+ if (reason != FSMONITOR_REASON_OK)
+ return reason;
+ reason = fsm_os__incompatible(r, ipc);
if (reason != FSMONITOR_REASON_OK)
return reason;
}
@@ -112,7 +163,7 @@ const char *fsm_settings__get_hook_path(struct repository *r)
void fsm_settings__set_ipc(struct repository *r)
{
- enum fsmonitor_reason reason = check_for_incompatible(r);
+ enum fsmonitor_reason reason = check_for_incompatible(r, 1);
if (reason != FSMONITOR_REASON_OK) {
fsm_settings__set_incompatible(r, reason);
@@ -135,7 +186,7 @@ void fsm_settings__set_ipc(struct repository *r)
void fsm_settings__set_hook(struct repository *r, const char *path)
{
- enum fsmonitor_reason reason = check_for_incompatible(r);
+ enum fsmonitor_reason reason = check_for_incompatible(r, 0);
if (reason != FSMONITOR_REASON_OK) {
fsm_settings__set_incompatible(r, reason);
@@ -192,10 +243,11 @@ enum fsmonitor_reason fsm_settings__get_reason(struct repository *r)
return r->settings.fsmonitor->reason;
}
-char *fsm_settings__get_incompatible_msg(const struct repository *r,
+char *fsm_settings__get_incompatible_msg(struct repository *r,
enum fsmonitor_reason reason)
{
struct strbuf msg = STRBUF_INIT;
+ const char *socket_dir;
switch (reason) {
case FSMONITOR_REASON_UNTESTED:
@@ -231,9 +283,11 @@ char *fsm_settings__get_incompatible_msg(const struct repository *r,
goto done;
case FSMONITOR_REASON_NOSOCKETS:
+ socket_dir = dirname((char *)fsmonitor_ipc__get_path(r));
strbuf_addf(&msg,
- _("repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"),
- r->worktree);
+ _("socket directory '%s' is incompatible with fsmonitor due"
+ " to lack of Unix sockets support"),
+ socket_dir);
goto done;
}
diff --git a/fsmonitor-settings.h b/fsmonitor-settings.h
index d9c2605197f..ab02e3995ee 100644
--- a/fsmonitor-settings.h
+++ b/fsmonitor-settings.h
@@ -33,7 +33,7 @@ enum fsmonitor_mode fsm_settings__get_mode(struct repository *r);
const char *fsm_settings__get_hook_path(struct repository *r);
enum fsmonitor_reason fsm_settings__get_reason(struct repository *r);
-char *fsm_settings__get_incompatible_msg(const struct repository *r,
+char *fsm_settings__get_incompatible_msg(struct repository *r,
enum fsmonitor_reason reason);
struct fsmonitor_settings;
@@ -48,7 +48,7 @@ struct fsmonitor_settings;
* fsm_os__* routines should considered private to fsm_settings__
* routines.
*/
-enum fsmonitor_reason fsm_os__incompatible(struct repository *r);
+enum fsmonitor_reason fsm_os__incompatible(struct repository *r, int ipc);
#endif /* HAVE_FSMONITOR_OS_SETTINGS */
#endif /* FSMONITOR_SETTINGS_H */
diff --git a/fsmonitor.c b/fsmonitor.c
index 57d6a483bee..08af00c7387 100644
--- a/fsmonitor.c
+++ b/fsmonitor.c
@@ -295,6 +295,7 @@ static int fsmonitor_force_update_threshold = 100;
void refresh_fsmonitor(struct index_state *istate)
{
+ static int warn_once = 0;
struct strbuf query_result = STRBUF_INIT;
int query_success = 0, hook_version = -1;
size_t bol = 0; /* beginning of line */
@@ -305,6 +306,14 @@ void refresh_fsmonitor(struct index_state *istate)
int is_trivial = 0;
struct repository *r = istate->repo ? istate->repo : the_repository;
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
+ enum fsmonitor_reason reason = fsm_settings__get_reason(r);
+
+ if (!warn_once && reason > FSMONITOR_REASON_OK) {
+ char *msg = fsm_settings__get_incompatible_msg(r, reason);
+ warn_once = 1;
+ warning("%s", msg);
+ free(msg);
+ }
if (fsm_mode <= FSMONITOR_MODE_DISABLED ||
istate->fsmonitor_has_run_once)
diff --git a/gettext.c b/gettext.c
index bb5ba1fe7cc..f139008d0a3 100644
--- a/gettext.c
+++ b/gettext.c
@@ -10,7 +10,6 @@
#include "config.h"
#ifndef NO_GETTEXT
-# include <locale.h>
# include <libintl.h>
# ifdef GIT_WINDOWS_NATIVE
@@ -80,7 +79,6 @@ static int test_vsnprintf(const char *fmt, ...)
static void init_gettext_charset(const char *domain)
{
- setlocale(LC_CTYPE, "");
charset = locale_charset();
bind_textdomain_codeset(domain, charset);
diff --git a/git-bisect.sh b/git-bisect.sh
index 405cf76f2a3..dfce4b4f44e 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -57,28 +57,11 @@ case "$#" in
case "$cmd" in
help)
git bisect -h ;;
- start)
- git bisect--helper --bisect-start "$@" ;;
bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD")
- git bisect--helper --bisect-state "$cmd" "$@" ;;
- skip)
- git bisect--helper --bisect-skip "$@" || exit;;
- next)
- # Not sure we want "next" at the UI level anymore.
- git bisect--helper --bisect-next "$@" || exit ;;
- visualize|view)
- git bisect--helper --bisect-visualize "$@" || exit;;
- reset)
- git bisect--helper --bisect-reset "$@" ;;
- replay)
- git bisect--helper --bisect-replay "$@" || exit;;
+ git bisect--helper state "$cmd" "$@" ;;
log)
- git bisect--helper --bisect-log || exit ;;
- run)
- git bisect--helper --bisect-run "$@" || exit;;
- terms)
- git bisect--helper --bisect-terms "$@" || exit;;
+ git bisect--helper log || exit ;;
*)
- usage ;;
+ git bisect--helper "$cmd" "$@" ;;
esac
esac
diff --git a/git-compat-util.h b/git-compat-util.h
index 4e51a1c48bc..a76d0526f79 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -189,6 +189,16 @@ struct strbuf;
#define _NETBSD_SOURCE 1
#define _SGI_SOURCE 1
+#if GIT_GNUC_PREREQ(4, 5)
+#define UNUSED __attribute__((unused)) \
+ __attribute__((deprecated ("parameter declared as UNUSED")))
+#elif defined(__GNUC__)
+#define UNUSED __attribute__((unused)) \
+ __attribute__((deprecated))
+#else
+#define UNUSED
+#endif
+
#if defined(WIN32) && !defined(__CYGWIN__) /* Both MinGW and MSVC */
# if !defined(_WIN32_WINNT)
# define _WIN32_WINNT 0x0600
@@ -215,6 +225,7 @@ struct strbuf;
#endif
#include <errno.h>
#include <limits.h>
+#include <locale.h>
#ifdef NEEDS_SYS_PARAM_H
#include <sys/param.h>
#endif
@@ -303,7 +314,9 @@ typedef unsigned long uintptr_t;
#ifdef PRECOMPOSE_UNICODE
#include "compat/precompose_utf8.h"
#else
-static inline const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix)
+static inline const char *precompose_argv_prefix(int argc UNUSED,
+ const char **argv UNUSED,
+ const char *prefix)
{
return prefix;
}
@@ -328,7 +341,9 @@ struct itimerval {
#endif
#ifdef NO_SETITIMER
-static inline int setitimer(int which, const struct itimerval *value, struct itimerval *newvalue) {
+static inline int setitimer(int which UNUSED,
+ const struct itimerval *value UNUSED,
+ struct itimerval *newvalue UNUSED) {
return 0; /* pretend success */
}
#endif
@@ -398,7 +413,9 @@ typedef uintmax_t timestamp_t;
#endif
#ifndef platform_core_config
-static inline int noop_core_config(const char *var, const char *value, void *cb)
+static inline int noop_core_config(const char *var UNUSED,
+ const char *value UNUSED,
+ void *cb UNUSED)
{
return 0;
}
@@ -411,7 +428,7 @@ int lstat_cache_aware_rmdir(const char *path);
#endif
#ifndef has_dos_drive_prefix
-static inline int git_has_dos_drive_prefix(const char *path)
+static inline int git_has_dos_drive_prefix(const char *path UNUSED)
{
return 0;
}
@@ -419,7 +436,7 @@ static inline int git_has_dos_drive_prefix(const char *path)
#endif
#ifndef skip_dos_drive_prefix
-static inline int git_skip_dos_drive_prefix(char **path)
+static inline int git_skip_dos_drive_prefix(char **path UNUSED)
{
return 0;
}
@@ -491,7 +508,8 @@ static inline void extract_id_from_env(const char *env, uid_t *id)
}
}
-static inline int is_path_owned_by_current_uid(const char *path, struct strbuf *report)
+static inline int is_path_owned_by_current_uid(const char *path,
+ struct strbuf *report UNUSED)
{
struct stat st;
uid_t euid;
@@ -569,8 +587,11 @@ static inline int git_has_dir_sep(const char *path)
/* The sentinel attribute is valid from gcc version 4.0 */
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define LAST_ARG_MUST_BE_NULL __attribute__((sentinel))
+/* warn_unused_result exists as of gcc 3.4.0, but be lazy and check 4.0 */
+#define RESULT_MUST_BE_USED __attribute__ ((warn_unused_result))
#else
#define LAST_ARG_MUST_BE_NULL
+#define RESULT_MUST_BE_USED
#endif
#define MAYBE_UNUSED __attribute__((__unused__))
@@ -1450,11 +1471,11 @@ int open_nofollow(const char *path, int flags);
#endif
#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
-static inline void flockfile(FILE *fh)
+static inline void flockfile(FILE *fh UNUSED)
{
; /* nothing */
}
-static inline void funlockfile(FILE *fh)
+static inline void funlockfile(FILE *fh UNUSED)
{
; /* nothing */
}
diff --git a/git-submodule.sh b/git-submodule.sh
index 5e5d21c010f..9a50f2e9124 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -343,7 +343,6 @@ cmd_update()
${recursive:+--recursive} \
${init:+--init} \
${nofetch:+--no-fetch} \
- ${wt_prefix:+--prefix "$wt_prefix"} \
${rebase:+--rebase} \
${merge:+--merge} \
${checkout:+--checkout} \
@@ -557,7 +556,7 @@ cmd_sync()
cmd_absorbgitdirs()
{
- git submodule--helper absorbgitdirs --prefix "$wt_prefix" "$@"
+ git ${wt_prefix:+-C "$wt_prefix"} submodule--helper absorbgitdirs "$@"
}
# This loop parses the command line arguments to find the
diff --git a/git.c b/git.c
index 0b9d8ef7677..10202a7f126 100644
--- a/git.c
+++ b/git.c
@@ -489,14 +489,14 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
static struct cmd_struct commands[] = {
{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
{ "am", cmd_am, RUN_SETUP | NEED_WORK_TREE },
- { "annotate", cmd_annotate, RUN_SETUP | NO_PARSEOPT },
+ { "annotate", cmd_annotate, RUN_SETUP },
{ "apply", cmd_apply, RUN_SETUP_GENTLY },
{ "archive", cmd_archive, RUN_SETUP_GENTLY },
{ "bisect--helper", cmd_bisect__helper, RUN_SETUP },
{ "blame", cmd_blame, RUN_SETUP },
{ "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG },
{ "bugreport", cmd_bugreport, RUN_SETUP_GENTLY },
- { "bundle", cmd_bundle, RUN_SETUP_GENTLY | NO_PARSEOPT },
+ { "bundle", cmd_bundle, RUN_SETUP_GENTLY },
{ "cat-file", cmd_cat_file, RUN_SETUP },
{ "check-attr", cmd_check_attr, RUN_SETUP },
{ "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
@@ -514,7 +514,7 @@ static struct cmd_struct commands[] = {
{ "column", cmd_column, RUN_SETUP_GENTLY },
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-graph", cmd_commit_graph, RUN_SETUP },
- { "commit-tree", cmd_commit_tree, RUN_SETUP | NO_PARSEOPT },
+ { "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config, RUN_SETUP_GENTLY | DELAY_PAGER_CONFIG },
{ "count-objects", cmd_count_objects, RUN_SETUP },
{ "credential", cmd_credential, RUN_SETUP_GENTLY | NO_PARSEOPT },
@@ -554,9 +554,9 @@ static struct cmd_struct commands[] = {
{ "ls-files", cmd_ls_files, RUN_SETUP },
{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
- { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT },
+ { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY },
{ "mailsplit", cmd_mailsplit, NO_PARSEOPT },
- { "maintenance", cmd_maintenance, RUN_SETUP | NO_PARSEOPT },
+ { "maintenance", cmd_maintenance, RUN_SETUP },
{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
{ "merge-base", cmd_merge_base, RUN_SETUP },
{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
@@ -567,7 +567,7 @@ static struct cmd_struct commands[] = {
{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-tree", cmd_merge_tree, RUN_SETUP },
- { "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
+ { "mktag", cmd_mktag, RUN_SETUP },
{ "mktree", cmd_mktree, RUN_SETUP },
{ "multi-pack-index", cmd_multi_pack_index, RUN_SETUP },
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
@@ -628,7 +628,7 @@ static struct cmd_struct commands[] = {
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
{ "version", cmd_version },
{ "whatchanged", cmd_whatchanged, RUN_SETUP },
- { "worktree", cmd_worktree, RUN_SETUP | NO_PARSEOPT },
+ { "worktree", cmd_worktree, RUN_SETUP },
{ "write-tree", cmd_write_tree, RUN_SETUP },
};
@@ -787,7 +787,7 @@ static int run_argv(int *argcp, const char ***argv)
if (!done_alias)
handle_builtin(*argcp, *argv);
else if (get_builtin(**argv)) {
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int i;
/*
@@ -804,18 +804,21 @@ static int run_argv(int *argcp, const char ***argv)
commit_pager_choice();
- strvec_push(&args, "git");
+ strvec_push(&cmd.args, "git");
for (i = 0; i < *argcp; i++)
- strvec_push(&args, (*argv)[i]);
+ strvec_push(&cmd.args, (*argv)[i]);
- trace_argv_printf(args.v, "trace: exec:");
+ trace_argv_printf(cmd.args.v, "trace: exec:");
/*
* if we fail because the command is not found, it is
* OK to return. Otherwise, we just pass along the status code.
*/
- i = run_command_v_opt_tr2(args.v, RUN_SILENT_EXEC_FAILURE |
- RUN_CLEAN_ON_EXIT | RUN_WAIT_AFTER_CLEAN, "git_alias");
+ cmd.silent_exec_failure = 1;
+ cmd.clean_on_exit = 1;
+ cmd.wait_after_clean = 1;
+ cmd.trace2_child_class = "git_alias";
+ i = run_command(&cmd);
if (i >= 0 || errno != ENOENT)
exit(i);
die("could not execute builtin %s", **argv);
@@ -894,12 +897,8 @@ int cmd_main(int argc, const char **argv)
argv++;
argc--;
handle_options(&argv, &argc, NULL);
- if (argc > 0) {
- if (!strcmp("--version", argv[0]) || !strcmp("-v", argv[0]))
- argv[0] = "version";
- else if (!strcmp("--help", argv[0]) || !strcmp("-h", argv[0]))
- argv[0] = "help";
- } else {
+
+ if (!argc) {
/* The user didn't specify a command; give them help */
commit_pager_choice();
printf(_("usage: %s\n\n"), git_usage_string);
@@ -907,6 +906,12 @@ int cmd_main(int argc, const char **argv)
printf("\n%s\n", _(git_more_info_string));
exit(1);
}
+
+ if (!strcmp("--version", argv[0]) || !strcmp("-v", argv[0]))
+ argv[0] = "version";
+ else if (!strcmp("--help", argv[0]) || !strcmp("-h", argv[0]))
+ argv[0] = "help";
+
cmd = argv[0];
/*
diff --git a/gpg-interface.c b/gpg-interface.c
index 6dff2414603..f877a1ea564 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -699,7 +699,7 @@ void set_signing_key(const char *key)
configured_signing_key = xstrdup(key);
}
-int git_gpg_config(const char *var, const char *value, void *cb)
+int git_gpg_config(const char *var, const char *value, void *cb UNUSED)
{
struct gpg_format *fmt = NULL;
char *fmtname = NULL;
@@ -1059,12 +1059,11 @@ static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature,
strbuf_addbuf(&ssh_signature_filename, &buffer_file->filename);
strbuf_addstr(&ssh_signature_filename, ".sig");
if (strbuf_read_file(signature, ssh_signature_filename.buf, 0) < 0) {
- error_errno(
+ ret = error_errno(
_("failed reading ssh signing data buffer from '%s'"),
ssh_signature_filename.buf);
+ goto out;
}
- unlink_or_warn(ssh_signature_filename.buf);
-
/* Strip CR from the line endings, in case we are on Windows. */
remove_cr_after(signature, bottom);
@@ -1073,6 +1072,8 @@ out:
delete_tempfile(&key_file);
if (buffer_file)
delete_tempfile(&buffer_file);
+ if (ssh_signature_filename.len)
+ unlink_or_warn(ssh_signature_filename.buf);
strbuf_release(&signer_stderr);
strbuf_release(&ssh_signature_filename);
FREE_AND_NULL(ssh_signing_key_file);
diff --git a/grep.c b/grep.c
index 52a894c9890..06eed694936 100644
--- a/grep.c
+++ b/grep.c
@@ -708,6 +708,7 @@ void compile_grep_patterns(struct grep_opt *opt)
{
struct grep_pat *p;
struct grep_expr *header_expr = prep_header_patterns(opt);
+ int extended = 0;
for (p = opt->pattern_list; p; p = p->next) {
switch (p->token) {
@@ -717,14 +718,14 @@ void compile_grep_patterns(struct grep_opt *opt)
compile_regexp(p, opt);
break;
default:
- opt->extended = 1;
+ extended = 1;
break;
}
}
if (opt->all_match || opt->no_body_match || header_expr)
- opt->extended = 1;
- else if (!opt->extended)
+ extended = 1;
+ else if (!extended)
return;
p = opt->pattern_list;
@@ -790,7 +791,7 @@ void free_grep_patterns(struct grep_opt *opt)
free(p);
}
- if (!opt->extended)
+ if (!opt->pattern_expression)
return;
free_pattern_expr(opt->pattern_expression);
}
@@ -971,8 +972,6 @@ static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x,
{
int h = 0;
- if (!x)
- die("Not a valid grep expression");
switch (x->node) {
case GREP_NODE_TRUE:
h = 1;
@@ -1052,7 +1051,7 @@ static int match_line(struct grep_opt *opt,
struct grep_pat *p;
int hit = 0;
- if (opt->extended)
+ if (opt->pattern_expression)
return match_expr(opt, bol, eol, ctx, col, icol,
collect_hits);
@@ -1370,7 +1369,7 @@ static int should_lookahead(struct grep_opt *opt)
{
struct grep_pat *p;
- if (opt->extended)
+ if (opt->pattern_expression)
return 0; /* punt for too complex stuff */
if (opt->invert)
return 0;
diff --git a/grep.h b/grep.h
index bdcadce61b8..6075f997e68 100644
--- a/grep.h
+++ b/grep.h
@@ -151,7 +151,6 @@ struct grep_opt {
#define GREP_BINARY_TEXT 2
int binary;
int allow_textconv;
- int extended;
int use_reflog_filter;
int relative;
int pathname;
diff --git a/hash.h b/hash.h
index ea87ae9d92f..36b64165fc9 100644
--- a/hash.h
+++ b/hash.h
@@ -4,9 +4,7 @@
#include "git-compat-util.h"
#include "repository.h"
-#if defined(SHA1_PPC)
-#include "ppc/sha1.h"
-#elif defined(SHA1_APPLE)
+#if defined(SHA1_APPLE)
#include <CommonCrypto/CommonDigest.h>
#elif defined(SHA1_OPENSSL)
#include <openssl/sha.h>
@@ -32,7 +30,7 @@
* platform's underlying implementation of SHA-1; could be OpenSSL,
* blk_SHA, Apple CommonCrypto, etc... Note that the relevant
* SHA-1 header may have already defined platform_SHA_CTX for our
- * own implementations like block-sha1 and ppc-sha1, so we list
+ * own implementations like block-sha1, so we list
* the default for OpenSSL compatible SHA-1 implementations here.
*/
#define platform_SHA_CTX SHA_CTX
diff --git a/hashmap.c b/hashmap.c
index 134d2eec804..cf5fea87eb0 100644
--- a/hashmap.c
+++ b/hashmap.c
@@ -142,10 +142,10 @@ static inline struct hashmap_entry **find_entry_ptr(const struct hashmap *map,
return e;
}
-static int always_equal(const void *unused_cmp_data,
- const struct hashmap_entry *unused1,
- const struct hashmap_entry *unused2,
- const void *unused_keydata)
+static int always_equal(const void *cmp_data UNUSED,
+ const struct hashmap_entry *entry1 UNUSED,
+ const struct hashmap_entry *entry2 UNUSED,
+ const void *keydata UNUSED)
{
return 0;
}
@@ -313,7 +313,7 @@ struct pool_entry {
unsigned char data[FLEX_ARRAY];
};
-static int pool_entry_cmp(const void *unused_cmp_data,
+static int pool_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
diff --git a/help.c b/help.c
index 991e33f8a6e..f1e090a4428 100644
--- a/help.c
+++ b/help.c
@@ -39,7 +39,7 @@ static struct category_description main_categories[] = {
{ CAT_synchingrepositories, N_("Low-level Commands / Syncing Repositories") },
{ CAT_purehelpers, N_("Low-level Commands / Internal Helpers") },
{ CAT_userinterfaces, N_("User-facing repository, command and file interfaces") },
- { CAT_developerinterfaces, N_("Developer-facing file file formats, protocols and interfaces") },
+ { CAT_developerinterfaces, N_("Developer-facing file formats, protocols and other interfaces") },
{ 0, NULL }
};
@@ -757,7 +757,7 @@ int cmd_version(int argc, const char **argv, const char *prefix)
struct strbuf buf = STRBUF_INIT;
int build_options = 0;
const char * const usage[] = {
- N_("git version [<options>]"),
+ N_("git version [--build-options]"),
NULL
};
struct option options[] = {
@@ -781,8 +781,9 @@ struct similar_ref_cb {
struct string_list *similar_refs;
};
-static int append_similar_ref(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+static int append_similar_ref(const char *refname,
+ const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data)
{
struct similar_ref_cb *cb = (struct similar_ref_cb *)(cb_data);
char *branch = strrchr(refname, '/') + 1;
diff --git a/hook.c b/hook.c
index a493939a4fc..a4fa1031f28 100644
--- a/hook.c
+++ b/hook.c
@@ -114,8 +114,20 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
.options = options,
};
const char *const hook_path = find_hook(hook_name);
- int jobs = 1;
int ret = 0;
+ const struct run_process_parallel_opts opts = {
+ .tr2_category = "hook",
+ .tr2_label = hook_name,
+
+ .processes = 1,
+ .ungroup = 1,
+
+ .get_next_task = pick_next_hook,
+ .start_failure = notify_start_failure,
+ .task_finished = notify_hook_finished,
+
+ .data = &cb_data,
+ };
if (!options)
BUG("a struct run_hooks_opt must be provided to run_hooks");
@@ -137,14 +149,7 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
cb_data.hook_path = abs_path.buf;
}
- run_processes_parallel_ungroup = 1;
- run_processes_parallel_tr2(jobs,
- pick_next_hook,
- notify_start_failure,
- notify_hook_finished,
- &cb_data,
- "hook",
- hook_name);
+ run_processes_parallel(&opts);
ret = cb_data.rc;
cleanup:
strbuf_release(&abs_path);
diff --git a/http-backend.c b/http-backend.c
index 58b83a9f66b..6eb3b2fe51c 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -505,7 +505,7 @@ static void run_service(const char **argv, int buffer_input)
}
static int show_text_ref(const char *name, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data)
{
const char *name_nons = strip_namespace(name);
struct strbuf *buf = cb_data;
diff --git a/ident.c b/ident.c
index 7f66beda428..6de76f9421d 100644
--- a/ident.c
+++ b/ident.c
@@ -668,7 +668,7 @@ static int set_ident(const char *var, const char *value)
return 0;
}
-int git_ident_config(const char *var, const char *value, void *data)
+int git_ident_config(const char *var, const char *value, void *data UNUSED)
{
if (!strcmp(var, "user.useconfigonly")) {
ident_use_config_only = git_config_bool(var, value);
diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c
index 4b25287886d..53396602380 100644
--- a/list-objects-filter-options.c
+++ b/list-objects-filter-options.c
@@ -108,7 +108,7 @@ int gently_parse_list_objects_filter(
strbuf_addf(errbuf, _("invalid filter-spec '%s'"), arg);
- memset(filter_options, 0, sizeof(*filter_options));
+ list_objects_filter_init(filter_options);
return 1;
}
@@ -143,6 +143,7 @@ static int parse_combine_subfilter(
ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
filter_options->sub_alloc);
+ list_objects_filter_init(&filter_options->sub[new_index]);
decoded = url_percent_decode(subspec->buf);
@@ -187,10 +188,8 @@ static int parse_combine_filter(
cleanup:
strbuf_list_free(subspecs);
- if (result) {
+ if (result)
list_objects_filter_release(filter_options);
- memset(filter_options, 0, sizeof(*filter_options));
- }
return result;
}
@@ -204,10 +203,10 @@ static int allow_unencoded(char ch)
static void filter_spec_append_urlencode(
struct list_objects_filter_options *filter, const char *raw)
{
- struct strbuf buf = STRBUF_INIT;
- strbuf_addstr_urlencode(&buf, raw, allow_unencoded);
- trace_printf("Add to combine filter-spec: %s\n", buf.buf);
- string_list_append(&filter->filter_spec, strbuf_detach(&buf, NULL));
+ size_t orig_len = filter->filter_spec.len;
+ strbuf_addstr_urlencode(&filter->filter_spec, raw, allow_unencoded);
+ trace_printf("Add to combine filter-spec: %s\n",
+ filter->filter_spec.buf + orig_len);
}
/*
@@ -225,13 +224,13 @@ static void transform_to_combine_type(
struct list_objects_filter_options *sub_array =
xcalloc(initial_sub_alloc, sizeof(*sub_array));
sub_array[0] = *filter_options;
- memset(filter_options, 0, sizeof(*filter_options));
+ list_objects_filter_init(filter_options);
filter_options->sub = sub_array;
filter_options->sub_alloc = initial_sub_alloc;
}
filter_options->sub_nr = 1;
filter_options->choice = LOFC_COMBINE;
- string_list_append(&filter_options->filter_spec, xstrdup("combine:"));
+ strbuf_addstr(&filter_options->filter_spec, "combine:");
filter_spec_append_urlencode(
filter_options,
list_objects_filter_spec(&filter_options->sub[0]));
@@ -239,7 +238,7 @@ static void transform_to_combine_type(
* We don't need the filter_spec strings for subfilter specs, only the
* top level.
*/
- string_list_clear(&filter_options->sub[0].filter_spec, /*free_util=*/0);
+ strbuf_release(&filter_options->sub[0].filter_spec);
}
void list_objects_filter_die_if_populated(
@@ -256,26 +255,32 @@ void parse_list_objects_filter(
struct strbuf errbuf = STRBUF_INIT;
int parse_error;
+ if (!filter_options->filter_spec.buf)
+ BUG("filter_options not properly initialized");
+
if (!filter_options->choice) {
- string_list_append(&filter_options->filter_spec, xstrdup(arg));
+ strbuf_addstr(&filter_options->filter_spec, arg);
parse_error = gently_parse_list_objects_filter(
filter_options, arg, &errbuf);
} else {
+ struct list_objects_filter_options *sub;
+
/*
* Make filter_options an LOFC_COMBINE spec so we can trivially
* add subspecs to it.
*/
transform_to_combine_type(filter_options);
- string_list_append(&filter_options->filter_spec, xstrdup("+"));
+ strbuf_addch(&filter_options->filter_spec, '+');
filter_spec_append_urlencode(filter_options, arg);
ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
filter_options->sub_alloc);
+ sub = &filter_options->sub[filter_options->sub_nr - 1];
- parse_error = gently_parse_list_objects_filter(
- &filter_options->sub[filter_options->sub_nr - 1], arg,
- &errbuf);
+ list_objects_filter_init(sub);
+ parse_error = gently_parse_list_objects_filter(sub, arg,
+ &errbuf);
}
if (parse_error)
die("%s", errbuf.buf);
@@ -299,31 +304,18 @@ int opt_parse_list_objects_filter(const struct option *opt,
const char *list_objects_filter_spec(struct list_objects_filter_options *filter)
{
- if (!filter->filter_spec.nr)
+ if (!filter->filter_spec.len)
BUG("no filter_spec available for this filter");
- if (filter->filter_spec.nr != 1) {
- struct strbuf concatted = STRBUF_INIT;
- strbuf_add_separated_string_list(
- &concatted, "", &filter->filter_spec);
- string_list_clear(&filter->filter_spec, /*free_util=*/0);
- string_list_append(
- &filter->filter_spec, strbuf_detach(&concatted, NULL));
- }
-
- return filter->filter_spec.items[0].string;
+ return filter->filter_spec.buf;
}
const char *expand_list_objects_filter_spec(
struct list_objects_filter_options *filter)
{
if (filter->choice == LOFC_BLOB_LIMIT) {
- struct strbuf expanded_spec = STRBUF_INIT;
- strbuf_addf(&expanded_spec, "blob:limit=%lu",
+ strbuf_release(&filter->filter_spec);
+ strbuf_addf(&filter->filter_spec, "blob:limit=%lu",
filter->blob_limit_value);
- string_list_clear(&filter->filter_spec, /*free_util=*/0);
- string_list_append(
- &filter->filter_spec,
- strbuf_detach(&expanded_spec, NULL));
}
return list_objects_filter_spec(filter);
@@ -336,12 +328,12 @@ void list_objects_filter_release(
if (!filter_options)
return;
- string_list_clear(&filter_options->filter_spec, /*free_util=*/0);
+ strbuf_release(&filter_options->filter_spec);
free(filter_options->sparse_oid_name);
for (sub = 0; sub < filter_options->sub_nr; sub++)
list_objects_filter_release(&filter_options->sub[sub]);
free(filter_options->sub);
- memset(filter_options, 0, sizeof(*filter_options));
+ list_objects_filter_init(filter_options);
}
void partial_clone_register(
@@ -394,11 +386,11 @@ void partial_clone_get_default_filter_spec(
/*
* Parse default value, but silently ignore it if it is invalid.
*/
- if (!promisor)
+ if (!promisor || !promisor->partial_clone_filter)
return;
- string_list_append(&filter_options->filter_spec,
- promisor->partial_clone_filter);
+ strbuf_addstr(&filter_options->filter_spec,
+ promisor->partial_clone_filter);
gently_parse_list_objects_filter(filter_options,
promisor->partial_clone_filter,
&errbuf);
@@ -410,16 +402,21 @@ void list_objects_filter_copy(
const struct list_objects_filter_options *src)
{
int i;
- struct string_list_item *item;
/* Copy everything. We will overwrite the pointers shortly. */
memcpy(dest, src, sizeof(struct list_objects_filter_options));
- string_list_init_dup(&dest->filter_spec);
- for_each_string_list_item(item, &src->filter_spec)
- string_list_append(&dest->filter_spec, item->string);
+ strbuf_init(&dest->filter_spec, 0);
+ strbuf_addbuf(&dest->filter_spec, &src->filter_spec);
+ dest->sparse_oid_name = xstrdup_or_null(src->sparse_oid_name);
ALLOC_ARRAY(dest->sub, dest->sub_alloc);
for (i = 0; i < src->sub_nr; i++)
list_objects_filter_copy(&dest->sub[i], &src->sub[i]);
}
+
+void list_objects_filter_init(struct list_objects_filter_options *filter_options)
+{
+ struct list_objects_filter_options blank = LIST_OBJECTS_FILTER_INIT;
+ memcpy(filter_options, &blank, sizeof(*filter_options));
+}
diff --git a/list-objects-filter-options.h b/list-objects-filter-options.h
index ffc02d77e76..7eeadab2dd0 100644
--- a/list-objects-filter-options.h
+++ b/list-objects-filter-options.h
@@ -35,7 +35,7 @@ struct list_objects_filter_options {
* To get the raw filter spec given by the user, use the result of
* list_objects_filter_spec().
*/
- struct string_list filter_spec;
+ struct strbuf filter_spec;
/*
* 'choice' is determined by parsing the filter-spec. This indicates
@@ -69,6 +69,9 @@ struct list_objects_filter_options {
*/
};
+#define LIST_OBJECTS_FILTER_INIT { .filter_spec = STRBUF_INIT }
+void list_objects_filter_init(struct list_objects_filter_options *filter_options);
+
/*
* Parse value of the argument to the "filter" keyword.
* On the command line this looks like:
diff --git a/ll-merge.c b/ll-merge.c
index 14b83620191..22a603e8af4 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -49,14 +49,14 @@ void reset_merge_attributes(void)
/*
* Built-in low-levels
*/
-static enum ll_merge_result ll_binary_merge(const struct ll_merge_driver *drv_unused,
+static enum ll_merge_result ll_binary_merge(const struct ll_merge_driver *drv UNUSED,
mmbuffer_t *result,
- const char *path,
- mmfile_t *orig, const char *orig_name,
- mmfile_t *src1, const char *name1,
- mmfile_t *src2, const char *name2,
+ const char *path UNUSED,
+ mmfile_t *orig, const char *orig_name UNUSED,
+ mmfile_t *src1, const char *name1 UNUSED,
+ mmfile_t *src2, const char *name2 UNUSED,
const struct ll_merge_options *opts,
- int marker_size)
+ int marker_size UNUSED)
{
enum ll_merge_result ret;
mmfile_t *stolen;
@@ -183,9 +183,9 @@ static void create_temp(mmfile_t *src, char *path, size_t len)
static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
mmbuffer_t *result,
const char *path,
- mmfile_t *orig, const char *orig_name,
- mmfile_t *src1, const char *name1,
- mmfile_t *src2, const char *name2,
+ mmfile_t *orig, const char *orig_name UNUSED,
+ mmfile_t *src1, const char *name1 UNUSED,
+ mmfile_t *src2, const char *name2 UNUSED,
const struct ll_merge_options *opts,
int marker_size)
{
@@ -193,7 +193,7 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
struct strbuf cmd = STRBUF_INIT;
struct strbuf_expand_dict_entry dict[6];
struct strbuf path_sq = STRBUF_INIT;
- const char *args[] = { NULL, NULL };
+ struct child_process child = CHILD_PROCESS_INIT;
int status, fd, i;
struct stat st;
enum ll_merge_result ret;
@@ -219,8 +219,9 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
- args[0] = cmd.buf;
- status = run_command_v_opt(args, RUN_USING_SHELL);
+ child.use_shell = 1;
+ strvec_push(&child.args, cmd.buf);
+ status = run_command(&child);
fd = open(temp[1], O_RDONLY);
if (fd < 0)
goto bad;
@@ -249,7 +250,8 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
static struct ll_merge_driver *ll_user_merge, **ll_user_merge_tail;
static const char *default_ll_merge;
-static int read_merge_config(const char *var, const char *value, void *cb)
+static int read_merge_config(const char *var, const char *value,
+ void *cb UNUSED)
{
struct ll_merge_driver *fn;
const char *key, *name;
diff --git a/log-tree.c b/log-tree.c
index 3e8c70ddcf4..1dd5fcbf7be 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -135,7 +135,8 @@ static int ref_filter_match(const char *refname,
}
static int add_ref_decoration(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+ int flags UNUSED,
+ void *cb_data)
{
int i;
struct object *obj;
diff --git a/ls-refs.c b/ls-refs.c
index 98e69373c84..fa0d01b47c1 100644
--- a/ls-refs.c
+++ b/ls-refs.c
@@ -136,7 +136,8 @@ static void send_possibly_unborn_head(struct ls_refs_data *data)
strbuf_release(&namespaced);
}
-static int ls_refs_config(const char *var, const char *value, void *data)
+static int ls_refs_config(const char *var, const char *value,
+ void *data UNUSED)
{
/*
* We only serve fetches over v2 for now, so respect only "uploadpack"
diff --git a/mailinfo.c b/mailinfo.c
index 9621ba62a39..833d28612f7 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -317,7 +317,7 @@ static void cleanup_subject(struct mailinfo *mi, struct strbuf *subject)
pos = strchr(subject->buf + at, ']');
if (!pos)
break;
- remove = pos - subject->buf + at + 1;
+ remove = pos - (subject->buf + at) + 1;
if (!mi->keep_non_patch_brackets_in_subject ||
(7 <= remove &&
memmem(subject->buf + at, remove, "PATCH", 5)))
diff --git a/merge-ort.c b/merge-ort.c
index 99dcee2db8a..d1611ca400a 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -397,7 +397,7 @@ struct conflicted_submodule_item {
int flag;
};
-static void conflicted_submodule_item_free(void *util, const char *str)
+static void conflicted_submodule_item_free(void *util, const char *str UNUSED)
{
struct conflicted_submodule_item *item = util;
@@ -2619,8 +2619,40 @@ static void apply_directory_rename_modifications(struct merge_options *opt,
}
assert(ci->filemask == 2 || ci->filemask == 4);
- assert(ci->dirmask == 0);
- strmap_remove(&opt->priv->paths, old_path, 0);
+ assert(ci->dirmask == 0 || ci->dirmask == 1);
+ if (ci->dirmask == 0)
+ strmap_remove(&opt->priv->paths, old_path, 0);
+ else {
+ /*
+ * This file exists on one side, but we still had a directory
+ * at the old location that we can't remove until after
+ * processing all paths below it. So, make a copy of ci in
+ * new_ci and only put the file information into it.
+ */
+ new_ci = mem_pool_calloc(&opt->priv->pool, 1, sizeof(*new_ci));
+ memcpy(new_ci, ci, sizeof(*ci));
+ assert(!new_ci->match_mask);
+ new_ci->dirmask = 0;
+ new_ci->stages[1].mode = 0;
+ oidcpy(&new_ci->stages[1].oid, null_oid());
+
+ /*
+ * Now that we have the file information in new_ci, make sure
+ * ci only has the directory information.
+ */
+ ci->filemask = 0;
+ ci->merged.clean = 1;
+ for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
+ if (ci->dirmask & (1 << i))
+ continue;
+ /* zero out any entries related to files */
+ ci->stages[i].mode = 0;
+ oidcpy(&ci->stages[i].oid, null_oid());
+ }
+
+ // Now we want to focus on new_ci, so reassign ci to it
+ ci = new_ci;
+ }
branch_with_new_path = (ci->filemask == 2) ? opt->branch1 : opt->branch2;
branch_with_dir_rename = (ci->filemask == 2) ? opt->branch2 : opt->branch1;
@@ -2807,6 +2839,8 @@ static int process_renames(struct merge_options *opt,
pathnames,
1 + 2 * opt->priv->call_depth,
&merged);
+ if (clean_merge < 0)
+ return -1;
if (!clean_merge &&
merged.mode == side1->stages[1].mode &&
oideq(&merged.oid, &side1->stages[1].oid))
@@ -2916,7 +2950,7 @@ static int process_renames(struct merge_options *opt,
struct version_info merged;
struct conflict_info *base, *side1, *side2;
- unsigned clean;
+ int clean;
pathnames[0] = oldpath;
pathnames[other_source_index] = oldpath;
@@ -2937,6 +2971,8 @@ static int process_renames(struct merge_options *opt,
pathnames,
1 + 2 * opt->priv->call_depth,
&merged);
+ if (clean < 0)
+ return -1;
memcpy(&newinfo->stages[target_index], &merged,
sizeof(merged));
@@ -3571,15 +3607,15 @@ static int tree_entry_order(const void *a_, const void *b_)
b->string, strlen(b->string), bmi->result.mode);
}
-static void write_tree(struct object_id *result_oid,
- struct string_list *versions,
- unsigned int offset,
- size_t hash_size)
+static int write_tree(struct object_id *result_oid,
+ struct string_list *versions,
+ unsigned int offset,
+ size_t hash_size)
{
size_t maxlen = 0, extra;
unsigned int nr;
struct strbuf buf = STRBUF_INIT;
- int i;
+ int i, ret = 0;
assert(offset <= versions->nr);
nr = versions->nr - offset;
@@ -3605,8 +3641,10 @@ static void write_tree(struct object_id *result_oid,
}
/* Write this object file out, and record in result_oid */
- write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid);
+ if (write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid))
+ ret = -1;
strbuf_release(&buf);
+ return ret;
}
static void record_entry_for_tree(struct directory_versions *dir_metadata,
@@ -3625,13 +3663,13 @@ static void record_entry_for_tree(struct directory_versions *dir_metadata,
basename)->util = &mi->result;
}
-static void write_completed_directory(struct merge_options *opt,
- const char *new_directory_name,
- struct directory_versions *info)
+static int write_completed_directory(struct merge_options *opt,
+ const char *new_directory_name,
+ struct directory_versions *info)
{
const char *prev_dir;
struct merged_info *dir_info = NULL;
- unsigned int offset;
+ unsigned int offset, ret = 0;
/*
* Some explanation of info->versions and info->offsets...
@@ -3717,7 +3755,7 @@ static void write_completed_directory(struct merge_options *opt,
* strcmp here.)
*/
if (new_directory_name == info->last_directory)
- return;
+ return 0;
/*
* If we are just starting (last_directory is NULL), or last_directory
@@ -3739,7 +3777,7 @@ static void write_completed_directory(struct merge_options *opt,
*/
string_list_append(&info->offsets,
info->last_directory)->util = (void*)offset;
- return;
+ return 0;
}
/*
@@ -3769,8 +3807,9 @@ static void write_completed_directory(struct merge_options *opt,
*/
dir_info->is_null = 0;
dir_info->result.mode = S_IFDIR;
- write_tree(&dir_info->result.oid, &info->versions, offset,
- opt->repo->hash_algo->rawsz);
+ if (write_tree(&dir_info->result.oid, &info->versions, offset,
+ opt->repo->hash_algo->rawsz) < 0)
+ ret = -1;
}
/*
@@ -3798,13 +3837,15 @@ static void write_completed_directory(struct merge_options *opt,
/* And, of course, we need to update last_directory to match. */
info->last_directory = new_directory_name;
info->last_directory_len = strlen(info->last_directory);
+
+ return ret;
}
/* Per entry merge function */
-static void process_entry(struct merge_options *opt,
- const char *path,
- struct conflict_info *ci,
- struct directory_versions *dir_metadata)
+static int process_entry(struct merge_options *opt,
+ const char *path,
+ struct conflict_info *ci,
+ struct directory_versions *dir_metadata)
{
int df_file_index = 0;
@@ -3818,7 +3859,7 @@ static void process_entry(struct merge_options *opt,
record_entry_for_tree(dir_metadata, path, &ci->merged);
if (ci->filemask == 0)
/* nothing else to handle */
- return;
+ return 0;
assert(ci->df_conflict);
}
@@ -3865,7 +3906,7 @@ static void process_entry(struct merge_options *opt,
*/
if (ci->filemask == 1) {
ci->filemask = 0;
- return;
+ return 0;
}
/*
@@ -4060,7 +4101,7 @@ static void process_entry(struct merge_options *opt,
} else if (ci->filemask >= 6) {
/* Need a two-way or three-way content merge */
struct version_info merged_file;
- unsigned clean_merge;
+ int clean_merge;
struct version_info *o = &ci->stages[0];
struct version_info *a = &ci->stages[1];
struct version_info *b = &ci->stages[2];
@@ -4069,6 +4110,8 @@ static void process_entry(struct merge_options *opt,
ci->pathnames,
opt->priv->call_depth * 2,
&merged_file);
+ if (clean_merge < 0)
+ return -1;
ci->merged.clean = clean_merge &&
!ci->df_conflict && !ci->path_conflict;
ci->merged.result.mode = merged_file.mode;
@@ -4164,6 +4207,7 @@ static void process_entry(struct merge_options *opt,
/* Record metadata for ci->merged in dir_metadata */
record_entry_for_tree(dir_metadata, path, &ci->merged);
+ return 0;
}
static void prefetch_for_content_merges(struct merge_options *opt,
@@ -4214,8 +4258,8 @@ static void prefetch_for_content_merges(struct merge_options *opt,
oid_array_clear(&to_fetch);
}
-static void process_entries(struct merge_options *opt,
- struct object_id *result_oid)
+static int process_entries(struct merge_options *opt,
+ struct object_id *result_oid)
{
struct hashmap_iter iter;
struct strmap_entry *e;
@@ -4224,11 +4268,12 @@ static void process_entries(struct merge_options *opt,
struct directory_versions dir_metadata = { STRING_LIST_INIT_NODUP,
STRING_LIST_INIT_NODUP,
NULL, 0 };
+ int ret = 0;
trace2_region_enter("merge", "process_entries setup", opt->repo);
if (strmap_empty(&opt->priv->paths)) {
oidcpy(result_oid, opt->repo->hash_algo->empty_tree);
- return;
+ return 0;
}
/* Hack to pre-allocate plist to the desired size */
@@ -4270,13 +4315,19 @@ static void process_entries(struct merge_options *opt,
*/
struct merged_info *mi = entry->util;
- write_completed_directory(opt, mi->directory_name,
- &dir_metadata);
+ if (write_completed_directory(opt, mi->directory_name,
+ &dir_metadata) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
if (mi->clean)
record_entry_for_tree(&dir_metadata, path, mi);
else {
struct conflict_info *ci = (struct conflict_info *)mi;
- process_entry(opt, path, ci, &dir_metadata);
+ if (process_entry(opt, path, ci, &dir_metadata) < 0) {
+ ret = -1;
+ goto cleanup;
+ };
}
}
trace2_region_leave("merge", "processing", opt->repo);
@@ -4291,12 +4342,16 @@ static void process_entries(struct merge_options *opt,
fflush(stdout);
BUG("dir_metadata accounting completely off; shouldn't happen");
}
- write_tree(result_oid, &dir_metadata.versions, 0,
- opt->repo->hash_algo->rawsz);
+ if (write_tree(result_oid, &dir_metadata.versions, 0,
+ opt->repo->hash_algo->rawsz) < 0)
+ ret = -1;
+cleanup:
string_list_clear(&plist, 0);
string_list_clear(&dir_metadata.versions, 0);
string_list_clear(&dir_metadata.offsets, 0);
trace2_region_leave("merge", "process_entries cleanup", opt->repo);
+
+ return ret;
}
/*** Function Grouping: functions related to merge_switch_to_result() ***/
@@ -4928,15 +4983,18 @@ redo:
}
trace2_region_enter("merge", "process_entries", opt->repo);
- process_entries(opt, &working_tree_oid);
+ if (process_entries(opt, &working_tree_oid) < 0)
+ result->clean = -1;
trace2_region_leave("merge", "process_entries", opt->repo);
/* Set return values */
result->path_messages = &opt->priv->conflicts;
- result->tree = parse_tree_indirect(&working_tree_oid);
- /* existence of conflicted entries implies unclean */
- result->clean &= strmap_empty(&opt->priv->conflicted);
+ if (result->clean >= 0) {
+ result->tree = parse_tree_indirect(&working_tree_oid);
+ /* 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;
diff --git a/merge-recursive.c b/merge-recursive.c
index b83a129b431..4ddd3adea00 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -45,7 +45,7 @@ struct path_hashmap_entry {
char path[FLEX_ARRAY];
};
-static int path_hashmap_cmp(const void *cmp_data,
+static int path_hashmap_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
@@ -89,10 +89,10 @@ static struct dir_rename_entry *dir_rename_find_entry(struct hashmap *hashmap,
return hashmap_get_entry(hashmap, &key, ent, NULL);
}
-static int dir_rename_cmp(const void *unused_cmp_data,
+static int dir_rename_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct dir_rename_entry *e1, *e2;
@@ -134,10 +134,10 @@ static struct collision_entry *collision_find_entry(struct hashmap *hashmap,
return hashmap_get_entry(hashmap, &key, ent, NULL);
}
-static int collision_cmp(const void *unused_cmp_data,
+static int collision_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct collision_entry *e1, *e2;
@@ -456,7 +456,7 @@ static void unpack_trees_finish(struct merge_options *opt)
clear_unpack_trees_porcelain(&opt->priv->unpack_opts);
}
-static int save_files_dirs(const struct object_id *oid,
+static int save_files_dirs(const struct object_id *oid UNUSED,
struct strbuf *base, const char *path,
unsigned int mode, void *context)
{
diff --git a/merge.c b/merge.c
index 2382ff66d35..445b4f19aa8 100644
--- a/merge.c
+++ b/merge.c
@@ -19,22 +19,22 @@ int try_merge_command(struct repository *r,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
{
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int i, ret;
struct commit_list *j;
- strvec_pushf(&args, "merge-%s", strategy);
+ strvec_pushf(&cmd.args, "merge-%s", strategy);
for (i = 0; i < xopts_nr; i++)
- strvec_pushf(&args, "--%s", xopts[i]);
+ strvec_pushf(&cmd.args, "--%s", xopts[i]);
for (j = common; j; j = j->next)
- strvec_push(&args, merge_argument(j->item));
- strvec_push(&args, "--");
- strvec_push(&args, head_arg);
+ strvec_push(&cmd.args, merge_argument(j->item));
+ strvec_push(&cmd.args, "--");
+ strvec_push(&cmd.args, head_arg);
for (j = remotes; j; j = j->next)
- strvec_push(&args, merge_argument(j->item));
+ strvec_push(&cmd.args, merge_argument(j->item));
- ret = run_command_v_opt(args.v, RUN_GIT_CMD);
- strvec_clear(&args);
+ cmd.git_cmd = 1;
+ ret = run_command(&cmd);
discard_index(r->index);
if (repo_read_index(r) < 0)
diff --git a/midx.c b/midx.c
index 4e956cacb71..7cfad04a240 100644
--- a/midx.c
+++ b/midx.c
@@ -278,7 +278,7 @@ uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos)
(off_t)pos * MIDX_CHUNK_OFFSET_WIDTH);
}
-int fill_midx_entry(struct repository * r,
+int fill_midx_entry(struct repository *r,
const struct object_id *oid,
struct pack_entry *e,
struct multi_pack_index *m)
@@ -577,6 +577,78 @@ static void fill_pack_entry(uint32_t pack_int_id,
entry->preferred = !!preferred;
}
+struct midx_fanout {
+ struct pack_midx_entry *entries;
+ uint32_t nr;
+ uint32_t alloc;
+};
+
+static void midx_fanout_grow(struct midx_fanout *fanout, uint32_t nr)
+{
+ ALLOC_GROW(fanout->entries, nr, fanout->alloc);
+}
+
+static void midx_fanout_sort(struct midx_fanout *fanout)
+{
+ QSORT(fanout->entries, fanout->nr, midx_oid_compare);
+}
+
+static void midx_fanout_add_midx_fanout(struct midx_fanout *fanout,
+ struct multi_pack_index *m,
+ uint32_t cur_fanout,
+ int preferred_pack)
+{
+ uint32_t start = 0, end;
+ uint32_t cur_object;
+
+ if (cur_fanout)
+ start = ntohl(m->chunk_oid_fanout[cur_fanout - 1]);
+ end = ntohl(m->chunk_oid_fanout[cur_fanout]);
+
+ for (cur_object = start; cur_object < end; cur_object++) {
+ if ((preferred_pack > -1) &&
+ (preferred_pack == nth_midxed_pack_int_id(m, cur_object))) {
+ /*
+ * Objects from preferred packs are added
+ * separately.
+ */
+ continue;
+ }
+
+ midx_fanout_grow(fanout, fanout->nr + 1);
+ nth_midxed_pack_midx_entry(m,
+ &fanout->entries[fanout->nr],
+ cur_object);
+ fanout->entries[fanout->nr].preferred = 0;
+ fanout->nr++;
+ }
+}
+
+static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
+ struct pack_info *info,
+ uint32_t cur_pack,
+ int preferred,
+ uint32_t cur_fanout)
+{
+ struct packed_git *pack = info[cur_pack].p;
+ uint32_t start = 0, end;
+ uint32_t cur_object;
+
+ if (cur_fanout)
+ start = get_pack_fanout(pack, cur_fanout - 1);
+ end = get_pack_fanout(pack, cur_fanout);
+
+ for (cur_object = start; cur_object < end; cur_object++) {
+ midx_fanout_grow(fanout, fanout->nr + 1);
+ fill_pack_entry(cur_pack,
+ info[cur_pack].p,
+ cur_object,
+ &fanout->entries[fanout->nr],
+ preferred);
+ fanout->nr++;
+ }
+}
+
/*
* It is possible to artificially get into a state where there are many
* duplicate copies of objects. That can create high memory pressure if
@@ -595,8 +667,8 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
int preferred_pack)
{
uint32_t cur_fanout, cur_pack, cur_object;
- uint32_t alloc_fanout, alloc_objects, total_objects = 0;
- struct pack_midx_entry *entries_by_fanout = NULL;
+ uint32_t alloc_objects, total_objects = 0;
+ struct midx_fanout fanout = { 0 };
struct pack_midx_entry *deduplicated_entries = NULL;
uint32_t start_pack = m ? m->num_packs : 0;
@@ -608,74 +680,51 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
* slices to be evenly distributed, with some noise. Hence,
* allocate slightly more than one 256th.
*/
- alloc_objects = alloc_fanout = total_objects > 3200 ? total_objects / 200 : 16;
+ alloc_objects = fanout.alloc = total_objects > 3200 ? total_objects / 200 : 16;
- ALLOC_ARRAY(entries_by_fanout, alloc_fanout);
+ ALLOC_ARRAY(fanout.entries, fanout.alloc);
ALLOC_ARRAY(deduplicated_entries, alloc_objects);
*nr_objects = 0;
for (cur_fanout = 0; cur_fanout < 256; cur_fanout++) {
- uint32_t nr_fanout = 0;
-
- if (m) {
- uint32_t start = 0, end;
-
- if (cur_fanout)
- start = ntohl(m->chunk_oid_fanout[cur_fanout - 1]);
- end = ntohl(m->chunk_oid_fanout[cur_fanout]);
-
- for (cur_object = start; cur_object < end; cur_object++) {
- ALLOC_GROW(entries_by_fanout, nr_fanout + 1, alloc_fanout);
- nth_midxed_pack_midx_entry(m,
- &entries_by_fanout[nr_fanout],
- cur_object);
- if (nth_midxed_pack_int_id(m, cur_object) == preferred_pack)
- entries_by_fanout[nr_fanout].preferred = 1;
- else
- entries_by_fanout[nr_fanout].preferred = 0;
- nr_fanout++;
- }
- }
+ fanout.nr = 0;
+
+ if (m)
+ midx_fanout_add_midx_fanout(&fanout, m, cur_fanout,
+ preferred_pack);
for (cur_pack = start_pack; cur_pack < nr_packs; cur_pack++) {
- uint32_t start = 0, end;
int preferred = cur_pack == preferred_pack;
-
- if (cur_fanout)
- start = get_pack_fanout(info[cur_pack].p, cur_fanout - 1);
- end = get_pack_fanout(info[cur_pack].p, cur_fanout);
-
- for (cur_object = start; cur_object < end; cur_object++) {
- ALLOC_GROW(entries_by_fanout, nr_fanout + 1, alloc_fanout);
- fill_pack_entry(cur_pack,
- info[cur_pack].p,
- cur_object,
- &entries_by_fanout[nr_fanout],
- preferred);
- nr_fanout++;
- }
+ midx_fanout_add_pack_fanout(&fanout,
+ info, cur_pack,
+ preferred, cur_fanout);
}
- QSORT(entries_by_fanout, nr_fanout, midx_oid_compare);
+ if (-1 < preferred_pack && preferred_pack < start_pack)
+ midx_fanout_add_pack_fanout(&fanout, info,
+ preferred_pack, 1,
+ cur_fanout);
+
+ midx_fanout_sort(&fanout);
/*
* The batch is now sorted by OID and then mtime (descending).
* Take only the first duplicate.
*/
- for (cur_object = 0; cur_object < nr_fanout; cur_object++) {
- if (cur_object && oideq(&entries_by_fanout[cur_object - 1].oid,
- &entries_by_fanout[cur_object].oid))
+ for (cur_object = 0; cur_object < fanout.nr; cur_object++) {
+ if (cur_object && oideq(&fanout.entries[cur_object - 1].oid,
+ &fanout.entries[cur_object].oid))
continue;
ALLOC_GROW(deduplicated_entries, *nr_objects + 1, alloc_objects);
memcpy(&deduplicated_entries[*nr_objects],
- &entries_by_fanout[cur_object],
+ &fanout.entries[cur_object],
sizeof(struct pack_midx_entry));
(*nr_objects)++;
}
}
- free(entries_by_fanout);
+ free(fanout.entries);
return deduplicated_entries;
}
@@ -864,6 +913,8 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx)
uint32_t *pack_order;
uint32_t i;
+ trace2_region_enter("midx", "midx_pack_order", the_repository);
+
ALLOC_ARRAY(data, ctx->entries_nr);
for (i = 0; i < ctx->entries_nr; i++) {
struct pack_midx_entry *e = &ctx->entries[i];
@@ -881,6 +932,8 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx)
pack_order[i] = data[i].nr;
free(data);
+ trace2_region_leave("midx", "midx_pack_order", the_repository);
+
return pack_order;
}
@@ -890,6 +943,8 @@ static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
struct strbuf buf = STRBUF_INIT;
const char *tmp_file;
+ trace2_region_enter("midx", "write_midx_reverse_index", the_repository);
+
strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex(midx_hash));
tmp_file = write_rev_file_order(NULL, ctx->pack_order, ctx->entries_nr,
@@ -899,6 +954,8 @@ static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
die(_("cannot store reverse index file"));
strbuf_release(&buf);
+
+ trace2_region_leave("midx", "write_midx_reverse_index", the_repository);
}
static void clear_midx_files_ext(const char *object_dir, const char *ext,
@@ -914,6 +971,8 @@ static void prepare_midx_packing_data(struct packing_data *pdata,
{
uint32_t i;
+ trace2_region_enter("midx", "prepare_midx_packing_data", the_repository);
+
memset(pdata, 0, sizeof(struct packing_data));
prepare_packing_data(the_repository, pdata);
@@ -924,6 +983,8 @@ static void prepare_midx_packing_data(struct packing_data *pdata,
oe_set_in_pack(pdata, to,
ctx->info[ctx->pack_perm[from->pack_int_id]].p);
}
+
+ trace2_region_leave("midx", "prepare_midx_packing_data", the_repository);
}
static int add_ref_to_pending(const char *refname,
@@ -931,6 +992,7 @@ static int add_ref_to_pending(const char *refname,
int flag, void *cb_data)
{
struct rev_info *revs = (struct rev_info*)cb_data;
+ struct object_id peeled;
struct object *object;
if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) {
@@ -938,6 +1000,9 @@ static int add_ref_to_pending(const char *refname,
return 0;
}
+ if (!peel_iterated_oid(oid, &peeled))
+ oid = &peeled;
+
object = parse_object_or_die(oid, refname);
if (object->type != OBJ_COMMIT)
return 0;
@@ -1017,6 +1082,9 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
struct rev_info revs;
struct bitmap_commit_cb cb = {0};
+ trace2_region_enter("midx", "find_commits_for_midx_bitmap",
+ the_repository);
+
cb.ctx = ctx;
repo_init_revisions(the_repository, &revs, NULL);
@@ -1050,6 +1118,10 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
*indexed_commits_nr_p = cb.commits_nr;
release_revisions(&revs);
+
+ trace2_region_leave("midx", "find_commits_for_midx_bitmap",
+ the_repository);
+
return cb.commits;
}
@@ -1067,9 +1139,14 @@ static int write_midx_bitmap(const char *midx_name,
char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name,
hash_to_hex(midx_hash));
+ trace2_region_enter("midx", "write_midx_bitmap", the_repository);
+
if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
options |= BITMAP_OPT_HASH_CACHE;
+ if (flags & MIDX_WRITE_BITMAP_LOOKUP_TABLE)
+ options |= BITMAP_OPT_LOOKUP_TABLE;
+
/*
* Build the MIDX-order index based on pdata.objects (which is already
* in MIDX order; c.f., 'midx_pack_order_cmp()' for the definition of
@@ -1109,6 +1186,9 @@ static int write_midx_bitmap(const char *midx_name,
cleanup:
free(index);
free(bitmap_name);
+
+ trace2_region_leave("midx", "write_midx_bitmap", the_repository);
+
return ret;
}
@@ -1155,6 +1235,8 @@ static int write_midx_internal(const char *object_dir,
int result = 0;
struct chunkfile *cf;
+ trace2_region_enter("midx", "write_midx_internal", the_repository);
+
get_midx_filename(&midx_name, object_dir);
if (safe_create_leading_directories(midx_name.buf))
die_errno(_("unable to create leading directories of %s"),
@@ -1496,6 +1578,8 @@ cleanup:
free(ctx.pack_order);
strbuf_release(&midx_name);
+ trace2_region_leave("midx", "write_midx_internal", the_repository);
+
return result;
}
@@ -1787,7 +1871,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
if (prepare_midx_pack(r, m, i))
continue;
- if (m->packs[i]->pack_keep)
+ if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
continue;
pack_name = xstrdup(m->packs[i]->pack_name);
@@ -1843,6 +1927,8 @@ static int fill_included_packs_all(struct repository *r,
continue;
if (!pack_kept_objects && m->packs[i]->pack_keep)
continue;
+ if (m->packs[i]->is_cruft)
+ continue;
include_pack[i] = 1;
count++;
@@ -1858,9 +1944,11 @@ static int fill_included_packs_batch(struct repository *r,
{
uint32_t i, packs_to_repack;
size_t total_size;
- struct repack_info *pack_info = xcalloc(m->num_packs, sizeof(struct repack_info));
+ struct repack_info *pack_info;
int pack_kept_objects = 0;
+ CALLOC_ARRAY(pack_info, m->num_packs);
+
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
for (i = 0; i < m->num_packs; i++) {
@@ -1872,7 +1960,7 @@ static int fill_included_packs_batch(struct repository *r,
pack_info[i].mtime = m->packs[i]->mtime;
}
- for (i = 0; batch_size && i < m->num_objects; i++) {
+ for (i = 0; i < m->num_objects; i++) {
uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
pack_info[pack_int_id].referenced_objects++;
}
@@ -1890,6 +1978,8 @@ static int fill_included_packs_batch(struct repository *r,
continue;
if (!pack_kept_objects && p->pack_keep)
continue;
+ if (p->is_cruft)
+ continue;
if (open_pack_index(p) || !p->num_objects)
continue;
diff --git a/midx.h b/midx.h
index 22e8e53288e..5578cd7b835 100644
--- a/midx.h
+++ b/midx.h
@@ -47,6 +47,7 @@ struct multi_pack_index {
#define MIDX_WRITE_REV_INDEX (1 << 1)
#define MIDX_WRITE_BITMAP (1 << 2)
#define MIDX_WRITE_BITMAP_HASH_CACHE (1 << 3)
+#define MIDX_WRITE_BITMAP_LOOKUP_TABLE (1 << 4)
const unsigned char *get_midx_checksum(struct multi_pack_index *m);
void get_midx_filename(struct strbuf *out, const char *object_dir);
diff --git a/name-hash.c b/name-hash.c
index 7487d331240..cd009c7c8ae 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -18,7 +18,7 @@ struct dir_entry {
char name[FLEX_ARRAY];
};
-static int dir_entry_cmp(const void *unused_cmp_data,
+static int dir_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
@@ -120,7 +120,7 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
add_dir_entry(istate, ce);
}
-static int cache_entry_cmp(const void *unused_cmp_data,
+static int cache_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *remove)
diff --git a/negotiator/default.c b/negotiator/default.c
index 434189ae5dc..b7e79feaf04 100644
--- a/negotiator/default.c
+++ b/negotiator/default.c
@@ -36,7 +36,8 @@ static void rev_list_push(struct negotiation_state *ns,
}
static int clear_marks(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data UNUSED)
{
struct object *o = deref_tag(the_repository, parse_object(the_repository, oid), refname, 0);
diff --git a/negotiator/skipping.c b/negotiator/skipping.c
index 1236e792248..0f5ac48e876 100644
--- a/negotiator/skipping.c
+++ b/negotiator/skipping.c
@@ -72,7 +72,8 @@ static struct entry *rev_list_push(struct data *data, struct commit *commit, int
}
static int clear_marks(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data UNUSED)
{
struct object *o = deref_tag(the_repository, parse_object(the_repository, oid), refname, 0);
@@ -85,21 +86,26 @@ static int clear_marks(const char *refname, const struct object_id *oid,
/*
* Mark this SEEN commit and all its SEEN ancestors as COMMON.
*/
-static void mark_common(struct data *data, struct commit *c)
+static void mark_common(struct data *data, struct commit *seen_commit)
{
- struct commit_list *p;
+ struct prio_queue queue = { NULL };
+ struct commit *c;
- if (c->object.flags & COMMON)
- return;
- c->object.flags |= COMMON;
- if (!(c->object.flags & POPPED))
- data->non_common_revs--;
+ prio_queue_put(&queue, seen_commit);
+ while ((c = prio_queue_get(&queue))) {
+ struct commit_list *p;
+ if (c->object.flags & COMMON)
+ return;
+ c->object.flags |= COMMON;
+ if (!(c->object.flags & POPPED))
+ data->non_common_revs--;
- if (!c->object.parsed)
- return;
- for (p = c->parents; p; p = p->next) {
- if (p->item->object.flags & SEEN)
- mark_common(data, p->item);
+ if (!c->object.parsed)
+ return;
+ for (p = c->parents; p; p = p->next) {
+ if (p->item->object.flags & SEEN)
+ prio_queue_put(&queue, p->item);
+ }
}
}
diff --git a/notes.c b/notes.c
index 7bade6d8f69..f2805d51bb1 100644
--- a/notes.c
+++ b/notes.c
@@ -924,8 +924,9 @@ out:
return ret;
}
-static int string_list_add_one_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb)
+static int string_list_add_one_ref(const char *refname,
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cb)
{
struct string_list *refs = cb;
if (!unsorted_string_list_has_string(refs, refname))
diff --git a/object-file.c b/object-file.c
index 5b270f046dd..957790098fa 100644
--- a/object-file.c
+++ b/object-file.c
@@ -140,27 +140,32 @@ static void git_hash_sha256_final_oid(struct object_id *oid, git_hash_ctx *ctx)
oid->algo = GIT_HASH_SHA256;
}
-static void git_hash_unknown_init(git_hash_ctx *ctx)
+static void git_hash_unknown_init(git_hash_ctx *ctx UNUSED)
{
BUG("trying to init unknown hash");
}
-static void git_hash_unknown_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+static void git_hash_unknown_clone(git_hash_ctx *dst UNUSED,
+ const git_hash_ctx *src UNUSED)
{
BUG("trying to clone unknown hash");
}
-static void git_hash_unknown_update(git_hash_ctx *ctx, const void *data, size_t len)
+static void git_hash_unknown_update(git_hash_ctx *ctx UNUSED,
+ const void *data UNUSED,
+ size_t len UNUSED)
{
BUG("trying to update unknown hash");
}
-static void git_hash_unknown_final(unsigned char *hash, git_hash_ctx *ctx)
+static void git_hash_unknown_final(unsigned char *hash UNUSED,
+ git_hash_ctx *ctx UNUSED)
{
BUG("trying to finalize unknown hash");
}
-static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)
+static void git_hash_unknown_final_oid(struct object_id *oid UNUSED,
+ git_hash_ctx *ctx UNUSED)
{
BUG("trying to finalize unknown hash");
}
@@ -1599,10 +1604,6 @@ static int do_oid_object_info_extended(struct repository *r,
if (fetch_if_missing && repo_has_promisor_remote(r) &&
!already_retried &&
!(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
- /*
- * TODO Investigate checking promisor_remote_get_direct()
- * TODO return value and stopping on error here.
- */
promisor_remote_get_direct(r, real, 1);
already_retried = 1;
continue;
diff --git a/object-name.c b/object-name.c
index 4d2746574cd..2dd1a0f56e1 100644
--- a/object-name.c
+++ b/object-name.c
@@ -1306,7 +1306,8 @@ struct handle_one_ref_cb {
};
static int handle_one_ref(const char *path, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data)
{
struct handle_one_ref_cb *cb = cb_data;
struct commit_list **list = cb->list;
@@ -1384,8 +1385,11 @@ struct grab_nth_branch_switch_cbdata {
struct strbuf *sb;
};
-static int grab_nth_branch_switch(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
+static int grab_nth_branch_switch(struct object_id *ooid UNUSED,
+ struct object_id *noid UNUSED,
+ const char *email UNUSED,
+ timestamp_t timestamp UNUSED,
+ int tz UNUSED,
const char *message, void *cb_data)
{
struct grab_nth_branch_switch_cbdata *cb = cb_data;
diff --git a/object-store.h b/object-store.h
index 5222ee54600..1be57abaf10 100644
--- a/object-store.h
+++ b/object-store.h
@@ -141,7 +141,7 @@ struct packed_git {
struct multi_pack_index;
-static inline int pack_map_entry_cmp(const void *unused_cmp_data,
+static inline int pack_map_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *entry,
const struct hashmap_entry *entry2,
const void *keydata)
diff --git a/object.c b/object.c
index 588b8156f1d..8a74eb85e94 100644
--- a/object.c
+++ b/object.c
@@ -233,7 +233,8 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id
if (commit) {
if (parse_commit_buffer(r, commit, buffer, size, 1))
return NULL;
- if (!get_cached_commit_buffer(r, commit, NULL)) {
+ if (save_commit_buffer &&
+ !get_cached_commit_buffer(r, commit, NULL)) {
set_commit_buffer(r, commit, buffer, size);
*eaten_p = 1;
}
@@ -263,8 +264,11 @@ struct object *parse_object_or_die(const struct object_id *oid,
die(_("unable to parse object: %s"), name ? name : oid_to_hex(oid));
}
-struct object *parse_object(struct repository *r, const struct object_id *oid)
+struct object *parse_object_with_flags(struct repository *r,
+ const struct object_id *oid,
+ enum parse_object_flags flags)
{
+ int skip_hash = !!(flags & PARSE_OBJECT_SKIP_HASH_CHECK);
unsigned long size;
enum object_type type;
int eaten;
@@ -276,10 +280,16 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
if (obj && obj->parsed)
return obj;
+ if (skip_hash) {
+ struct commit *commit = lookup_commit_in_graph(r, repl);
+ if (commit)
+ return &commit->object;
+ }
+
if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
(!obj && repo_has_object_file(r, oid) &&
oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
- if (stream_object_signature(r, repl) < 0) {
+ if (!skip_hash && stream_object_signature(r, repl) < 0) {
error(_("hash mismatch %s"), oid_to_hex(oid));
return NULL;
}
@@ -289,7 +299,8 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
buffer = repo_read_object_file(r, oid, &type, &size);
if (buffer) {
- if (check_object_signature(r, repl, buffer, size, type) < 0) {
+ if (!skip_hash &&
+ check_object_signature(r, repl, buffer, size, type) < 0) {
free(buffer);
error(_("hash mismatch %s"), oid_to_hex(repl));
return NULL;
@@ -304,6 +315,11 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
return NULL;
}
+struct object *parse_object(struct repository *r, const struct object_id *oid)
+{
+ return parse_object_with_flags(r, oid, 0);
+}
+
struct object_list *object_list_insert(struct object *item,
struct object_list **list_p)
{
diff --git a/object.h b/object.h
index 9caef89f1f0..31ebe114585 100644
--- a/object.h
+++ b/object.h
@@ -128,7 +128,13 @@ void *object_as_type(struct object *obj, enum object_type type, int quiet);
*
* Returns NULL if the object is missing or corrupt.
*/
+enum parse_object_flags {
+ PARSE_OBJECT_SKIP_HASH_CHECK = 1 << 0,
+};
struct object *parse_object(struct repository *r, const struct object_id *oid);
+struct object *parse_object_with_flags(struct repository *r,
+ const struct object_id *oid,
+ enum parse_object_flags flags);
/*
* Like parse_object, but will die() instead of returning NULL. If the
diff --git a/oidmap.c b/oidmap.c
index 286a04a53c2..49965fe8568 100644
--- a/oidmap.c
+++ b/oidmap.c
@@ -1,7 +1,7 @@
#include "cache.h"
#include "oidmap.h"
-static int oidmap_neq(const void *hashmap_cmp_fn_data,
+static int oidmap_neq(const void *hashmap_cmp_fn_data UNUSED,
const struct hashmap_entry *e1,
const struct hashmap_entry *e2,
const void *keydata)
diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore
new file mode 100644
index 00000000000..9acb74412ef
--- /dev/null
+++ b/oss-fuzz/.gitignore
@@ -0,0 +1,3 @@
+fuzz-commit-graph
+fuzz-pack-headers
+fuzz-pack-idx
diff --git a/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c
index 914026f5d80..914026f5d80 100644
--- a/fuzz-commit-graph.c
+++ b/oss-fuzz/fuzz-commit-graph.c
diff --git a/fuzz-pack-headers.c b/oss-fuzz/fuzz-pack-headers.c
index 99da1d0fd38..99da1d0fd38 100644
--- a/fuzz-pack-headers.c
+++ b/oss-fuzz/fuzz-pack-headers.c
diff --git a/fuzz-pack-idx.c b/oss-fuzz/fuzz-pack-idx.c
index 0c3d777aac8..0c3d777aac8 100644
--- a/fuzz-pack-idx.c
+++ b/oss-fuzz/fuzz-pack-idx.c
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index 4fcfaed428f..cfa67a510fd 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -384,6 +384,8 @@ static int fill_bitmap_tree(struct bitmap *bitmap,
return 0;
}
+static int reused_bitmaps_nr;
+
static int fill_bitmap_commit(struct bb_commit *ent,
struct commit *commit,
struct prio_queue *queue,
@@ -409,8 +411,10 @@ static int fill_bitmap_commit(struct bb_commit *ent,
* bitmap and add its bits to this one. No need to walk
* parents or the tree for this commit.
*/
- if (old && !rebuild_bitmap(mapping, old, ent->bitmap))
+ if (old && !rebuild_bitmap(mapping, old, ent->bitmap)) {
+ reused_bitmaps_nr++;
continue;
+ }
}
/*
@@ -526,6 +530,8 @@ int bitmap_writer_build(struct packing_data *to_pack)
trace2_region_leave("pack-bitmap-write", "building_bitmaps_total",
the_repository);
+ trace2_data_intmax("pack-bitmap-write", the_repository,
+ "building_bitmaps_reused", reused_bitmaps_nr);
stop_progress(&writer.progress);
@@ -649,21 +655,18 @@ static const struct object_id *oid_access(size_t pos, const void *table)
}
static void write_selected_commits_v1(struct hashfile *f,
- struct pack_idx_entry **index,
- uint32_t index_nr)
+ uint32_t *commit_positions,
+ off_t *offsets)
{
int i;
for (i = 0; i < writer.selected_nr; ++i) {
struct bitmapped_commit *stored = &writer.selected[i];
- int commit_pos =
- oid_pos(&stored->commit->object.oid, index, index_nr, oid_access);
+ if (offsets)
+ offsets[i] = hashfile_total(f);
- if (commit_pos < 0)
- BUG("trying to write commit not in index");
-
- hashwrite_be32(f, commit_pos);
+ hashwrite_be32(f, commit_positions[i]);
hashwrite_u8(f, stored->xor_offset);
hashwrite_u8(f, stored->flags);
@@ -671,6 +674,79 @@ static void write_selected_commits_v1(struct hashfile *f,
}
}
+static int table_cmp(const void *_va, const void *_vb, void *_data)
+{
+ uint32_t *commit_positions = _data;
+ uint32_t a = commit_positions[*(uint32_t *)_va];
+ uint32_t b = commit_positions[*(uint32_t *)_vb];
+
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+
+ return 0;
+}
+
+static void write_lookup_table(struct hashfile *f,
+ uint32_t *commit_positions,
+ off_t *offsets)
+{
+ uint32_t i;
+ uint32_t *table, *table_inv;
+
+ ALLOC_ARRAY(table, writer.selected_nr);
+ ALLOC_ARRAY(table_inv, writer.selected_nr);
+
+ for (i = 0; i < writer.selected_nr; i++)
+ table[i] = i;
+
+ /*
+ * At the end of this sort table[j] = i means that the i'th
+ * bitmap corresponds to j'th bitmapped commit (among the selected
+ * commits) in lex order of OIDs.
+ */
+ QSORT_S(table, writer.selected_nr, table_cmp, commit_positions);
+
+ /* table_inv helps us discover that relationship (i'th bitmap
+ * to j'th commit by j = table_inv[i])
+ */
+ for (i = 0; i < writer.selected_nr; i++)
+ table_inv[table[i]] = i;
+
+ trace2_region_enter("pack-bitmap-write", "writing_lookup_table", the_repository);
+ for (i = 0; i < writer.selected_nr; i++) {
+ struct bitmapped_commit *selected = &writer.selected[table[i]];
+ uint32_t xor_offset = selected->xor_offset;
+ uint32_t xor_row;
+
+ if (xor_offset) {
+ /*
+ * xor_index stores the index (in the bitmap entries)
+ * of the corresponding xor bitmap. But we need to convert
+ * this index into lookup table's index. So, table_inv[xor_index]
+ * gives us the index position w.r.t. the lookup table.
+ *
+ * If "k = table[i] - xor_offset" then the xor base is the k'th
+ * bitmap. `table_inv[k]` gives us the position of that bitmap
+ * in the lookup table.
+ */
+ uint32_t xor_index = table[i] - xor_offset;
+ xor_row = table_inv[xor_index];
+ } else {
+ xor_row = 0xffffffff;
+ }
+
+ hashwrite_be32(f, commit_positions[table[i]]);
+ hashwrite_be64(f, (uint64_t)offsets[table[i]]);
+ hashwrite_be32(f, xor_row);
+ }
+ trace2_region_leave("pack-bitmap-write", "writing_lookup_table", the_repository);
+
+ free(table);
+ free(table_inv);
+}
+
static void write_hash_cache(struct hashfile *f,
struct pack_idx_entry **index,
uint32_t index_nr)
@@ -697,6 +773,9 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
static uint16_t flags = BITMAP_OPT_FULL_DAG;
struct strbuf tmp_file = STRBUF_INIT;
struct hashfile *f;
+ uint32_t *commit_positions = NULL;
+ off_t *offsets = NULL;
+ uint32_t i;
struct bitmap_disk_header header;
@@ -715,7 +794,26 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
dump_bitmap(f, writer.trees);
dump_bitmap(f, writer.blobs);
dump_bitmap(f, writer.tags);
- write_selected_commits_v1(f, index, index_nr);
+
+ if (options & BITMAP_OPT_LOOKUP_TABLE)
+ CALLOC_ARRAY(offsets, index_nr);
+
+ ALLOC_ARRAY(commit_positions, writer.selected_nr);
+
+ for (i = 0; i < writer.selected_nr; i++) {
+ struct bitmapped_commit *stored = &writer.selected[i];
+ int commit_pos = oid_pos(&stored->commit->object.oid, index, index_nr, oid_access);
+
+ if (commit_pos < 0)
+ BUG(_("trying to write commit not in index"));
+
+ commit_positions[i] = commit_pos;
+ }
+
+ write_selected_commits_v1(f, commit_positions, offsets);
+
+ if (options & BITMAP_OPT_LOOKUP_TABLE)
+ write_lookup_table(f, commit_positions, offsets);
if (options & BITMAP_OPT_HASH_CACHE)
write_hash_cache(f, index, index_nr);
@@ -730,4 +828,6 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
die_errno("unable to rename temporary bitmap file to '%s'", filename);
strbuf_release(&tmp_file);
+ free(commit_positions);
+ free(offsets);
}
diff --git a/pack-bitmap.c b/pack-bitmap.c
index ef580be9e3f..440407f1be7 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -84,6 +84,12 @@ struct bitmap_index {
const unsigned char *checksum;
/*
+ * If not NULL, this point into the commit table extension
+ * (within the memory mapped region `map`).
+ */
+ unsigned char *table_lookup;
+
+ /*
* Extended index.
*
* When trying to perform bitmap operations with objects that are not
@@ -186,6 +192,16 @@ static int load_bitmap_header(struct bitmap_index *index)
index->hashes = (void *)(index_end - cache_size);
index_end -= cache_size;
}
+
+ if (flags & BITMAP_OPT_LOOKUP_TABLE) {
+ size_t table_size = st_mult(ntohl(header->entry_count),
+ BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH);
+ if (table_size > index_end - index->map - header_size)
+ return error(_("corrupted bitmap index file (too short to fit lookup table)"));
+ if (git_env_bool("GIT_TEST_READ_COMMIT_TABLE", 1))
+ index->table_lookup = (void *)(index_end - table_size);
+ index_end -= table_size;
+ }
}
index->entry_count = ntohl(header->entry_count);
@@ -212,9 +228,11 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
hash_pos = kh_put_oid_map(index->bitmaps, stored->oid, &ret);
- /* a 0 return code means the insertion succeeded with no changes,
- * because the SHA1 already existed on the map. this is bad, there
- * shouldn't be duplicated commits in the index */
+ /*
+ * A 0 return code means the insertion succeeded with no changes,
+ * because the SHA1 already existed on the map. This is bad, there
+ * shouldn't be duplicated commits in the index.
+ */
if (ret == 0) {
error(_("duplicate entry in bitmap index: '%s'"), oid_to_hex(oid));
return NULL;
@@ -482,7 +500,7 @@ static int load_bitmap(struct bitmap_index *bitmap_git)
!(bitmap_git->tags = read_bitmap_1(bitmap_git)))
goto failed;
- if (load_bitmap_entries_v1(bitmap_git) < 0)
+ if (!bitmap_git->table_lookup && load_bitmap_entries_v1(bitmap_git) < 0)
goto failed;
return 0;
@@ -570,13 +588,255 @@ struct include_data {
struct bitmap *seen;
};
+struct bitmap_lookup_table_triplet {
+ uint32_t commit_pos;
+ uint64_t offset;
+ uint32_t xor_row;
+};
+
+struct bitmap_lookup_table_xor_item {
+ struct object_id oid;
+ uint64_t offset;
+};
+
+/*
+ * Given a `triplet` struct pointer and pointer `p`, this
+ * function reads the triplet beginning at `p` into the struct.
+ * Note that this function assumes that there is enough memory
+ * left for filling the `triplet` struct from `p`.
+ */
+static int bitmap_lookup_table_get_triplet_by_pointer(struct bitmap_lookup_table_triplet *triplet,
+ const unsigned char *p)
+{
+ if (!triplet)
+ return -1;
+
+ triplet->commit_pos = get_be32(p);
+ p += sizeof(uint32_t);
+ triplet->offset = get_be64(p);
+ p += sizeof(uint64_t);
+ triplet->xor_row = get_be32(p);
+ return 0;
+}
+
+/*
+ * This function gets the raw triplet from `row`'th row in the
+ * lookup table and fills that data to the `triplet`.
+ */
+static int bitmap_lookup_table_get_triplet(struct bitmap_index *bitmap_git,
+ uint32_t pos,
+ struct bitmap_lookup_table_triplet *triplet)
+{
+ unsigned char *p = NULL;
+ if (pos >= bitmap_git->entry_count)
+ return error(_("corrupt bitmap lookup table: triplet position out of index"));
+
+ p = bitmap_git->table_lookup + st_mult(pos, BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH);
+
+ return bitmap_lookup_table_get_triplet_by_pointer(triplet, p);
+}
+
+/*
+ * Searches for a matching triplet. `commit_pos` is a pointer
+ * to the wanted commit position value. `table_entry` points to
+ * a triplet in lookup table. The first 4 bytes of each
+ * triplet (pointed by `table_entry`) are compared with `*commit_pos`.
+ */
+static int triplet_cmp(const void *commit_pos, const void *table_entry)
+{
+
+ uint32_t a = *(uint32_t *)commit_pos;
+ uint32_t b = get_be32(table_entry);
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+
+ return 0;
+}
+
+static uint32_t bitmap_bsearch_pos(struct bitmap_index *bitmap_git,
+ struct object_id *oid,
+ uint32_t *result)
+{
+ int found;
+
+ if (bitmap_is_midx(bitmap_git))
+ found = bsearch_midx(oid, bitmap_git->midx, result);
+ else
+ found = bsearch_pack(oid, bitmap_git->pack, result);
+
+ return found;
+}
+
+/*
+ * `bsearch_triplet_by_pos` function searches for the raw triplet
+ * having commit position same as `commit_pos` and fills `triplet`
+ * object from the raw triplet. Returns 1 on success and 0 on
+ * failure.
+ */
+static int bitmap_bsearch_triplet_by_pos(uint32_t commit_pos,
+ struct bitmap_index *bitmap_git,
+ struct bitmap_lookup_table_triplet *triplet)
+{
+ unsigned char *p = bsearch(&commit_pos, bitmap_git->table_lookup, bitmap_git->entry_count,
+ BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH, triplet_cmp);
+
+ if (!p)
+ return -1;
+
+ return bitmap_lookup_table_get_triplet_by_pointer(triplet, p);
+}
+
+static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_git,
+ struct commit *commit)
+{
+ uint32_t commit_pos, xor_row;
+ uint64_t offset;
+ int flags;
+ struct bitmap_lookup_table_triplet triplet;
+ struct object_id *oid = &commit->object.oid;
+ struct ewah_bitmap *bitmap;
+ struct stored_bitmap *xor_bitmap = NULL;
+ const int bitmap_header_size = 6;
+ static struct bitmap_lookup_table_xor_item *xor_items = NULL;
+ static size_t xor_items_nr = 0, xor_items_alloc = 0;
+ static int is_corrupt = 0;
+ int xor_flags;
+ khiter_t hash_pos;
+ struct bitmap_lookup_table_xor_item *xor_item;
+
+ if (is_corrupt)
+ return NULL;
+
+ if (!bitmap_bsearch_pos(bitmap_git, oid, &commit_pos))
+ return NULL;
+
+ if (bitmap_bsearch_triplet_by_pos(commit_pos, bitmap_git, &triplet) < 0)
+ return NULL;
+
+ xor_items_nr = 0;
+ offset = triplet.offset;
+ xor_row = triplet.xor_row;
+
+ while (xor_row != 0xffffffff) {
+ ALLOC_GROW(xor_items, xor_items_nr + 1, xor_items_alloc);
+
+ if (xor_items_nr + 1 >= bitmap_git->entry_count) {
+ error(_("corrupt bitmap lookup table: xor chain exceeds entry count"));
+ goto corrupt;
+ }
+
+ if (bitmap_lookup_table_get_triplet(bitmap_git, xor_row, &triplet) < 0)
+ goto corrupt;
+
+ xor_item = &xor_items[xor_items_nr];
+ xor_item->offset = triplet.offset;
+
+ if (nth_bitmap_object_oid(bitmap_git, &xor_item->oid, triplet.commit_pos) < 0) {
+ error(_("corrupt bitmap lookup table: commit index %u out of range"),
+ triplet.commit_pos);
+ goto corrupt;
+ }
+
+ hash_pos = kh_get_oid_map(bitmap_git->bitmaps, xor_item->oid);
+
+ /*
+ * If desired bitmap is already stored, we don't need
+ * to iterate further. Because we know that bitmaps
+ * that are needed to be parsed to parse this bitmap
+ * has already been stored. So, assign this stored bitmap
+ * to the xor_bitmap.
+ */
+ if (hash_pos < kh_end(bitmap_git->bitmaps) &&
+ (xor_bitmap = kh_value(bitmap_git->bitmaps, hash_pos)))
+ break;
+ xor_items_nr++;
+ xor_row = triplet.xor_row;
+ }
+
+ while (xor_items_nr) {
+ xor_item = &xor_items[xor_items_nr - 1];
+ bitmap_git->map_pos = xor_item->offset;
+ if (bitmap_git->map_size - bitmap_git->map_pos < bitmap_header_size) {
+ error(_("corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""),
+ oid_to_hex(&xor_item->oid));
+ goto corrupt;
+ }
+
+ bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
+ xor_flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
+ bitmap = read_bitmap_1(bitmap_git);
+
+ if (!bitmap)
+ goto corrupt;
+
+ xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid, xor_bitmap, xor_flags);
+ xor_items_nr--;
+ }
+
+ bitmap_git->map_pos = offset;
+ if (bitmap_git->map_size - bitmap_git->map_pos < bitmap_header_size) {
+ error(_("corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""),
+ oid_to_hex(oid));
+ goto corrupt;
+ }
+
+ /*
+ * Don't bother reading the commit's index position or its xor
+ * offset:
+ *
+ * - The commit's index position is irrelevant to us, since
+ * load_bitmap_entries_v1 only uses it to learn the object
+ * id which is used to compute the hashmap's key. We already
+ * have an object id, so no need to look it up again.
+ *
+ * - The xor_offset is unusable for us, since it specifies how
+ * many entries previous to ours we should look at. This
+ * makes sense when reading the bitmaps sequentially (as in
+ * load_bitmap_entries_v1()), since we can keep track of
+ * each bitmap as we read them.
+ *
+ * But it can't work for us, since the bitmap's don't have a
+ * fixed size. So we learn the position of the xor'd bitmap
+ * from the commit table (and resolve it to a bitmap in the
+ * above if-statement).
+ *
+ * Instead, we can skip ahead and immediately read the flags and
+ * ewah bitmap.
+ */
+ bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
+ flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
+ bitmap = read_bitmap_1(bitmap_git);
+
+ if (!bitmap)
+ goto corrupt;
+
+ return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags);
+
+corrupt:
+ free(xor_items);
+ is_corrupt = 1;
+ return NULL;
+}
+
struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
struct commit *commit)
{
khiter_t hash_pos = kh_get_oid_map(bitmap_git->bitmaps,
commit->object.oid);
- if (hash_pos >= kh_end(bitmap_git->bitmaps))
- return NULL;
+ if (hash_pos >= kh_end(bitmap_git->bitmaps)) {
+ struct stored_bitmap *bitmap = NULL;
+ if (!bitmap_git->table_lookup)
+ return NULL;
+
+ /* this is a fairly hot codepath - no trace2_region please */
+ /* NEEDSWORK: cache misses aren't recorded */
+ bitmap = lazy_bitmap_for_commit(bitmap_git, commit);
+ if (!bitmap)
+ return NULL;
+ return lookup_stored_bitmap(bitmap);
+ }
return lookup_stored_bitmap(kh_value(bitmap_git->bitmaps, hash_pos));
}
@@ -1712,8 +1972,10 @@ void test_bitmap_walk(struct rev_info *revs)
if (revs->pending.nr != 1)
die(_("you must specify exactly one commit to test"));
- fprintf_ln(stderr, "Bitmap v%d test (%d entries loaded)",
- bitmap_git->version, bitmap_git->entry_count);
+ fprintf_ln(stderr, "Bitmap v%d test (%d entries%s)",
+ bitmap_git->version,
+ bitmap_git->entry_count,
+ bitmap_git->table_lookup ? "" : " loaded");
root = revs->pending.objects[0].item;
bm = bitmap_for_commit(bitmap_git, (struct commit *)root);
@@ -1766,13 +2028,22 @@ void test_bitmap_walk(struct rev_info *revs)
int test_bitmap_commits(struct repository *r)
{
- struct bitmap_index *bitmap_git = prepare_bitmap_git(r);
struct object_id oid;
MAYBE_UNUSED void *value;
+ struct bitmap_index *bitmap_git = prepare_bitmap_git(r);
if (!bitmap_git)
die(_("failed to load bitmap indexes"));
+ /*
+ * As this function is only used to print bitmap selected
+ * commits, we don't have to read the commit table.
+ */
+ if (bitmap_git->table_lookup) {
+ if (load_bitmap_entries_v1(bitmap_git) < 0)
+ die(_("failed to load bitmap indexes"));
+ }
+
kh_foreach(bitmap_git->bitmaps, oid, value, {
printf_ln("%s", oid_to_hex(&oid));
});
diff --git a/pack-bitmap.h b/pack-bitmap.h
index f3a57ca065f..f0180b5276b 100644
--- a/pack-bitmap.h
+++ b/pack-bitmap.h
@@ -23,9 +23,19 @@ struct bitmap_disk_header {
#define NEEDS_BITMAP (1u<<22)
+/*
+ * The width in bytes of a single triplet in the lookup table
+ * extension:
+ * (commit_pos, offset, xor_row)
+ *
+ * whose fields ar 32-, 64-, 32- bits wide, respectively.
+ */
+#define BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH (16)
+
enum pack_bitmap_opts {
- BITMAP_OPT_FULL_DAG = 1,
- BITMAP_OPT_HASH_CACHE = 4,
+ BITMAP_OPT_FULL_DAG = 0x1,
+ BITMAP_OPT_HASH_CACHE = 0x4,
+ BITMAP_OPT_LOOKUP_TABLE = 0x10,
};
enum pack_bitmap_flags {
diff --git a/packfile.c b/packfile.c
index a41887c9445..c0d7dd93f46 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1392,7 +1392,7 @@ static int delta_base_cache_key_eq(const struct delta_base_cache_key *a,
return a->p == b->p && a->base_offset == b->base_offset;
}
-static int delta_base_cache_hash_cmp(const void *unused_cmp_data,
+static int delta_base_cache_hash_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *va,
const struct hashmap_entry *vb,
const void *vkey)
diff --git a/pager.c b/pager.c
index 5cfe23b025c..b66bbff2785 100644
--- a/pager.c
+++ b/pager.c
@@ -38,7 +38,8 @@ static void wait_for_pager_signal(int signo)
raise(signo);
}
-static int core_pager_config(const char *var, const char *value, void *data)
+static int core_pager_config(const char *var, const char *value,
+ void *data UNUSED)
{
if (!strcmp(var, "core.pager"))
return git_config_string(&pager_program, var, value);
diff --git a/parse-options.c b/parse-options.c
index edf55d3ef5d..a1ec932f0f9 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -324,6 +324,8 @@ static enum parse_opt_result parse_long_opt(
const char *rest, *long_name = options->long_name;
enum opt_parsed flags = OPT_LONG, opt_flags = OPT_LONG;
+ if (options->type == OPTION_SUBCOMMAND)
+ continue;
if (!long_name)
continue;
@@ -332,7 +334,7 @@ again:
rest = NULL;
if (!rest) {
/* abbreviated? */
- if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN) &&
+ if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
!strncmp(long_name, arg, arg_end - arg)) {
is_abbreviated:
if (abbrev_option &&
@@ -419,6 +421,19 @@ static enum parse_opt_result parse_nodash_opt(struct parse_opt_ctx_t *p,
return PARSE_OPT_ERROR;
}
+static enum parse_opt_result parse_subcommand(const char *arg,
+ const struct option *options)
+{
+ for (; options->type != OPTION_END; options++)
+ if (options->type == OPTION_SUBCOMMAND &&
+ !strcmp(options->long_name, arg)) {
+ *(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
+ return PARSE_OPT_SUBCOMMAND;
+ }
+
+ return PARSE_OPT_UNKNOWN;
+}
+
static void check_typos(const char *arg, const struct option *options)
{
if (strlen(arg) < 3)
@@ -442,6 +457,7 @@ static void check_typos(const char *arg, const struct option *options)
static void parse_options_check(const struct option *opts)
{
char short_opts[128];
+ void *subcommand_value = NULL;
memset(short_opts, '\0', sizeof(short_opts));
for (; opts->type != OPTION_END; opts++) {
@@ -489,6 +505,14 @@ static void parse_options_check(const struct option *opts)
"Are you using parse_options_step() directly?\n"
"That case is not supported yet.");
break;
+ case OPTION_SUBCOMMAND:
+ if (!opts->value || !opts->subcommand_fn)
+ optbug(opts, "OPTION_SUBCOMMAND needs a value and a subcommand function");
+ if (!subcommand_value)
+ subcommand_value = opts->value;
+ else if (subcommand_value != opts->value)
+ optbug(opts, "all OPTION_SUBCOMMANDs need the same value");
+ break;
default:
; /* ok. (usually accepts an argument) */
}
@@ -499,6 +523,14 @@ static void parse_options_check(const struct option *opts)
BUG_if_bug("invalid 'struct option'");
}
+static int has_subcommands(const struct option *options)
+{
+ for (; options->type != OPTION_END; options++)
+ if (options->type == OPTION_SUBCOMMAND)
+ return 1;
+ return 0;
+}
+
static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
int argc, const char **argv, const char *prefix,
const struct option *options,
@@ -515,7 +547,20 @@ static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
ctx->prefix = prefix;
ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
ctx->flags = flags;
- if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
+ ctx->has_subcommands = has_subcommands(options);
+ if (!ctx->has_subcommands && (flags & PARSE_OPT_SUBCOMMAND_OPTIONAL))
+ BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands");
+ if (ctx->has_subcommands) {
+ if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
+ BUG("subcommands are incompatible with PARSE_OPT_STOP_AT_NON_OPTION");
+ if (!(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
+ if (flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
+ BUG("subcommands are incompatible with PARSE_OPT_KEEP_UNKNOWN_OPT unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
+ if (flags & PARSE_OPT_KEEP_DASHDASH)
+ BUG("subcommands are incompatible with PARSE_OPT_KEEP_DASHDASH unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
+ }
+ }
+ if ((flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
(flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
!(flags & PARSE_OPT_ONE_SHOT))
BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
@@ -589,6 +634,7 @@ static int show_gitcomp(const struct option *opts, int show_all)
int nr_noopts = 0;
for (; opts->type != OPTION_END; opts++) {
+ const char *prefix = "--";
const char *suffix = "";
if (!opts->long_name)
@@ -598,6 +644,9 @@ static int show_gitcomp(const struct option *opts, int show_all)
continue;
switch (opts->type) {
+ case OPTION_SUBCOMMAND:
+ prefix = "";
+ break;
case OPTION_GROUP:
continue;
case OPTION_STRING:
@@ -620,7 +669,8 @@ static int show_gitcomp(const struct option *opts, int show_all)
suffix = "=";
if (starts_with(opts->long_name, "no-"))
nr_noopts++;
- printf(" --%s%s", opts->long_name, suffix);
+ printf("%s%s%s%s", opts == original_opts ? "" : " ",
+ prefix, opts->long_name, suffix);
}
show_negated_gitcomp(original_opts, show_all, -1);
show_negated_gitcomp(original_opts, show_all, nr_noopts);
@@ -743,10 +793,38 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
if (*arg != '-' || !arg[1]) {
if (parse_nodash_opt(ctx, arg, options) == 0)
continue;
- if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
- return PARSE_OPT_NON_OPTION;
- ctx->out[ctx->cpidx++] = ctx->argv[0];
- continue;
+ if (!ctx->has_subcommands) {
+ if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
+ return PARSE_OPT_NON_OPTION;
+ ctx->out[ctx->cpidx++] = ctx->argv[0];
+ continue;
+ }
+ switch (parse_subcommand(arg, options)) {
+ case PARSE_OPT_SUBCOMMAND:
+ return PARSE_OPT_SUBCOMMAND;
+ case PARSE_OPT_UNKNOWN:
+ if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
+ /*
+ * arg is neither a short or long
+ * option nor a subcommand. Since
+ * this command has a default
+ * operation mode, we have to treat
+ * this arg and all remaining args
+ * as args meant to that default
+ * operation mode.
+ * So we are done parsing.
+ */
+ return PARSE_OPT_DONE;
+ error(_("unknown subcommand: `%s'"), arg);
+ usage_with_options(usagestr, options);
+ case PARSE_OPT_COMPLETE:
+ case PARSE_OPT_HELP:
+ case PARSE_OPT_ERROR:
+ case PARSE_OPT_DONE:
+ case PARSE_OPT_NON_OPTION:
+ /* Impossible. */
+ BUG("parse_subcommand() cannot return these");
+ }
}
/* lone -h asks for help */
@@ -774,6 +852,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
goto show_usage;
goto unknown;
case PARSE_OPT_NON_OPTION:
+ case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_HELP:
case PARSE_OPT_COMPLETE:
BUG("parse_short_opt() cannot return these");
@@ -799,6 +878,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
*(char *)ctx->argv[0] = '-';
goto unknown;
case PARSE_OPT_NON_OPTION:
+ case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_COMPLETE:
case PARSE_OPT_HELP:
BUG("parse_short_opt() cannot return these");
@@ -830,6 +910,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
case PARSE_OPT_HELP:
goto show_usage;
case PARSE_OPT_NON_OPTION:
+ case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_COMPLETE:
BUG("parse_long_opt() cannot return these");
case PARSE_OPT_DONE:
@@ -839,7 +920,19 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
unknown:
if (ctx->flags & PARSE_OPT_ONE_SHOT)
break;
- if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
+ if (ctx->has_subcommands &&
+ (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL) &&
+ (ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) {
+ /*
+ * Found an unknown option given to a command with
+ * subcommands that has a default operation mode:
+ * we treat this option and all remaining args as
+ * arguments meant to that default operation mode.
+ * So we are done parsing.
+ */
+ return PARSE_OPT_DONE;
+ }
+ if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT))
return PARSE_OPT_UNKNOWN;
ctx->out[ctx->cpidx++] = ctx->argv[0];
ctx->opt = NULL;
@@ -884,7 +977,14 @@ int parse_options(int argc, const char **argv,
case PARSE_OPT_COMPLETE:
exit(0);
case PARSE_OPT_NON_OPTION:
+ case PARSE_OPT_SUBCOMMAND:
+ break;
case PARSE_OPT_DONE:
+ if (ctx.has_subcommands &&
+ !(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
+ error(_("need a subcommand"));
+ usage_with_options(usagestr, options);
+ }
break;
case PARSE_OPT_UNKNOWN:
if (ctx.argv[0][1] == '-') {
@@ -1009,6 +1109,8 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
size_t pos;
int pad;
+ if (opts->type == OPTION_SUBCOMMAND)
+ continue;
if (opts->type == OPTION_GROUP) {
fputc('\n', outfile);
need_newline = 0;
diff --git a/parse-options.h b/parse-options.h
index 685fccac137..b6ef86e0d15 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -11,6 +11,7 @@ enum parse_opt_type {
OPTION_GROUP,
OPTION_NUMBER,
OPTION_ALIAS,
+ OPTION_SUBCOMMAND,
/* options with no arguments */
OPTION_BIT,
OPTION_NEGBIT,
@@ -30,10 +31,11 @@ enum parse_opt_flags {
PARSE_OPT_KEEP_DASHDASH = 1 << 0,
PARSE_OPT_STOP_AT_NON_OPTION = 1 << 1,
PARSE_OPT_KEEP_ARGV0 = 1 << 2,
- PARSE_OPT_KEEP_UNKNOWN = 1 << 3,
+ PARSE_OPT_KEEP_UNKNOWN_OPT = 1 << 3,
PARSE_OPT_NO_INTERNAL_HELP = 1 << 4,
PARSE_OPT_ONE_SHOT = 1 << 5,
PARSE_OPT_SHELL_EVAL = 1 << 6,
+ PARSE_OPT_SUBCOMMAND_OPTIONAL = 1 << 7,
};
enum parse_opt_option_flags {
@@ -56,6 +58,7 @@ enum parse_opt_result {
PARSE_OPT_ERROR = -1, /* must be the same as error() */
PARSE_OPT_DONE = 0, /* fixed so that "return 0" works */
PARSE_OPT_NON_OPTION,
+ PARSE_OPT_SUBCOMMAND,
PARSE_OPT_UNKNOWN
};
@@ -67,6 +70,9 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
const struct option *opt,
const char *arg, int unset);
+typedef int parse_opt_subcommand_fn(int argc, const char **argv,
+ const char *prefix);
+
/*
* `type`::
* holds the type of the option, you must have an OPTION_END last in your
@@ -76,7 +82,8 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
* the character to use as a short option name, '\0' if none.
*
* `long_name`::
- * the long option name, without the leading dashes, NULL if none.
+ * the long option (without the leading dashes) or subcommand name,
+ * NULL if none.
*
* `value`::
* stores pointers to the values to be filled.
@@ -93,7 +100,7 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
*
* `help`::
* the short help associated to what the option does.
- * Must never be NULL (except for OPTION_END).
+ * Must never be NULL (except for OPTION_END and OPTION_SUBCOMMAND).
* OPTION_GROUP uses this pointer to store the group header.
* Should be wrapped by N_() for translation.
*
@@ -109,7 +116,8 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
* is last on the command line. If the option is
* not last it will require an argument.
* Should not be used with PARSE_OPT_OPTARG.
- * PARSE_OPT_NODASH: this option doesn't start with a dash.
+ * PARSE_OPT_NODASH: this option doesn't start with a dash; can only be a
+ * short option and can't accept arguments.
* PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets
* (i.e. '<argh>') in the help message.
* Useful for options with multiple parameters.
@@ -130,6 +138,9 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
* `ll_callback`::
* pointer to the callback to use for OPTION_LOWLEVEL_CALLBACK
*
+ * `subcommand_fn`::
+ * pointer to a function to use for OPTION_SUBCOMMAND.
+ * It will be put in value when the subcommand is given on the command line.
*/
struct option {
enum parse_opt_type type;
@@ -144,6 +155,7 @@ struct option {
intptr_t defval;
parse_opt_ll_cb *ll_callback;
intptr_t extra;
+ parse_opt_subcommand_fn *subcommand_fn;
};
#define OPT_BIT_F(s, l, v, h, b, f) { OPTION_BIT, (s), (l), (v), NULL, (h), \
@@ -205,6 +217,14 @@ struct option {
#define OPT_ALIAS(s, l, source_long_name) \
{ OPTION_ALIAS, (s), (l), (source_long_name) }
+#define OPT_SUBCOMMAND_F(l, v, fn, f) { \
+ .type = OPTION_SUBCOMMAND, \
+ .long_name = (l), \
+ .value = (v), \
+ .flags = (f), \
+ .subcommand_fn = (fn) }
+#define OPT_SUBCOMMAND(l, v, fn) OPT_SUBCOMMAND_F((l), (v), (fn), 0)
+
/*
* parse_options() will filter out the processed options and leave the
* non-option arguments in argv[]. argv0 is assumed program name and
@@ -294,6 +314,7 @@ struct parse_opt_ctx_t {
int argc, cpidx, total;
const char *opt;
enum parse_opt_flags flags;
+ unsigned has_subcommands;
const char *prefix;
const char **alias_groups; /* must be in groups of 3 elements! */
struct option *updated_options;
diff --git a/patch-ids.c b/patch-ids.c
index 8bf425555de..31534466266 100644
--- a/patch-ids.c
+++ b/patch-ids.c
@@ -11,7 +11,7 @@ static int patch_id_defined(struct commit *commit)
}
int commit_patch_id(struct commit *commit, struct diff_options *options,
- struct object_id *oid, int diff_header_only, int stable)
+ struct object_id *oid, int diff_header_only)
{
if (!patch_id_defined(commit))
return -1;
@@ -22,7 +22,7 @@ int commit_patch_id(struct commit *commit, struct diff_options *options,
else
diff_root_tree_oid(&commit->object.oid, "", options);
diffcore_std(options);
- return diff_flush_patch_id(options, oid, diff_header_only, stable);
+ return diff_flush_patch_id(options, oid, diff_header_only);
}
/*
@@ -38,7 +38,7 @@ int commit_patch_id(struct commit *commit, struct diff_options *options,
static int patch_id_neq(const void *cmpfn_data,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
/* NEEDSWORK: const correctness? */
struct diff_options *opt = (void *)cmpfn_data;
@@ -48,11 +48,11 @@ static int patch_id_neq(const void *cmpfn_data,
b = container_of(entry_or_key, struct patch_id, ent);
if (is_null_oid(&a->patch_id) &&
- commit_patch_id(a->commit, opt, &a->patch_id, 0, 0))
+ commit_patch_id(a->commit, opt, &a->patch_id, 0))
return error("Could not get patch ID for %s",
oid_to_hex(&a->commit->object.oid));
if (is_null_oid(&b->patch_id) &&
- commit_patch_id(b->commit, opt, &b->patch_id, 0, 0))
+ commit_patch_id(b->commit, opt, &b->patch_id, 0))
return error("Could not get patch ID for %s",
oid_to_hex(&b->commit->object.oid));
return !oideq(&a->patch_id, &b->patch_id);
@@ -82,7 +82,7 @@ static int init_patch_id_entry(struct patch_id *patch,
struct object_id header_only_patch_id;
patch->commit = commit;
- if (commit_patch_id(commit, &ids->diffopts, &header_only_patch_id, 1, 0))
+ if (commit_patch_id(commit, &ids->diffopts, &header_only_patch_id, 1))
return -1;
hashmap_entry_init(&patch->ent, oidhash(&header_only_patch_id));
diff --git a/patch-ids.h b/patch-ids.h
index ab6c6a68047..490d7393716 100644
--- a/patch-ids.h
+++ b/patch-ids.h
@@ -20,7 +20,7 @@ struct patch_ids {
};
int commit_patch_id(struct commit *commit, struct diff_options *options,
- struct object_id *oid, int, int);
+ struct object_id *oid, int);
int init_patch_ids(struct repository *, struct patch_ids *);
int free_patch_ids(struct patch_ids *);
diff --git a/path.c b/path.c
index a3cfcd8a6e9..492e17ad121 100644
--- a/path.c
+++ b/path.c
@@ -901,7 +901,13 @@ int adjust_shared_perm(const char *path)
if (S_ISDIR(old_mode)) {
/* Copy read bits to execute bits */
new_mode |= (new_mode & 0444) >> 2;
- new_mode |= FORCE_DIR_SET_GID;
+
+ /*
+ * g+s matters only if any extra access is granted
+ * based on group membership.
+ */
+ if (FORCE_DIR_SET_GID && (new_mode & 060))
+ new_mode |= FORCE_DIR_SET_GID;
}
if (((old_mode ^ new_mode) & ~S_IFMT) &&
diff --git a/perl/Git.pm b/perl/Git.pm
index 080cdc2a21d..117765dc73c 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -177,16 +177,27 @@ sub repository {
-d $opts{Directory} or throw Error::Simple("Directory not found: $opts{Directory} $!");
my $search = Git->repository(WorkingCopy => $opts{Directory});
- my $dir;
+
+ # This rev-parse will throw an exception if we're not in a
+ # repository, which is what we want, but it's kind of noisy.
+ # Ideally we'd capture stderr and relay it, but doing so is
+ # awkward without depending on it fitting in a pipe buffer. So
+ # we just reproduce a plausible error message ourselves.
+ my $out;
try {
- $dir = $search->command_oneline(['rev-parse', '--git-dir'],
- STDERR => 0);
+ # Note that "--is-bare-repository" must come first, as
+ # --git-dir output could contain newlines.
+ $out = $search->command([qw(rev-parse --is-bare-repository --git-dir)],
+ STDERR => 0);
} catch Git::Error::Command with {
- $dir = undef;
+ throw Error::Simple("fatal: not a git repository: $opts{Directory}");
};
+ chomp $out;
+ my ($bare, $dir) = split /\n/, $out, 2;
+
require Cwd;
- if ($dir) {
+ if ($bare ne 'true') {
require File::Spec;
File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir;
$opts{Repository} = Cwd::abs_path($dir);
@@ -204,21 +215,6 @@ sub repository {
$opts{WorkingSubdir} = $prefix;
} else {
- # A bare repository? Let's see...
- $dir = $opts{Directory};
-
- unless (-d "$dir/refs" and -d "$dir/objects" and -e "$dir/HEAD") {
- # Mimic git-rev-parse --git-dir error message:
- throw Error::Simple("fatal: Not a git repository: $dir");
- }
- my $search = Git->repository(Repository => $dir);
- try {
- $search->command('symbolic-ref', 'HEAD');
- } catch Git::Error::Command with {
- # Mimic git-rev-parse --git-dir error message:
- throw Error::Simple("fatal: Not a git repository: $dir");
- }
-
$opts{Repository} = Cwd::abs_path($dir);
}
diff --git a/po/bg.po b/po/bg.po
index 934784fe523..8b2a936ba0d 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -1,8 +1,7 @@
# Bulgarian translation of git po-file.
-# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Alexander Shopov <ash@kambanaria.org>.
+# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Alexander Shopov <ash@kambanaria.org>.
# This file is distributed under the same license as the git package.
# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022.
-#
# ========================
# DICTIONARY TO MERGE IN GIT GUI
# ------------------------
@@ -64,6 +63,8 @@
# pathspec magic Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° магичеÑки пътища
# bitmap index Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки
# multi-pack bitmap многопакетната битова маÑка
+# ewah bitmap битова маÑка във формат EWAH
+# type bitmap битова маÑка на видовете
# mark маркер
# plumbing команди от ÑиÑтемно ниво
# porcelain команди от потребителÑко ниво
@@ -165,6 +166,7 @@
# scheduler планиращ модул
# snapshot Ñнимка
# enlistment зачиÑлена директориÑ
+# remove enlistment отчиÑлÑвам директориÑ
# zealous merge заÑилено Ñливане
# unregister отчиÑлÑвам
# marked counting изброÑване
@@ -184,7 +186,13 @@
# traverse обхождам
# timestamp времево клеймо
# bare repository голо хранилище
-#
+# resolve-undo отмÑна на разрешените подаваниÑ
+# maintenance задачи по поддръжка
+# GLE поÑледна грешка в нишката - от GetLatError: https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
+# lookup table таблица ÑÑŠÑ ÑъответÑтвиÑ
+# out of range извън диапазона
+# checksum Ñума за проверка
+# superproject обхващащ проект
# ------------------------
# „$var“ - може да не Ñработва за shell има gettext и eval_gettext - проверка - намират Ñе леÑно по „$
# ------------------------
@@ -199,13 +207,12 @@
# msgcat todo1.po todo2.po > todo.po
# grep '^#: ' todo.po | sed 's/^#: //' | tr ' ' '\n' | sed 's/:[0-9]*$//' > FILES
# for i in `sort -u FILES`; do cnt=`grep $i FILES | wc -l`; echo $cnt $i ;done | sort -n
-#
msgid ""
msgstr ""
-"Project-Id-Version: git 2.37\n"
+"Project-Id-Version: git 2.38\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-22 15:43+0200\n"
-"PO-Revision-Date: 2022-06-22 15:44+0200\n"
+"POT-Creation-Date: 2022-09-28 10:59+0200\n"
+"PO-Revision-Date: 2022-09-28 10:59+0200\n"
"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
"Language: bg\n"
@@ -363,7 +370,6 @@ msgstr "път"
msgid "could not refresh index"
msgstr "индекÑÑŠÑ‚ не може да бъде обновен"
-#
#, c-format
msgid "Bye.\n"
msgstr "Изход.\n"
@@ -625,6 +631,24 @@ msgstr ""
"d — без прилагане на това и вÑички Ñледващи парчета от файла от индекÑа и "
"работното дърво\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr ""
+"Прилагане на промÑната в правата за доÑтъп към работното дърво [y,n,q,a,d"
+"%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Прилагане на изтриването към работното дърво [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Прилагане на добавÑнето към работното дърво [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Прилагане на парчето към работното дърво [y,n,q,a,d%s,?]? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -642,10 +666,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "заглавната чаÑÑ‚ на парчето „%.*s“ не може да Ñе анализира"
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "заглавната чаÑÑ‚ на оцветеното парче „%.*s“ не може да Ñе анализира"
-
msgid "could not parse diff"
msgstr "разликата не може да Ñе анализира"
@@ -936,6 +956,29 @@ msgstr ""
"detachedHead“\n"
"да е „false“ (лъжа̀).\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Следните пътища Ñа премеÑтени извън дефинициите за чаÑтично\n"
+"изтеглÑне, но вече не Ñа чаÑтични заради локални промени.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Ðко иÑкате да ги обновите, пробвайте едно от Ñледните:\n"
+" ⃠обновете индекÑа Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð°:\n"
+"\n"
+" git add --sparse ПЪТ…\n"
+"\n"
+" ⃠приложете правилата за чаÑтичноÑÑ‚ Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð°:\n"
+"\n"
+" git sparse-checkout reapply"
+
msgid "cmdline ends with \\"
msgstr "командниÑÑ‚ ред завършва Ñ â€ž/“"
@@ -1461,6 +1504,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "неподдържани права за доÑтъп до файл: 0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "грешка при декомпреÑиране Ñ â€ždeflate“ (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "филтърът „%s“ не може да бъде Ñтартиран"
@@ -1480,10 +1527,6 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "твърде дълъг път (%d знака, SHA1: %s): %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "грешка при декомпреÑиране Ñ â€ždeflate“ (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "времевото клеймо е твърде голÑмо за тази ÑиÑтема: %<PRIuMAX>"
@@ -3315,8 +3358,13 @@ msgstr "библиотека на C: "
msgid "not run from a git repository - no hooks to show\n"
msgstr "командата е Ñтартирана извън хранилище на Git, затова нÑма куки\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory ФÐЙЛ] [-s|--suffix ФОРМÐТ]"
+# FIXME
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory ФÐЙЛ] [-s|--suffix ФОРМÐТ] [--"
+"diagnose[=РЕЖИМ]]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3353,16 +3401,29 @@ msgstr ""
"Разгледайте оÑтаналата чаÑÑ‚ от доклада за грешка по-долу.\n"
"Може да изтриете редовете, които не иÑкате да Ñподелите.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "укажете файла, в който да Ñе запази докладът за грешка"
+msgid "mode"
+msgstr "РЕЖИМ"
-msgid "specify a strftime format suffix for the filename"
-msgstr "укажете ÑуфикÑа на файла във формат за „strftime“"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr ""
+"Ñъздаване на допълнителен архив във формат zip Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¸ диагноÑтични "
+"ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (Ñтандартно е „stats“ — ÑтатиÑтика)"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "укажете меÑтоположение, в което да Ñе запазÑÑ‚ докладите за грешка"
+
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "укажете ÑуфикÑа на файловете във формат за „strftime“"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "родителÑките директории на „%s“ не може да бъдат Ñъздадени"
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "не може да Ñе Ñъздаде архив за диагноÑтичните ÑъобщениÑ: %s"
+
msgid "System Info"
msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° ÑиÑтемата"
@@ -3422,10 +3483,6 @@ msgid "Unbundling objects"
msgstr "Разпакетиране на пратки от обекти"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Ðепозната подкоманда: %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "обектът „%s“ (%s) не може да бъде прочетен"
@@ -3504,6 +3561,11 @@ msgstr "извеждане на размера на обект"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "позволÑване на опциите „-s“ и „-t“ да работÑÑ‚ Ñ Ð¿Ð¾Ð²Ñ€ÐµÐ´ÐµÐ½Ð¸ обекти"
+msgid "use mail map file"
+msgstr ""
+"използване на файл за ÑъответÑтвиÑта на имената и адреÑите на е-поща („."
+"mailmap“)"
+
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr ""
"Пакетно извеждане на заÑвените обекти на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´ (или „--batch-all-"
@@ -3515,6 +3577,9 @@ msgstr "извеждане на пълното Ñъдържание на ОБЕÐ
msgid "like --batch, but don't emit <contents>"
msgstr "като „--batch“, но без извеждане на Ñъдържанието"
+msgid "stdin is NUL-terminated"
+msgstr "ÑтандартниÑÑ‚ вход да ползва Ð½ÑƒÐ»ÐµÐ²Ð¸Ñ Ð·Ð½Ð°Ðº „NUL“ за разделител"
+
msgid "read commands from stdin"
msgstr "изчитане на командите от ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð²Ñ…Ð¾Ð´"
@@ -4403,6 +4468,13 @@ msgstr ""
"инициализиране на файла за чаÑтично изтеглÑне („.git/info/sparse-checkout“) "
"да Ñъдържа Ñамо файловете в оÑновната директориÑ"
+msgid "uri"
+msgstr "ÐДРЕС"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr ""
+"ÐДРЕС за доÑтавÑне на пратки на git преди доÑтавÑне от отдалеченото хранилище"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr ""
@@ -4468,10 +4540,10 @@ msgstr "обектът „%s“ не може да бъде обновен"
msgid "failed to initialize sparse-checkout"
msgstr "чаÑтичното изтеглÑне не може да Ñе инициализира"
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
msgstr ""
-"указателÑÑ‚ „HEAD“ от отдалеченото хранилище Ñочи към нещо,\n"
-"което не ÑъщеÑтвува. Ðе може да Ñе изтегли определен клон.\n"
+"указателÑÑ‚ „HEAD“ от отдалеченото хранилище Ñочи към нещо, което не "
+"ÑъщеÑтвува. ИзтеглÑне не може да Ñе извърши"
msgid "unable to checkout working tree"
msgstr "работното дърво не може да бъде подготвено"
@@ -4495,6 +4567,13 @@ msgstr "ТрÑбва да укажете кое хранилище иÑкате
msgid "options '%s' and '%s %s' cannot be used together"
msgstr "опциите „%s“ и „%s %s“ Ñа неÑъвмеÑтими"
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"опциÑта „--bundle-uri“ е неÑъвмеÑтима Ñ â€ž--depth“, „--shallow-since“ и „--"
+"shallow-exclude“"
+
#, c-format
msgid "repository '%s' does not exist"
msgstr "не ÑъщеÑтвува хранилище „%s“"
@@ -4574,6 +4653,14 @@ msgstr "опциÑта „--local“ Ñе преÑкача"
msgid "cannot clone from filtered bundle"
msgstr "не може да Ñе клонира от филтрирана пратка"
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr ""
+"хранилището не може да Ñе инициализира, адреÑÑŠÑ‚ на пратката Ñе преÑкача"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "неуÑпешно доÑтавÑне на обекти от пратка на Ð°Ð´Ñ€ÐµÑ â€ž%s“"
+
msgid "remote transport reported error"
msgstr "отдалечениÑÑ‚ транÑпорт върна грешка"
@@ -4694,10 +4781,6 @@ msgstr ""
msgid "Collecting commits from input"
msgstr "Получаване на подаваниÑта от входа"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "непозната подкоманда: %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -5066,9 +5149,6 @@ msgstr "подробна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° ÑÑŠÑтоÑнието (ÑÑ‚Ð
msgid "terminate entries with NUL"
msgstr "разделÑне на елементите Ñ Ð½ÑƒÐ»ÐµÐ²Ð¸Ñ Ð·Ð½Ð°Ðº „NUL“"
-msgid "mode"
-msgstr "РЕЖИМ"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
"извеждане на неÑледените файлове. Възможните РЕЖИМи Ñа „all“ (подробна "
@@ -5685,6 +5765,22 @@ msgstr "Ðе Ñа открити имена — нищо не може да бъ
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "опциите „%s“ и указателите към обекти Ñа неÑъвмеÑтими"
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory ФÐЙЛ] [-s|--suffix ФОРМÐТ] [--"
+"diagnose[=РЕЖИМ]]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "укажете меÑтоположение на архива Ñ Ð´Ð¸Ð°Ð³Ð½Ð¾Ñтичната информациÑ"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr "укажете ÑуфикÑа на файла във формат за „strftime“"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "указване на Ñъдържанието на диагноÑÑ‚Ð¸Ñ‡Ð½Ð¸Ñ Ð°Ñ€Ñ…Ð¸Ð²"
+
msgid "--merge-base only works with two commits"
msgstr "опциÑта „--merge-base“ изиÑква точно две подаваниÑ"
@@ -6066,12 +6162,9 @@ msgstr "[актуален]"
msgid "[rejected]"
msgstr "[отхвърлен]"
-msgid "can't fetch in current branch"
+msgid "can't fetch into checked-out branch"
msgstr "в Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½ не може да Ñе доÑтавÑ"
-msgid "checked out in another worktree"
-msgstr "изтеглен в друго работно дърво"
-
msgid "[tag update]"
msgstr "[обновÑване на етикетите]"
@@ -6487,7 +6580,6 @@ msgstr "Проверка на директориите Ñ Ð¾Ð±ÐµÐºÑ‚Ð¸"
msgid "Checking %s link"
msgstr "Проверка на връзките на „%s“"
-#
#, c-format
msgid "invalid %s"
msgstr "неправилен указател „%s“"
@@ -6514,6 +6606,10 @@ msgstr "„%s“: неправилен указател за SHA1 в дървоÑ
msgid "non-tree in cache-tree"
msgstr "в дървото на кеша има нещо, което не е дърво"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "„%s“: неправилен указател за отмÑна на разрешените подаваниÑ"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [ОПЦИЯ…] [ОБЕКТ…]"
@@ -6578,7 +6674,7 @@ msgstr "git fsmonitor--daemon status"
#, c-format
msgid "value of '%s' out of range: %d"
-msgstr "дължината на „%s“ e извън интервала: %d"
+msgstr "дължината на „%s“ e извън диапазона: %d"
#, c-format
msgid "value of '%s' not bool or int: %d"
@@ -6856,13 +6952,16 @@ msgstr ""
"неуÑпешно изпълнение на „crontab -l“. СиÑтемата ви може да не поддържа "
"„cron“"
+msgid "failed to create crontab temporary file"
+msgstr "не може да Ñе Ñъздаде временен файл за crontab"
+
+msgid "failed to open temporary file"
+msgstr "временниÑÑ‚ файл не може да Ñе отвори"
+
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr ""
"неуÑпешно изпълнение на „crontab“. СиÑтемата ви може да не поддържа „cron“"
-msgid "failed to open stdin of 'crontab'"
-msgstr "ÑтандартниÑÑ‚ вход на „crontab“ не може да Ñе отвори"
-
msgid "'crontab' died"
msgstr "процеÑÑŠÑ‚ на „crontab“ умрÑ"
@@ -6909,10 +7008,6 @@ msgstr "неуÑпешно добавÑне на хранилище към фаÐ
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance ПОДКОМÐÐДР[ОПЦИЯ…]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "неправилна подкоманда: „%s“"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [ОПЦИЯ…] [-e] ШÐБЛОР[ВЕРСИЯ…] [[--] ПЪТ…]"
@@ -7094,6 +7189,9 @@ msgstr ""
"позволÑване на Ñтартирането на grep(1) (текущиÑÑ‚ компилат пренебрегва тази "
"опциÑ)"
+msgid "maximum number of results per file"
+msgstr "макÑимален брой резултати във файл"
+
msgid "no pattern given"
msgstr "не Ñте задали шаблон"
@@ -7178,16 +7276,22 @@ msgid "show info page"
msgstr "показване на информационна Ñтраница"
msgid "print command description"
-msgstr "извеждане на опиÑанието на команда"
+msgstr "показване на опиÑанието на команда"
msgid "print list of useful guides"
msgstr "показване на ÑпиÑък Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÐ½Ð¸Ñ"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr "показване на ÑпиÑък Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ‚Ðµ за файлове и хранилища за потребители"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr "показване на ÑпиÑък Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¸ формати, протоколи и др. за програмиÑти"
+
msgid "print all configuration variable names"
msgstr "показване на имената на вÑички конфигуриращи променливи"
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [КОМÐÐДÐ…]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [КОМÐÐДÐ|ДОКУМЕÐТ]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -7403,7 +7507,7 @@ msgstr[1] "дейÑтвието завърши Ñ %d локални обекта
#, c-format
msgid "Unexpected tail checksum for %s (disk corruption?)"
msgstr ""
-"Ðеочаквана поÑледваща Ñума за грешки за „%s“ (причината може да е грешка в "
+"Ðеочаквана поÑледваща Ñума за проверка на „%s“ (причината може да е грешка в "
"диÑка)"
#, c-format
@@ -7666,10 +7770,8 @@ msgstr "без извеждане на разликите"
msgid "show source"
msgstr "извеждане на Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸Ñ ÐºÐ¾Ð´"
-msgid "use mail map file"
-msgstr ""
-"използване на файл за ÑъответÑтвиÑта на имената и адреÑите на е-поща („."
-"mailmap“)"
+msgid "clear all previously-defined decoration filters"
+msgstr "изчиÑтване на зададените филтри за форма̀та на извежданата информациÑ"
msgid "only decorate refs that match <pattern>"
msgstr "Ñпециален формат Ñамо на указателите напаÑващи на ШÐБЛОÐа"
@@ -7936,6 +8038,11 @@ msgstr ""
msgid "percentage by which creation is weighted"
msgstr "процент за претеглÑне при оценка на Ñъздаването"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr ""
+"показване на заглавната чаÑÑ‚ „From:“ в Ñ‚Ñлото на пиÑмото дори и да е Ñъщата "
+"като тази на плика на пиÑмото"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "грешна идентичноÑÑ‚: %s"
@@ -7998,6 +8105,18 @@ msgstr ""
"СледениÑÑ‚ отдалечен клон не бе открит, затова изрично задайте "
"ОТДÐЛЕЧЕÐ_КЛОÐ.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "неправилен формат за „ls-tree“: елементът „%s“ не започва Ñ â€ž(“"
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "неправилен формат за „ls-tree“: елементът „%s“ не завършва Ñ â€ž)“"
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "неправилен формат за „ls-tree“: %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [ОПЦИЯ…] [ФÐЙЛ…]"
@@ -8086,6 +8205,13 @@ msgstr ""
"указване на чаÑтично изтеглените директории при наличието на чаÑтичен индекÑ"
msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"опциÑта „--format“ е неÑъвмеÑтима Ñ â€ž-s“/„-o“/„-k“/„-t“/„--resolve-undo“/„--"
+"deduplicate“/„--eol“"
+
+msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url]\n"
" [--symref] [<repository> [<refs>...]]"
@@ -8310,6 +8436,40 @@ msgstr "указателÑÑ‚ „%s“ не може да бъде изтрит"
msgid "Merging %s with %s\n"
msgstr "Сливане на „%s“ Ñ â€ž%s“\n"
+msgid "not something we can merge"
+msgstr "не може да Ñе Ñлее"
+
+msgid "refusing to merge unrelated histories"
+msgstr "незавиÑими иÑтории не може да Ñе ÑлеÑÑ‚"
+
+msgid "failure to merge"
+msgstr "неуÑпешно Ñливане"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [ОПЦИЯ…] КЛОÐ_1 КЛОÐ_2"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] БÐЗОВО_ДЪРВО КЛОÐ_1 КЛОÐ_2"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "ÑъщинÑко, а не тривиално Ñливане"
+
+msgid "do a trivial merge only"
+msgstr "Ñамо тривиално Ñливане"
+
+msgid "also show informational/conflict messages"
+msgstr "показване и информационните ÑъобщениÑ, и тези при конфликт"
+
+msgid "list filenames without modes/oids/stages"
+msgstr ""
+"извеждане на имената на файлове без режими/идентификатори на обекти/етапи"
+
+msgid "allow merging unrelated histories"
+msgstr "позволÑване на Ñливане на незавиÑими иÑтории"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "„--trivial-merge“ е неÑъвмеÑтима Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ‚Ðµ опции"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [ОПЦИЯ…] [ПОДÐÐ’ÐÐЕ…]"
@@ -8391,9 +8551,6 @@ msgstr "преуÑтановÑване (--abort) без промÑна на ин
msgid "continue the current in-progress merge"
msgstr "продължаване на текущото Ñливане"
-msgid "allow merging unrelated histories"
-msgstr "позволÑване на Ñливане на незавиÑими иÑтории"
-
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr ""
"без изпълнение на куките преди подаване и Ñливане и при промÑна на "
@@ -8516,9 +8673,6 @@ msgstr "„%s“ не може да Ñе затвори"
msgid "not something we can merge in %s: %s"
msgstr "не може да Ñе Ñлее в „%s“: %s"
-msgid "not something we can merge"
-msgstr "не може да Ñе Ñлее"
-
msgid "--abort expects no arguments"
msgstr "опциÑта „--abort“ не приема аргументи"
@@ -8573,14 +8727,19 @@ msgstr "„%s“ — не е нещо, което може да Ñе Ñлее"
msgid "Can merge only exactly one commit into empty head"
msgstr "Може да Ñлеете точно едно подаване във връх без иÑториÑ"
-msgid "refusing to merge unrelated histories"
-msgstr "незавиÑими иÑтории не може да Ñе ÑлеÑÑ‚"
-
#, c-format
msgid "Updating %s..%s\n"
msgstr "ОбновÑване „%s..%s“\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Сливането ще презапише локалните промѐни на тези файлове:\n"
+" %s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Проба ÑÑŠÑ Ñливане в рамките на индекÑа…\n"
@@ -8616,6 +8775,10 @@ msgstr ""
"Ðвтоматичното Ñливане завърши уÑпешно. Самото подаване не е извършено\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "При завършване Ñкатаните промени да Ñе приложат Ñ â€žgit stash pop“\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
msgstr "ПРЕДУПРЕЖДЕÐИЕ: аргументът-етикет не минава проверка Ñ â€žfsck“: %s"
@@ -8738,6 +8901,9 @@ msgstr "Проверка на преименуването на обект от
msgid "bad source"
msgstr "неправилен обект"
+msgid "destination exists"
+msgstr "целта ÑъщеÑтвува"
+
msgid "can not move directory into itself"
msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да Ñе премеÑти в Ñебе Ñи"
@@ -8753,9 +8919,6 @@ msgstr "не е под контрола на Git"
msgid "conflicted"
msgstr "конфликт"
-msgid "destination exists"
-msgstr "целта ÑъщеÑтвува"
-
#, c-format
msgid "overwriting '%s'"
msgstr "презапиÑване на „%s“"
@@ -8769,6 +8932,9 @@ msgstr "множеÑтво източници за една цел"
msgid "destination directory does not exist"
msgstr "целевата Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ ÑъщеÑтвува"
+msgid "destination exists in the index"
+msgstr "целта ÑъщеÑтвува в индекÑа"
+
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, обект: „%s“, цел: „%s“"
@@ -9136,8 +9302,8 @@ msgid "use notes from <notes-ref>"
msgstr "да Ñе използва бележката Ñочена от този УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "непозната подкоманда: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "непозната подкоманда: „%s“"
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -10066,11 +10232,16 @@ msgid "only emit output related to the second range"
msgstr "извеждане Ñамо на информациÑта за Ð²Ñ‚Ð¾Ñ€Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "„%s“ не е верÑиÑ"
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "не е диапазон Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ: „%s“"
-msgid "single arg format must be symmetric range"
-msgstr "вариантът Ñ ÐµÐ´Ð¸Ð½Ñтвен аргумент изиÑква Ñиметричен диапазон"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "не е Ñиметричен диапазон: „%s“"
msgid "need two commit ranges"
msgstr "необходими Ñа два диапазона Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ"
@@ -10344,6 +10515,9 @@ msgid "move commits that begin with squash!/fixup! under -i"
msgstr ""
"премеÑтване на подаваниÑта, които започват ÑÑŠÑ â€žsquash!“/“fixup!“ при „-i“"
+msgid "update branches that point to commits that are being rebased"
+msgstr "обновÑване на клоните, които Ñочат към пребазирани подаваниÑ"
+
msgid "add exec lines after each commit of the editable list"
msgstr ""
"добавÑне на редове Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ за изпълнение Ñлед вÑÑко подаване в "
@@ -10895,6 +11069,9 @@ msgstr " нов (Ñледващото доÑтавÑне ще го разполÐ
msgid " tracked"
msgstr " Ñледен"
+msgid " skipped"
+msgstr " преÑкочен"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " Ñтар (изтрийте чрез „git remote prune“)"
@@ -11587,6 +11764,10 @@ msgstr "ÐовиÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ може да бъде запиÑан."
msgid "unable to get disk usage of %s"
msgstr "използваното мÑÑто за „%s“ не може да бъде получено"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "неправилна ÑтойноÑÑ‚ за „%s“: „%s“, единÑтвениÑÑ‚ позволен формат е „%s“"
+
msgid "rev-list does not support display of notes"
msgstr "командата „rev-list“ не поддържа извеждането на бележки"
@@ -11612,6 +11793,9 @@ msgstr "неочакван край на входа"
msgid "no usage string given before the `--' separator"
msgstr "липÑва низ преди Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ â€ž--“"
+msgid "missing opt-spec before option flags"
+msgstr "липÑват опции пред флаговете за опции"
+
msgid "Needed a single revision"
msgstr "ИзиÑква точно една верÑиÑ"
@@ -12392,6 +12576,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "Очаква Ñе пълно име на указател, а не „%s“"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "не може да Ñе получи връзка към хранилище за подмодула „%s“"
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -12399,12 +12587,6 @@ msgstr ""
"наÑтройката „%s“ липÑва. Приема Ñе, че това хранилище е правилниÑÑ‚ източник "
"за Ñебе Ñи."
-msgid "alternative anchor for relative paths"
-msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð° определÑнето на отноÑителните пътища"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=ПЪТ] [ПЪТ…]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "Във файла „.gitmodules“ не е открит Ð°Ð´Ñ€ÐµÑ Ð·Ð° Ð¿ÑŠÑ‚Ñ ÐºÑŠÐ¼ подмодул „%s“"
@@ -12437,8 +12619,8 @@ msgstr "без извеждане на изход при въвеждането
msgid "recurse into nested submodules"
msgstr "рекурÑивно обхождане на подмодулите"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] КОМÐÐДÐ"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] КОМÐÐДÐ"
#, c-format
msgid "Failed to register url for submodule path '%s'"
@@ -12460,8 +12642,8 @@ msgstr ""
msgid "suppress output for initializing a submodule"
msgstr "без извеждане на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ инициализирането на подмодул"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [ОПЦИЯ…] [ПЪТ]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [ОПЦИЯ…] [ПЪТ]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -12488,9 +12670,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [ПЪТ…]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name ПЪТ"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "◠%s %s(обект-BLOB)→%s(подмодул)"
@@ -12527,8 +12706,8 @@ msgstr "преÑкачане на подмодули, чиÑто наÑтройÐ
msgid "limit the summary size"
msgstr "ограничаване на размера на обобщението"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [ОПЦИЯ…] [ПОДÐÐ’ÐÐЕ] [--] [ПЪТ]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [ОПЦИЯ…] [ПОДÐÐ’ÐÐЕ] [--] [ПЪТ]"
msgid "could not fetch a revision for HEAD"
msgstr "не може да Ñе доÑтави верÑÐ¸Ñ Ð·Ð° „HEAD“"
@@ -12542,18 +12721,14 @@ msgid "failed to register url for submodule path '%s'"
msgstr "неуÑпешно региÑтриране на Ð°Ð´Ñ€ÐµÑ Ð·Ð° Ð¿ÑŠÑ‚Ñ ÐºÑŠÐ¼ подмодул „%s“"
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "отдалечениÑÑ‚ Ð°Ð´Ñ€ÐµÑ Ð½Ð° подмодула „%s“ не може да бъде получен"
-
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "отдалечениÑÑ‚ Ð°Ð´Ñ€ÐµÑ Ð½Ð° подмодула „%s“ не може да бъде променен"
msgid "suppress output of synchronizing submodule url"
msgstr "без извеждане на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ Ñинхронизирането на подмодул"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [ПЪТ]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [ПЪТ]"
#, c-format
msgid ""
@@ -12616,6 +12791,10 @@ msgstr ""
"при клониране ползвайте опциÑта „--reference-if-able“ вмеÑто „--reference“."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "не може да Ñе получи връзка към хранилище за директориÑта на git „%s“"
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "към подмодула „%s“ не може да Ñе добави алтернативен източник: %s"
@@ -12646,6 +12825,9 @@ msgstr "директориÑта не е празна: „%s“"
msgid "could not get submodule directory for '%s'"
msgstr "директориÑта на подмодула „%s“ не може да бъде получена"
+msgid "alternative anchor for relative paths"
+msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð° определÑнето на отноÑителните пътища"
+
msgid "where the new submodule will be cloned to"
msgstr "къде да Ñе клонира новиÑÑ‚ подмодул"
@@ -12674,10 +12856,6 @@ msgstr ""
"ÐДРЕС --path ПЪТ"
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Ðеправилен режим на обновÑване „%s“ за Ð¿ÑŠÑ‚Ñ ÐºÑŠÐ¼ подмодул „%s“"
-
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr ""
"ÐаÑтроен е неправилен режим на обновÑване „%s“ за Ð¿ÑŠÑ‚Ñ ÐºÑŠÐ¼ подмодул „%s“"
@@ -12753,6 +12931,10 @@ msgstr ""
"„%s“. Директното доÑтавÑне на това подаване е неуÑпешно."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "подмодулът в „%s“ не може да Ñе инициализира"
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -12761,10 +12943,6 @@ msgstr ""
"но той не е на никой клон"
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "не може да Ñе получи връзка към хранилище за подмодула „%s“"
-
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "Текущата верÑÐ¸Ñ Ð·Ð° подмодула в „%s“ липÑва"
@@ -12798,13 +12976,15 @@ msgstr "без доÑтавÑне на новите обекти от отдал
msgid "path into the working tree"
msgstr "път към работното дърво"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "път към работното дърво, през границите на вложените подмодули"
-
-msgid "rebase, merge, checkout or none"
+msgid "use the 'checkout' update strategy (default)"
msgstr ""
-"„rebase“ (пребазиране), „merge“ (Ñливане), „checkout“ (изтеглÑне) или "
-"„none“ (нищо да не Ñе прави)"
+"използване на ÑтратегиÑта за обновÑване „checkout“ (изтеглÑне — Ñтандартно)"
+
+msgid "use the 'merge' update strategy"
+msgstr "използване на ÑтратегиÑта за обновÑване „merge“ (Ñливане)"
+
+msgid "use the 'rebase' update strategy"
+msgstr "използване на ÑтратегиÑта за обновÑване „rebase“ (пребазиране)"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr "извършване на плитко клониране, отрÑзано до ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð±Ñ€Ð¾Ð¹ верÑии"
@@ -12818,6 +12998,9 @@ msgstr "дали първоначалното клониране да е плиÑ
msgid "don't print cloning progress"
msgstr "без извеждане на напредъка на клонирането"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "предотвратÑване на клониране в непразна иÑториÑ, включва „--init“"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12829,14 +13012,11 @@ msgstr ""
"shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] "
"[--] [ПЪТ…]"
-msgid "bad value for update parameter"
-msgstr "неправилен параметър към опциÑта „--update“"
-
msgid "recurse into submodules"
msgstr "рекурÑивно обхождане подмодулите"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [ОПЦИЯ…] [ПЪТ…]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [ОПЦИЯ…] [ПЪТ…]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr "проверка дали пиÑането във файла „.gitmodules“ е безопаÑно"
@@ -12856,8 +13036,8 @@ msgstr "файлът „.gitmodules“ Ñ‚Ñ€Ñбва да е в работнотÐ
msgid "suppress output for setting url of a submodule"
msgstr "без извеждане на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ задаването на адреÑа на подмодул"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] [ПЪТ] [ÐОВ_ПЪТ]"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] [ПЪТ] [ÐОВ_ПЪТ]"
msgid "set the default tracking branch to master"
msgstr "задаване на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÑледÑщ клон да е „master“"
@@ -12865,12 +13045,11 @@ msgstr "задаване на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÑледÑщ клон да
msgid "set the default tracking branch"
msgstr "задаване на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÑледÑщ клон"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) ПЪТ"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) ПЪТ"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-b|--branch) КЛОРПЪТ"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) КЛОРПЪТ"
msgid "--branch or --default required"
msgstr "необходимо е една от опциите „--branch“ и „--default“"
@@ -12968,8 +13147,8 @@ msgid ""
msgstr ""
"името на подмодула да е указаното, а не да е автоматично Ñъщото като пътÑ"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [ОПЦИЯ…] [--] ХРÐÐИЛИЩЕ [ПЪТ]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [ОПЦИЯ…] [--] ХРÐÐИЛИЩЕ [ПЪТ]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr ""
@@ -13178,6 +13357,16 @@ msgstr "Обновен етикет „%s“ (бе „%s“)\n"
msgid "pack exceeds maximum allowed size"
msgstr "пакетниÑÑ‚ файл надвишава макÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ð²ÑŠÐ·Ð¼Ð¾Ð¶ÐµÐ½ размер"
+msgid "failed to write object in stream"
+msgstr "нÑкой обект не може да Ñе запише в потока"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "декомпреÑирането Ñ â€žinflate“ завърши (%d)"
+
+msgid "invalid blob object from stream"
+msgstr "неправилен обект-BLOB от потока"
+
msgid "Unpacking objects"
msgstr "Разпакетиране на обектите"
@@ -13726,6 +13915,27 @@ msgstr "Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° обект-дърво за поддиректориÑÑ‚Ð
msgid "only useful for debugging"
msgstr "Ñамо за изчиÑтване на грешки"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "„core.fsyncMethod = batch“ не Ñе поддържа на тази платформа"
+
+msgid "failed to create temporary file"
+msgstr "не може да Ñе Ñъздаде временен файл"
+
+msgid "insufficient capabilities"
+msgstr "недоÑтатъчно възможноÑти"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "неуÑпешно изтеглÑне на пратка от адреÑ: „%s“"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "файлът на Ð°Ð´Ñ€ÐµÑ â€ž%s“ не е пратка"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "неуÑпешно разпакетиране на пратка от Ð°Ð´Ñ€ÐµÑ â€ž%s“"
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
msgstr "непознат алгоритъм за контролни Ñуми за пратки „%s“"
@@ -13939,6 +14149,9 @@ msgstr ""
"Задаване на име удобно за потребителите на обект въз оÑнова на наличен "
"указател"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Създаване на архив във формат zip Ñ Ð´Ð¸Ð°Ð³Ð½Ð¾Ñтична информациÑ"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr "Извеждане на разликите между подаваниÑта, верÑиите, работното дърво"
@@ -14070,8 +14283,8 @@ msgstr "Сливане на файловете, които Ñе нуждаÑÑ‚ Ð
msgid "The standard helper program to use with git-merge-index"
msgstr "Стандартната помощна програма за „git-merge-index“"
-msgid "Show three-way merge without touching index"
-msgstr "Извеждане на тройно Ñливане без промÑна на индекÑа"
+msgid "Perform merge without touching index or working tree"
+msgstr "Извършване на Ñливането без промени по индекÑа или работното време"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr "Изпълнение на програмите за коригиране на конфликтите при Ñливане"
@@ -14266,6 +14479,9 @@ msgstr "Проверка на пакетираните архивни файло
msgid "Check the GPG signature of tags"
msgstr "Проверка на подпиÑите GPG върху етикетите"
+msgid "Display version information about Git"
+msgstr "Извеждане на верÑиÑта на Git"
+
msgid "Show logs with difference each commit introduces"
msgstr "Извеждане на журнал Ñ Ñ€Ð°Ð·Ð»Ð¸ÐºÐ¸Ñ‚Ðµ, въведени Ñ Ð²ÑÑко подаване"
@@ -14299,6 +14515,24 @@ msgstr "Полезен минимален набор от команди за е
msgid "Frequently asked questions about using Git"
msgstr "ЧеÑто задавани въпроÑи за употребата на Git"
+msgid "The bundle file format"
+msgstr "Формат на пратките"
+
+msgid "Chunk-based file formats"
+msgstr "Формати на откъÑите"
+
+msgid "Git commit graph format"
+msgstr "Формат на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта"
+
+msgid "Git index format"
+msgstr "Формат на индекÑа"
+
+msgid "Git pack format"
+msgstr "Формат на пакетите"
+
+msgid "Git cryptographic signature formats"
+msgstr "Формати на криптографÑките подпиÑи"
+
msgid "A Git Glossary"
msgstr "Речник Ñ Ñ‚ÐµÑ€Ð¼Ð¸Ð½Ð¸Ñ‚Ðµ на Git"
@@ -14320,6 +14554,21 @@ msgstr "Дефиниране на ÑвойÑтвата на подмодулит
msgid "Git namespaces"
msgstr "ПроÑтранÑтва от имена на Git"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "ВъзможноÑти на протоколи, верÑÐ¸Ñ 1 и 2"
+
+msgid "Things common to various protocols"
+msgstr "Общи за различните протоколи възможноÑти"
+
+msgid "Git HTTP-based protocols"
+msgstr "Протоколи на Git на оÑнова на HTTP"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Как пакетите Ñе пренаÑÑÑ‚ по мрежата"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Мрежов протокол на Git, верÑÐ¸Ñ 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Помощни програми за работа Ñ Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ‚Ðµ хранилища"
@@ -14344,6 +14593,9 @@ msgstr "Уеб Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð½Ð° Git"
msgid "An overview of recommended workflows with Git"
msgstr "Общ преглед на препоръчваните начини за работа Ñ Git"
+msgid "A tool for managing large Git repositories"
+msgstr "ИнÑтрумент за управление на големи хранилища на Git "
+
msgid "commit-graph file is too small"
msgstr "файлът за гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е твърде малък"
@@ -14602,6 +14854,14 @@ msgid "no libc information available\n"
msgstr "липÑва Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° библиотеката на C\n"
#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "не може да Ñе определи Ñвободното диÑково проÑтранÑтво за „%s“"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "не може да Ñе получи информациÑта за „%s“"
+
+#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
msgstr ""
"нишката за Ñледенето на ÑÑŠÑтоÑнието не може да отвори „%2$ls“ [поÑледна "
@@ -14673,6 +14933,18 @@ msgstr ""
"нишката: GLE=%ld]"
#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr ""
+"файлът „%2$ls“ не може да бъде отворен за четене [поÑледна грешка в нишката: "
+"GLE=%1$ld]"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr ""
+"информациÑта за протокола на „%2$ls“ не може да Ñе получи [поÑледна грешка в "
+"нишката: GLE=%1$ld]"
+
+#, c-format
msgid "failed to copy SID (%ld)"
msgstr "идентификаторът за ÑигурноÑÑ‚ (SID=%ld) не може да бъде копиран"
@@ -14942,7 +15214,7 @@ msgstr "„%s“ не е правилна ÑтойноÑÑ‚ за време за
#, c-format
msgid "abbrev length out of range: %d"
-msgstr "дължината на Ñъкращаване е извън интервала ([4; 40]): %d"
+msgstr "дължината на Ñъкращаване е извън диапазона ([4; 40]): %d"
#, c-format
msgid "bad zlib compression level %d"
@@ -15225,182 +15497,6 @@ msgid "failed to close rev-list's stdin"
msgstr "ÑтандартниÑÑ‚ вход на ÑпиÑъка Ñ Ð²ÐµÑ€Ñиите не може да бъде затворен"
#, c-format
-msgid "'%s' does not exist"
-msgstr "„%s“ не ÑъщеÑтвува."
-
-msgid "need a working directory"
-msgstr "необходима е работна директориÑ"
-
-msgid "could not find enlistment root"
-msgstr "началната зачиÑлена Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да бъде открита"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "не може да Ñе премине към „%s“"
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "наÑтройката „%s=%s“ не може да Ñе зададе"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "„log.excludeDecoration“ не може да Ñе наÑтрои"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "ЗачиÑлÑването на директории чрез „scalar“ изиÑква работно дърво"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "директориÑта „%s“ не може да бъде отворена"
-
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "„%s“ Ñе преÑкача, защото не е нито файл, нито директориÑ"
-
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "не може да Ñе определи Ñвободното диÑково проÑтранÑтво за „%s“"
-
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "не може да Ñе получи информациÑта за „%s“"
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "отдалечениÑÑ‚ указател „HEAD“ не Ñочи към клон: „%.*s“"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-"името на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½ на отдалеченото хранилище не може да Ñе получи, "
-"затова ще Ñе ползва локално наÑтроеното име на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½"
-
-msgid "failed to get default branch name"
-msgstr "неуÑпешно получаване на името на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½"
-
-msgid "failed to unregister repository"
-msgstr "хранилището не може да бъде отчиÑлено"
-
-msgid "failed to delete enlistment directory"
-msgstr "зачиÑлената Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да бъде изтрита"
-
-msgid "branch to checkout after clone"
-msgstr "към кой клон да Ñе премине Ñлед клониране"
-
-msgid "when cloning, create full working directory"
-msgstr "при клониране да Ñе Ñъздава пълна работна директориÑ"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "да Ñе ÑвалÑÑ‚ метаданните Ñамо за изтеглÑÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [ОПЦИЯ…] [--] ХРÐÐИЛИЩЕ [ДИРЕКТОРИЯ]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "името на работното дърво не може да Ñе извлече от „%s“"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "директориÑта „%s“ вече ÑъщеÑтвува"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "оÑновниÑÑ‚ клон на „%s“ не може да бъде получен"
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "отдалеченото хранилище в „%s“ не може да Ñе наÑтрои"
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "„%s“ не може да Ñе наÑтрои"
-
-msgid "partial clone failed; attempting full clone"
-msgstr "неуÑпешно Ñъздаване на непълно хранилище, ще Ñе опита пълно хранилище"
-
-msgid "could not configure for full clone"
-msgstr "не може да Ñе наÑтрои пълно клониране"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
-
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "директориÑта за „%s“ не може да Ñе Ñъздадe"
-
-msgid "could not duplicate stdout"
-msgstr "ÑтандартниÑÑ‚ изход не може да Ñе дублира"
-
-msgid "failed to write archive"
-msgstr "неуÑпешен Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° архива"
-
-msgid "`scalar list` does not take arguments"
-msgstr "„scalar list“ не приема аргументи"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "пренаÑтройване на вÑички зачиÑлени директории"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "опциÑта „--all“ и указването на зачиÑлена Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ Ñа ÑъвмеÑтими"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "вече нÑма хранилище на git в „%s“"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run ЗÐДÐЧР[ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]\n"
-"Задачи:\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "нÑма задача Ñ Ð¸Ð¼Ðµ „%s“"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
-
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ"
-
-msgid "refusing to delete current working directory"
-msgstr "текущата работна Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ñма да бъде изтрита"
-
-msgid "include Git version"
-msgstr "включване и на верÑиÑта на git"
-
-msgid "include Git's build options"
-msgstr "включване и на опциите за компилиране на git"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "„-C“ изиÑква ДИРЕКТОРИЯ"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "не може да Ñе влезе в директориÑта „%s“"
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "опциÑта „-c“ изиÑква аргумент във вид КЛЮЧ=СТОЙÐОСТ"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C ДИРЕКТОРИЯ] [-c КЛЮЧ=СТОЙÐОСТ] КОМÐÐДР[ОПЦИЯ…]<\n"
-"\n"
-"Команди:\n"
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "неправилно дейÑтвие за край на ред (crlf_action): %d"
@@ -15613,6 +15709,32 @@ msgstr ""
msgid "Marked %d islands, done.\n"
msgstr "ОтбелÑзани Ñа %d групи, работата приключи.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "неправилна ÑтойноÑÑ‚ за „--%s“: „%s“"
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "директориÑта „%s“ липÑва и не може да Ñе архивира"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "директориÑта „%s“ не може да бъде отворена"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "„%s“ Ñе преÑкача, защото не е нито файл, нито директориÑ"
+
+msgid "could not duplicate stdout"
+msgstr "ÑтандартниÑÑ‚ изход не може да Ñе дублира"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "директориÑта „%s“ не може да бъде добавена към архива"
+
+msgid "failed to write archive"
+msgstr "неуÑпешен Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° архива"
+
msgid "--merge-base does not work with ranges"
msgstr "опциÑта „--merge-base“ не работи Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¸"
@@ -16242,6 +16364,9 @@ msgstr "git fetch-pack: очаква Ñе „ACK“/„NAK“, а бе полуÑ
msgid "unable to write to remote"
msgstr "невъзможно пиÑане към отдалечено хранилище"
+msgid "Server supports filter"
+msgstr "Сървърът поддържа филтри"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "неправилен плитък ред: „%s“"
@@ -16352,9 +16477,6 @@ msgstr "Ñървърът не поддържа алгоритъм „%s“"
msgid "Server does not support shallow requests"
msgstr "Сървърът не поддържа плитки заÑвки"
-msgid "Server supports filter"
-msgstr "Сървърът поддържа филтри"
-
msgid "unable to write request to remote"
msgstr "невъзможно пиÑане към отдалечено хранилище"
@@ -16710,6 +16832,12 @@ msgstr "Команди от ниÑко ниво / Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð
msgid "Low-level Commands / Internal Helpers"
msgstr "Команди от ниÑко ниво / Допълнителни инÑтрументи"
+msgid "User-facing repository, command and file interfaces"
+msgstr "Команди за хранилища, файлове и др. интерфейÑи за потребители:"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Файлови формати, протоколи и др. интерфейÑи за програмиÑти:"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "налични команди на git от „%s“"
@@ -16723,6 +16851,12 @@ msgstr "Това Ñа най-чеÑто използваните команди
msgid "The Git concept guides are:"
msgstr "РъководÑтвата за концепциите в Git Ñа:"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Команди за хранилища, файлове и др. за потребители:"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Файлови формати, протоколи и др. за програмиÑти:"
+
msgid "External commands"
msgstr "Външни команди"
@@ -16811,10 +16945,6 @@ msgstr ""
" git config advice.ignoredHook false"
#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "Куката „%s“ не може да Ñе Ñтартира\n"
-
-#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "опциÑта „--packfile“ изиÑква валидна контролна Ñума (а не „%s“)"
@@ -17006,18 +17136,14 @@ msgid "quoted CRLF detected"
msgstr "цитирани знаци CRLF"
#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Сливането ще презапише локалните промѐни на тези файлове:\n"
-" %s"
-
-#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "ÐеуÑпешно Ñливане на подмодула „%s“ (не е изтеглен)"
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "ÐеуÑпешно Ñливане на подмодула „%s“ (нÑма база за Ñливане)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
msgstr "ÐеуÑпешно Ñливане на подмодула „%s“ (нÑма подаваниÑ)"
@@ -17037,26 +17163,8 @@ msgstr "ÐеуÑпешно Ñливане на подмодула „%s“"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-"ÐеуÑпешно Ñливане на подмодула „%s“, но е открито възможно решение:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Ðко това е така, добавете го към индекÑа Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° като Ñледната:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"Това приема предложеното.\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
+msgstr "ÐеуÑпешно Ñливане на подмодула „%s“, но е открито възможно решение: %s"
#, c-format
msgid ""
@@ -17219,13 +17327,45 @@ msgstr ""
"КОÐФЛИКТ (промÑна/изтриване): „%s“ е изтрит в %s, а е променен в %s. ВерÑÐ¸Ñ "
"%s на „%s“ е оÑтавена в дървото."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
msgstr ""
-"Бележка: „%s“ не е актуален и пречи за преминаването към верÑиÑта Ñ "
-"конфликт. СтариÑÑ‚ вариант е преименуван на „%s“"
+" ⃠преминаване към подмодула (%s), Ñлед които или де Ñе Ñлее подаването\n"
+" „%s“, или да Ñе обновÑви към ÑъщеÑтвуващо подаване, в които\n"
+" тези промени Ñа Ñлети\n"
+
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"Ð’ момента рекурÑивното Ñливане Ñ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ поддържа Ñамо тривиалните Ñлучаи.\n"
+"Ще Ñ‚Ñ€Ñбва ръчно да разрешавате конфликтите във вÑеки модул, в който Ñе "
+"поÑвÑÑ‚.\n"
+"Това може да Ñе поÑтигне чрез Ñледните Ñтъпки:\n"
+"%s — върнете Ñе към Ð¾Ð±Ñ…Ð²Ð°Ñ‰Ð°Ñ‰Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚ и изпълнете:\n"
+"\n"
+" git add %s\n"
+"\n"
+" за да отбележите Ñливането или обновÑването\n"
+" ⃠решете конфликтите в Ð¾Ð±Ñ…Ð²Ð°Ñ‰Ð°Ñ‰Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚\n"
+" ⃠подайте индекÑа в Ð¾Ð±Ñ…Ð²Ð°Ñ‰Ð°Ñ‰Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -17306,6 +17446,21 @@ msgstr ""
"подмодула:\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Ðко това е така, добавете го към индекÑа Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° като Ñледната:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"Това приема предложеното.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "ÐеуÑпешно Ñливане на подмодула „%s“ (открити Ñа множеÑтво ÑливаниÑ)"
@@ -17546,7 +17701,8 @@ msgstr "неправилен ред: „%s“."
msgid "ignoring existing multi-pack-index; checksum mismatch"
msgstr ""
-"индекÑÑŠÑ‚ за множеÑтво пакети Ñе преÑкача, защото контролната Ñума не Ñъвпада"
+"индекÑÑŠÑ‚ за множеÑтво пакети Ñе преÑкача, защото Ñумата за проверка не "
+"Ñъвпада"
msgid "could not load pack"
msgstr "пакетът не може да Ñе зареди"
@@ -17596,7 +17752,7 @@ msgid "multi-pack-index file exists, but failed to parse"
msgstr "файлът Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети, но не може да бъде анализиран"
msgid "incorrect checksum"
-msgstr "неправилна контролна Ñума"
+msgstr "неправилна Ñума за проверка"
msgid "Looking for referenced packfiles"
msgstr "ТърÑене на указаните пакетни файлове"
@@ -17852,6 +18008,22 @@ msgid "confused by unstable object source data for %s"
msgstr "грешка поради неÑÑ‚Ð°Ð±Ð¸Ð»Ð½Ð¸Ñ Ð¸Ð·Ñ‚Ð¾Ñ‡Ð½Ð¸Ðº данни за обектите „%s“"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "при запиÑа на обект в потока: %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "новиÑÑ‚ обект не може да Ñе компреÑира поточно Ñ â€ždeflate“ (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "неуÑпешно изпълнение на „deflateEnd“ върху Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ Ð¾Ð±ÐµÐºÑ‚: %d"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "директориÑта „%s“ не може да бъде Ñъздадена"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "обектът за „%s“ не може да Ñе прочете"
@@ -18079,6 +18251,66 @@ msgstr "обектът „%s“ не може да бъде анализиран
msgid "hash mismatch %s"
msgstr "разлика в контролната Ñума: „%s“"
+msgid "trying to write commit not in index"
+msgstr "опит за запиÑване на обект за подаване извън индекÑа"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr ""
+"индекÑÑŠÑ‚ на база битови маÑки не може да Ñе зареди (възможно е да е повреден)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "повреден Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки (прекалено малък)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "повреден Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки (неправилна заглавна чаÑÑ‚)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "верÑÐ¸Ñ â€ž%d“ на файла за индекÑа на база битови маÑки не Ñе поддържа"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr ""
+"повреден Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки (прекалено малък, за да напаÑне на кеша "
+"за контролните Ñуми)"
+
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr ""
+"повреден файл за Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки (прекалено е малък дори и за "
+"таблицата ÑÑŠÑ ÑъответÑтвиÑ)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "повтарÑщ Ñе Ð·Ð°Ð¿Ð¸Ñ Ð² Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки: „%s“"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr ""
+"повредена битова маÑка във формат EWAH: отрÑзана заглавна чаÑÑ‚ за Ð·Ð°Ð¿Ð¸Ñ %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr ""
+"повредена битова маÑка във формат EWAH: индекÑÑŠÑ‚ на подаването %u е извън "
+"диапазона"
+
+msgid "corrupted bitmap pack index"
+msgstr "повреден пакетен Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "неправилно отмеÑтване по XOR в пакетен Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки"
+
+msgid "cannot fstat bitmap file"
+msgstr "не може да Ñе получи Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° файла Ñ Ð±Ð¸Ñ‚Ð¾Ð²Ð¸ маÑки Ñ â€žfstat“"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "игнориране на Ð¸Ð·Ð»Ð¸ÑˆÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð» Ñ Ð±Ð¸Ñ‚Ð¾Ð²Ð¸ маÑки: „%s“"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr ""
+"Ñумата за проверка Ñе различава във файла Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети и "
+"битовата маÑка"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "задължителниÑÑ‚ обратен Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ð¿Ñва в многопакетната битова маÑка"
@@ -18090,11 +18322,66 @@ msgstr "пакетът „%s“ не може да Ñе отвори"
msgid "preferred pack (%s) is invalid"
msgstr "предпочитаниÑÑ‚ пакет „%s“ е неправилен"
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr ""
+"повредена таблица ÑÑŠÑ ÑъответÑтвиÑ: меÑтоположението на тройката е извън "
+"индекÑа"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr ""
+"повредена таблица ÑÑŠÑ ÑъответÑтвиÑ: веригата за XOR е по-дълга от Ð±Ñ€Ð¾Ñ Ð½Ð° "
+"запиÑите"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr ""
+"повредена таблица ÑÑŠÑ ÑъответÑтвиÑ: индекÑÑŠÑ‚ на подаването %u е извън "
+"диапазона"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr ""
+"повредена битова маÑка във формат EWAH: отрÑзана заглавна чаÑÑ‚ за битовата "
+"маÑка на подаване „%s“"
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "обектът „%s“ липÑва в битовата маÑка на видовете"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "обектът „%s“ нÑма уникален вид"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "обект „%s“: иÑтинÑкиÑÑ‚ му вид е „%s“, а Ñе очакваше „%s“"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "обектът „%s“ липÑва в индекÑа на база битови маÑки"
+
+msgid "failed to load bitmap indexes"
+msgstr "неуÑпешно зареждане на индекÑи на база битови маÑки"
+
+msgid "you must specify exactly one commit to test"
+msgstr "Ñ‚Ñ€Ñбва да укажете точно едно подаване за теÑтване"
+
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "подаването „%s“ нÑма Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки"
+
+msgid "mismatch in bitmap results"
+msgstr "различие в резултатите от битовите маÑки"
+
+#, c-format
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
msgstr "„%s“ липÑва в пакет „%s“ при отмеÑтване %<PRIuMAX>"
#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "използваното мÑÑто за Ñъхранение на „%s“ не може да бъде получено"
+
+#, c-format
msgid "mtimes file %s is too small"
msgstr "файлът Ñ Ð²Ñ€ÐµÐ¼ÐµÑ‚Ð¾ на промÑна (mtime) „%s“ е твърде малък"
@@ -18230,6 +18517,9 @@ msgstr "„--%s“ (Ñ 2 тирета) ли имахте предвид?"
msgid "alias of --%s"
msgstr "пÑевдоним на „--%s“"
+msgid "need a subcommand"
+msgstr "необходима е подкоманда"
+
#, c-format
msgid "unknown option `%s'"
msgstr "непозната опциÑ: „%s“"
@@ -18683,9 +18973,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -18712,7 +19005,12 @@ msgstr ""
" — Ñъздаване на подаване ÑÑŠÑ Ñливане ÑÑŠÑ Ñъобщението от\n"
" първоначалното подаване (или Ñъобщението от ЕДИÐ_РЕД,\n"
" ако не е зададено подаване ÑÑŠÑ Ñливане. С опциÑта\n"
-" „-c ПОДÐÐ’ÐÐЕ“, може да Ñмените Ñъобщението.\n"
+" „-c ПОДÐÐ’ÐÐЕ“, може да Ñмените Ñъобщението\n"
+"u, update-ref УКÐЗÐТЕЛ\n"
+" — проÑледÑване на замеÑтител на УКÐЗÐТЕЛÑ, който Ñ‚Ñ€Ñбва\n"
+" да Ñе обнови до това положение в новите подаваниÑ.\n"
+" УКÐЗÐТЕЛÑÑ‚ Ñе обновÑва в ÐºÑ€Ð°Ñ Ð½Ð° пребазирането\n"
+"\n"
"\n"
"Може да променÑте поÑледователноÑтта на редовете — те Ñе изпълнÑват\n"
"поÑледователно отгоре-надолу.\n"
@@ -19188,6 +19486,13 @@ msgstr "протоколна грешка: очаква Ñе SHA1 или укаÐ
msgid "http transport does not support %s"
msgstr "транÑпортът по http не поддържа „%s“"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "протоколна грешка: очаква Ñе „ÐДРЕС ПЪТ“, липÑва интервал"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "файлът на Ð°Ð´Ñ€ÐµÑ â€ž%s“ не може да Ñе Ñвали"
+
msgid "git-http-push failed"
msgstr "неуÑпешно изпълнение на „git-http-push“"
@@ -19532,6 +19837,16 @@ msgstr "не може да Ñе определи към какво да Ñочи
msgid "failed to find tree of %s"
msgstr "дървото, Ñочено от „%s“, не може да бъде открито"
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr ""
+"в информациÑта за отмÑна на разрешените Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸ÑÑŠÑтва „%s“, който "
+"липÑва"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "подаването „%s“ към опциÑта „--ancestry-path“ не може да бъде получено"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "опциÑта „--unpacked=ПÐКЕТЕÐ_ФÐЙЛ“ вече не Ñе поддържа"
@@ -19554,6 +19869,174 @@ msgstr ""
msgid "cannot create async thread: %s"
msgstr "не може да Ñе Ñъздаде аÑинхронна нишка: %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "„%s“ не ÑъщеÑтвува."
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "не може да Ñе премине към „%s“"
+
+msgid "need a working directory"
+msgstr "необходима е работна директориÑ"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "ЗачиÑлÑването на директории чрез „scalar“ изиÑква работно дърво"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "наÑтройката „%s=%s“ не може да Ñе зададе"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "„log.excludeDecoration“ не може да Ñе наÑтрои"
+
+msgid "could not add enlistment"
+msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да Ñе зачиÑли"
+
+msgid "could not set recommended config"
+msgstr "препоръчаните наÑтройки не може да Ñе зададат"
+
+msgid "could not turn on maintenance"
+msgstr "задачите по поддръжка не може да Ñе включат"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "фоновиÑÑ‚ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ð° FSMonitor не може да бъде ÑпрÑн"
+
+msgid "could not turn off maintenance"
+msgstr "задачите по поддръжка не може да Ñе изключат"
+
+msgid "could not remove enlistment"
+msgstr "директориÑта не може да Ñе отчиÑли"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "отдалечениÑÑ‚ указател „HEAD“ не Ñочи към клон: „%.*s“"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"името на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½ на отдалеченото хранилище не може да Ñе получи, "
+"затова ще Ñе ползва локално наÑтроеното име на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½"
+
+msgid "failed to get default branch name"
+msgstr "неуÑпешно получаване на името на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½"
+
+msgid "failed to unregister repository"
+msgstr "хранилището не може да бъде отчиÑлено"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "фоновиÑÑ‚ Ð¿Ñ€Ð¾Ñ†ÐµÑ FSMonitor не може да бъде ÑпрÑн"
+
+msgid "failed to delete enlistment directory"
+msgstr "зачиÑлената Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да бъде изтрита"
+
+msgid "branch to checkout after clone"
+msgstr "към кой клон да Ñе премине Ñлед клониране"
+
+msgid "when cloning, create full working directory"
+msgstr "при клониране да Ñе Ñъздава пълна работна директориÑ"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "да Ñе ÑвалÑÑ‚ метаданните Ñамо за изтеглÑÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [ОПЦИЯ…] [--] ХРÐÐИЛИЩЕ [ДИРЕКТОРИЯ]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "името на работното дърво не може да Ñе извлече от „%s“"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "директориÑта „%s“ вече ÑъщеÑтвува"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "оÑновниÑÑ‚ клон на „%s“ не може да бъде получен"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "отдалеченото хранилище в „%s“ не може да Ñе наÑтрои"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "„%s“ не може да Ñе наÑтрои"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "неуÑпешно Ñъздаване на непълно хранилище, ще Ñе опита пълно хранилище"
+
+msgid "could not configure for full clone"
+msgstr "не може да Ñе наÑтрои пълно клониране"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "„scalar list“ не приема аргументи"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "пренаÑтройване на вÑички зачиÑлени директории"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "опциÑта „--all“ и указването на зачиÑлена Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ Ñа ÑъвмеÑтими"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "вече нÑма хранилище на git в „%s“"
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run ЗÐДÐЧР[ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]\n"
+"Задачи:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "нÑма задача Ñ Ð¸Ð¼Ðµ „%s“"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ"
+
+msgid "refusing to delete current working directory"
+msgstr "текущата работна Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ñма да бъде изтрита"
+
+msgid "include Git version"
+msgstr "включване и на верÑиÑта на git"
+
+msgid "include Git's build options"
+msgstr "включване и на опциите за компилиране на git"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "„-C“ изиÑква ДИРЕКТОРИЯ"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "не може да Ñе влезе в директориÑта „%s“"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "опциÑта „-c“ изиÑква аргумент във вид КЛЮЧ=СТОЙÐОСТ"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C ДИРЕКТОРИЯ] [-c КЛЮЧ=СТОЙÐОСТ] КОМÐÐДР[ОПЦИЯ…]<\n"
+"\n"
+"Команди:\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr ""
"неочакван изчиÑтващ пакет „flush“ при изчитане на ÑÑŠÑтоÑнието от "
@@ -19703,10 +20186,6 @@ msgstr "локалните промѐни ще бъдат презапиÑан
msgid "commit your changes or stash them to proceed."
msgstr "подайте или Ñкатайте промѐните, за да продължите"
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: превъртане"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -20208,6 +20687,29 @@ msgstr "Ñливането на „%.*s“ не може даже да запоÑ
msgid "merge: Unable to write new index file"
msgstr "Ñливане: новиÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ може да бъде запазен"
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr ""
+"изглежда в момента тече друг Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð° пребазиране; файлът „%s.lock“ вече "
+"ÑъщеÑтвува"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Следните указатели Ñа обновени Ñ %s:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"ÐеуÑпешно обновÑване на Ñледните указатели Ñ %s:\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "Ðе може да Ñе Ñкатае автоматично"
@@ -20378,6 +20880,10 @@ msgid "the script was already rearranged."
msgstr "Ñкриптът вече е преподреден."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "файлът за обновÑване на указателите „%s“ е неправилен"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "„%s“ е извън хранилището при „%s“"
@@ -20504,17 +21010,22 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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"
-"За да зададете изключение за тази директориÑ, изпълнете:\n"
+"заÑечено е проблемно притежание на хранилището „%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“)"
+
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -21388,6 +21899,18 @@ msgstr "неправилен номер на порт"
msgid "invalid '..' path segment"
msgstr "неправилна чаÑÑ‚ от Ð¿ÑŠÑ‚Ñ â€ž..“"
+msgid "usage: "
+msgstr "употреба: "
+
+msgid "fatal: "
+msgstr "фатална грешка: "
+
+msgid "error: "
+msgstr "грешка: "
+
+msgid "warning: "
+msgstr "предупреждение: "
+
msgid "Fetching objects"
msgstr "ДоÑтавÑне на обектите"
@@ -22220,24 +22743,6 @@ msgstr "Избраните парчета не може да Ñе добавÑÑ‚
msgid "ignoring unmerged: %s\n"
msgstr "пренебрегване на неÑлÑтото: „%s“\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-"Прилагане на промÑната в правата за доÑтъп към работното дърво [y,n,q,a,d"
-"%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Прилагане на изтриването към работното дърво [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Прилагане на добавÑнето към работното дърво [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "Прилагане на парчето към работното дърво [y,n,q,a,d%s,?]? "
-
msgid "No other hunks to goto\n"
msgstr "ÐÑма други парчета\n"
diff --git a/po/ca.po b/po/ca.po
index 80c430df454..7a17ed59360 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -13,6 +13,7 @@
# bundle | farcell
# chunk | fragment
# cover letter | carta de presentació
+# cruft | superflu
# delta | diferència
# deprecated | en desús
# detached | separat
@@ -21,12 +22,14 @@
# fetch | obtenir
# flush | buidar / buidatge
# graph | graf
+# hash | resum
# hint | consell
# hook | lligam
# hunk | tros
# not supported | no està admès
# pull | baixar
# push | pujar
+# quote | cometes (ortogràfiques)
# repository | repositori
# setting | paràmetre
# shallow | superficial
@@ -65,8 +68,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-24 13:30+0200\n"
-"PO-Revision-Date: 2022-06-03 19:00-0600\n"
+"POT-Creation-Date: 2022-09-28 18:55+0200\n"
+"PO-Revision-Date: 2022-09-28 19:00-0600\n"
"Last-Translator: Jordi Mas i Hernàndez <jmas@softcatala.org>\n"
"Language-Team: Catalan\n"
"Language: ca\n"
@@ -472,6 +475,22 @@ msgstr ""
"a - aplica aquest tros i tots els trossos posteriors en el fitxer\n"
"d - no apliquis aquest tros ni cap dels trossos posteriors en el fitxer\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "Aplica el canvi de mode a l'arbre de treball [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Aplica la supressió a l'arbre de treball [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Aplica l'addició a l'arbre de treball [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Aplica aquest tros a l'arbre de treball [y,n,q,a,d%s,?]? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -489,10 +508,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "no s'ha pogut analitzar la capçalera del tros «%.*s»"
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "no s'ha pogut analitzar la capçalera del tros acolorida «%.*s»"
-
msgid "could not parse diff"
msgstr "no s'ha pogut analitzar el diff"
@@ -780,11 +795,30 @@ msgstr ""
"«false»\n"
"\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Els camins següents s'han mogut fora de la\n"
+"definició de sparse-checkout però no són dispersos\n"
+"a causa de modificacions en local.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Per a corregir la dispersió d'aquests camins, feu el següent:\n"
+"* Useu «git add --sparse <paths>» per a actualitzar l'índex\n"
+"* Useu «git sparse-checkout reapply» per a aplicar les regles de dispersió"
+
msgid "cmdline ends with \\"
msgstr "la línia d'ordres acaba amb \\"
msgid "unclosed quote"
-msgstr "cita no tancada"
+msgstr "commetes no tancades"
#, c-format
msgid "unrecognized whitespace option '%s'"
@@ -1219,7 +1253,7 @@ msgid "instead of applying the patch, output a summary for the input"
msgstr "en lloc d'aplicar el pedaç, emet un resum de l'entrada"
msgid "instead of applying the patch, see if the patch is applicable"
-msgstr "en lloc d'aplicar el pedaç, veges si el pedaç és aplicable"
+msgstr "en lloc d'aplicar el pedaç, determina si el pedaç és aplicable"
msgid "make sure the patch is applicable to the current index"
msgstr "assegura que el pedaç sigui aplicable a l'índex actual"
@@ -1295,6 +1329,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "mode de fitxer no compatible: 0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "error de deflació (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "no s'ha pogut iniciar el filtre «%s»"
@@ -1314,10 +1352,6 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "el camí és massa llarg (%d caràcters, SHA1: %s): %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "error de deflació (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "marca de temps massa gran per a aquest sistema: %<PRIuMAX>"
@@ -1364,17 +1398,17 @@ msgstr "Fitxer no trobat: %s"
msgid "Not a regular file: %s"
msgstr "No és un fitxer normal: %s"
-#, fuzzy, c-format
+#, c-format
msgid "unclosed quote: '%s'"
-msgstr "cita no tancada"
+msgstr "cometes no tancades: «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "missing colon: '%s'"
-msgstr "falta el valor per «%s»"
+msgstr "falten els dos punts: «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "empty file name: '%s'"
-msgstr "mbox buit: «%s»"
+msgstr "nom de fitxer buit: «%s»"
msgid "fmt"
msgstr "format"
@@ -1394,9 +1428,8 @@ msgstr "fitxer"
msgid "add untracked file to archive"
msgstr "inclou els fitxers no seguits a l'arxiu"
-#, fuzzy
msgid "path:content"
-msgstr "contingut"
+msgstr "camí: contingut"
msgid "write the archive to this file"
msgstr "escriu l'arxiu a aquest fitxer"
@@ -2423,16 +2456,20 @@ msgid "Are you sure [Y/n]? "
msgstr "N'esteu segur [Y/n]? "
msgid "status: waiting for both good and bad commits\n"
-msgstr ""
+msgstr "estat: s'estan esperant les comissions bones i dolentes\n"
#, c-format
msgid "status: waiting for bad commit, %d good commit known\n"
msgid_plural "status: waiting for bad commit, %d good commits known\n"
msgstr[0] ""
+"estat: s'està esperant una comissió incorrecta, es coneix %d comissió bona\n"
msgstr[1] ""
+"estat: s'està esperant una comissió incorrecta, es coneixen %d comissions "
+"bones\n"
msgid "status: waiting for good commit(s), bad commit known\n"
msgstr ""
+"estat: s'està esperant comissions bones, es coneix una comissió incorrecta\n"
msgid "no terms defined"
msgstr "cap terme definit"
@@ -2472,7 +2509,7 @@ msgid "'%s' does not appear to be a valid revision"
msgstr "«%s» no sembla ser una revisió vàlida"
msgid "bad HEAD - I need a HEAD"
-msgstr "HEAD incorrecte - cal un HEAD"
+msgstr "HEAD incorrecte - cal una HEAD"
#, c-format
msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'."
@@ -2650,7 +2687,7 @@ msgstr ""
"no tractis les comissions arrel com de frontera (per defecte: desactivat)"
msgid "show work cost statistics"
-msgstr "mostra les estadístiques de preu de treball"
+msgstr "mostra les estadístiques del cost de treball"
msgid "force progress reporting"
msgstr "força l'informe de progrés"
@@ -2912,7 +2949,7 @@ msgid "Generic options"
msgstr "Opcions genèriques"
msgid "show hash and subject, give twice for upstream branch"
-msgstr "mostra el hash i l'assumpte, doneu dues vegades per a la branca font"
+msgstr "mostra el hash i l'assumpte, useu-lo dues vegades per a la branca font"
msgid "suppress informational messages"
msgstr "omet els missatges informatius"
@@ -2999,7 +3036,7 @@ msgid "print only branches of the object"
msgstr "imprimeix només les branques de l'objecte"
msgid "sorting and filtering are case insensitive"
-msgstr "l'ordenació i el filtratge distingeixen entre majúscules i minúscules"
+msgstr "ordenació i filtratge distingeixen entre majúscules i minúscules"
msgid "recurse through submodules"
msgstr "inclou recursivament als submòduls"
@@ -3027,7 +3064,7 @@ msgid "branch name required"
msgstr "cal el nom de branca"
msgid "Cannot give description to detached HEAD"
-msgstr "No es pot donar descripció a un HEAD separat"
+msgstr "No es pot donar descripció a una HEAD separada"
msgid "cannot edit description of more than one branch"
msgstr "no es pot editar la descripció de més d'una branca"
@@ -3105,8 +3142,12 @@ msgid "not run from a git repository - no hooks to show\n"
msgstr ""
"no s'està executant en un repositori de git - no hi ha lligams a mostrar\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3141,16 +3182,28 @@ msgstr ""
"Reviseu la resta de l'informe d'error de sota.\n"
"Podeu eliminar qualsevol línia que vulgueu.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "especifiqueu una destinació per al fitxer d'informe d'error"
+msgid "mode"
+msgstr "mode"
-msgid "specify a strftime format suffix for the filename"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr ""
+"crea un arxiu zip addicional amb diagnòstics detallats (per defecte «stats»)"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "especifiqueu una destinació per al fitxer de l'informe d'error"
+
+msgid "specify a strftime format suffix for the filename(s)"
msgstr "especifiqueu un sufix en format strftime per al nom de fitxer"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "no s'han pogut crear els directoris principals de «%s»"
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "no s'ha pogut crear l'arxiu de diagnòstic %s"
+
msgid "System Info"
msgstr "Informació del sistema"
@@ -3209,10 +3262,6 @@ msgid "Unbundling objects"
msgstr "S'estan desagrupant objectes"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Subordre desconeguda: %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "no es pot llegir l'objecte %s «%s»"
@@ -3274,17 +3323,16 @@ msgstr "Comprova l'existència de l'objecte o emet el contingut de l'objecte"
msgid "check if <object> exists"
msgstr "comprova si <object> existeix"
-#, fuzzy
msgid "pretty-print <object> content"
-msgstr "empremta de <object> contingut"
+msgstr "impressió embellida del contingut de l'<objecte>"
-#, fuzzy
msgid "Emit [broken] object attributes"
-msgstr "Emet els atributs de l'objecte objectbroken]"
+msgstr "Emet els atributs [broken] de l'objecte"
-#, fuzzy
msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"
-msgstr "mostra el tipus d'objecte (un de 'blob', 'tree', 'commit', 'tag', ...)"
+msgstr ""
+"mostra el tipus d'objecte (un dels següents: «blob», «tree», «commit», "
+"«tag», ...)"
msgid "show object size"
msgstr "mostra la mida de l'objecte"
@@ -3292,62 +3340,57 @@ msgstr "mostra la mida de l'objecte"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "permet que -s i -t funcionin amb objectes trencats/malmesos"
-#, fuzzy
+msgid "use mail map file"
+msgstr "usa el fitxer de mapa de correu"
+
msgid "Batch objects requested on stdin (or --batch-all-objects)"
-msgstr "Objectes lots sol·licitats a stdin (o --batch-all-objects)"
+msgstr "Objectes de lots sol·licitats a stdin (o --batch-all-objects)"
-#, fuzzy
msgid "show full <object> or <rev> contents"
-msgstr "mostra el contingut complet de <object> o <rev>"
+msgstr "mostra el contingut complet de <objecte> o <rev>"
-#, fuzzy
msgid "like --batch, but don't emit <contents>"
-msgstr "com --batch, però no emeti <contents>"
+msgstr "com a --batch, però no emetis <contents>"
+
+msgid "stdin is NUL-terminated"
+msgstr "l'entrada és acabada amb NUL"
-#, fuzzy
msgid "read commands from stdin"
msgstr "llegeix les ordres de stdin"
-#, fuzzy
msgid "with --batch[-check]: ignores stdin, batches all known objects"
-msgstr "amb --batch--check:: ignora stdin, bateja tots els objectes coneguts"
+msgstr ""
+"amb --batch[-check]: ignora stdin, posa en lots tots els objectes coneguts"
-#, fuzzy
msgid "Change or optimize batch output"
msgstr "Canvia o optimitza la sortida per lots"
msgid "buffer --batch output"
msgstr "posa la sortida de --batch en memòria intermèdia"
-#, fuzzy
msgid "follow in-tree symlinks"
msgstr "segueix els enllaços simbòlics en l'arbre"
-#, fuzzy
msgid "do not order objects before emitting them"
-msgstr "no ordena objectes abans d'emetre'ls"
+msgstr "no ordenis els objectes abans d'emetre'ls"
-#, fuzzy
msgid ""
"Emit object (blob or tree) with conversion or filter (stand-alone, or with "
"batch)"
msgstr ""
"Emet l'objecte (blob o arbre) amb conversió o filtre (stand-alone, o amb lot)"
-#, fuzzy
msgid "run textconv on object's content"
msgstr "executar textconv al contingut de l'objecte"
-#, fuzzy
msgid "run filters on object's content"
msgstr "executa els filtres al contingut de l'objecte"
msgid "blob|tree"
msgstr "blob|tree"
-#, fuzzy
msgid "use a <path> for (--textconv | --filters); Not with 'batch'"
-msgstr "useu un <path> per a (--textconv | --filters); No amb 'batch'"
+msgstr "useu un <path> per a (--textconv | --filters); no amb «batch»"
#, c-format
msgid "'%s=<%s>' needs '%s' or '%s'"
@@ -3358,7 +3401,7 @@ msgstr "path|tree-ish"
#, c-format
msgid "'%s' requires a batch mode"
-msgstr "%s requereix un mode batch"
+msgstr "«%s» requereix un mode batch"
#, c-format
msgid "'-%c' is incompatible with batch mode"
@@ -3378,11 +3421,9 @@ msgstr "<object> requerit amb «-%c»"
msgid "too many arguments"
msgstr "hi ha massa arguments"
-#, fuzzy, c-format
+#, c-format
msgid "only two arguments allowed in <type> <object> mode, not %d"
-msgstr ""
-"només es permeten dos arguments en el mode <type> <object>, no en un "
-"percentatge"
+msgstr "només es permeten dos arguments en el mode <type> <object>, no %d"
msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..."
msgstr "git check-attr [-a | --all | <atribut>...] [--] <nom-de-camí>..."
@@ -3460,9 +3501,8 @@ msgstr "«stage» ha de ser entre 1 i 3 o all"
msgid "check out all files in the index"
msgstr "agafa tots els fitxers en l'índex"
-#, fuzzy
msgid "do not skip files with skip-worktree set"
-msgstr "no ometis els fitxers amb el conjunt d'arbres de salt"
+msgstr "no ometis els fitxers amb skip-worktree establert"
msgid "force overwrite of existing files"
msgstr "força la sobreescriptura de fitxers existents"
@@ -4016,7 +4056,7 @@ msgstr ""
"ask each - confirma cada supressió (com «rm -i»)\n"
"quit - deixa de netejar\n"
"help - aquesta pantalla\n"
-"? - ajuda de selecció de l'avís"
+"? - ajuda de selecció manual"
msgid "Would remove the following item:"
msgid_plural "Would remove the following items:"
@@ -4176,9 +4216,8 @@ msgstr "usa només adreces IPv4"
msgid "use IPv6 addresses only"
msgstr "usa només adreces IPv6"
-#, fuzzy
msgid "apply partial clone filters to submodules"
-msgstr "Aplica els filtres de clonatge parcial als submòduls"
+msgstr "aplica els filtres de clonatge parcial als submòduls"
msgid "any cloned submodules will use their remote-tracking branch"
msgstr "qualsevol submòdul clonat utilitzarà la seva branca de seguiment remot"
@@ -4188,6 +4227,12 @@ msgstr ""
"inicialitza el fitxer «sparse-checkout» per a incloure només els fitxers a "
"l'arrel"
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "un URI per a baixar paquets abans d'obtenir des del remot origen"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: No s'ha pogut afegir un alternatiu per a «%s»: %s\n"
@@ -4247,10 +4292,10 @@ msgstr "no s'ha pogut actualitzar %s"
msgid "failed to initialize sparse-checkout"
msgstr "no s'ha pogut inicialitzar «sparse-checkout»"
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
msgstr ""
-"la HEAD remot es refereix a una referència que no existeix; no s'ha pogut "
-"agafar.\n"
+"la HEAD remot es refereix a una referència que no existeix, no s'ha pogut "
+"agafar"
msgid "unable to checkout working tree"
msgstr "no s'ha pogut agafar l'arbre de treball"
@@ -4274,6 +4319,12 @@ msgstr "Heu d'especificar un repositori per a clonar."
msgid "options '%s' and '%s %s' cannot be used together"
msgstr "les opcions «%s» i «%s %s» no es poden usar juntes"
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri és incompatible amb --depth, --shallow-since i --shallow-exclude"
+
#, c-format
msgid "repository '%s' does not exist"
msgstr "el repositori «%s» no existeix"
@@ -4347,6 +4398,13 @@ msgstr "--local s'ignora"
msgid "cannot clone from filtered bundle"
msgstr "no es pot clonar des del farell filtrat"
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "no s'ha pogut inicialitzar el repositori, s'omet l'URI del paquet"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "no s'han pogut obtenir els objectes de l'URI del paquet «%s»"
+
msgid "remote transport reported error"
msgstr "el transport remot ha informat d'un error"
@@ -4462,10 +4520,6 @@ msgstr "usa com a màxim un --reachable, --stdin-commits, o --stdin-packs"
msgid "Collecting commits from input"
msgstr "S'estan recollint les comissions de l'entrada"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "subordre no reconeguda: %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -4821,9 +4875,6 @@ msgstr "mostra l'estat en format llarg (per defecte)"
msgid "terminate entries with NUL"
msgstr "acaba les entrades amb NUL"
-msgid "mode"
-msgstr "mode"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
"mostra els fitxers no seguits, modes opcionals: all, normal, no. (Per "
@@ -4869,7 +4920,7 @@ msgid "Commit message options"
msgstr "Opcions de missatge de comissió"
msgid "read message from file"
-msgstr "llegiu el missatge des d'un fitxer"
+msgstr "llegeix el missatge des d'un fitxer"
msgid "author"
msgstr "autor"
@@ -5095,7 +5146,7 @@ msgid "type"
msgstr "tipus"
msgid "value is given this type"
-msgstr "el valor té donat aquest tipus"
+msgstr "el valor és d'aquest tipus que s'ha donat"
msgid "value is \"true\" or \"false\""
msgstr "el valor és «true» o «false»"
@@ -5356,7 +5407,7 @@ msgstr ""
#, c-format
msgid "traversed %lu commits\n"
-msgstr "%lu comissions travessades\n"
+msgstr "%lu comissions recorregudes\n"
#, c-format
msgid ""
@@ -5427,6 +5478,22 @@ msgstr "No s'ha trobat cap nom, no es pot descriure res."
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "les opcions «%s» i de comissió no es poden usar juntes"
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "especifiqueu una destinació per a l'arxiu de diagnòstic"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr "especifiqueu un sufix en format strftime per al nom de fitxer"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "especifica el contingut de l'arxiu de diagnòstic"
+
msgid "--merge-base only works with two commits"
msgstr "--merge-base només funciona amb dues comissions"
@@ -5695,7 +5762,7 @@ msgid "set upstream for git pull/fetch"
msgstr "estableix la font per a git pull/fetch"
msgid "append to .git/FETCH_HEAD instead of overwriting"
-msgstr "annexa a .git/FETCH_HEAD en lloc de sobreescriure"
+msgstr "annexa a .git/FETCH_HEAD en lloc de sobreescriure'l"
msgid "use atomic transaction to update references"
msgstr "usa una transacció atòmica per a actualitzar les referències"
@@ -5755,9 +5822,8 @@ msgstr "aprofundeix la història d'un clon superficial basat en una data"
msgid "convert to a complete repository"
msgstr "converteix en un repositori complet"
-#, fuzzy
msgid "re-fetch without negotiating common commits"
-msgstr "tornar a capturar sense negociar comissions comunes"
+msgstr "tornar a obtenir sense negociar comissions comunes"
msgid "prepend this to submodule path output"
msgstr "anteposa això a la sortida de camí del submòdul"
@@ -5812,12 +5878,9 @@ msgstr "[al dia]"
msgid "[rejected]"
msgstr "[rebutjat]"
-msgid "can't fetch in current branch"
+msgid "can't fetch into checked-out branch"
msgstr "no es pot obtenir en la branca actual"
-msgid "checked out in another worktree"
-msgstr "s'ha agafat en un altre arbre de treball"
-
msgid "[tag update]"
msgstr "[actualització d'etiqueta]"
@@ -5974,7 +6037,6 @@ msgstr ""
msgid "you need to specify a tag name"
msgstr "necessiteu especificar un nom d'etiqueta"
-#, fuzzy
msgid "--negotiate-only needs one or more --negotiation-tip=*"
msgstr "--negotiate-only necessita un o més --negotiation-tip=*"
@@ -6025,7 +6087,7 @@ msgid "populate log with at most <n> entries from shortlog"
msgstr "emplena el registre amb <n> entrades del registre curt com a màxim"
msgid "alias for --log (deprecated)"
-msgstr "àlies per --log (en desús)"
+msgstr "àlies per a --log (en desús)"
msgid "text"
msgstr "text"
@@ -6054,7 +6116,8 @@ msgstr ""
msgid "quote placeholders suitably for shells"
msgstr ""
-"posa els marcadors de posició de forma adequada per a intèrprets d'ordres"
+"posa els marcadors de posició entre cometes adequades per a intèrprets "
+"d'ordres"
msgid "quote placeholders suitably for perl"
msgstr "posa els marcadors de posició entre cometes adequades per al perl"
@@ -6131,15 +6194,15 @@ msgstr "S'està comprovant la connectivitat"
#, c-format
msgid "missing %s %s"
-msgstr "manca %s %s"
+msgstr "%s %s manca"
#, c-format
msgid "unreachable %s %s"
-msgstr "inabastable %s %s"
+msgstr "%s %s inabastable"
#, c-format
msgid "dangling %s %s"
-msgstr "sense assignació %s %s"
+msgstr "%s %s sense assignació"
msgid "could not create lost-found"
msgstr "no s'ha pogut crear el trobat-perdut"
@@ -6238,7 +6301,7 @@ msgstr "%s apunta a una cosa estranya (%s)"
#, c-format
msgid "%s: detached HEAD points at nothing"
-msgstr "%s: el HEAD separat no apunta a res"
+msgstr "%s: la HEAD separada no apunta a res"
#, c-format
msgid "notice: %s points to an unborn branch (%s)"
@@ -6254,6 +6317,10 @@ msgstr "%s: apuntador sha1 no vàlid a l'arbre de la memòria cau"
msgid "non-tree in cache-tree"
msgstr "un no arbre en l'arbre de la memòria cau"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s: el punter sha1 no és vàlid a «resolve-undo»"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<opcions>] [<objecte>...]"
@@ -6320,49 +6387,45 @@ msgstr "git fsmonitor--daemon status"
msgid "value of '%s' out of range: %d"
msgstr "el valor de «%s» està fora de rang: %d"
-#, fuzzy, c-format
+#, c-format
msgid "value of '%s' not bool or int: %d"
-msgstr "valor de \"%s\" no bool ni int: el percentatge"
+msgstr "valor de «%s» no és booleà ni enter: %d"
#, c-format
msgid "fsmonitor-daemon is watching '%s'\n"
-msgstr "fsmonitor-daemon està veient '%s'\n"
+msgstr "fsmonitor-daemon està veient «%s»\n"
#, c-format
msgid "fsmonitor-daemon is not watching '%s'\n"
msgstr "fsmonitor-daemon no està vigilant «%s»\n"
-#, fuzzy, c-format
+#, c-format
msgid "could not create fsmonitor cookie '%s'"
-msgstr "no s'ha pogut crear la galeta fsmonitor '%s'"
+msgstr "no s'ha pogut crear la galeta fsmonitor «%s»"
#, c-format
msgid "fsmonitor: cookie_result '%d' != SEEN"
-msgstr "fsmonitor: cookie_result '%d' != SEEN"
+msgstr "fsmonitor: cookie_result «%d» != SEEN"
-#, fuzzy, c-format
+#, c-format
msgid "could not start IPC thread pool on '%s'"
msgstr "no s'ha pogut iniciar el grup de fils IPC a «%s»"
-#, fuzzy
msgid "could not start fsmonitor listener thread"
-msgstr "no s'ha pogut iniciar el fil d'oient del fsmonitor"
+msgstr "no s'ha pogut iniciar el fil receptor del fsmonitor"
-#, fuzzy
msgid "could not start fsmonitor health thread"
-msgstr "no s'ha pogut iniciar el fil d'oient del fsmonitor"
+msgstr "no s'ha pogut iniciar el fil de salut del fsmonitor"
-#, fuzzy
msgid "could not initialize listener thread"
-msgstr "no s'ha pogut inicialitzar el fil d'oient"
+msgstr "no s'ha pogut inicialitzar el fil receptor"
-#, fuzzy
msgid "could not initialize health thread"
-msgstr "no s'ha pogut inicialitzar el fil d'oient"
+msgstr "no s'ha pogut inicialitzar el fil de salut"
-#, fuzzy, c-format
+#, c-format
msgid "could not cd home '%s'"
-msgstr "no s'ha pogut tancar «%s»"
+msgstr "no s'ha pogut fer cd home «%s»"
#, c-format
msgid "fsmonitor--daemon is already running '%s'"
@@ -6372,15 +6435,13 @@ msgstr "fsmonitor--daemon is already running «%s»"
msgid "running fsmonitor-daemon in '%s'\n"
msgstr "s'està executant fsmonitor-daemon en «%s»\n"
-#, fuzzy, c-format
+#, c-format
msgid "starting fsmonitor-daemon in '%s'\n"
-msgstr "s'està iniciant fsmonitor-daemon a «%s»"
+msgstr "s'està iniciant fsmonitor-daemon a «%s»\n"
-#, fuzzy
msgid "daemon failed to start"
msgstr "el dimoni ha fallat en iniciar"
-#, fuzzy
msgid "daemon not online yet"
msgstr "el dimoni encara no està en línia"
@@ -6393,19 +6454,17 @@ msgstr "separat de la consola"
msgid "use <n> ipc worker threads"
msgstr "usa <n> fils de treball ipc"
-#, fuzzy
msgid "max seconds to wait for background daemon startup"
-msgstr "màxim de segons a esperar a l'inici del dimoni de fons"
+msgstr "màxim de segons a esperar a l'inici del dimoni en segon pla"
-#, fuzzy, c-format
+#, c-format
msgid "invalid 'ipc-threads' value (%d)"
-msgstr "valor «ipc-threads» no vàlid (%)"
+msgstr "valor «ipc-threads» no vàlid (%d)"
-#, fuzzy, c-format
+#, c-format
msgid "Unhandled subcommand '%s'"
-msgstr "Subordre no gestionada '%s'"
+msgstr "Subordre no gestionada «%s»"
-#, fuzzy
msgid "fsmonitor--daemon not supported on this platform"
msgstr "fsmonitor--daemon no és compatible amb aquesta plataforma"
@@ -6441,9 +6500,8 @@ msgstr ""
msgid "prune unreferenced objects"
msgstr "poda objectes sense referència"
-#, fuzzy
msgid "pack unreferenced objects separately"
-msgstr "poda objectes sense referència"
+msgstr "empaqueta els objectes no referenciats de forma separada"
msgid "be more thorough (increased runtime)"
msgstr "sigues més exhaustiu (el temps d'execució augmenta)"
@@ -6458,9 +6516,9 @@ msgstr ""
msgid "repack all other packs except the largest pack"
msgstr "reempaqueta tots els altres paquets excepte el paquet més gran"
-#, fuzzy, c-format
+#, c-format
msgid "failed to parse gc.logExpiry value %s"
-msgstr "no s'ha pogut analitzar el valor %s de gc.logexpiry"
+msgstr "no s'ha pogut analitzar el valor %s de gc.logExpiry"
#, c-format
msgid "failed to parse prune expiry value %s"
@@ -6598,13 +6656,16 @@ msgstr ""
"no s'ha pogut executar «crontab -l»; el vostre sistema podria no admetre "
"«cron»"
+msgid "failed to create crontab temporary file"
+msgstr "no s'ha pogut crear un fitxer temporal crontab"
+
+msgid "failed to open temporary file"
+msgstr "no s'ha pogut obrir el fitxer temporal"
+
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr ""
"no s'ha pogut executar «crontab»; el vostre sistema podria no admetre «cron»"
-msgid "failed to open stdin of 'crontab'"
-msgstr "s'ha produït un error en obrir stdin de «crontab»"
-
msgid "'crontab' died"
msgstr "«crontab» ha mort"
@@ -6651,10 +6712,6 @@ msgstr "no s'ha pogut afegir un repositori a la configuració global"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <subcommand> [<options>]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "subordre no vàlida: %s"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<opcions>] [-e] <patró> [<revisió>...] [[--] <camí>...]"
@@ -6715,7 +6772,7 @@ msgid "process binary files as text"
msgstr "processa els fitxers binaris com a text"
msgid "don't match patterns in binary files"
-msgstr "no coincideixis amb els patrons en els fitxers binaris"
+msgstr "no cerquis els patrons en els fitxers binaris"
msgid "process binary files with textconv filters"
msgstr "processa els fitxers binaris amb filtres de textconv"
@@ -6829,6 +6886,9 @@ msgstr "mostra els fitxers coincidents en el paginador"
msgid "allow calling of grep(1) (ignored by this build)"
msgstr "permet la invocació de grep(1) (ignorat per aquesta compilació)"
+msgid "maximum number of results per file"
+msgstr "nombre màxim de resultats per fitxer"
+
msgid "no pattern given"
msgstr "no s'ha donat cap patró"
@@ -6892,11 +6952,9 @@ msgstr "processa el fitxer com si fos d'aquest camí"
msgid "print all available commands"
msgstr "imprimeix totes les ordres disponibles"
-#, fuzzy
msgid "show external commands in --all"
msgstr "mostra les ordres externes a --all"
-#, fuzzy
msgid "show aliases in --all"
msgstr "mostra els àlies a --all"
@@ -6918,11 +6976,21 @@ msgstr "imprimeix la descripció de l'ordre"
msgid "print list of useful guides"
msgstr "imprimeix la llista de guies útils"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr ""
+"imprimeix la llista de repositoris, ordres i interfícies de fitxers que veu "
+"l'usuari"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr ""
+"mostra la llista de formats de fitxer, protocols i altres interfícies de "
+"desenvolupador"
+
msgid "print all configuration variable names"
msgstr "imprimeix tots els noms de les variables de configuració"
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -6976,16 +7044,15 @@ msgstr "«%s» és un àlies de «%s»"
msgid "bad alias.%s string: %s"
msgstr "cadena «alias.%s» incorrecte: %s"
-#, fuzzy, c-format
+#, c-format
msgid "the '%s' option doesn't take any non-option arguments"
msgstr "l'opció «%s» no pren cap argument que no sigui una opció"
-#, fuzzy
msgid ""
"the '--no-[external-commands|aliases]' options can only be used with '--all'"
msgstr ""
-"les opcions «--no-exexternal-commands|aliases with» només es poden utilitzar "
-"amb «--all»"
+"les opcions «--no-[external-commands|aliases]» només es poden utilitzar amb "
+"«--all»"
#, c-format
msgid "usage: %s%s"
@@ -7144,8 +7211,8 @@ msgstr "Suma de verificació final no esperada per a %s (corrupció de disc?)"
#, c-format
msgid "pack has %d unresolved delta"
msgid_plural "pack has %d unresolved deltas"
-msgstr[0] "El paquet té %d diferència no resolta"
-msgstr[1] "El paquet té %d diferències no resoltes"
+msgstr[0] "el paquet té %d diferència no resolta"
+msgstr[1] "el paquet té %d diferències no resoltes"
#, c-format
msgid "unable to deflate appended object (%d)"
@@ -7174,9 +7241,9 @@ msgstr "no s'ha pogut canviar el nom del fitxer temporal «*.%s» a «%s»"
msgid "error while closing pack file"
msgstr "error en tancar el fitxer empaquetat"
-#, fuzzy, c-format
+#, c-format
msgid "bad pack.indexVersion=%<PRIu32>"
-msgstr "pack.indexversion=%<PRIu32> incorrecte"
+msgstr "bad pack.indexVersion=%<PRIu32>"
#, c-format
msgid "Cannot open existing pack file '%s'"
@@ -7207,7 +7274,7 @@ msgstr "%s incorrecte"
#, c-format
msgid "unknown hash algorithm '%s'"
-msgstr "algorisme hash desconegut «%s»"
+msgstr "algorisme de resum desconegut «%s»"
msgid "--stdin requires a git repository"
msgstr "--stdin requereix un repositori git"
@@ -7263,7 +7330,7 @@ msgid "unable to move %s to %s"
msgstr "no s'ha pogut moure %s a %s"
msgid "attempt to reinitialize repository with different hash"
-msgstr "s'ha intentat reinicialitzar el repositori amb un hash diferent"
+msgstr "s'ha intentat reinicialitzar el repositori amb un resum diferent"
#, c-format
msgid "%s already exists"
@@ -7307,7 +7374,7 @@ msgid "override the name of the initial branch"
msgstr "sobreescriu el nom de la branca inicial"
msgid "hash"
-msgstr "hash"
+msgstr "resum"
msgid "specify the hash algorithm to use"
msgstr "especifiqueu l'algorisme de resum a usar"
@@ -7397,8 +7464,8 @@ msgstr "omet la sortida de diferències"
msgid "show source"
msgstr "mostra la font"
-msgid "use mail map file"
-msgstr "usa el fitxer de mapa de correu"
+msgid "clear all previously-defined decoration filters"
+msgstr "neteja tots els filtres de decoració prèviament definits"
msgid "only decorate refs that match <pattern>"
msgstr "només decora les referències que coincideixin amb <patró>"
@@ -7427,7 +7494,6 @@ msgstr "-L<range>:<file> no es pot usar amb una especificació de camí"
msgid "Final output: %d %s\n"
msgstr "Sortida final: %d %s\n"
-#, fuzzy
msgid "unable to create temporary object directory"
msgstr "no s'ha pogut crear el directori temporal de l'objecte"
@@ -7494,7 +7560,7 @@ msgid ""
msgstr ""
"no s'ha pogut obtenir la font, si voleu registrar la comissió base\n"
"automàticament, useu git branch --set-upstream-to per a seguir una\n"
-"una branca remota. També podeu especificar la comissió base amb --base=<base-"
+"branca remota. També podeu especificar la comissió base amb --base=<base-"
"commit-id> manualment"
msgid "failed to find exact merge base"
@@ -7574,7 +7640,7 @@ msgid "don't output binary diffs"
msgstr "no emetis diferències binàries"
msgid "output all-zero hash in From header"
-msgstr "emet un hash de tots zeros en la capçalera From"
+msgstr "emet un resum de tots zeros en la capçalera From"
msgid "don't include a patch matching a commit upstream"
msgstr "no incloguis pedaços que coincideixin amb comissions a la font"
@@ -7658,6 +7724,11 @@ msgstr ""
msgid "percentage by which creation is weighted"
msgstr "percentatge pel qual la creació és ponderada"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr ""
+"mostra en el cos el remitent: encara que sigui idèntic a la capçalera del "
+"correu electrònic"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "línia d'identitat no vàlida: %s"
@@ -7718,6 +7789,18 @@ msgstr ""
"No s'ha pogut trobar una branca remota seguida. Especifiqueu <font> "
"manualment.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "format incorrecte del ls-files: l'element «%s» no comença amb «(»"
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "format incorrecte del ls-files: l'element «%s» no acaba amb «)»"
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "format incorrecte de ls-files: %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<opcions>] [<fitxer>...]"
@@ -7805,6 +7888,13 @@ msgid "show sparse directories in the presence of a sparse index"
msgstr "mostra els directoris dispersos en presència d'un índex dispers"
msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format no es pot usar amb -s, -o, -k, -t, --resolve-undo, --deduplicate, --"
+"eol"
+
+msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url]\n"
" [--symref] [<repository> [<refs>...]]"
@@ -7826,7 +7916,7 @@ msgid "limit to tags"
msgstr "limita a etiquetes"
msgid "limit to heads"
-msgstr "limita a caps"
+msgstr "limita a «heads»"
msgid "do not show peeled tags"
msgstr "no mostris les etiquetes pelades"
@@ -7843,21 +7933,21 @@ msgstr "mostra la referència subjacent a més de l'objecte que assenyali"
msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
msgstr "git ls-tree [<opcions>] <arbre> [<camí>...]"
-#, fuzzy, c-format
+#, c-format
msgid "could not get object info about '%s'"
-msgstr "no s'ha pogut obtenir la informació de l'objecte sobre «%s»"
+msgstr "no s'ha pogut obtenir la informació sobre l'objecte «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "format ls-tree dolent: l'element '%s' no comença amb '('"
+msgstr "format incorrecte del ls-tree: l'element '%s' no comença amb «(»"
-#, fuzzy, c-format
+#, c-format
msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "format ls-tree dolent: l'element '%s' no acaba en ')'"
+msgstr "format incorrecte del ls-tree: l'element '%s' no acaba en «(»"
-#, fuzzy, c-format
+#, c-format
msgid "bad ls-tree format: %%%.*s"
-msgstr "format incorrecte de ls-tree:%%.*s"
+msgstr "format incorrecte de ls-tree: %%%.*s"
msgid "only show trees"
msgstr "mostra només els arbres"
@@ -7877,7 +7967,6 @@ msgstr "mida de l'objecte d'inclusió"
msgid "list only filenames"
msgstr "llista només els noms de fitxer"
-#, fuzzy
msgid "list only objects"
msgstr "llista només els objectes"
@@ -7888,7 +7977,6 @@ msgid "list entire tree; not just current directory (implies --full-name)"
msgstr ""
"llista l'arbre sencer; no només el directori actual (implica --full-name)"
-#, fuzzy
msgid "--format can't be combined with other format-altering options"
msgstr "--format no es pot combinar amb altres opcions d'alteració de format"
@@ -7924,14 +8012,13 @@ msgid "<action>"
msgstr "<acció>"
msgid "action when quoted CR is found"
-msgstr "acció quan es troba un CR en una cita"
+msgstr "acció quan es troba un CR entre cometes"
msgid "use headers in message's body"
msgstr "utilitza les capçaleres en el cos del missatge"
-#, fuzzy
msgid "reading patches from stdin/tty..."
-msgstr "llegir pedaços de stdin/tty..."
+msgstr "s'estan llegint pedaços de stdin/tty..."
#, c-format
msgid "empty mbox: '%s'"
@@ -8027,6 +8114,39 @@ msgstr "no s'ha pogut resoldre la referència «%s»"
msgid "Merging %s with %s\n"
msgstr "S'està fusionant %s amb %s\n"
+msgid "not something we can merge"
+msgstr "no és quelcom que puguem fusionar"
+
+msgid "refusing to merge unrelated histories"
+msgstr "s'està refusant fusionar històries no relacionades"
+
+msgid "failure to merge"
+msgstr "s'ha produït un error en fusionar"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "fes una fusió real en lloc d'una fusió trivial"
+
+msgid "do a trivial merge only"
+msgstr "fes només una fusió trivial"
+
+msgid "also show informational/conflict messages"
+msgstr "també mostra missatges informatius i de conflictes"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "llista els noms de fitxer sense modes/oids/stages"
+
+msgid "allow merging unrelated histories"
+msgstr "permet fusionar històries no relacionades"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge és incompatible amb totes les altres opcions"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<opcions>] [<comissió>...]"
@@ -8106,10 +8226,7 @@ msgid "--abort but leave index and working tree alone"
msgstr "--abort però deixa l'índex i l'arbre de treball intactes"
msgid "continue the current in-progress merge"
-msgstr "continua la fusió en curs actual"
-
-msgid "allow merging unrelated histories"
-msgstr "permet fusionar històries no relacionades"
+msgstr "continua la fusió actual en curs"
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "evita els lligams pre-merge-commit i commit-msg"
@@ -8230,9 +8347,6 @@ msgstr "no s'ha pogut tancar «%s»"
msgid "not something we can merge in %s: %s"
msgstr "no és quelcom que puguem fusionar en %s: %s"
-msgid "not something we can merge"
-msgstr "no és quelcom que puguem fusionar"
-
msgid "--abort expects no arguments"
msgstr "--abort no espera cap argument"
@@ -8271,26 +8385,31 @@ msgstr ""
"establert."
msgid "Squash commit into empty head not supported yet"
-msgstr "Una comissió «squash» a un HEAD buit encara no es permet"
+msgstr "Una comissió «squash» a una HEAD buida encara no es permet"
msgid "Non-fast-forward commit does not make sense into an empty head"
-msgstr "Una comissió no d'avanç ràpid no té sentit a un HEAD buit"
+msgstr "Una comissió no d'avanç ràpid no té sentit a una HEAD buida"
#, c-format
msgid "%s - not something we can merge"
msgstr "%s - no és una cosa que puguem fusionar"
msgid "Can merge only exactly one commit into empty head"
-msgstr "Es pot fusionar només una comissió a un HEAD buit"
-
-msgid "refusing to merge unrelated histories"
-msgstr "s'està refusant fusionar històries no relacionades"
+msgstr "Es pot fusionar només una comissió a una HEAD buida"
#, c-format
msgid "Updating %s..%s\n"
msgstr "S'estan actualitzant %s..%s\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Els canvis locals als fitxers següents se sobreescriuran per la fusió:\n"
+" %s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "S'està intentant una fusió molt trivial en l'índex...\n"
@@ -8325,6 +8444,10 @@ msgstr ""
"demanat\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "Quan acabi, aplica els canvis «stashed» amb «git stash pop»\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
msgstr "avís: l'entrada d'etiqueta no passa fsck: %s"
@@ -8381,9 +8504,8 @@ msgstr "git multi-pack-index [<opcions>] expire"
msgid "git multi-pack-index [<options>] repack [--batch-size=<size>]"
msgstr "git multi-pack-index [<opcions>] repack [--batch-size=<mida>]"
-#, fuzzy
msgid "directory"
-msgstr "fitxer/directori"
+msgstr "directori"
msgid "object directory containing set of packfile and pack-index pairs"
msgstr ""
@@ -8447,6 +8569,9 @@ msgstr "S'està comprovant el canvi de nom de «%s» a «%s»\n"
msgid "bad source"
msgstr "origen incorrecte"
+msgid "destination exists"
+msgstr "el destí existeix"
+
msgid "can not move directory into itself"
msgstr "no es pot moure un directori a dins d'ell mateix"
@@ -8462,9 +8587,6 @@ msgstr "no està sota control de versions"
msgid "conflicted"
msgstr "en conflicte"
-msgid "destination exists"
-msgstr "el destí existeix"
-
#, c-format
msgid "overwriting '%s'"
msgstr "s'està sobreescrivint «%s»"
@@ -8478,6 +8600,9 @@ msgstr "múltiples orígens per al mateix destí"
msgid "destination directory does not exist"
msgstr "el directori destí no existeix"
+msgid "destination exists in the index"
+msgstr "el destí existeix a l'índex"
+
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, origen=%s, destí=%s"
@@ -8514,11 +8639,9 @@ msgstr "ignora les referències que coincideixin amb <patró>"
msgid "list all commits reachable from all refs"
msgstr "llista totes les comissions abastables de totes les referències"
-#, fuzzy
msgid "deprecated: use --annotate-stdin instead"
-msgstr "obsolet: useu annotate-stdin"
+msgstr "obsolet: useu en comptes --annotate-stdin"
-#, fuzzy
msgid "annotate text from stdin"
msgstr "anota el text de stdin"
@@ -8842,8 +8965,8 @@ msgid "use notes from <notes-ref>"
msgstr "usa les notes de <referència-de-notes>"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "subordre desconeguda: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "subordre desconeguda: «%s»"
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -8986,21 +9109,18 @@ msgstr "no s'ha pogut obtenir el tipus de l'objecte %s al paquet %s"
msgid "could not find pack '%s'"
msgstr "no s'ha pogut trobar el paquet «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "packfile %s cannot be accessed"
-msgstr "el fitxer de paquet %s no es pot mapar%s"
+msgstr "no es pot accedir al fitxer de paquet %s"
-#, fuzzy
msgid "Enumerating cruft objects"
-msgstr "S'estan enumerant els objectes"
+msgstr "S'estan enumerant els objectes superflus"
-#, fuzzy
msgid "unable to add cruft objects"
-msgstr "no s'han pogut afegir els objectes recents"
+msgstr "no s'han pogut afegir els objectes superflus"
-#, fuzzy
msgid "Traversing cruft objects"
-msgstr "S'estan comprimint els objectes"
+msgstr "S'estan recorrent els objectes superflus"
#, c-format
msgid ""
@@ -9018,9 +9138,8 @@ msgstr ""
"s'esperava un identificador d'objecte, s'ha rebut brossa:\n"
" %s"
-#, fuzzy
msgid "could not load cruft pack .mtimes"
-msgstr "no s'ha pogut carregar el paquet"
+msgstr "no s'ha pogut carregar superflus del paquet superflu"
msgid "cannot open pack index"
msgstr "no s'ha pogut obrir l'índex del paquet"
@@ -9090,16 +9209,16 @@ msgid "use OFS_DELTA objects"
msgstr "usa objectes OFS_DELTA"
msgid "use threads when searching for best delta matches"
-msgstr "usa fils en cercar les millores coincidències de diferències"
+msgstr "usa fils en cercar les millors coincidències de diferències"
msgid "do not create an empty pack output"
-msgstr "no creïs una emissió de paquet buida"
+msgstr "no creïs una emissió de paquet buit"
msgid "read revision arguments from standard input"
msgstr "llegeix els arguments de revisió des de l'entrada estàndard"
msgid "limit the objects to those that are not yet packed"
-msgstr "limita els objectes als quals encara no s'hagin empaquetat"
+msgstr "limita els objectes a aquells que encara no estan empaquetats"
msgid "include objects reachable from any reference"
msgstr "inclou els objectes abastables de qualsevol referència"
@@ -9131,13 +9250,11 @@ msgstr "empaqueta els objectes inabastables solts"
msgid "unpack unreachable objects newer than <time>"
msgstr "desempaqueta els objectes inabastables més nous que <data>"
-#, fuzzy
msgid "create a cruft pack"
-msgstr "crea paquets prims"
+msgstr "crea un paquet superflu"
-#, fuzzy
msgid "expire cruft objects older than <time>"
-msgstr "fes caducar els objectes més antics que <data>"
+msgstr "fes caducar els objectes superflus més antics que <data>"
msgid "use the sparse reachability algorithm"
msgstr "utilitza l'algorisme d'accessibilitat dispers"
@@ -9175,7 +9292,7 @@ msgid "handling for missing objects"
msgstr "gestió dels objectes absents"
msgid "do not pack objects in promisor packfiles"
-msgstr "empaquetis els objectes als fitxers de paquet «promisor»"
+msgstr "no empaquetis els objectes als fitxers de paquet «promisor»"
msgid "respect islands during delta compression"
msgstr "respecta les illes durant la compressió delta"
@@ -9219,17 +9336,14 @@ msgstr "no es pot utilitzar --filter sense --stdin-packs"
msgid "cannot use internal rev list with --stdin-packs"
msgstr "no es pot utilitzar la llista de revisió interna amb --stdin-packs"
-#, fuzzy
msgid "cannot use internal rev list with --cruft"
-msgstr "no es pot utilitzar la llista de revisió interna amb --stdin-packs"
+msgstr "no es pot utilitzar la llista de revisió interna amb --cruft"
-#, fuzzy
msgid "cannot use --stdin-packs with --cruft"
-msgstr "no es pot usar -a amb -d"
+msgstr "no es pot --stdin-packs amb --cruft"
-#, fuzzy
msgid "cannot use --max-pack-size with --cruft"
-msgstr "no es pot usar -a amb -d"
+msgstr "no es pot usar --max-pack-size amb --cruft"
msgid "Enumerating objects"
msgstr "S'estan enumerant els objectes"
@@ -9408,7 +9522,7 @@ msgstr ""
"preferència per defecte per a tots els repositoris. Podeu també usar --"
"rebase,\n"
"--no-rebase o --ff-only en la línia d'ordres per a sobreescriure el valor\n"
-"per defecte configuració en aquesta execució.\n"
+"per defecte de la configuració en aquesta execució.\n"
msgid "Updating an unborn branch with changes added to the index."
msgstr ""
@@ -9448,7 +9562,7 @@ msgstr ""
"per a recuperar."
msgid "Cannot merge multiple branches into empty head."
-msgstr "No es poden fusionar múltiples branques a un HEAD buit."
+msgstr "No es poden fusionar múltiples branques a una HEAD buida."
msgid "Cannot rebase onto multiple branches."
msgstr "No es pot fer «rebase» sobre múltiples branques."
@@ -9473,14 +9587,13 @@ msgstr "abreviatura d'etiqueta sense <tag>"
msgid "--delete only accepts plain target ref names"
msgstr "--delete només accepta noms de referència de destí senzills"
-#, fuzzy
msgid ""
"\n"
"To choose either option permanently, see push.default in 'git help config'.\n"
msgstr ""
"\n"
-"Per a triar qualsevol opció permanentment, vegeu push.default a «git help "
-"config»."
+"Per a triar qualsevol de les opcions permanentment, vegeu push.default a "
+"«git help config».\n"
msgid ""
"\n"
@@ -9489,8 +9602,13 @@ msgid ""
"autoSetupMerge\n"
"in 'git help config'.\n"
msgstr ""
+"\n"
+"Per a evitar configurar automàticament les branques font quan el seu nom\n"
+"no coincideix amb el de la branca local, vegeu l'opció «simple» de «branch."
+"autoSetupMerge»\n"
+"a «git help config».\n"
-#, fuzzy, c-format
+#, c-format
msgid ""
"The upstream branch of your current branch does not match\n"
"the name of your current branch. To push to the upstream branch\n"
@@ -9512,7 +9630,7 @@ msgstr ""
"Per a pujar a la branca del mateix nom en el remot, useu\n"
"\n"
" git push %s HEAD\n"
-"%s"
+"%s%s"
#, c-format
msgid ""
@@ -9533,8 +9651,12 @@ msgid ""
"To have this happen automatically for branches without a tracking\n"
"upstream, see 'push.autoSetupRemote' in 'git help config'.\n"
msgstr ""
+"\n"
+"Per fer que això succeeixi automàticament per a les branques sense "
+"seguiment\n"
+"font, vegeu «push.autoSetupRemote» a «git help config».\n"
-#, fuzzy, c-format
+#, c-format
msgid ""
"The current branch %s has no upstream branch.\n"
"To push the current branch and set the remote as upstream, use\n"
@@ -9546,6 +9668,7 @@ msgstr ""
"Per a pujar la branca actual i establir el remot com a font, useu\n"
"\n"
" git push --set-upstream %s %s\n"
+"%s"
#, c-format
msgid "The current branch %s has multiple upstream branches, refusing to push."
@@ -9761,11 +9884,16 @@ msgid "only emit output related to the second range"
msgstr "emet només la sortida relacionada amb el segon interval"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "«%s» no és una revisió"
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "no és un rang de comissions: «%s»"
-msgid "single arg format must be symmetric range"
-msgstr "el format de l'argument únic ha de ser de rang simètric"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "no és un rang simètric: «%s»"
msgid "need two commit ranges"
msgstr "calen dos rangs de comissió"
@@ -9804,7 +9932,7 @@ msgid "<subdirectory>/"
msgstr "<subdirectori>/"
msgid "read the tree into the index under <subdirectory>/"
-msgstr "llegiu l'arbre a l'índex sota <subdirectori>/"
+msgstr "llegeix l'arbre a l'índex sota <subdirectori>/"
msgid "update working tree with merge result"
msgstr "actualitza l'arbre de treball amb el resultat de fusió"
@@ -9983,7 +10111,7 @@ msgid "add a Signed-off-by trailer to each commit"
msgstr "afegeix un «trailer» tipus «Signed-off-by» a cada comissió"
msgid "make committer date match author date"
-msgstr "fes que la data del «comitter» coincideixi amb la data de l'autor"
+msgstr "fes que la data del «committer» coincideixi amb la data de l'autor"
msgid "ignore author date and use current date"
msgstr "ignora la data de l'autor i utilitza la data actual"
@@ -10027,9 +10155,8 @@ msgstr "utilitza estratègies de fusió per a fer «rebase»"
msgid "let the user edit the list of commits to rebase"
msgstr "permet a l'usuari editar la llista de comissions a fer «rebase»"
-#, fuzzy
msgid "(REMOVED) was: try to recreate merges instead of ignoring them"
-msgstr "(EN DESÚS) intenta recrear fusions en lloc d'ignorar-les"
+msgstr "(SUPRIMIT) era: intenta recrear fusions en lloc d'ignorar-les"
msgid "how to handle commits that become empty"
msgstr "com gestionar les comissions que queden buides"
@@ -10040,6 +10167,11 @@ msgstr "manté les comissions que comencen en blanc"
msgid "move commits that begin with squash!/fixup! under -i"
msgstr "mou les comissions que comencen amb squash!/fixup! sota -i"
+msgid "update branches that point to commits that are being rebased"
+msgstr ""
+"actualitza les branques que apunten a comissions a les quals se'ls està fent "
+"«rebase»"
+
msgid "add exec lines after each commit of the editable list"
msgstr "afegeix línies d'exec després de cada comissió de la llista editable"
@@ -10078,12 +10210,18 @@ msgid ""
"Use `git rebase --abort` to terminate current rebase.\n"
"Or downgrade to v2.33, or earlier, to complete the rebase."
msgstr ""
+"«rebase --preserve-merges» (-p) ja no és admès.\n"
+"Utilitzeu «git rebase --abort» per a finalitzar el «rebase» actual.\n"
+"O bé baixeu a la versió v2.33, o anterior, per a completar el «rebase»."
msgid ""
"--preserve-merges was replaced by --rebase-merges\n"
"Note: Your `pull.rebase` configuration may also be set to 'preserve',\n"
"which is no longer supported; use 'merges' instead"
msgstr ""
+"--preserve-merges s'ha substituït per --rebase-merges\n"
+"Nota: la configuració «pull.rebase» també podria estar establerta a\n"
+"+-«preserve», que ja no s'admet; utilitzeu «merge» en el seu lloc"
msgid "No rebase in progress?"
msgstr "No hi ha un «rebase» en curs?"
@@ -10195,7 +10333,7 @@ msgid "Current branch %s is up to date, rebase forced.\n"
msgstr "La branca actual %s està al dia; «rebase» forçat.\n"
msgid "The pre-rebase hook refused to rebase."
-msgstr "El lligam pre-«rebase» ha refusat a fer «rebase»."
+msgstr "El lligam pre-rebase ha refusat a fer «rebase»."
#, c-format
msgid "Changes to %s:\n"
@@ -10302,13 +10440,12 @@ msgstr ""
msgid "git reflog exists <ref>"
msgstr "git reflog exists <referència>"
-#, fuzzy, c-format
+#, c-format
msgid "invalid timestamp '%s' given to '--%s'"
-msgstr "el codi de temps «%s» no és vàlid donat a «--%s»"
+msgstr "marca de temps «%s» donada a «--%s» no és vàlida"
-#, fuzzy
msgid "do not actually prune any entries"
-msgstr "no practiquis cap entrada"
+msgstr "no eliminis cap entrada"
msgid ""
"rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"
@@ -10317,34 +10454,28 @@ msgstr "reescriu l'antic SHA1 amb el nou SHA1 de l'entrada que ara precedeix"
msgid "update the reference to the value of the top reflog entry"
msgstr "actualitza la referència al valor de l'entrada de reflog superior"
-#, fuzzy
msgid "print extra information on screen"
msgstr "imprimeix informació extra a la pantalla"
msgid "timestamp"
msgstr "marca de temps"
-#, fuzzy
msgid "prune entries older than the specified time"
msgstr "poda les entrades més antigues que el temps especificat"
-#, fuzzy
msgid ""
"prune entries older than <time> that are not reachable from the current tip "
"of the branch"
msgstr ""
-"poda les entrades més antigues de <time> que no es poden accedir des de la "
+"poda les entrades més antigues de <data> que no es poden accedir des de la "
"punta actual de la branca"
-#, fuzzy
msgid "prune any reflog entries that point to broken commits"
msgstr "poda qualsevol entrada de reflog que apunti a comissions trencades"
-#, fuzzy
msgid "process the reflogs of all references"
msgstr "processa els reflogs de totes les referències"
-#, fuzzy
msgid "limits processing to reflogs from the current worktree only"
msgstr "limita el processament a reflogs només de l'arbre de treball actual"
@@ -10532,9 +10663,8 @@ msgstr ""
"\t%s\n"
"\tActualitzeu la configuració manualment si és necessari."
-#, fuzzy
msgid "Renaming remote references"
-msgstr "Canviant el nom de les referències remotes"
+msgstr "S'està canviant el nom de les referències remotes"
#, c-format
msgid "deleting '%s' failed"
@@ -10569,6 +10699,9 @@ msgstr " nou (la pròxima obtenció emmagatzemarà a remotes/%s)"
msgid " tracked"
msgstr " seguit"
+msgid " skipped"
+msgstr " omès"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " estancat (useu «git remote prune» per a eliminar)"
@@ -10795,7 +10928,6 @@ msgstr "sigues detallat; s'ha de col·locar abans d'una subordre"
msgid "git repack [<options>]"
msgstr "git repack [<opcions>]"
-#, fuzzy
msgid ""
"Incremental repacks are incompatible with bitmap indexes. Use\n"
"--no-write-bitmap-index or disable the pack.writeBitmaps configuration."
@@ -10803,7 +10935,7 @@ msgstr ""
"Els reempaquetaments incrementals són incompatibles amb els índexs de mapes "
"de bits. Useu\n"
"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració pack."
-"writebitmaps."
+"writeBitmaps."
msgid "could not start pack-objects to repack promisor objects"
msgstr ""
@@ -10847,16 +10979,16 @@ msgstr "empaqueta-ho tot en un únic paquet"
msgid "same as -a, and turn unreachable objects loose"
msgstr "el mateix que -a, i solta els objectes inabastables"
-#, fuzzy
msgid "same as -a, pack unreachable cruft objects separately"
-msgstr "el mateix que -a, i solta els objectes inabastables"
+msgstr ""
+"el mateix que -a, empaqueta els objectes superflus inabastables de forma "
+"separada"
msgid "approxidate"
msgstr "data aproximada"
-#, fuzzy
msgid "with -C, expire objects older than this"
-msgstr "fes caducar els objectes més antics que <data>"
+msgstr "amb -C, venç els objectes més antics que aquest"
msgid "remove redundant packs, and run git-prune-packed"
msgstr "elimina els paquets redundants, i executeu git-prune-packed"
@@ -10923,9 +11055,9 @@ msgstr "no es poden suprimir paquets en un repositori d'objectes preciosos"
msgid "Nothing new to pack."
msgstr "Res nou a empaquetar."
-#, fuzzy, c-format
+#, c-format
msgid "pack prefix %s does not begin with objdir %s"
-msgstr "el nom del fitxer de paquet «%s» no acaba amb «.%s»"
+msgstr "el prefix de paquet %s no comença amb objdir %s"
#, c-format
msgid "missing required file: %s"
@@ -11168,7 +11300,7 @@ msgid "keep"
msgstr "reteniment"
msgid "You do not have a valid HEAD."
-msgstr "No teniu un HEAD vàlid."
+msgstr "No teniu una HEAD vàlida."
msgid "Failed to find tree of HEAD."
msgstr "S'ha produït un error en trobar l'arbre de HEAD."
@@ -11230,14 +11362,14 @@ msgstr "el restabliment de %s no es permet en un repositori nu"
msgid "Unstaged changes after reset:"
msgstr "Canvis «unstaged» després del restabliment:"
-#, fuzzy, c-format
+#, c-format
msgid ""
"It took %.2f seconds to refresh the index after reset. You can use\n"
"'--no-refresh' to avoid this."
msgstr ""
-"Es van trigar un temps de,2f segons a actualitzar l'índex després de "
-"reiniciar. Pots utilitzar\n"
-".--no-refresh' per evitar això."
+"Es van trigar %.2f segons a actualitzar l'índex després de reiniciar. Podeu "
+"usar\n"
+".--no-refresh' per a evitar això."
#, c-format
msgid "Could not reset index file to revision '%s'."
@@ -11250,6 +11382,10 @@ msgstr "No s'ha pogut escriure el fitxer d'índex nou."
msgid "unable to get disk usage of %s"
msgstr "no s'ha pogut obtenir l'ús del disc de %s"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "valor no vàlid per a «%s»: «%s», l'únic format permès és «%s»"
+
msgid "rev-list does not support display of notes"
msgstr "el rev-list no permet mostrar notes"
@@ -11275,6 +11411,9 @@ msgstr "final prematur de l'entrada"
msgid "no usage string given before the `--' separator"
msgstr "no s'ha indicat cap cadena d'ús abans del separador «--»"
+msgid "missing opt-spec before option flags"
+msgstr "manca l'opció opt-spec abans de les altres opcions"
+
msgid "Needed a single revision"
msgstr "Cal una sola revisió"
@@ -11392,7 +11531,7 @@ msgid "keep redundant, empty commits"
msgstr "retén les comissions redundants i buides"
msgid "use the 'reference' format to refer to commits"
-msgstr ""
+msgstr "useu el format «referència» per a referir-vos a les comissions"
msgid "revert failed"
msgstr "la reversió ha fallat"
@@ -11511,7 +11650,7 @@ msgid "unknown group type: %s"
msgstr "tipus de grup desconegut: %s"
msgid "group by committer rather than author"
-msgstr "agrupa per «comitter» en comptes de per autor"
+msgstr "agrupa per «committer» en comptes de per autor"
msgid "sort output according to the number of commits per author"
msgstr "ordena la sortida segons el nombre de comissions per autor"
@@ -11675,7 +11814,7 @@ msgid "dereference tags into object IDs"
msgstr "desreferencia les etiquetes a ID d'objecte"
msgid "only show SHA1 hash using <n> digits"
-msgstr "mostra el hash SHA1 usant només <n> xifres"
+msgstr "mostra el resum SHA1 usant només <n> xifres"
msgid "do not print results to stdout (useful with --verify)"
msgstr "no imprimeixis els resultats a stdout (útil amb --verify)"
@@ -11709,9 +11848,8 @@ msgstr "s'ha produït un error en suprimir el directori «%s»"
msgid "failed to create directory for sparse-checkout file"
msgstr "no s'ha pogut crear el directori per al fitxer sparse-checkout"
-#, fuzzy
msgid "failed to initialize worktree config"
-msgstr "no s'ha pogut inicialitzar l'arbre de treball to"
+msgstr "no s'ha pogut inicialitzar la configuració de l'arbre de treball"
msgid "failed to modify sparse-index config"
msgstr "no s'ha pogut modificar la configuració de l'índex dispers"
@@ -11736,7 +11874,7 @@ msgstr "no s'ha pogut normalitzar el camí %s"
#, c-format
msgid "unable to unquote C-style string '%s'"
-msgstr "no s'ha pogut treure la cita a la cadena amb estil C «%s»"
+msgstr "no s'han pogut treure les cometes a la cadena amb estil C «%s»"
msgid "unable to load existing sparse-checkout patterns"
msgstr "no s'han pogut carregar els patrons de «sparse-checkout» existents"
@@ -11744,51 +11882,45 @@ msgstr "no s'han pogut carregar els patrons de «sparse-checkout» existents"
msgid "existing sparse-checkout patterns do not use cone mode"
msgstr "els patrons de «sparse-checkout» existents no usen el mode con"
-#, fuzzy
msgid "please run from the toplevel directory in non-cone mode"
-msgstr ""
-"executeu des del directori de nivell superior en mode que no sigui compatible"
+msgstr "executeu des del directori de nivell superior en mode que no sigui con"
-#, fuzzy
msgid "specify directories rather than patterns (no leading slash)"
msgstr "especifica els directoris en lloc dels patrons (sense barra inclinada)"
-#, fuzzy
msgid ""
"specify directories rather than patterns. If your directory starts with a "
"'!', pass --skip-checks"
msgstr ""
"especifica els directoris en lloc dels patrons. Si el vostre directori "
-"comença amb un '!', passeu --skip-checks"
+"comença amb un «!», passeu --skip-checks"
-#, fuzzy
msgid ""
"specify directories rather than patterns. If your directory really has any "
"of '*?[]\\' in it, pass --skip-checks"
msgstr ""
"especifica els directoris en lloc dels patrons. Si el vostre directori "
-"realment té alguna de '*?\\\\', passeu --skip-checks"
+"realment té alguna de «*?[]\\», useu --skip-checks"
-#, fuzzy, c-format
+#, c-format
msgid ""
"'%s' is not a directory; to treat it as a directory anyway, rerun with --"
"skip-checks"
msgstr ""
-"%%s' no és un directori; per tractar-lo com un directori de totes maneres, "
-"torneu a executar amb --skip-checks"
+"«%s» no és un directori; per a tractar-lo com un directori, torneu a "
+"executar amb --skip-checks"
-#, fuzzy, c-format
+#, c-format
msgid ""
"pass a leading slash before paths such as '%s' if you want a single file "
"(see NON-CONE PROBLEMS in the git-sparse-checkout manual)."
msgstr ""
"passa una barra d'inici abans dels camins com ara «%s» si voleu un sol "
-"fitxer (vegeu els problemes NO CONE al manual de git-sparse-checkout)."
+"fitxer (vegeu «NON-CONE PROBLEMS» al manual de git-sparse-checkout)."
msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"
msgstr "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"
-#, fuzzy
msgid ""
"skip some sanity checks on the given paths that might give false positives"
msgstr ""
@@ -12050,6 +12182,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "S'espera un nom de referència ple, s'ha rebut %s"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "no s'ha pogut obtenir el gestor del repositori pel submòdul «%s»"
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -12057,12 +12193,6 @@ msgstr ""
"no s'ha pogut trobar la configuració «%s». S'assumeix que aquest repositori "
"és el seu repositori font autoritzat."
-msgid "alternative anchor for relative paths"
-msgstr "àncora alternativa per als camins relatius"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<camí>] [<camí>...]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "No s'ha trobat cap url per al camí de submòdul «%s» a .gitmodules"
@@ -12095,8 +12225,8 @@ msgstr "omet la sortida en entrar a cada ordre del submòdul"
msgid "recurse into nested submodules"
msgstr "inclou recursivament els submòduls imbricats"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <ordre>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <ordre>"
#, c-format
msgid "Failed to register url for submodule path '%s'"
@@ -12121,8 +12251,8 @@ msgstr ""
msgid "suppress output for initializing a submodule"
msgstr "omet la sortida en inicialitzar un submòdul"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<opcions>] [<camí>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<opcions>] [<camí>]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -12149,9 +12279,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<camí>...]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <camí>"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submòdul)"
@@ -12188,8 +12315,8 @@ msgstr "omet els submòduls amb el valor «ignore_config» establert a «all»"
msgid "limit the summary size"
msgstr "limita la mida del resum"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<options>] [<commit>] [--] [<path>]"
msgid "could not fetch a revision for HEAD"
msgstr "no s'ha pogut obtenir una revisió per a HEAD"
@@ -12203,19 +12330,14 @@ msgid "failed to register url for submodule path '%s'"
msgstr "s'ha produït un error en registrar l'url per al camí del submòdul «%s»"
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr ""
-"s'ha produït un error en obtenir el remot per defecte pel submòdul «%s»"
-
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "s'ha produït un error en actualitzar el remot pel submòdul «%s»"
msgid "suppress output of synchronizing submodule url"
msgstr "omet la sortida de la sincronització de l'URL del submòdul"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<camí>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<path>]"
#, c-format
msgid ""
@@ -12278,6 +12400,10 @@ msgstr ""
"«--reference-if-able' en comptes de «--reference»."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "no s'ha pogut obtenir el gestor del repositori per al gitdir «%s»"
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "el submòdul «%s» no pot afegir un alternatiu: %s"
@@ -12305,6 +12431,9 @@ msgstr "directori no buit: «%s»"
msgid "could not get submodule directory for '%s'"
msgstr "no s'ha pogut obtenir el directori de submòdul per a «%s»"
+msgid "alternative anchor for relative paths"
+msgstr "àncora alternativa per als camins relatius"
+
msgid "where the new submodule will be cloned to"
msgstr "a on es clonarà el submòdul nou"
@@ -12323,7 +12452,6 @@ msgstr "força el progrés del clonatge"
msgid "disallow cloning into non-empty directory"
msgstr "no permetis clonar en un directori no buit"
-#, fuzzy
msgid ""
"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
"<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter "
@@ -12331,11 +12459,7 @@ msgid ""
msgstr ""
"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
"<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter "
-"<filter-spec>]--url <url> --path <path>"
-
-#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Mode d'actualització «%s» no vàlid per al camí de submòdul «%s»"
+"<filter-spec>] --url <url> --path <path>"
#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
@@ -12412,6 +12536,10 @@ msgstr ""
"directa d'aquesta comissió ha fallat."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "no s'ha pogut inicialitzar el submòdul al camí «%s»"
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -12420,25 +12548,21 @@ msgstr ""
"superprojecte, però el superprojecte no és en cap branca"
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "no s'ha pogut obtenir el gestor del repositori pel submòdul «%s»"
-
-#, fuzzy, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "No s'ha pogut trobar la revisió actual al camí del submòdul «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "Unable to fetch in submodule path '%s'"
-msgstr "No s'ha pogut recuperar el camí del submòdul «%s»"
+msgstr "No s'ha pogut obtenir el camí del submòdul «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "Unable to find %s revision in submodule path '%s'"
-msgstr ""
-"No s'ha pogut trobar la revisió de percentatges en el camí del submòdul «%s»"
+msgstr "No s'ha pogut trobar la revisió %s en el camí del submòdul «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "Failed to recurse into submodule path '%s'"
-msgstr "No s'ha pogut tornar a repetir al camí del submòdul «%s»"
+msgstr ""
+"s'ha produït un error en cercar recursivament al camí del submòdul «%s»"
msgid "force checkout updates"
msgstr "força les actualitzacions"
@@ -12446,13 +12570,11 @@ msgstr "força les actualitzacions"
msgid "initialize uninitialized submodules before update"
msgstr "inicialitza els submòduls sense inicialitzar abans d'actualitzar"
-#, fuzzy
msgid "use SHA-1 of submodule's remote tracking branch"
-msgstr "utilitza SHA-1 de la branca de seguiment remota del submòdul"
+msgstr "usa el SHA-1 de la branca de seguiment remota del submòdul"
-#, fuzzy
msgid "traverse submodules recursively"
-msgstr "traverteix els submòduls recursivament"
+msgstr "recorre els submòduls recursivament"
msgid "don't fetch new objects from the remote site"
msgstr "no obtinguis els objectes nous del lloc remot"
@@ -12460,11 +12582,14 @@ msgstr "no obtinguis els objectes nous del lloc remot"
msgid "path into the working tree"
msgstr "camí a l'arbre de treball"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "camí a l'arbre de treball, a través de fronteres de submòduls niats"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "utilitza l'estratègia d'actualització «checkout» (predeterminada)"
-msgid "rebase, merge, checkout or none"
-msgstr "rebase, merge, checkout o none"
+msgid "use the 'merge' update strategy"
+msgstr "utilitza l'estratègia d'actualització de «merge»"
+
+msgid "use the 'rebase' update strategy"
+msgstr "utilitza l'estratègia d'actualització de «rebase»"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr "crea un clon superficial truncat al nombre de revisions especificat"
@@ -12478,6 +12603,9 @@ msgstr "si el clonatge inicial ha de seguir la recomanació de superficialitat"
msgid "don't print cloning progress"
msgstr "no imprimeixis el progrés del clonatge"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "no permetis clonar en un directori no buit, implica --init"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12489,14 +12617,11 @@ msgstr ""
"shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] "
"[--] [<path>...]"
-msgid "bad value for update parameter"
-msgstr "valor incorrecte per al paràmetre update"
-
msgid "recurse into submodules"
msgstr "inclou recursivament als submòduls"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<opcions>] [<camí>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<options>] [<path>...]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr "comprova si és segur escriure al fitxer .gitmodules"
@@ -12516,8 +12641,8 @@ msgstr "assegureu-vos que el fitxer .gitmodules és a l'arbre de treball"
msgid "suppress output for setting url of a submodule"
msgstr "omet la sortida en configurar un URL d'un submòdul"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <path> <newurl>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <path> <newurl>"
msgid "set the default tracking branch to master"
msgstr "estableix la branca de seguiment per defecte a «master»"
@@ -12525,13 +12650,11 @@ msgstr "estableix la branca de seguiment per defecte a «master»"
msgid "set the default tracking branch"
msgstr "estableix la branca de seguiment per defecte"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
msgid "--branch or --default required"
msgstr "cal --branch o --default"
@@ -12542,17 +12665,15 @@ msgstr "mostra només els missatges d'error"
msgid "force creation"
msgstr "força la creació"
-#, fuzzy
msgid "show whether the branch would be created"
msgstr "mostra si es crearà la branca"
-#, fuzzy
msgid ""
"git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--"
"quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"
msgstr ""
"git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--"
-"quiet] [-t|--track] [-n|--dry-run] <name> <start_oid> <start_name>"
+"quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"
#, c-format
msgid "creating branch '%s'"
@@ -12624,7 +12745,6 @@ msgstr "permet afegir un camí de submòdul que si no s'hagués ignorat"
msgid "borrow the objects from reference repositories"
msgstr "manlleva els objectes dels repositoris de referències"
-#, fuzzy
msgid ""
"sets the submodule's name to the given string instead of defaulting to its "
"path"
@@ -12632,8 +12752,8 @@ msgstr ""
"estableix el nom del submòdul a la cadena donada en lloc de per defecte al "
"seu camí"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<opcions>] [--] <repositori> [<camí>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<options>] [--] <repository> [<path>]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr ""
@@ -12841,6 +12961,16 @@ msgstr "Etiqueta «%s» actualitzada (era %s)\n"
msgid "pack exceeds maximum allowed size"
msgstr "el paquet supera la mida màxima permesa"
+msgid "failed to write object in stream"
+msgstr "no s'ha pogut escriure l'objecte al flux"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "inflate ha retornat (%d)"
+
+msgid "invalid blob object from stream"
+msgstr "l'objecte blob del flux no és vàlid"
+
msgid "Unpacking objects"
msgstr "S'estan desempaquetant els objectes"
@@ -13353,7 +13483,7 @@ msgstr ""
#, c-format
msgid "validation failed, cannot remove working tree: %s"
-msgstr "la validació ha fallat, no es pot suprmir l'arbre de treball: %s"
+msgstr "la validació ha fallat, no es pot suprimir l'arbre de treball: %s"
#, c-format
msgid "repair: %s: %s"
@@ -13375,9 +13505,30 @@ msgstr "escriu l'objecte d'arbre per a un subdirectori <prefix>"
msgid "only useful for debugging"
msgstr "només útil per a la depuració"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch no és compatible amb aquesta plataforma"
+
+msgid "failed to create temporary file"
+msgstr "no s'ha pogut crear un fitxer temporal"
+
+msgid "insufficient capabilities"
+msgstr "capacitats insuficients"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "no s'ha pogut baixar el paquet de l'URI «%s»"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "el fitxer a l'URI «%s» no és farcell"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "s'ha produït un error en desempaquetar el farcell de l'URI «%s»"
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
-msgstr "algoritme de hash del farcell desconegut: %s"
+msgstr "algoritme de resum del farcell desconegut: %s"
#, c-format
msgid "unknown capability '%s'"
@@ -13460,7 +13611,7 @@ msgid "final chunk has non-zero id %<PRIx32>"
msgstr "el fragment final té un id %<PRIx32> que no és zero"
msgid "invalid hash version"
-msgstr "especificació de hash no vàlida"
+msgstr "especificació de resum no vàlida"
#, c-format
msgid "invalid color value: %.*s"
@@ -13582,6 +13733,9 @@ msgid "Give an object a human readable name based on an available ref"
msgstr ""
"Dona un nom llegible per a humans basant-se en les referències disponibles"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Genera un arxiu zip d'informació de diagnòstic"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr ""
"Mostra els canvis entre comissions, la comissió i l'arbre de treball, etc"
@@ -13714,8 +13868,8 @@ msgstr "Executa una fusió per als fitxers que cal fusionar"
msgid "The standard helper program to use with git-merge-index"
msgstr "El programa d'ajuda estàndard a utilitzar amb git-merge-index"
-msgid "Show three-way merge without touching index"
-msgstr "Mostra la fusió de tres vies sense tocar l'índex"
+msgid "Perform merge without touching index or working tree"
+msgstr "Realitza la fusió sense tocar l'índex o l'arbre de treball"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr ""
@@ -13916,6 +14070,9 @@ msgstr "Valida els fitxers d'arxius Git empaquetats"
msgid "Check the GPG signature of tags"
msgstr "Verifica la signatura GPG de les etiquetes"
+msgid "Display version information about Git"
+msgstr "Mostra informació de la versió del Git"
+
msgid "Show logs with difference each commit introduces"
msgstr "Mostra registres amb la diferència introduïda per cada comissió"
@@ -13949,6 +14106,24 @@ msgstr "Un conjunt mínim útil d'ordres diàries del Git"
msgid "Frequently asked questions about using Git"
msgstr "Preguntes freqüents sobre l'ús del Git"
+msgid "The bundle file format"
+msgstr "El format del fitxer de farcell"
+
+msgid "Chunk-based file formats"
+msgstr "Formats de fitxer basats en blocs"
+
+msgid "Git commit graph format"
+msgstr "Format de graf de comissions del Git"
+
+msgid "Git index format"
+msgstr "Format de l'índex del Git"
+
+msgid "Git pack format"
+msgstr "format de paquet del Git"
+
+msgid "Git cryptographic signature formats"
+msgstr "Formats de signatura criptogràfica del Git"
+
msgid "A Git Glossary"
msgstr "Un glossari de Git"
@@ -13970,6 +14145,21 @@ msgstr "La definició de les propietats de submòduls"
msgid "Git namespaces"
msgstr "Espais de noms del Git"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Capacitats de protocol v0 i v1"
+
+msgid "Things common to various protocols"
+msgstr "Coses comunes en diversos protocols"
+
+msgid "Git HTTP-based protocols"
+msgstr "Protocols basats en HTTP del Git"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Com es transfereixen els paquets en la xarxa"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Protocol Git Wire, versió 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Programes d'ajuda per a interactuar amb repositoris remots"
@@ -13994,6 +14184,9 @@ msgstr "Interfície web del Git (interfície web pels repositoris Git)"
msgid "An overview of recommended workflows with Git"
msgstr "Una visió de conjunt de fluxos de treball recomanats amb Git"
+msgid "A tool for managing large Git repositories"
+msgstr "Una eina per a gestionar dipòsits Git grans"
+
msgid "commit-graph file is too small"
msgstr "el fitxer del graf de comissions és massa petit"
@@ -14009,7 +14202,7 @@ msgstr "la versió del graf de comissions %X no coincideix amb la versió %X"
#, c-format
msgid "commit-graph hash version %X does not match version %X"
msgstr ""
-"la versió del hash del graf de comissions %X no coincideix amb la versió %X"
+"la versió del resum del graf de comissions %X no coincideix amb la versió %X"
#, c-format
msgid "commit-graph file is too small to hold %u chunks"
@@ -14244,13 +14437,12 @@ msgstr "La comissió %s no té signatura GPG."
msgid "Commit %s has a good GPG signature by %s\n"
msgstr "La comissió %s té una signatura GPG bona de %s\n"
-#, fuzzy
msgid ""
"Warning: commit message did not conform to UTF-8.\n"
"You may want to amend it after fixing the message, or set the config\n"
"variable i18n.commitEncoding to the encoding your project uses.\n"
msgstr ""
-"Advertència: el missatge de comissió no és compatible amb UTF-8.\n"
+"Avís: el missatge de comissió no és compatible amb UTF-8.\n"
"Potser voleu esmenar-lo després de corregir el missatge, o establir\n"
"la variable de configuració i18n.commitencoding a la codificació que\n"
"usi el vostre projecte.\n"
@@ -14261,31 +14453,37 @@ msgstr "no hi ha informació disponible del compilador\n"
msgid "no libc information available\n"
msgstr "no hi ha informació disponible de libc\n"
-#, fuzzy, c-format
+#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "no s'ha pogut determinar l'espai de disc lliure per a «%s»"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "no s'ha pogut obtenir la informació per a «%s»"
+
+#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
-msgstr "no s'ha pogut commutar a «%s»"
+msgstr "[GLE %ld] el fil de salut no ha pogut obrir «%ls»"
#, c-format
msgid "[GLE %ld] health thread getting BHFI for '%ls'"
-msgstr ""
+msgstr "[GLE %ld] s'està obtenint BHFI del fil de salut per a «%ls»"
-#, fuzzy, c-format
+#, c-format
msgid "could not convert to wide characters: '%s'"
-msgstr ""
-"no s'han pogut convertir els següents «grafts»:\n"
-"%s"
+msgstr "no s'ha pogut convertir a caràcters amples: «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "BHFI changed '%ls'"
-msgstr "no es pot canviar a «%s»"
+msgstr "S'ha canviat BHFI «%ls»"
#, c-format
msgid "unhandled case in 'has_worktree_moved': %d"
-msgstr ""
+msgstr "cas no gestionat a «has_worktree_moved»: %d"
#, c-format
msgid "health thread wait failed [GLE %ld]"
-msgstr ""
+msgstr "ha fallat l'espera del fil de salut [GLE %ld]"
msgid "Unable to create FSEventStream."
msgstr "No s'ha pogut crear el FSEventStream."
@@ -14295,102 +14493,100 @@ msgstr "No s'ha pogut iniciar el FSEventStream"
#, c-format
msgid "[GLE %ld] could not convert path to UTF-8: '%.*ls'"
-msgstr ""
+msgstr "[GLE %ld] no s'ha pogut convertir el camí a UTF-8: «%.*ls»"
-#, fuzzy, c-format
+#, c-format
msgid "[GLE %ld] could not watch '%s'"
-msgstr "no s'ha pogut commutar a «%s»"
+msgstr "[GLE %ld] no s'ha pogut vigilar «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "[GLE %ld] could not get longname of '%s'"
-msgstr "no s'ha pogut commutar a «%s»"
+msgstr "[GLE %ld] no s'ha pogut obtenir el nom llarg de «%s»"
#, c-format
msgid "ReadDirectoryChangedW failed on '%s' [GLE %ld]"
-msgstr ""
+msgstr "Ha fallat ReadDirectoryChangedW a «%s» [GLE %ld]"
#, c-format
msgid "GetOverlappedResult failed on '%s' [GLE %ld]"
-msgstr ""
+msgstr "Ha fallat GetOverlappedResult a «%s» [GLE %ld]"
-#, fuzzy, c-format
+#, c-format
msgid "could not read directory changes [GLE %ld]"
-msgstr "no s'han pogut crear directoris per %s"
+msgstr "no s'han pogut llegir els canvis de directori [GLE %ld]"
-#, fuzzy, c-format
+#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] no s'ha pogut obrir per a llegir «%ls»"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] no s'ha pogut obtenir la informació del protocol per a «%ls»"
+
+#, c-format
msgid "failed to copy SID (%ld)"
-msgstr "s'ha produït un error en copiar el fitxer a «%s»"
+msgstr "no s'ha pogut copiar el SID (%ld)"
-#, fuzzy, c-format
+#, c-format
msgid "failed to get owner for '%s' (%ld)"
-msgstr "s'ha produït un error en obtenir la branca per defecte per a «%s»"
+msgstr "no s'ha pogut obtenir el propietari de «%s» (%ld)"
msgid "memory exhausted"
msgstr "memòria esgotada"
msgid "Success"
-msgstr ""
+msgstr "Èxit"
msgid "No match"
-msgstr ""
+msgstr "Cap coincidència"
-#, fuzzy
msgid "Invalid regular expression"
-msgstr "usa les expressions regulars POSIX ampliades"
+msgstr "Expressió regular no vàlida"
-#, fuzzy
msgid "Invalid collation character"
-msgstr "caràcter de llast"
+msgstr "El caràcter de col·lació no és vàlid"
-#, fuzzy
msgid "Invalid character class name"
-msgstr "hi ha caràcters no vàlids en el nom de màquina"
+msgstr "Nom de la classe del caràcter no vàlid"
msgid "Trailing backslash"
-msgstr ""
+msgstr "Barra inversa del final"
-#, fuzzy
msgid "Invalid back reference"
-msgstr "referència no vàlida: %s"
+msgstr "Referència anterior no vàlida"
msgid "Unmatched [ or [^"
-msgstr ""
+msgstr "[ or [^ no emparellat"
msgid "Unmatched ( or \\("
-msgstr ""
+msgstr "( o \\( no emparellat"
msgid "Unmatched \\{"
-msgstr ""
+msgstr "\\{ no emparellat"
-#, fuzzy
msgid "Invalid content of \\{\\}"
-msgstr "contingut no vàlid: «%s»"
+msgstr "Contingut no vàlid de \\{\\}"
-#, fuzzy
msgid "Invalid range end"
-msgstr "codificació de transferència no vàlida"
+msgstr "Fi d'interval no vàlid"
-#, fuzzy
msgid "Memory exhausted"
-msgstr "memòria esgotada"
+msgstr "Memòria esgotada"
-#, fuzzy
msgid "Invalid preceding regular expression"
-msgstr "usa les expressions regulars POSIX ampliades"
+msgstr "Expressió regular anterior no vàlida"
-#, fuzzy
msgid "Premature end of regular expression"
-msgstr "usa les expressions regulars POSIX ampliades"
+msgstr "Fi prematur d'expressió regular"
msgid "Regular expression too big"
-msgstr ""
+msgstr "Expressió regular és massa gran"
msgid "Unmatched ) or \\)"
-msgstr ""
+msgstr ") o \\) no no emparellat"
-#, fuzzy
msgid "No previous regular expression"
-msgstr "usa les expressions regulars compatibles amb Perl"
+msgstr "No hi ha expressió regular anterior"
msgid "could not send IPC command"
msgstr "no s'ha pogut enviar l'ordre IPC"
@@ -14406,21 +14602,21 @@ msgstr "no s'ha pogut començar un fil «accept_thread» «%s»"
msgid "could not start worker[0] for '%s'"
msgstr "no s'ha pogut iniciar el fil[0] per a «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "ConnectNamedPipe failed for '%s' (%lu)"
-msgstr "uname() ha fallat amb l'error «%s» (%d)\n"
+msgstr "Ha fallat ConnectNamedPipe per a «%s» (%lu)"
-#, fuzzy, c-format
+#, c-format
msgid "could not create fd from pipe for '%s'"
-msgstr "no s'han pogut crear directoris per %s"
+msgstr "no s'ha pogut crear un fd a partir de la canonada per a «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "could not start thread[0] for '%s'"
msgstr "no s'ha pogut iniciar el fil[0] per a «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "wait for hEvent failed for '%s'"
-msgstr "S'ha produït un error en autenticar per «%s»"
+msgstr "ha fallat l'espera de hEvent per a «%s»"
msgid "cannot resume in the background, please use 'fg' to resume"
msgstr "no es pot reprendre en segon pla, si us plau useu «fg» per a reprendre"
@@ -14877,185 +15073,6 @@ msgid "failed to close rev-list's stdin"
msgstr "s'ha produït un error en tancar l'stdin del rev-list"
#, c-format
-msgid "'%s' does not exist"
-msgstr "«%s» no existeix"
-
-msgid "need a working directory"
-msgstr "cal un directori de treball"
-
-msgid "could not find enlistment root"
-msgstr "no s'ha pogut trobar un arrel d'allistament"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "no s'ha pogut commutar a «%s»"
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "no s'ha pogut configurar %s=%s"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "no s'ha pogut configurar log.excludeDecoration"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "Els allistaments escalars requereixen un arbre de treball"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "no s'ha pogut obrir el directori «%s»"
-
-#, fuzzy, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "el destí «%s» no és un directori"
-
-#, fuzzy, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "no s'ha pogut crear el directori d'arbre de treball «%s»"
-
-#, fuzzy, c-format
-msgid "could not get info for '%s'"
-msgstr "no s'ha pogut llegir el fitxer de registre per a «%s»"
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "el HEAD remot no és una branca: «%.*s»"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-"no s'ha pogut obtenir el nom de la branca per defecte del remot; s'usa ela "
-"predeterminada localment"
-
-msgid "failed to get default branch name"
-msgstr "s'ha produït un error en obtenir el nom de branca predeterminada"
-
-msgid "failed to unregister repository"
-msgstr "s'ha produït un error en desregistrar el repositori"
-
-msgid "failed to delete enlistment directory"
-msgstr "s'ha produït un error en suprimir l'allistament del directori"
-
-msgid "branch to checkout after clone"
-msgstr "branca a agafar després de clonar"
-
-msgid "when cloning, create full working directory"
-msgstr "quan es clona, crear un directori de treball complet"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "només baixa les metadades per a la branca que s'agafarà"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<opcions>] [--] <repo> [<dir>]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "no es pot deduir el nom de l'arbre de treball de «%s»"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "el directori «%s» ja existeix"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "s'ha produït un error en obtenir la branca per defecte per a «%s»"
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "no s'ha pogut configurar el remot a «%s»"
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "no s'ha pogut configurar «%s»"
-
-msgid "partial clone failed; attempting full clone"
-msgstr "ha fallat la clonació parcial; s'està intentant la clonació completa"
-
-msgid "could not configure for full clone"
-msgstr "no s'ha pogut configurar per a una clonació completa"
-
-#, fuzzy
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar register [<enlistment>]"
-
-#, fuzzy, c-format
-msgid "could not create directory for '%s'"
-msgstr "No s'ha pogut crear el directori per a «%s»"
-
-#, fuzzy
-msgid "could not duplicate stdout"
-msgstr "no s'ha pogut actualitzar %s"
-
-#, fuzzy
-msgid "failed to write archive"
-msgstr "s'ha produït un error en llegir la memòria cau"
-
-msgid "`scalar list` does not take arguments"
-msgstr "«scalar list» no accepta arguments"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<enlistment>]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "reconfigura tots els allistaments registrats"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <enlistment>]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "--all o <enlistment>, però no ambdós"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "no existeix un repositori de git a: «%s»"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <task> {<enlistment>]\n"
-"Tasques:\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "no existeix la tasca: «%s»"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<enlistment>]"
-
-msgid "scalar delete <enlistment>"
-msgstr "supressió de l'escalar <enlistment>"
-
-msgid "refusing to delete current working directory"
-msgstr "s'ha rebutjat suprimir el directori de treball actual"
-
-msgid "include Git version"
-msgstr "inclou la versió del Git"
-
-msgid "include Git's build options"
-msgstr "inclou les opcions de construcció del Git"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "-C requereix un <directory>"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "no s'ha pogut canviar a «%s»"
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c requereix un argument <key>=<value>"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Ordres:\n"
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "crlf_action %d il·legal"
@@ -15068,6 +15085,8 @@ msgid ""
"in the working copy of '%s', CRLF will be replaced by LF the next time Git "
"touches it"
msgstr ""
+"a la còpia de treball de «%s», CRLF serà substituït per LF, la propera "
+"vegada que el Git ho modifiqui"
#, c-format
msgid "LF would be replaced by CRLF in %s"
@@ -15078,6 +15097,8 @@ msgid ""
"in the working copy of '%s', LF will be replaced by CRLF the next time Git "
"touches it"
msgstr ""
+"a la còpia de treball de «%s», LF serà substituït per CRLF la propera vegada "
+"que Git ho modifiqui"
#, c-format
msgid "BOM is prohibited in '%s' if encoded as %s"
@@ -15260,6 +15281,32 @@ msgstr ""
msgid "Marked %d islands, done.\n"
msgstr "Marcades %d illes, fet.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "no és vàlid --%s amb valor «%s»"
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "no s'ha pogut arxivar el directori que falta «%s»"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "no s'ha pogut obrir el directori «%s»"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "s'omet «%s», que no és ni fitxer ni directori"
+
+msgid "could not duplicate stdout"
+msgstr "no s'ha pogut duplicar stdout"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "no s'ha pogut afegir el directori «%s» a l'arxivador"
+
+msgid "failed to write archive"
+msgstr "s'ha produït un error en escriure arxiu"
+
msgid "--merge-base does not work with ranges"
msgstr "--merge-base no funciona amb intervals"
@@ -15441,7 +15488,7 @@ msgid "synonym for '-p --stat'"
msgstr "sinònim de «-p --stat»"
msgid "machine friendly --stat"
-msgstr "llegible per màquina --stat"
+msgstr "llegible per una màquina --stat"
msgid "output only the last line of --stat"
msgstr "mostra només l'última línia de --stat"
@@ -15666,7 +15713,7 @@ msgid "equivalent to --word-diff=color --word-diff-regex=<regex>"
msgstr "equivalent a --word-diff=color --word-diff-regex=<regex>"
msgid "moved lines of code are colored differently"
-msgstr "les línies de codi que s'ha mogut s'acoloreixen diferent"
+msgstr "les línies de codi que s'han mogut s'acoloreixen diferent"
msgid "how white spaces are ignored in --color-moved"
msgstr "com s'ignoren els espais en blanc a --color-moved"
@@ -15887,6 +15934,9 @@ msgstr "git fetch-pack: s'esperava ACK/NAK, s'ha rebut «%s»"
msgid "unable to write to remote"
msgstr "no s'ha pogut escriure al remot"
+msgid "Server supports filter"
+msgstr "El servidor accepta filtratge"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "línia de shallow no vàlida: %s"
@@ -15998,9 +16048,6 @@ msgstr "el servidor no és compatible amb l'algorisme «%s»"
msgid "Server does not support shallow requests"
msgstr "El servidor no permet sol·licituds superficials"
-msgid "Server supports filter"
-msgstr "El servidor accepta filtratge"
-
msgid "unable to write request to remote"
msgstr "no s'ha pogut escriure la sol·licitud al remot"
@@ -16008,9 +16055,9 @@ msgstr "no s'ha pogut escriure la sol·licitud al remot"
msgid "expected '%s', received '%s'"
msgstr "s'esperava «%s», s'ha rebut «%s»"
-#, fuzzy, c-format
+#, c-format
msgid "expected '%s'"
-msgstr "línia inesperada: «%s»"
+msgstr "s'esperava «%s»"
#, c-format
msgid "unexpected acknowledgment line: '%s'"
@@ -16082,28 +16129,29 @@ msgstr "fsmonitor--daemon no s'està executant"
msgid "could not send '%s' command to fsmonitor--daemon"
msgstr "no s'ha pogut enviar l'ordre «%s» a fsmonitor--daemon"
-#, fuzzy, c-format
+#, c-format
msgid "bare repository '%s' is incompatible with fsmonitor"
-msgstr "%s és incompatible amb %s"
+msgstr "el repositori nu «%s» és incompatible amb fsmonitor"
#, c-format
msgid "repository '%s' is incompatible with fsmonitor due to errors"
-msgstr ""
+msgstr "el repositori «%s» és incompatible amb fsmonitor a causa d'errors"
-#, fuzzy, c-format
+#, c-format
msgid "remote repository '%s' is incompatible with fsmonitor"
-msgstr "%s és incompatible amb %s"
+msgstr "el repositori remot «%s» no és compatible amb fsmonitor"
-#, fuzzy, c-format
+#, c-format
msgid "virtual repository '%s' is incompatible with fsmonitor"
-msgstr "%s és incompatible amb %s"
+msgstr "el repositori virtual «%s» és incompatible amb fsmonitor"
#, c-format
msgid ""
"repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"
msgstr ""
+"el repositori «%s» és incompatible amb fsmonitor a causa de la manca de "
+"sòcols Unix"
-#, fuzzy
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
@@ -16113,7 +16161,7 @@ msgid ""
" [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
" <command> [<args>]"
msgstr ""
-"git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
+"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"
@@ -16263,9 +16311,8 @@ msgstr "gpg.ssh.defaultKeyCommand ha fallat: %s %s"
msgid "gpg failed to sign the data"
msgstr "gpg ha fallat en signar les dades"
-#, fuzzy
msgid "user.signingKey needs to be set for ssh signing"
-msgstr "user.signingkey s'ha d'establir per a signar amb ssh"
+msgstr "user.signingKey s'ha d'establir per a signar amb ssh"
#, c-format
msgid "failed writing ssh signing key to '%s'"
@@ -16344,6 +16391,12 @@ msgstr "Ordres de baix nivell / Sincronització de repositoris"
msgid "Low-level Commands / Internal Helpers"
msgstr "Ordres de baix nivell / Ajudants interns"
+msgid "User-facing repository, command and file interfaces"
+msgstr "Repositori, ordre i interfície de fitxers que veu l'usuari"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Formats de fitxers, protocols i interfícies que veu el desenvolupador"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "ordres de git disponibles en «%s»"
@@ -16357,6 +16410,12 @@ msgstr "Aquestes són ordres habituals del Git usades en diverses situacions:"
msgid "The Git concept guides are:"
msgstr "Les guies de Git de conceptes són:"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Repositori, ordre i interfície de fitxers que veu l'usuari:"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Formats de fitxer, protocols i altres interfícies de desenvolupador:"
+
msgid "External commands"
msgstr "Ordres externes"
@@ -16441,19 +16500,15 @@ msgstr ""
"Podeu desactivar aquest avís amb «git config advice.ignoredHook false»."
#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "No s'ha pogut iniciar el lligam «%s»'\n"
-
-#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "l'argument a --packfile ha de ser un resum vàlid (s'ha obtingut «%s»)"
msgid "not a git repository"
msgstr "no és un repositori de git"
-#, fuzzy, c-format
+#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
-msgstr "valor negatiu per http.postbuffer; utilitzant el valor %d"
+msgstr "valor negatiu per http.postBuffer; utilitzant el valor %d"
msgid "Delegation control is not supported with cURL < 7.22.0"
msgstr "No s'admet el control de delegació amb el cURL < 7.22.0"
@@ -16631,21 +16686,17 @@ msgid "expected flush after ls-refs arguments"
msgstr "s'esperava una neteja després dels arguments ls-refs"
msgid "quoted CRLF detected"
-msgstr "CRLF citat detectat"
-
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Els canvis locals als fitxers següents se sobreescriuran per la fusió:\n"
-" %s"
+msgstr "CRLF entre cometes detectat"
#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "S'ha produït un error en fusionar el submòdul %s (no està agafat)"
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha fusió base)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha comissions)"
@@ -16665,28 +16716,10 @@ msgstr "S'ha produït un error en fusionar el submòdul «%s»"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
msgstr ""
"S'ha produït un error en fusionar el submòdul %s, però existeix una solució "
-"possible:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Si això és correcte simplement afegiu-ho a l'índex per exemple\n"
-"utilitzant:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s «%s»\n"
-"\n"
-"que acceptarà aquest suggeriment.\n"
+"possible: %s"
#, c-format
msgid ""
@@ -16852,13 +16885,43 @@ msgstr ""
"CONFLICTE: (modificació/supressió): %s suprimit a %s i modificat a %s. La "
"versió %s de %s s'ha deixat en l'arbre."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
+#, c-format
+msgid ""
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
+msgstr ""
+" - aneu al submòdul (%s), i fusioneu la comissió %s\n"
+" o actualitzeu-la a una comissió existent que ha fusionat aquests canvis\n"
+
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
msgstr ""
-"Nota: %s no està actualitzat i en forma de comprovar la versió en conflicte; "
-"còpia antiga reanomenada a %s"
+"La fusió recursiva amb submòduls actualment només admet casos trivials.\n"
+"Si us plau, manegeu manualment la fusió de cada submòdul en conflicte.\n"
+"Això es pot aconseguir amb els passos següents:\n"
+"%s - torneu al superprojecte i executeu:\n"
+"\n"
+" git add %s\n"
+"\n"
+" per a enregistrar la fusió o actualització de dalt\n"
+" - resoleu qualsevol altre conflicte al superprojecte\n"
+" - publiqueu l'índex resultant al superprojecte\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -16933,6 +16996,22 @@ msgid "Found a possible merge resolution for the submodule:\n"
msgstr "S'ha trobat una possible resolució de fusió pel submòdul:\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Si això és correcte simplement afegiu-ho a l'índex per exemple\n"
+"utilitzant:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s «%s»\n"
+"\n"
+"que acceptarà aquest suggeriment.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr ""
"S'ha produït un error en fusionar el submòdul %s (s'han trobat múltiples "
@@ -17123,7 +17202,8 @@ msgstr "no es reconeix la versió %d de l'índex multipaquet"
#, c-format
msgid "multi-pack-index hash version %u does not match version %u"
-msgstr "la versió del hash índex multipaquet %u no coincideix amb la versió %u"
+msgstr ""
+"la versió del resum índex multipaquet %u no coincideix amb la versió %u"
msgid "multi-pack-index missing required pack-name chunk"
msgstr "falta un fragment de nom de paquet necessari al multi-index"
@@ -17472,6 +17552,22 @@ msgid "confused by unstable object source data for %s"
msgstr "confós per la font de dades inestable de l'objecte per a %s"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "escriu l'objecte de flux %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "no s'ha pogut desinflar l'object nou (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "ha fallat deflateEnd a l'objecte del flux (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "s'ha produït un error en crear el directori %s"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "no es pot llegir l'objecte per a %s"
@@ -17507,7 +17603,7 @@ msgstr "no s'ha pogut obrir %s"
#, c-format
msgid "hash mismatch for %s (expected %s)"
-msgstr "no coincideix la suma per a %s (s'esperava %s)"
+msgstr "no coincideix el resum per a %s (s'esperava %s)"
#, c-format
msgid "unable to mmap %s"
@@ -17700,40 +17796,149 @@ msgstr "no s'ha pogut analitzar l'objecte: %s"
msgid "hash mismatch %s"
msgstr "el resum no coincideix %s"
+msgid "trying to write commit not in index"
+msgstr "s'està intentant no escriure la publicació a l'índex"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr ""
+"s'ha produït un error en carregar l'índex de mapa de bits (està malmès?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "índex de mapa de bits malmès (massa petit)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "fitxer d'índex de mapa de bits malmès (capçalera incorrecta)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "versió «%d» no admesa per al fitxer d'índex de mapa de bits"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr ""
+"fitxer d'índex de mapa de bits malmès (massa curt per a ajustar-se a la "
+"memòria cau de hash)"
+
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr ""
+"fitxer d'índex de mapa de bits malmès (massa curt per a ajustar-se a la "
+"taula de cerca)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "entrada duplicada a l'índex del mapa de bits: «%s»"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "mapa de bits ewah malmès: capçalera truncada per a l'entrada %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "mapa de bits ewah malmès: l'índex de comissió %u està fora de rang"
+
+msgid "corrupted bitmap pack index"
+msgstr "índex de paquets de mapa de bits malmès"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "el desplaçament XOR a l'índex de mapa de bits no és vàlid"
+
+msgid "cannot fstat bitmap file"
+msgstr "no es pot fer fstat en el fitxer de mapa de bits"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "s'ignorarà el fitxer extra de mapa de bits: «%s»"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "la suma de verificació no coincideix amb el MIDX i el mapa de bits"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "falta l'índex invers necessari al mapa de bits multipaquet"
-#, fuzzy, c-format
+#, c-format
msgid "could not open pack %s"
-msgstr "no s'ha pogut obrir «%s»"
+msgstr "no s'ha pogut obrir el paquet %s"
-#, fuzzy, c-format
+#, c-format
msgid "preferred pack (%s) is invalid"
-msgstr "el paquet preferit «%s» ha caducat"
+msgstr "el paquet preferit (%s) no és vàlid"
+
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr ""
+"taula de cerca de mapa de bits malmesa: posició la tripleta fora de l'índex"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr ""
+"taula de cerca de mapa de bits malmesa: la cadena xor excedeix el nombre "
+"d'entrades"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr ""
+"taula de cerca de mapa de bits malmesa: l'índex de comissió %u està fora de "
+"rang"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr ""
+"mapa de bits ewah malmès: capçalera truncada per al mapa de bits de la "
+"comissió «%s»"
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "no s'ha trobat l'objecte «%s» als tipus de mapes de bits"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "l'objecte «%s» no té un tipus únic"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "objecte «%s»: tipus real «%s», s'esperava: «%s»"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "objecte no trobat al mapa de bits: «%s»"
+
+msgid "failed to load bitmap indexes"
+msgstr "s'ha produït un error en carregar l'índex de mapa de bits"
+
+msgid "you must specify exactly one commit to test"
+msgstr "heu d'especificar exactament una comissió a provar"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "la comissió «%s» no té un mapa de bits indexat"
+
+msgid "mismatch in bitmap results"
+msgstr "no coincideix en els resultats del mapa de bits"
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "no s'ha pogut trobar %s al paquet %s al desplaçament %<PRIuMAX>"
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "no s'ha pogut trobar «%s» al paquet «%s» al desplaçament %<PRIuMAX>"
-#, fuzzy, c-format
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "no s'ha pogut obtenir l'ús del disc de «%s»"
+
+#, c-format
msgid "mtimes file %s is too small"
-msgstr "el fitxer de l'índex multipaquet %s és massa petit"
+msgstr "el fitxer mtimes %s és massa petit"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s has unknown signature"
-msgstr "el fitxer d'índex invers %s té una signatura desconeguda"
+msgstr "el fitxer mtimes %s té una signatura desconeguda"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s has unsupported version %<PRIu32>"
-msgstr "el fitxer d'índex invers %s té la versió %<PRIu32> no admesa"
+msgstr "el fitxer mtimes %s té la versió %<PRIu32> no admesa"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s has unsupported hash id %<PRIu32>"
-msgstr "el fitxer d'índex invers %s té un ID de resum %<PRIu32> no admès"
+msgstr "el fitxer mtimes %s té un ID de resum %<PRIu32> no admès"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s is corrupt"
-msgstr "el fitxer d'índex invers %s està malmès"
+msgstr "el fitxer mtimes %s està malmès"
#, c-format
msgid "reverse-index file %s is too small"
@@ -17839,6 +18044,9 @@ msgstr "voleu dir «--%s» (amb dos guionets)?"
msgid "alias of --%s"
msgstr "àlies de --%s"
+msgid "need a subcommand"
+msgstr "cal una subordre"
+
#, c-format
msgid "unknown option `%s'"
msgstr "opció desconeguda «%s»"
@@ -17991,7 +18199,7 @@ msgstr "l'especificació de camí «%s» és més enllà d'un enllaç simbòlic"
#, c-format
msgid "line is badly quoted: %s"
-msgstr "la línia està mal citada: %s"
+msgstr "la línia no està ben envoltada per cometes: %s"
msgid "unable to write flush packet"
msgstr "no s'ha pogut escriure el paquet de buidatge"
@@ -18280,9 +18488,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -18293,7 +18504,8 @@ msgstr ""
"e, edit <comissió> = usa la comissió, però atura't per a esmenar-la\n"
"s, squash <comissió> = usa la comissió, però fusiona-la a la comissió "
"prèvia\n"
-"f, fixup [-C | -c] <commit> = com a «squash», però manté només el missatge\n"
+"f, fixup [-C | -c] <comissió> = com a «squash», però manté només el "
+"missatge\n"
" de comissió previ, a menys que s'usi -C, en aquest cas\n"
" manté només el missatge d'aquesta comissió; -c és el "
"mateix\n"
@@ -18306,11 +18518,16 @@ msgstr ""
"l, label <etiqueta> = etiqueta la HEAD actual amb un nom\n"
"t, reset <etiqueta> = reinicia HEAD a una etiqueta\n"
"m, merge [-C <comissió> | -c <comissió>] <etiqueta> [# <oneline>]\n"
-". crea una comissió de fusió usant el missatge de la comissió\n"
-". de fusió original (o línia única, si no hi ha cap comissió de fusió "
+" crea una comissió de fusió usant el missatge de la comissió de fusió "
"original\n"
-". especificada). Useu -c <comissió> per a reescriure el missatge de la "
-"comissió.\n"
+" (o línia única, si no hi ha cap comissió de fusió original "
+"especificada).\n"
+" Useu -c <comissió> per a reescriure el missatge de la comissió.\n"
+"u, update-ref <ref> = segueix un marcador de posició per a actualitzar "
+"<ref>\n"
+" a aquesta posició en les comissions noves. La <ref> "
+"s'actualitza\n"
+" al final del «rebase»\n"
"\n"
"Es pot canviar l'ordre d'aquestes línies; s'executen de dalt a baix.\n"
@@ -18786,6 +19003,14 @@ msgstr "error de protocol: s'esperava sha/ref, s'ha obtingut «%s»"
msgid "http transport does not support %s"
msgstr "El transport http no admet %s"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr ""
+"s'ha produït un error de protocol: s'esperava «<url> <path>», falta espai"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "no s'ha pogut baixar el fitxer a l'URL «%s»"
+
msgid "git-http-push failed"
msgstr "git-http-push ha fallat"
@@ -18796,7 +19021,7 @@ msgid "remote-curl: error reading command stream from git"
msgstr "remote-curl: error en llegir el flux d'ordres del git"
msgid "remote-curl: fetch attempted without a local repo"
-msgstr "remote-curl: s'ha intentat l'obtenció sense un dipòsit local"
+msgstr "remote-curl: s'ha intentat l'obtenció sense un repositori local"
#, c-format
msgid "remote-curl: unknown command '%s' from git"
@@ -18813,13 +19038,13 @@ msgstr "més d'un paquet de recepció donat, usant el primer"
msgid "more than one uploadpack given, using the first"
msgstr "més d'un paquet de càrrega donat, usant el primer"
-#, fuzzy, c-format
+#, c-format
msgid "unrecognized value transfer.credentialsInUrl: '%s'"
-msgstr "patró no reconegut: «%s»"
+msgstr "valor no conegut per a transfer.credentialsInUrl: «%s»"
#, c-format
msgid "URL '%s' uses plaintext credentials"
-msgstr ""
+msgstr "L'URL «%s» utilitza credencials en text pla"
#, c-format
msgid "Cannot fetch both %s and %s to %s"
@@ -18843,12 +19068,12 @@ msgstr "el valor «%s» del patró no té «*»"
#, c-format
msgid "src refspec %s does not match any"
-msgstr "l'especificació de referència src %s no coincideix amb cap referència"
+msgstr "l'especificació de referència font %s no coincideix amb cap referència"
#, c-format
msgid "src refspec %s matches more than one"
msgstr ""
-"l'especificació de referència de src %s coincideix amb més d'una referència"
+"l'especificació de referència de font %s coincideix amb més d'una referència"
#. TRANSLATORS: "matches '%s'%" is the <dst> part of "git push
#. <remote> <src>:<dst>" push, and "being pushed ('%s')" is
@@ -19129,6 +19354,14 @@ msgstr "no s'ha pogut determinar la revisió de HEAD"
msgid "failed to find tree of %s"
msgstr "s'ha produït un error en cercar l'arbre de %s"
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo indica «%s» que manquen"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "no s'ha pogut obtenir la comissió per a l'argument d'ancestry-path %s"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<packfile> ja no s'admet"
@@ -19149,6 +19382,174 @@ msgstr "-L no és encara compatible amb formats que no siguin «-p» o «-s»"
msgid "cannot create async thread: %s"
msgstr "no s'ha pogut crear fil «async»: %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "«%s» no existeix"
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "no s'ha pogut commutar a «%s»"
+
+msgid "need a working directory"
+msgstr "cal un directori de treball"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "Els allistaments escalars requereixen un arbre de treball"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "no s'ha pogut configurar %s=%s"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "no s'ha pogut configurar log.excludeDecoration"
+
+msgid "could not add enlistment"
+msgstr "no s'ha afegit a l'allistament"
+
+msgid "could not set recommended config"
+msgstr "no s'ha pogut establir la configuració recomanada"
+
+msgid "could not turn on maintenance"
+msgstr "no s'ha pogut activar el manteniment"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "no s'ha pogut iniciar el dimoni del fsmonitor"
+
+msgid "could not turn off maintenance"
+msgstr "no s'ha pogut desactivar el manteniment"
+
+msgid "could not remove enlistment"
+msgstr "no s'ha pogut eliminar l'allistament"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "la HEAD remota no és una branca: «%.*s»"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"no s'ha pogut obtenir el nom de la branca per defecte del remot; s'usa ela "
+"predeterminada localment"
+
+msgid "failed to get default branch name"
+msgstr "s'ha produït un error en obtenir el nom de branca predeterminada"
+
+msgid "failed to unregister repository"
+msgstr "s'ha produït un error en desregistrar el repositori"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "no s'ha pogut aturar el dimoni del FSMonitor"
+
+msgid "failed to delete enlistment directory"
+msgstr "s'ha produït un error en suprimir l'allistament del directori"
+
+msgid "branch to checkout after clone"
+msgstr "branca a agafar després de clonar"
+
+msgid "when cloning, create full working directory"
+msgstr "quan es clona, crear un directori de treball complet"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "només baixa les metadades per a la branca que s'agafarà"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<opcions>] [--] <repo> [<dir>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "no es pot deduir el nom de l'arbre de treball de «%s»"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "el directori «%s» ja existeix"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "s'ha produït un error en obtenir la branca per defecte per a «%s»"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "no s'ha pogut configurar el remot a «%s»"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "no s'ha pogut configurar «%s»"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "ha fallat la clonació parcial; s'està intentant la clonació completa"
+
+msgid "could not configure for full clone"
+msgstr "no s'ha pogut configurar per a una clonació completa"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<enlistment>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "«scalar list» no accepta arguments"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<enlistment>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "reconfigura tots els allistaments registrats"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <enlistment>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all o <enlistment>, però no ambdós"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "no existeix un repositori de git a: «%s»"
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <task> {<enlistment>]\n"
+"Tasques:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "no existeix la tasca: «%s»"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<enlistment>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "supressió de l'escalar <enlistment>"
+
+msgid "refusing to delete current working directory"
+msgstr "s'ha rebutjat suprimir el directori de treball actual"
+
+msgid "include Git version"
+msgstr "inclou la versió del Git"
+
+msgid "include Git's build options"
+msgstr "inclou les opcions de construcció del Git"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C requereix un <directory>"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "no s'ha pogut canviar a «%s»"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c requereix un argument <key>=<value>"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Ordres:\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr ""
"paquet de buidatge no esperat quan estava llegint l'estat del "
@@ -19174,7 +19575,7 @@ msgstr ""
"l'empenta"
msgid "the receiving end does not support this repository's hash algorithm"
-msgstr "el receptor de destí no admet l'algorisme de hash del repositori"
+msgstr "el receptor de destí no admet l'algorisme de resum del repositori"
msgid "the receiving end does not support --signed push"
msgstr "el destí receptor no admet pujar --signed"
@@ -19273,10 +19674,6 @@ msgstr "els vostres canvis locals se sobreescriurien per %s."
msgid "commit your changes or stash them to proceed."
msgstr "cometeu els vostres canvis o feu un «stash» per a procedir."
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: avanç ràpid"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -19366,7 +19763,7 @@ msgid ""
" git commit --amend --reset-author\n"
msgstr ""
"S'han configurat el vostre nom i adreça electrònica\n"
-"automàticament basant-se en el vostre nom d'usuari i nom de màquina. \n"
+"automàticament basant-se en el vostre nom d'usuari i nom de màquina.\n"
"Comproveu que siguin correctes. Podeu suprimir aquest\n"
"missatge establint-los explícitament. Executeu l'ordre següent i\n"
"seguiu les instruccions en l'editor per a editar el vostre\n"
@@ -19391,7 +19788,7 @@ msgid ""
" git commit --amend --reset-author\n"
msgstr ""
"S'han configurat el vostre nom i adreça electrònica\n"
-"automàticament basats en el vostre nom d'usuari i nom de màquina. \n"
+"automàticament basats en el vostre nom d'usuari i nom de màquina.\n"
"Comproveu que siguin correctes. Podeu suprimir aquest\n"
"missatge establint-los explícitament:\n"
"\n"
@@ -19763,6 +20160,28 @@ msgstr "no s'ha pogut fusionar «%.*s»"
msgid "merge: Unable to write new index file"
msgstr "fusió: no s'ha pogut escriure un fitxer d'índex nou"
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr ""
+"sembla que s'està executant un altre procés «rebase»: «%s.lock» ja existeix"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"S'han actualitzat els següents refs amb %s:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"No s'han pogut actualitzar les referències següents amb %s:\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "No es pot fer un «stash» automàticament"
@@ -19930,6 +20349,10 @@ msgid "the script was already rearranged."
msgstr "l'script ja estava endreçat."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "el fitxer update-refs a «%s» no és vàlid"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "«%s» està fora del repositori a «%s»"
@@ -20051,11 +20474,19 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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'ha detectat una propietat dubtosa al repositori a «%s»\n"
+"%sPer a afegir una excepció per a aquest directori, executeu:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
+#, c-format
+msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
+msgstr "no es pot utilitzar el dipòsit nu «%s» (safe.bareRepository és «%s»)"
#, c-format
msgid ""
@@ -20132,9 +20563,8 @@ msgstr "no s'ha pogut editar «%s»"
msgid "ignoring suspicious submodule name: %s"
msgstr "s'està ignorant el nom de submòdul sospitós %s"
-#, fuzzy
msgid "negative values not allowed for submodule.fetchJobs"
-msgstr "no es permeten els valors negatius a submodule.fetchjobs"
+msgstr "no es permeten els valors negatius a submodule.fetchJobs"
#, c-format
msgid "ignoring '%s' which may be interpreted as a command-line option: %s"
@@ -20936,6 +21366,18 @@ msgstr "número de port no vàlid"
msgid "invalid '..' path segment"
msgstr "segment de camí «..» no vàlid"
+msgid "usage: "
+msgstr "ús: "
+
+msgid "fatal: "
+msgstr "fatal: "
+
+msgid "error: "
+msgstr "error: "
+
+msgid "warning: "
+msgstr "avís: "
+
msgid "Fetching objects"
msgstr "S'estan obtenint objectes"
@@ -20966,7 +21408,7 @@ msgid ".git file broken"
msgstr "fitxer .git malmès"
msgid ".git file incorrect"
-msgstr "fitxer .git malmès"
+msgstr "fitxer .git incorrecte"
msgid "not a valid path"
msgstr "no és un camí vàlid"
@@ -21668,7 +22110,7 @@ msgid ""
msgstr ""
"y - descarta aquest tros de l'arbre de treball\n"
"n - no descartis aquest tros des de l'arbre de treball\n"
-"q - surt; no apliquis aquest tros ni cap dels pendents\n"
+"q - surt; no descartis aquest tros ni cap dels pendents\n"
"a - descarta aquest tros i tots els trossos posteriors en el fitxer\n"
"d - no descartis aquest tros ni cap dels trossos posteriors en el fitxer"
@@ -21681,7 +22123,7 @@ msgid ""
msgstr ""
"y - descarta aquest tros de l'índex i de l'arbre de treball\n"
"n - no descartis aquest tros des de l'índex i de l'arbre de treball\n"
-"q - surt; no apliquis aquest tros ni cap dels pendents\n"
+"q - surt; no descartis aquest tros ni cap dels pendents\n"
"a - descarta aquest tros i tots els trossos posteriors en el fitxer\n"
"d - no descartis aquest tros ni cap dels trossos posteriors en el fitxer"
@@ -21739,22 +22181,6 @@ msgstr "Els trossos seleccionats no apliquen a l'índex\n"
msgid "ignoring unmerged: %s\n"
msgstr "s'està ignorant %s no fusionat\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "Aplica el canvi de mode a l'arbre de treball [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Aplica la supressió a l'arbre de treball [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Aplica l'addició a l'arbre de treball [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "Aplica aquest tros a l'arbre de treball [y,n,q,a,d%s,?]? "
-
msgid "No other hunks to goto\n"
msgstr "No hi ha altres trossos on anar-hi\n"
@@ -22120,13 +22546,13 @@ msgstr "no es pot enviar el missatge en 7 bits"
msgid "invalid transfer encoding"
msgstr "codificació de transferència no vàlida"
-#, fuzzy, perl-format
+#, perl-format
msgid ""
"fatal: %s: rejected by %s hook\n"
"%s\n"
"warning: no patches were sent\n"
msgstr ""
-"fatal: %s: rebutjat pel lligam sendemail-validate\n"
+"fatal: %s: rebutjat pel lligam %s\n"
"%s\n"
"avís: no s'ha enviat cap pedaç\n"
@@ -22151,302 +22577,83 @@ msgstr "S'està ometent %s amb el sufix de còpia de seguretat «%s».\n"
msgid "Do you really want to send %s? [y|N]: "
msgstr "Esteu segur que voleu enviar %s? [y|N]: "
-#~ msgid "--preserve-merges was replaced by --rebase-merges"
-#~ msgstr "--preserve-merges ha estat substituït per --rebase-merges"
-
-#, c-format
-#~ msgid ""
-#~ "CRLF will be replaced by LF in %s.\n"
-#~ "The file will have its original line endings in your working directory"
-#~ msgstr ""
-#~ "CRLF serà reemplaçat per LF en %s.\n"
-#~ "El fitxer tindrà els seus terminadors de línia originals en el vostre "
-#~ "directori de treball"
-
-#, c-format
-#~ msgid ""
-#~ "LF will be replaced by CRLF in %s.\n"
-#~ "The file will have its original line endings in your working directory"
-#~ msgstr ""
-#~ "LF serà reemplaçat per CRLF en %s.\n"
-#~ "El fitxer tindrà els seus terminadors de línia originals en el vostre "
-#~ "directori de treball"
-
-#, c-format
-#~ msgid "error reading section header '%s'"
-#~ msgstr "error en llegir la capçalera de la secció «%s»"
+#~ msgid "(stats|all)"
+#~ msgstr "(stats|all)"
-#~ msgid "load_reverse_index: could not open pack"
-#~ msgstr "load_reverse_index: no s'ha pogut obrir el paquet"
+#~ msgid "git maintenance register"
+#~ msgstr "git maintenance register"
-#, perl-format
-#~ msgid "fatal: %s: rejected by %s hook\n"
-#~ msgstr "fatal: %s: rebutjat pel lligam %s\n"
+#~ msgid "git maintenance unregister"
+#~ msgstr "git maintenance unregister"
-#~ msgid "git archive --list"
-#~ msgstr "git archive --list"
+#~ msgid "git maintenance stop"
+#~ msgstr "git maintenance stop"
#, c-format
-#~ msgid "unknown value for --diff-merges: %s"
-#~ msgstr "valor desconegut per a --diff-merges: %s"
+#~ msgid "could not parse colored hunk header '%.*s'"
+#~ msgstr "no s'ha pogut analitzar la capçalera del tros acolorida «%.*s»"
#, c-format
-#~ msgid "invalid value '%s' for lsrefs.unborn"
-#~ msgstr "valor «%s» no vàlid per a «lsrefs.unborn»"
+#~ msgid "Unknown subcommand: %s"
+#~ msgstr "Subordre desconeguda: %s"
-#~ msgid "backend for `git stash -p`"
-#~ msgstr "rerefons per a «git stash -p»"
+#~ msgid "checked out in another worktree"
+#~ msgstr "s'ha agafat en un altre arbre de treball"
-#, c-format
-#~ msgid "Invalid value for --empty: %s"
-#~ msgstr "Valor no vàlid per a --empty: %s"
+#~ msgid "failed to open stdin of 'crontab'"
+#~ msgstr "s'ha produït un error en obrir stdin de «crontab»"
#, c-format
-#~ msgid "Invalid value for --patch-format: %s"
-#~ msgstr "Valor no vàlid per a --patch-format: %s"
+#~ msgid "invalid subcommand: %s"
+#~ msgstr "subordre no vàlida: %s"
-#, c-format
-#~ msgid "Invalid value for --show-current-patch: %s"
-#~ msgstr "Valor no vàlid per --show-current-patch: %s"
+#~ msgid "single arg format must be symmetric range"
+#~ msgstr "el format de l'argument únic ha de ser de rang simètric"
-#~ msgid ""
-#~ "git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad "
-#~ "| --term-new]"
-#~ msgstr ""
-#~ "git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad "
-#~ "| --term-new]"
+#~ msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
+#~ msgstr "git submodule--helper list [--prefix=<camí>] [<camí>...]"
-#~ msgid "git bisect--helper --bisect-next"
-#~ msgstr "git bisect--helper --bisect-next"
-
-#~ msgid "git bisect--helper --bisect-visualize"
-#~ msgstr "git bisect--helper --bisect-visualize"
+#~ msgid "git submodule--helper name <path>"
+#~ msgstr "git submodule--helper name <camí>"
#, c-format
-#~ msgid "invalid color '%s' in color.blame.repeatedLines"
-#~ msgstr "color «%s» no vàlid en «color.blame.repeatedLines»"
-
-#~ msgid "invalid value for blame.coloring"
-#~ msgstr "valor no vàlid per a «blame.coloring»"
-
-#~ msgid ""
-#~ "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e "
-#~ "| -p | <type> | --textconv | --filters) [--path=<path>] <object>"
-#~ msgstr ""
-#~ "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e "
-#~ "| -p | <tipus> | --textconv | --filters [--path=<camí>]) <objecte>"
-
-#~ msgid "show object type"
-#~ msgstr "mostra el tipus de l'objecte"
-
-#~ msgid "exit with zero when there's no error"
-#~ msgstr "surt amb zero quan no hi ha error"
-
-#~ msgid "show info and content of objects fed from the standard input"
-#~ msgstr ""
-#~ "mostra la informació i contingut dels objectes rebuts de l'entrada "
-#~ "estàndard"
-
-#~ msgid "show info about objects fed from the standard input"
-#~ msgstr "mostra informació sobre els objectes rebuts de l'entrada estàndard"
-
-#~ msgid "follow in-tree symlinks (used with --batch or --batch-check)"
+#~ msgid "failed to get the default remote for submodule '%s'"
#~ msgstr ""
-#~ "segueix els enllaços simbòlics en l'arbre (s'usa amb --batch o --batch-"
-#~ "check)"
-
-#~ msgid "show all objects with --batch or --batch-check"
-#~ msgstr "mostra tots els objectes amb --batch o --batch-check"
-
-#~ msgid "do not order --batch-all-objects output"
-#~ msgstr "no ordenar la sortida de --batch-all-objects"
-
-#~ msgid "set up tracking mode (see git-pull(1))"
-#~ msgstr "configura el mode de seguiment (vegeu git-pull(1))"
-
-#~ msgid "Using both --reset-author and --author does not make sense"
-#~ msgstr "Usar ambdós --reset-author i --author no té sentit"
-
-#~ msgid "Options --squash and --fixup cannot be used together"
-#~ msgstr "Les opcions --squash i --fixup no es poden usar juntes"
-
-#~ msgid "Only one of -c/-C/-F/--fixup can be used."
-#~ msgstr "Només un de -c/-C/-F/--fixup es pot usar."
-
-#~ msgid "Option -m cannot be combined with -c/-C/-F."
-#~ msgstr "l'opció -m no es pot combinar amb -c/-C/-F/."
-
-#~ msgid ""
-#~ "Only one of --include/--only/--all/--interactive/--patch can be used."
-#~ msgstr ""
-#~ "Només un de --include/--only/--all/--interactive/--patch es pot usar."
-
-#~ msgid "git count-objects [-v] [-H | --human-readable]"
-#~ msgstr "git count-objects [-v] [-H | --human-readable]"
+#~ "s'ha produït un error en obtenir el remot per defecte pel submòdul «%s»"
#, c-format
-#~ msgid "configuration fetch.output contains invalid value %s"
-#~ msgstr "la configuració fetch.output conté un valor no vàlid %s"
+#~ msgid "Invalid update mode '%s' for submodule path '%s'"
+#~ msgstr "Mode d'actualització «%s» no vàlid per al camí de submòdul «%s»"
-#~ msgid "--cached or --untracked cannot be used with --no-index"
-#~ msgstr "--cached o --untracked no es pot usar amb --no-index"
+#~ msgid "path into the working tree, across nested submodule boundaries"
+#~ msgstr "camí a l'arbre de treball, a través de fronteres de submòduls niats"
-#~ msgid "--untracked cannot be used with --cached"
-#~ msgstr "--untracked no es pot usar amb --cached"
+#~ msgid "rebase, merge, checkout or none"
+#~ msgstr "rebase, merge, checkout o none"
-#~ msgid "git hash-object --stdin-paths"
-#~ msgstr "git hash-object --stdin-paths"
+#~ msgid "bad value for update parameter"
+#~ msgstr "valor incorrecte per al paràmetre update"
-#~ msgid "git help [-g|--guides]"
-#~ msgstr "git help [-g|--guides]"
-
-#~ msgid "git help [-c|--config]"
-#~ msgstr "git help [-c|--config]"
-
-#~ msgid "git mktag"
-#~ msgstr "git mktag"
-
-#~ msgid "git mktree [-z] [--missing] [--batch]"
-#~ msgstr "git mktree [-z] [--missing] [--batch]"
-
-#~ msgid "read from stdin"
-#~ msgstr "llegeix de stdin"
-
-#~ msgid "git notes merge --commit [-v | -q]"
-#~ msgstr "git notes merge --commit [-v | -q]"
-
-#~ msgid "git notes merge --abort [-v | -q]"
-#~ msgstr "git notes merge --abort [-v | -q]"
-
-#~ msgid "git notes get-ref"
-#~ msgstr "git notes get-ref"
-
-#~ msgid "invalid value for --missing"
-#~ msgstr "valor no vàlid per a --missing"
-
-#~ msgid "git prune-packed [-n | --dry-run] [-q | --quiet]"
-#~ msgstr "git prune-packed [-n | --dry-run] [-q | --quiet]"
-
-#, c-format
-#~ msgid "Invalid value for %s: %s"
-#~ msgstr "Valor no vàlid per a %s: %s"
+#~ msgid "Show three-way merge without touching index"
+#~ msgstr "Mostra la fusió de tres vies sense tocar l'índex"
+# c-format
#, c-format
-#~ msgid "Invalid value for pull.ff: %s"
-#~ msgstr "Valor no vàlid per a pull.ff: %s"
-
-#~ msgid "git rebase --continue | --abort | --skip | --edit-todo"
-#~ msgstr "git rebase --continue | --abort | --skip | --edit-todo"
+#~ msgid "could not create directory for '%s'"
+#~ msgstr "no s'ha pogut crear el directori per a «%s»"
#, c-format
-#~ msgid "'%s' is not a valid timestamp"
-#~ msgstr "«%s» no és una marca de temps vàlida"
-
-#~ msgid "git reflog [ show | expire | delete | exists ]"
-#~ msgstr "git reflog [ show | expire | delete | exists ]"
-
-#~ msgid "git remote [-v | --verbose]"
-#~ msgstr "git remote [-v | --verbose]"
-
-#~ msgid "git replace [-f] --convert-graft-file"
-#~ msgstr "git replace [-f] --convert-graft-file"
+#~ msgid "Couldn't start hook '%s'\n"
+#~ msgstr "No s'ha pogut iniciar el lligam «%s»'\n"
#, c-format
#~ msgid ""
-#~ "\n"
-#~ "It took %.2f seconds to enumerate unstaged changes after reset. You can\n"
-#~ "use '--quiet' to avoid this. Set the config setting reset.quiet to true\n"
-#~ "to make this the default.\n"
+#~ "Note: %s not up to date and in way of checking out conflicted version; "
+#~ "old copy renamed to %s"
#~ msgstr ""
-#~ "\n"
-#~ "S'ha trigat %.2f segons a enumerar els canvis «unstaged» després del "
-#~ "reinici.\n"
-#~ "Podeu utilitzar «--quiet» per a evitar-ho. Establiu el paràmetre de "
-#~ "configuració\n"
-#~ "reset.quiet a true per a fer que aquesta configuració sigui "
-#~ "predeterminada.\n"
-
-#~ msgid "git sparse-checkout list"
-#~ msgstr "git sparse-checkout list"
-
-#~ msgid "unable to upgrade repository format to enable worktreeConfig"
-#~ msgstr ""
-#~ "no s'ha pogut actualitzar el format del repositori per a habilitar "
-#~ "worktreeConfig"
-
-#~ msgid "git sparse-checkout init [--cone] [--[no-]sparse-index]"
-#~ msgstr "git sparse-checkout init [--cone] [--[no-]sparse-index]"
-
-#~ msgid "git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index]"
-#~ msgstr "git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index]"
-
-#~ msgid "git sparse-checkout disable"
-#~ msgstr "git sparse-checkout disable"
-
-#~ msgid ""
-#~ "the stash.useBuiltin support has been removed!\n"
-#~ "See its entry in 'git help config' for details."
-#~ msgstr ""
-#~ "s'ha eliminat l'opció stash.useBuiltin.\n"
-#~ "Per a més detalls vegeu la seva entrada a «git help config»."
-
-#~ msgid "git stripspace [-s | --strip-comments]"
-#~ msgstr "git stripspace [-s | --strip-comments]"
-
-#~ msgid "git stripspace [-c | --comment-lines]"
-#~ msgstr "git stripspace [-c | --comment-lines]"
-
-#~ msgid "submodule--helper print-default-remote takes no arguments"
-#~ msgstr "submodule--helper print-default-remote no pren cap argument"
-
-#~ msgid "git submodule--helper update-clone [--prefix=<path>] [<path>...]"
-#~ msgstr "git submodule--helper update-clone [--prefix=<camí>] [<camí>...]"
-
-#~ msgid "suppress output for update by rebase or merge"
-#~ msgstr "omet la sortida per les actualitzacions per «rebase» o fusió"
-
-#~ msgid "overrides update mode in case the repository is a fresh clone"
-#~ msgstr ""
-#~ "sobreescriu el mode d'actualització en cas que el repositori sigui un "
-#~ "clon nou"
-
-#~ msgid "depth for shallow fetch"
-#~ msgstr "profunditat per a les obtencions superficials"
+#~ "Nota: %s no està actualitzat i en forma de comprovar la versió en "
+#~ "conflicte; còpia antiga reanomenada a %s"
-#~ msgid "sha1"
-#~ msgstr "sha1"
-
-#~ msgid "SHA1 expected by superproject"
-#~ msgstr "SHA1 esperat per superproject"
-
-#~ msgid "subsha1"
-#~ msgstr "subsha1"
-
-#~ msgid "SHA1 of submodule's HEAD"
-#~ msgstr "SHA1 del HEAD del submòdul"
-
-#~ msgid "git submodule--helper run-update-procedure [<options>] <path>"
-#~ msgstr "git submodule--helper run-update-procedure [<options>] <path>"
-
-#~ msgid "git submodule--helper config --check-writeable"
-#~ msgstr "git submodule--helper config --check-writeable"
-
-#~ msgid "git update-server-info [--force]"
-#~ msgstr "git update-server-info [--force]"
-
-#~ msgid "Initialize and modify the sparse-checkout"
-#~ msgstr "Inicialitza i modifica el «sparse-checkout»"
-
-#, sh-format
-#~ msgid ""
-#~ "Unable to find current ${remote_name}/${branch} revision in submodule "
-#~ "path '$sm_path'"
-#~ msgstr ""
-#~ "No s'ha pogut trobar la revisió actual de ${remote_name}/${branch} en el "
-#~ "camí de submòdul «$sm_path»"
-
-#, sh-format
-#~ msgid "Failed to recurse into submodule path '$displaypath'"
-#~ msgstr ""
-#~ "S'ha produït un error en recórrer recursivament dins del camí de submòdul "
-#~ "«$displaypath»"
+#, c-format
+#~ msgid "%s: fast-forward"
+#~ msgstr "%s: avanç ràpid"
diff --git a/po/de.po b/po/de.po
index 76d6d3bea7c..f5c9c29e0b2 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,16 +8,16 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-21 19:57+0000\n"
-"PO-Revision-Date: 2022-06-20 21:17+0200\n"
-"Last-Translator: Matthias Rüster <matthias.ruester@gmail.com>\n"
-"Language-Team: Matthias Rüster <matthias.ruester@gmail.com>\n"
+"POT-Creation-Date: 2022-09-28 17:09+0200\n"
+"PO-Revision-Date: 2022-09-28 17:10+0200\n"
+"Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n"
+"Language-Team: German\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"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.1\n"
+"X-Generator: Poedit 3.1.1\n"
#, c-format
msgid "Huh (%s)?"
@@ -379,8 +379,8 @@ msgstr "Ergänzung im Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? "
#, c-format, perl-format
msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
msgstr ""
-"Diesen Patch-Block vom Index und Arbeitsverzeichnis verwerfen [y,n,q,a,"
-"d%s,?]? "
+"Diesen Patch-Block vom Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d"
+"%s,?]? "
msgid ""
"y - discard this hunk from index and worktree\n"
@@ -411,8 +411,8 @@ msgstr "Ergänzung auf Index und Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
#, c-format, perl-format
msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
msgstr ""
-"Diesen Patch-Block auf Index und Arbeitsverzeichnis anwenden [y,n,q,a,"
-"d%s,?]? "
+"Diesen Patch-Block auf Index und Arbeitsverzeichnis anwenden [y,n,q,a,d"
+"%s,?]? "
msgid ""
"y - apply this hunk to index and worktree\n"
@@ -428,6 +428,23 @@ msgstr ""
"a - diesen und alle weiteren Patch-Blöcke in der Datei anwenden\n"
"d - diesen oder alle weiteren Patch-Blöcke in der Datei nicht anwenden\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "Modusänderung auf Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Löschung auf Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Ergänzung auf Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr ""
+"Diesen Patch-Block auf das Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -445,10 +462,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "Konnte Block-Header '%.*s' nicht parsen."
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "Konnte farbigen Block-Header '%.*s' nicht parsen."
-
msgid "could not parse diff"
msgstr "konnte Diff nicht parsen"
@@ -506,7 +519,6 @@ msgstr ""
"Um '%c' Zeilen zu entfernen, löschen Sie diese.\n"
"Zeilen, die mit %c beginnen, werden entfernt.\n"
-#. #-#-#-#-# git-add--interactive.perl.po #-#-#-#-#
#. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
msgid ""
"If it does not apply cleanly, you will be given an opportunity to\n"
@@ -524,14 +536,12 @@ msgstr "konnte Block-Header nicht parsen"
msgid "'git apply --cached' failed"
msgstr "'git apply --cached' schlug fehl"
-#. #-#-#-#-# add-patch.c.po #-#-#-#-#
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input at this point.
#. Consider translating (saying "no" discards!) as
#. (saying "n" for "no" discards!) if the translation
#. of the word "no" does not start with n.
#.
-#. #-#-#-#-# git-add--interactive.perl.po #-#-#-#-#
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input
#. at this point.
@@ -750,6 +760,26 @@ msgstr ""
"'advice.detachedHead' auf 'false' setzen.\n"
"\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Die folgenden Pfade wurden aus der partiellen Checkout-Definition\n"
+"verschoben, sind aber aufgrund lokaler Änderungen nicht partiell.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Um den partiellen Checkout dieser Pfade zu korrigieren, gehen Sie wie folgt "
+"vor:\n"
+"* Verwenden Sie \"git add --sparse <Pfade>\", um den Index zu aktualisieren\n"
+"* Verwenden Sie \"git sparse-checkout reapply\", um die Regeln für partielle "
+"Checkouts anzuwenden"
+
msgid "cmdline ends with \\"
msgstr "Befehlszeile endet mit \\"
@@ -1272,6 +1302,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "Nicht unterstützter Dateimodus: 0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "Fehler beim Komprimieren (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "konnte '%s' Filter nicht starten"
@@ -1291,10 +1325,6 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "Pfad zu lang (%d Zeichen, SHA1: %s): %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "Fehler beim Komprimieren (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "Timestamp zu groß für dieses System: %<PRIuMAX>"
@@ -1618,12 +1648,10 @@ msgstr ""
msgid "not tracking: ambiguous information for ref '%s'"
msgstr "kein Tracking: mehrdeutige Informationen für Referenz '%s'"
-#. #-#-#-#-# branch.c.po #-#-#-#-#
#. TRANSLATORS: This is a line listing a remote with duplicate
#. refspecs in the advice message below. For RTL languages you'll
#. probably want to swap the "%s" and leading " " space around.
#.
-#. #-#-#-#-# object-name.c.po #-#-#-#-#
#. TRANSLATORS: This is line item of ambiguous object output
#. from describe_ambiguous_object() above. For RTL languages
#. you'll probably want to swap the "%s" and leading " " space
@@ -1990,8 +2018,8 @@ msgstr ""
#, c-format
msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
msgstr ""
-"Falls Sie diesen Patch auslassen möchten, führen Sie stattdessen \"%s --"
-"skip\" aus."
+"Falls Sie diesen Patch auslassen möchten, führen Sie stattdessen \"%s --skip"
+"\" aus."
#, c-format
msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
@@ -3108,8 +3136,12 @@ msgstr "libc Info: "
msgid "not run from a git repository - no hooks to show\n"
msgstr "nicht in einem Git-Repository ausgeführt - keine Hooks zum Anzeigen\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <Datei>] [-s|--suffix <Format>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <Datei>] [-s|--suffix <Format>] [--"
+"diagnose[=<Modus>]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3147,16 +3179,29 @@ msgstr ""
"Bitte überprüfen Sie den restlichen Teil des Fehlerberichts unten.\n"
"Sie können jede Zeile löschen, die Sie nicht mitteilen möchten.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "Speicherort für die Datei des Fehlerberichts angeben"
+msgid "mode"
+msgstr "Modus"
-msgid "specify a strftime format suffix for the filename"
-msgstr "Dateiendung im strftime-Format für den Dateinamen angeben"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr ""
+"ein zusätzliches Zip-Archiv mit detaillierten Diagnosen erstellen (Standard "
+"'stats')"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "einen Zielort für die Fehlerberichtsdatei(en) angeben"
+
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "ein Suffix im strftime-Format für den/die Dateinamen angeben"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "konnte vorangehende Verzeichnisse für '%s' nicht erstellen"
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "Diagnosearchiv %s kann nicht erstellt werden"
+
msgid "System Info"
msgstr "System Info"
@@ -3215,10 +3260,6 @@ msgid "Unbundling objects"
msgstr "Entpacken von Objekten"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Unbekannter Unterbefehl: %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "kann Objekt %s '%s' nicht lesen"
@@ -3296,6 +3337,9 @@ msgstr "Objektgröße anzeigen"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "-s und -t mit beschädigten Objekten erlauben"
+msgid "use mail map file"
+msgstr "\"mailmap\"-Datei verwenden"
+
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr ""
"Batch-Objekte von Standard-Eingabe (oder --batch-all-objects) angefordert"
@@ -3306,6 +3350,9 @@ msgstr "vollständige Inhalte von <Objekt> oder <Commit> anzeigen"
msgid "like --batch, but don't emit <contents>"
msgstr "wie --batch, aber keine Ausgabe von <Inhalten>"
+msgid "stdin is NUL-terminated"
+msgstr "stdin endet mit NUL"
+
msgid "read commands from stdin"
msgstr "Befehle von der Standard-Eingabe lesen"
@@ -4198,6 +4245,14 @@ msgstr ""
"Initialisiere Datei für partiellen Checkout, um nur Dateien im\n"
"Root-Verzeichnis einzubeziehen"
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr ""
+"eine URI für das Herunterladen von Bundles vor dem Abruf\n"
+"aus dem ursprünglichen Remote-Repository"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: Konnte Alternative für '%s' nicht hinzufügen: %s\n"
@@ -4257,10 +4312,10 @@ msgstr "kann %s nicht aktualisieren"
msgid "failed to initialize sparse-checkout"
msgstr "Fehler beim Initialisieren vom partiellen Checkout."
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
msgstr ""
-"Externer HEAD bezieht sich auf eine nicht existierende Referenz und kann "
-"nicht ausgecheckt werden.\n"
+"HEAD des Remote-Repositories verweist auf nicht existierende Referenz, kann "
+"nicht ausgecheckt werden"
msgid "unable to checkout working tree"
msgstr "Arbeitsverzeichnis konnte nicht ausgecheckt werden"
@@ -4284,6 +4339,13 @@ msgstr "Sie müssen ein Repository zum Klonen angeben."
msgid "options '%s' and '%s %s' cannot be used together"
msgstr "die Optionen '%s' und '%s %s' können nicht gemeinsam verwendet werden"
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri ist inkompatibel mit --depth, --shallow-since und --shallow-"
+"exclude"
+
#, c-format
msgid "repository '%s' does not exist"
msgstr "Repository '%s' existiert nicht"
@@ -4368,6 +4430,13 @@ msgstr "--local wird ignoriert"
msgid "cannot clone from filtered bundle"
msgstr "kann nicht von gefiltertem Bundle klonen"
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "konnte das Repository nicht initialisieren, überspringe Bundle-URI"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "Objekte aus Bundle-URI '%s' konnten nicht abgerufen werden"
+
msgid "remote transport reported error"
msgstr "Remoteübertragung meldete Fehler"
@@ -4489,10 +4558,6 @@ msgstr ""
msgid "Collecting commits from input"
msgstr "Sammle Commits von der Standard-Eingabe"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "Nicht erkannter Unterbefehl: %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -4856,9 +4921,6 @@ msgstr "Status im Langformat anzeigen (Standard)"
msgid "terminate entries with NUL"
msgstr "Einträge mit NUL-Zeichen abschließen"
-msgid "mode"
-msgstr "Modus"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
"unversionierte Dateien anzeigen, optionale Modi: all, normal, no. (Standard: "
@@ -5449,8 +5511,8 @@ msgstr "Markierung"
msgid "append <mark> on dirty working tree (default: \"-dirty\")"
msgstr ""
-"<Markierung> bei geändertem Arbeitsverzeichnis anhängen (Standard: \"-"
-"dirty\")"
+"<Markierung> bei geändertem Arbeitsverzeichnis anhängen (Standard: \"-dirty"
+"\")"
msgid "append <mark> on broken working tree (default: \"-broken\")"
msgstr ""
@@ -5463,6 +5525,22 @@ msgstr "Keine Namen gefunden, kann nichts beschreiben."
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "Option '%s' und Commit-Angaben können nicht gemeinsam verwendet werden"
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <Pfad>] [-s|--suffix <Format>] [--"
+"mode=<Modus>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "einen Zielort für das Diagnosearchiv angeben"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr "Dateiendung im strftime-Format für den Dateinamen angeben"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "den Inhalt des Diagnosearchivs angeben"
+
msgid "--merge-base only works with two commits"
msgstr "--merge-base funktioniert nur mit zwei Commits"
@@ -5597,13 +5675,13 @@ msgstr "Ausgaben unterdrücken; nur git_env_*() Werte als Exit-Code verwenden"
#, c-format
msgid "option `--default' expects a boolean value with `--type=bool`, not `%s`"
msgstr ""
-"Option `--default' erwartet einen booleschen Wert bei `--type=bool`, nicht "
-"`%s`"
+"Option `--default' erwartet einen booleschen Wert bei `--type=bool`, nicht `"
+"%s`"
#, c-format
msgid ""
-"option `--default' expects an unsigned long value with `--type=ulong`, not "
-"`%s`"
+"option `--default' expects an unsigned long value with `--type=ulong`, not `"
+"%s`"
msgstr ""
"Option `--default' erwartet einen vorzeichenlosen Long-Wert bei `--"
"type=ulong`, nicht `%s`"
@@ -5851,11 +5929,8 @@ msgstr "[aktuell]"
msgid "[rejected]"
msgstr "[zurückgewiesen]"
-msgid "can't fetch in current branch"
-msgstr "kann \"fetch\" im aktuellen Branch nicht ausführen"
-
-msgid "checked out in another worktree"
-msgstr "in einem anderen Arbeitsverzeichnis ausgecheckt"
+msgid "can't fetch into checked-out branch"
+msgstr "fetch kann in den ausgecheckten Branch nicht durchgeführt werden"
msgid "[tag update]"
msgstr "[Tag Aktualisierung]"
@@ -6299,6 +6374,10 @@ msgstr "%s: Ungültiger SHA1-Zeiger in Cache-Verzeichnis"
msgid "non-tree in cache-tree"
msgstr "non-tree in Cache-Verzeichnis"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s: Ungültiger sha1-Zeiger in resolve-undo"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<Optionen>] [<Objekt>...]"
@@ -6639,14 +6718,17 @@ msgstr ""
"Fehler beim Ausführen von 'crontab -l'; Ihr System unterstützt eventuell "
"'cron' nicht"
+msgid "failed to create crontab temporary file"
+msgstr "temporäre crontab Datei konnte nicht erstellt werden"
+
+msgid "failed to open temporary file"
+msgstr "temporäre Datei kann nicht geöffnet werden"
+
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr ""
"Fehler beim Ausführen von 'crontab'; Ihr System unterstützt eventuell 'cron' "
"nicht"
-msgid "failed to open stdin of 'crontab'"
-msgstr "Fehler beim Öffnen der Standard-Eingabe von 'crontab'"
-
msgid "'crontab' died"
msgstr "'crontab' abgebrochen"
@@ -6693,10 +6775,6 @@ msgstr "Repository konnte nicht zur globalen Konfiguration hinzugefügt werden"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <Unterbefehl> [<Optionen>]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "ungültiger Unterbefehl: %s"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<Optionen>] [-e] <Muster> [<Commit>...] [[--] <Pfad>...]"
@@ -6708,7 +6786,6 @@ msgstr "grep: Fehler beim Erzeugen eines Thread: %s"
msgid "invalid number of threads specified (%d) for %s"
msgstr "ungültige Anzahl von Threads (%d) für %s angegeben"
-#. #-#-#-#-# grep.c.po #-#-#-#-#
#. TRANSLATORS: %s is the configuration
#. variable for tweaking threads, currently
#. grep.threads
@@ -6871,6 +6948,9 @@ msgstr "Dateien mit Ãœbereinstimmungen im Anzeigeprogramm anzeigen"
msgid "allow calling of grep(1) (ignored by this build)"
msgstr "den Aufruf von grep(1) erlauben (von dieser Programmversion ignoriert)"
+msgid "maximum number of results per file"
+msgstr "maximale Anzahl von Ergebnissen pro Datei"
+
msgid "no pattern given"
msgstr "Kein Muster angegeben."
@@ -6962,11 +7042,21 @@ msgstr "Beschreibung des Befehls ausgeben"
msgid "print list of useful guides"
msgstr "Liste von allgemein verwendeten Anleitungen anzeigen"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr ""
+"Liste der benutzerseitigen Repository-, Befehls- und Dateischnittstellen "
+"ausgeben"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr ""
+"Liste von Dateiformaten, Protokollen und anderen Entwicklerschnittstellen "
+"ausgeben"
+
msgid "print all configuration variable names"
msgstr "alle Namen der Konfigurationsvariablen ausgeben"
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<Befehl>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<Befehl>|<Dokument>]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -7438,8 +7528,8 @@ msgstr "Ausgabe der Unterschiede unterdrücken"
msgid "show source"
msgstr "Quelle anzeigen"
-msgid "use mail map file"
-msgstr "\"mailmap\"-Datei verwenden"
+msgid "clear all previously-defined decoration filters"
+msgstr "alle zuvor definierten Dekorationsfilter löschen"
msgid "only decorate refs that match <pattern>"
msgstr "\"decorate\" nur bei Referenzen anwenden, die <Muster> entsprechen"
@@ -7698,6 +7788,11 @@ msgstr ""
msgid "percentage by which creation is weighted"
msgstr "Prozentsatz mit welchem Erzeugung gewichtet wird"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr ""
+"From: aus E-Mail Text anzeigen, auch wenn es mit der Kopfzeile der E-Mail "
+"identisch ist"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "Ungültige Identifikationszeile: %s"
@@ -7758,6 +7853,18 @@ msgstr ""
"Konnte gefolgten Remote-Branch nicht finden, bitte geben Sie <Upstream> "
"manuell an.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "ungültiges ls-files-Format: Element '%s' fängt nicht mit '(' an"
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "ungültiges ls-files-Format: Element '%s' endet nicht auf ')'"
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "ungültiges ls-files-Format: %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<Optionen>] [<Datei>...]"
@@ -7848,6 +7955,13 @@ msgid "show sparse directories in the presence of a sparse index"
msgstr "zeige partielle Verzeichnisse, wenn ein partieller Index vorhanden ist"
msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format kann nicht mit -s, -o, -k, -t, --resolve-undo, --deduplicate, --eol "
+"verwendet werden"
+
+msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url]\n"
" [--symref] [<repository> [<refs>...]]"
@@ -8070,6 +8184,40 @@ msgstr "Konnte Referenz '%s' nicht auflösen"
msgid "Merging %s with %s\n"
msgstr "Führe %s mit %s zusammen\n"
+msgid "not something we can merge"
+msgstr "nichts was wir zusammenführen können"
+
+msgid "refusing to merge unrelated histories"
+msgstr "verweigere den Merge von nicht zusammenhängenden Historien"
+
+msgid "failure to merge"
+msgstr "Fehler beim Merge"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<Optionen>] <Branch1> <Branch2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr ""
+"git merge-tree [--trivial-merge] <Basis-Tree-Objekt> <Branch1> <Branch2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "einen echten Merge anstelle eines trivialen Merge durchführen"
+
+msgid "do a trivial merge only"
+msgstr "nur einen trivialen Merge durchführen"
+
+msgid "also show informational/conflict messages"
+msgstr "auch Informations-/Konfliktmeldungen anzeigen"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "Dateinamen ohne Modi/Oids/Stufen auflisten"
+
+msgid "allow merging unrelated histories"
+msgstr "erlaube das Zusammenführen von nicht zusammenhängenden Historien"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge ist mit allen anderen Optionen inkompatibel"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<Optionen>] [<Commit>...]"
@@ -8152,9 +8300,6 @@ msgstr "--abort, aber Index und Arbeitsverzeichnis unverändert lassen"
msgid "continue the current in-progress merge"
msgstr "den sich im Gange befindlichen Merge fortsetzen"
-msgid "allow merging unrelated histories"
-msgstr "erlaube das Zusammenführen von nicht zusammenhängenden Historien"
-
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "Hooks pre-merge-commit und commit-msg umgehen"
@@ -8277,9 +8422,6 @@ msgstr "Konnte '%s' nicht schließen."
msgid "not something we can merge in %s: %s"
msgstr "nichts was wir in %s zusammenführen können: %s"
-msgid "not something we can merge"
-msgstr "nichts was wir zusammenführen können"
-
msgid "--abort expects no arguments"
msgstr "--abort akzeptiert keine Argumente"
@@ -8331,14 +8473,20 @@ msgstr "%s - nichts was wir zusammenführen können"
msgid "Can merge only exactly one commit into empty head"
msgstr "Kann nur exakt einen Commit in einem leeren Branch zusammenführen"
-msgid "refusing to merge unrelated histories"
-msgstr "verweigere den Merge von nicht zusammenhängenden Historien"
-
#, c-format
msgid "Updating %s..%s\n"
msgstr "Aktualisiere %s..%s\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Ihre lokalen Änderungen in den folgenden Dateien würden durch den Merge\n"
+"überschrieben werden:\n"
+" %s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Probiere wirklich trivialen \"in-index\"-Merge...\n"
@@ -8372,6 +8520,12 @@ msgstr ""
"Automatischer Merge abgeschlossen; halte, wie gewünscht, vor dem Commit an\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr ""
+"Wenn Sie fertig sind, wenden Sie die Änderungen aus dem Stash mit `git stash "
+"pop` an\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
msgstr "Warnung: Tag-Eingabe ungültig für fsck: %s"
@@ -8493,6 +8647,9 @@ msgstr "Prüfe Umbenennung von '%s' nach '%s'\n"
msgid "bad source"
msgstr "ungültige Quelle"
+msgid "destination exists"
+msgstr "Ziel existiert bereits"
+
msgid "can not move directory into itself"
msgstr "kann Verzeichnis nicht in sich selbst verschieben"
@@ -8508,9 +8665,6 @@ msgstr "nicht unter Versionskontrolle"
msgid "conflicted"
msgstr "in Konflikt"
-msgid "destination exists"
-msgstr "Ziel existiert bereits"
-
#, c-format
msgid "overwriting '%s'"
msgstr "überschreibe '%s'"
@@ -8524,6 +8678,9 @@ msgstr "mehrere Quellen für dasselbe Ziel"
msgid "destination directory does not exist"
msgstr "Zielverzeichnis existiert nicht"
+msgid "destination exists in the index"
+msgstr "Ziel existiert im Index"
+
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, Quelle=%s, Ziel=%s"
@@ -8889,8 +9046,8 @@ msgid "use notes from <notes-ref>"
msgstr "Notizen von <Notiz-Referenz> verwenden"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "Unbekannter Unterbefehl: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "unbekannter Unterbefehl: `%s'"
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -9826,11 +9983,16 @@ msgid "only emit output related to the second range"
msgstr "nur Ausgaben anzeigen, die sich auf den zweiten Bereich beziehen"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "kein Commit: '%s'"
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "kein Commit-Bereich: '%s'"
-msgid "single arg format must be symmetric range"
-msgstr "Format mit einfachem Argument muss symmetrischer Bereich sein."
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "kein symmetrischer Bereich: '%s'"
msgid "need two commit ranges"
msgstr "Benötige zwei Commit-Bereiche."
@@ -9988,8 +10150,8 @@ msgstr "Konnte nicht zu %s wechseln."
#, c-format
msgid ""
-"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask"
+"\"."
msgstr ""
"nicht erkannter leerer Typ '%s'; gültige Werte sind \"drop\", \"keep\", und "
"\"ask\"."
@@ -10112,6 +10274,10 @@ msgstr "behalte Commits, die leer beginnen"
msgid "move commits that begin with squash!/fixup! under -i"
msgstr "bei -i Commits verschieben, die mit squash!/fixup! beginnen"
+msgid "update branches that point to commits that are being rebased"
+msgstr ""
+"Branches aktualisieren, die auf Commits verweisen, die gerade rebased werden"
+
msgid "add exec lines after each commit of the editable list"
msgstr "exec-Zeilen nach jedem Commit der editierbaren Liste hinzufügen"
@@ -10654,6 +10820,9 @@ msgstr " neu (wird bei nächstem \"fetch\" in remotes/%s gespeichert)"
msgid " tracked"
msgstr " gefolgt"
+msgid " skipped"
+msgstr " übersprungen"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " veraltet (benutzen Sie 'git remote prune' zum Löschen)"
@@ -11335,6 +11504,10 @@ msgstr "Konnte neue Index-Datei nicht schreiben."
msgid "unable to get disk usage of %s"
msgstr "konnte Festplattennutzung von %s nicht bekommen"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "ungültiger Wert für '%s': '%s', das einzig zulässige Format ist '%s'"
+
msgid "rev-list does not support display of notes"
msgstr "rev-list unterstützt keine Anzeige von Notizen"
@@ -11361,6 +11534,9 @@ msgstr "frühzeitiges Ende der Eingabe"
msgid "no usage string given before the `--' separator"
msgstr "kein Verwendungstext vor dem `--' Separator angegeben"
+msgid "missing opt-spec before option flags"
+msgstr "fehlende opt-spec vor Optionsflags"
+
msgid "Needed a single revision"
msgstr "Benötigte einen einzelnen Commit"
@@ -12148,6 +12324,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "Vollständiger Referenzname erwartet, %s erhalten"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "Konnte kein Repository-Handle für Submodul '%s' erhalten."
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -12155,12 +12335,6 @@ msgstr ""
"Konnte Konfiguration '%s' nicht nachschlagen. Nehme an, dass dieses\n"
"Repository sein eigenes verbindliches Upstream-Repository ist."
-msgid "alternative anchor for relative paths"
-msgstr "Alternativer Anker für relative Pfade"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<Pfad>] [<Pfad>...]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "Keine URL für Submodul-Pfad '%s' in .gitmodules gefunden"
@@ -12194,8 +12368,8 @@ msgstr "Ausgaben beim Betreten eines Submodul-Befehls unterdrücken"
msgid "recurse into nested submodules"
msgstr "Rekursion in verschachtelte Submodule durchführen"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <Befehl>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <Befehl>"
#, c-format
msgid "Failed to register url for submodule path '%s'"
@@ -12219,8 +12393,8 @@ msgstr ""
msgid "suppress output for initializing a submodule"
msgstr "Ausgaben bei Initialisierung eines Submoduls unterdrücken"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<Optionen>] [<Pfad>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<Optionen>] [<Pfad>]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -12246,9 +12420,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<Pfad>...]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <Pfad>"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submodule)"
@@ -12283,8 +12454,8 @@ msgstr ""
msgid "limit the summary size"
msgstr "Größe der Zusammenfassung begrenzen"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<Optionen>] [<Commit>] [--] [<Pfad>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<Optionen>] [<Commit>] [--] [<Pfad>]"
msgid "could not fetch a revision for HEAD"
msgstr "konnte keinen Commit für HEAD holen"
@@ -12298,18 +12469,14 @@ msgid "failed to register url for submodule path '%s'"
msgstr "Fehler beim Registrieren der URL für Submodul-Pfad '%s'"
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "Fehler beim Lesen des Standard-Remote-Repositories für Submodul '%s'"
-
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "Fehler beim Aktualisieren des Remote-Repositories für Submodul '%s'"
msgid "suppress output of synchronizing submodule url"
msgstr "Ausgaben bei der Synchronisierung der Submodul-URLs unterdrücken"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<Pfad>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<Pfad>]"
#, c-format
msgid ""
@@ -12374,6 +12541,10 @@ msgstr ""
"'--reference-if-able' statt '--reference'."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "konnte kein Repository-Handle für gitdir '%s' erhalten"
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "Submodul '%s' kann Alternative nicht hinzufügen: %s"
@@ -12403,6 +12574,9 @@ msgstr "Verzeichnis ist nicht leer: '%s'"
msgid "could not get submodule directory for '%s'"
msgstr "Konnte Submodul-Verzeichnis '%s' nicht finden."
+msgid "alternative anchor for relative paths"
+msgstr "Alternativer Anker für relative Pfade"
+
msgid "where the new submodule will be cloned to"
msgstr "Pfad für neues Submodul"
@@ -12431,10 +12605,6 @@ msgstr ""
"<filter-spec>] --url <URL> --path <Pfad>"
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Ungültiger Aktualisierungsmodus '%s' für Submodul-Pfad '%s'."
-
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr ""
"Ungültiger Aktualisierungsmodus '%s' für Submodul-Pfad '%s' konfiguriert."
@@ -12509,6 +12679,10 @@ msgstr ""
"Anfordern dieses Commits ist fehlgeschlagen."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "konnte das Submodul unter dem Pfad '%s' nicht initialisieren"
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -12517,10 +12691,6 @@ msgstr ""
"zu erben, aber das Hauptprojekt befindet sich auf keinem Branch."
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "Konnte kein Repository-Handle für Submodul '%s' erhalten."
-
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "Konnte aktuellen Commit nicht in Submodul-Pfad '%s' finden"
@@ -12554,12 +12724,14 @@ msgstr "keine neuen Objekte von Remote abrufen"
msgid "path into the working tree"
msgstr "Pfad zum Arbeitsverzeichnis"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr ""
-"Pfad zum Arbeitsverzeichnis, über verschachtelte Submodul-Grenzen hinweg"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "die Aktualisierungsstrategie \"checkout\" verwenden (Standard)"
+
+msgid "use the 'merge' update strategy"
+msgstr "die Aktualisierungsstrategie 'merge' verwenden"
-msgid "rebase, merge, checkout or none"
-msgstr "rebase, merge, checkout oder none"
+msgid "use the 'rebase' update strategy"
+msgstr "die Aktualisierungsstrategie 'rebase' verwenden"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr ""
@@ -12577,6 +12749,10 @@ msgstr ""
msgid "don't print cloning progress"
msgstr "keine Fortschrittsanzeige beim Klonen"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr ""
+"klonen in ein nicht leeres Verzeichnis nicht zulassen, impliziert --init"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12588,14 +12764,11 @@ msgstr ""
"shallow] [--reference <Repository>] [--recursive] [--[no-]single-branch] "
"[--] [<Pfad>...]"
-msgid "bad value for update parameter"
-msgstr "Fehlerhafter Wert für update Parameter"
-
msgid "recurse into submodules"
msgstr "Rekursion in Submodule durchführen"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<Optionen>] [<Pfad>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<Optionen>] [<Pfad>...]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr "prüfen, ob es sicher ist, in die Datei .gitmodules zu schreiben"
@@ -12617,8 +12790,8 @@ msgstr ""
msgid "suppress output for setting url of a submodule"
msgstr "Ausgaben beim Setzen der URL eines Submoduls unterdrücken"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <Pfad> <neue URL>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <Pfad> <neue URL>"
msgid "set the default tracking branch to master"
msgstr "Standard-Tracking-Branch auf master setzen"
@@ -12626,13 +12799,11 @@ msgstr "Standard-Tracking-Branch auf master setzen"
msgid "set the default tracking branch"
msgstr "Standard-Tracking-Branch setzen"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) [<Pfad>]"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <Pfad>"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <Branch> <Pfad>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <Branch> <Pfad>"
msgid "--branch or --default required"
msgstr "Option --branch oder --default erforderlich"
@@ -12732,8 +12903,8 @@ msgstr ""
"setzt den Namen des Submoduls auf die angegebene Zeichenkette fest, statt "
"standardmäßig dessen Pfad zu nehmen"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<Optionen>] [--] <Repository> [<Pfad>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<Optionen>] [--] <Repository> [<Pfad>]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr ""
@@ -12942,6 +13113,16 @@ msgstr "Tag '%s' aktualisiert (war %s)\n"
msgid "pack exceeds maximum allowed size"
msgstr "Paket überschreitet die maximal erlaubte Größe"
+msgid "failed to write object in stream"
+msgstr "Objekt kann nicht in Stream geschrieben werden"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "Dekomprimierung gab (%d) zurück"
+
+msgid "invalid blob object from stream"
+msgstr "ungültiges Blob-Objekt aus Stream"
+
msgid "Unpacking objects"
msgstr "Entpacke Objekte"
@@ -13497,6 +13678,27 @@ msgstr "das Tree-Objekt für ein Unterverzeichnis <Präfix> schreiben"
msgid "only useful for debugging"
msgstr "nur nützlich für Fehlersuche"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch wird auf dieser Plattform nicht unterstützt"
+
+msgid "failed to create temporary file"
+msgstr "temporäre Datei kann nicht erstellt werden"
+
+msgid "insufficient capabilities"
+msgstr "unzureichende Fähigkeiten"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "Download des Bundles von URI '%s' fehlgeschlagen"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "Datei unter URI '%s' ist kein Bundle"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "Bundle von URI '%s' konnte nicht entpackt werden"
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
msgstr "unbekannter Paket-Hash-Algorithmus: %s"
@@ -13709,6 +13911,9 @@ msgstr ""
"einem Objekt einen für Menschen lesbaren Namen basierend auf\n"
"einer verfügbaren Referenz geben"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Erzeugen eines Zip-Archivs mit Diagnoseinformationen"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr ""
"Änderungen zwischen Commits, Commit und Arbeitsverzeichnis, etc. anzeigen"
@@ -13846,8 +14051,8 @@ msgstr "einen Merge für zusammenzuführende Dateien ausführen"
msgid "The standard helper program to use with git-merge-index"
msgstr "das Standard-Hilfsprogramm für die Verwendung mit git-merge-index"
-msgid "Show three-way merge without touching index"
-msgstr "3-Wege-Merge anzeigen ohne den Index zu verändern"
+msgid "Perform merge without touching index or working tree"
+msgstr "Merge ohne Berührung von Index oder Arbeitsverzeichnis durchführen"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr ""
@@ -14053,6 +14258,9 @@ msgstr "gepackte Git-Archivdateien validieren"
msgid "Check the GPG signature of tags"
msgstr "die GPG-Signatur von Tags prüfen"
+msgid "Display version information about Git"
+msgstr "Versionsinformationen über Git anzeigen"
+
msgid "Show logs with difference each commit introduces"
msgstr "Logs mit dem Unterschied, den jeder Commit einführt, anzeigen"
@@ -14087,6 +14295,24 @@ msgstr ""
msgid "Frequently asked questions about using Git"
msgstr "Häufig gestellte Fragen über die Nutzung von Git"
+msgid "The bundle file format"
+msgstr "Das Bundle-Dateiformat"
+
+msgid "Chunk-based file formats"
+msgstr "Chunk-basierte Dateiformate"
+
+msgid "Git commit graph format"
+msgstr "Git Commit Graph Format"
+
+msgid "Git index format"
+msgstr "Git-Index-Format"
+
+msgid "Git pack format"
+msgstr "Git-Pack-Format"
+
+msgid "Git cryptographic signature formats"
+msgstr "Git kryptographische Signaturformate"
+
msgid "A Git Glossary"
msgstr "ein Git-Glossar"
@@ -14108,6 +14334,21 @@ msgstr "Definition von Submodul-Eigenschaften"
msgid "Git namespaces"
msgstr "Git Namensbereiche"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Fähigkeiten des Protokolls v0 und v1"
+
+msgid "Things common to various protocols"
+msgstr "Gemeinsamkeiten zwischen verschiedenen Protokollen"
+
+msgid "Git HTTP-based protocols"
+msgstr "Git HTTP-basierte Protokolle"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Wie Pakete über die Leitung übertragen werden"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Git Wire Protokoll, Version 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Hilfsprogramme zur Interaktion mit Remote-Repositories"
@@ -14132,6 +14373,9 @@ msgstr "Git Web Interface (Web-Frontend für Git-Repositories)"
msgid "An overview of recommended workflows with Git"
msgstr "Eine Übersicht über empfohlene Arbeitsabläufe mit Git"
+msgid "A tool for managing large Git repositories"
+msgstr "Ein Werkzeug zur Verwaltung großer Git-Repositories"
+
msgid "commit-graph file is too small"
msgstr "Commit-Graph-Datei ist zu klein"
@@ -14378,6 +14622,14 @@ msgid "no libc information available\n"
msgstr "keine libc Informationen verfügbar\n"
#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "konnte freien Speicherplatz für '%s' nicht bestimmen"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "konnte keine Info für '%s' bekommen"
+
+#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
msgstr "[GLE %ld] health Thread konnte '%ls' nicht öffnen"
@@ -14432,6 +14684,14 @@ msgid "could not read directory changes [GLE %ld]"
msgstr "konnte Verzeichnisveränderungen nicht lesen [GLE %ld]"
#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] '%ls' kann nicht zum Lesen geöffnet werden"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] kann keine Protokollinformationen für '%ls' erhalten"
+
+#, c-format
msgid "failed to copy SID (%ld)"
msgstr "Fehler beim Kopieren von SID (%ld)"
@@ -14990,182 +15250,6 @@ msgid "failed to close rev-list's stdin"
msgstr "Fehler beim Schließen von rev-lists Standard-Eingabe"
#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' existiert nicht."
-
-msgid "need a working directory"
-msgstr "Arbeitsverzeichnis benötigt"
-
-msgid "could not find enlistment root"
-msgstr "konnte Root-Verzeichnis für Eintragungen nicht finden"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "konnte nicht zu '%s' wechseln"
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "konnte %s=%s nicht konfigurieren"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "konnte log.excludeDecoration nicht konfigurieren"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "Skalare Eintragungen erfordern ein Arbeitsverzeichnis"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "konnte Verzeichnis '%s' nicht öffnen"
-
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "überspringe '%s', das weder Datei noch Verzeichnis ist"
-
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "konnte freien Speicherplatz für '%s' nicht bestimmen"
-
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "konnte keine Info für '%s' bekommen"
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "externer HEAD ist kein Branch: '%.*s'"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-"Fehler beim Abfragen des Standard-Branchnamens vom Remote-Repository; nutze "
-"lokalen Standardwert"
-
-msgid "failed to get default branch name"
-msgstr "Fehler beim Abfragen des Standard-Branchnamens"
-
-msgid "failed to unregister repository"
-msgstr "Fehler beim Austragen des Repositories"
-
-msgid "failed to delete enlistment directory"
-msgstr "Fehler beim Löschen des Eintragungs-Verzeichnisses"
-
-msgid "branch to checkout after clone"
-msgstr "Branch, der nach dem Klonen ausgecheckt werden soll"
-
-msgid "when cloning, create full working directory"
-msgstr "vollständiges Arbeitsverzeichnis beim Klonen erstellen"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "lade nur Metadaten des Branches herunter, der ausgecheckt wird"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<Optionen>] [--] <Repository> [<Verzeichnis>]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "konnte Name für Arbeitsverzeichnis nicht von '%s' ableiten"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "Verzeichnis '%s' existiert bereits"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "Fehler beim Abfragen des Default-Branches für '%s'"
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "konnte Remote-Repository in '%s' nicht konfigurieren"
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "konnte '%s' nicht konfigurieren"
-
-msgid "partial clone failed; attempting full clone"
-msgstr "partielles Klonen fehlgeschlagen; versuche vollständiges Klonen"
-
-msgid "could not configure for full clone"
-msgstr "konnte nicht für vollständiges Klonen konfigurieren"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<Eintragung>]"
-
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "konnte Verzeichnis für '%s' nicht erstellen"
-
-msgid "could not duplicate stdout"
-msgstr "konnte Standard-Ausgabe nicht duplizieren"
-
-msgid "failed to write archive"
-msgstr "Schreiben des Archivs fehlgeschlagen"
-
-msgid "`scalar list` does not take arguments"
-msgstr "`scalar list` akzeptiert keine Argumente"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<Eintragung>]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "alle registrierten Eintragungen neu konfigurieren"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <Eintragung>]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "--all oder <Eintragung>, aber nicht beides"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "Git-Repository entfernt in '%s'"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <Aufgabe> [<Eintragung>]\n"
-"Aufgaben:\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "Aufgabe nicht gefunden: '%s'"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<Eintragung>]"
-
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <Eintragung>"
-
-msgid "refusing to delete current working directory"
-msgstr "Löschen des aktuellen Arbeitsverzeichnisses wurde verweigert"
-
-msgid "include Git version"
-msgstr "Git-Version einbeziehen"
-
-msgid "include Git's build options"
-msgstr "Build-Optionen von Git einbeziehen"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "-C erfordert ein <Verzeichnis>"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "konnte nicht zu '%s' wechseln"
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c benötigt ein <Schlüssel>=<Wert> Argument"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <Verzeichnis>] [-c <Schlüssel>=<Wert>] <Befehl> [<Optionen>]\n"
-"\n"
-"Befehle:\n"
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "Unerlaubte crlf_action %d"
@@ -15373,6 +15457,32 @@ msgstr ""
msgid "Marked %d islands, done.\n"
msgstr "%d Delta-Islands markiert, fertig.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "ungültiger --%s Wert '%s'"
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "fehlendes Verzeichnis '%s' konnte nicht archiviert werden"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "konnte Verzeichnis '%s' nicht öffnen"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "überspringe '%s', das weder Datei noch Verzeichnis ist"
+
+msgid "could not duplicate stdout"
+msgstr "konnte Standard-Ausgabe nicht duplizieren"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "konnte das Verzeichnis '%s' nicht zum Archivierungssystem hinzufügen"
+
+msgid "failed to write archive"
+msgstr "Schreiben des Archivs fehlgeschlagen"
+
msgid "--merge-base does not work with ranges"
msgstr "--merge-base funktioniert nicht mit Bereichen"
@@ -16004,6 +16114,9 @@ msgstr "git fetch-pack: ACK/NAK erwartet, '%s' bekommen"
msgid "unable to write to remote"
msgstr "konnte nicht zum Remote schreiben"
+msgid "Server supports filter"
+msgstr "Server unterstützt Filter"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "ungültige shallow-Zeile: %s"
@@ -16114,9 +16227,6 @@ msgstr "der Server unterstützt Algorithmus '%s' nicht"
msgid "Server does not support shallow requests"
msgstr "Server unterstützt keine shallow-Anfragen"
-msgid "Server supports filter"
-msgstr "Server unterstützt Filter"
-
msgid "unable to write request to remote"
msgstr "konnte Anfrage nicht zum Remote schreiben"
@@ -16462,6 +16572,12 @@ msgstr "Systembefehle / Repositories synchronisieren"
msgid "Low-level Commands / Internal Helpers"
msgstr "Systembefehle / Interne Hilfsbefehle"
+msgid "User-facing repository, command and file interfaces"
+msgstr "Benutzerseitige Repository-, Befehls- und Dateischnittstellen"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Dateiformate, Protokolle und andere Schnittstellen für Entwickler"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "Vorhandene Git-Befehle in '%s'"
@@ -16475,6 +16591,12 @@ msgstr "Allgemeine Git-Befehle, verwendet in verschiedenen Situationen:"
msgid "The Git concept guides are:"
msgstr "Die Git-Konzeptanleitungen sind:"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Benutzerseitige Repository-, Befehls- und Dateischnittstellen:"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Dateiformate, Protokolle und andere Entwicklerschnittstellen:"
+
msgid "External commands"
msgstr "Externe Befehle"
@@ -16561,10 +16683,6 @@ msgstr ""
"deaktivieren."
#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "Konnte Hook '%s' nicht starten\n"
-
-#, 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)"
@@ -16752,19 +16870,14 @@ msgid "quoted CRLF detected"
msgstr "angeführtes CRLF entdeckt"
#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Ihre lokalen Änderungen in den folgenden Dateien würden durch den Merge\n"
-"überschrieben werden:\n"
-" %s"
-
-#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Fehler beim Merge von Submodul %s (nicht ausgecheckt)."
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "Merge von Submodul %s fehlgeschlagen (keine Merge-Basis)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
msgstr "Fehler beim Merge von Submodul %s (Commits nicht vorhanden)."
@@ -16782,28 +16895,10 @@ msgstr "Fehler beim Zusammenführen von Submodul %s"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
msgstr ""
-"Fehler beim Zusammenführen von Submodul %s, aber es ist eine mögliche "
-"Auflösung des Merges vorhanden:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Falls das korrekt ist, fügen Sie es einfach der Staging-Area, zum Beispiel "
-"mit:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"hinzu, um diesen Vorschlag zu akzeptieren.\n"
+"Der Merge von Submodul %s ist fehlgeschlagen, aber es gibt eine mögliche "
+"Auflösung des Merges: %s"
#, c-format
msgid ""
@@ -16971,13 +17066,46 @@ msgstr ""
"KONFLIKT (ändern/löschen): %s gelöscht in %s und geändert in %s. Stand %s "
"von %s wurde im Arbeitsbereich gelassen."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
msgstr ""
-"Hinweis: %s nicht aktuell und konfliktbehaftete Version während des "
-"Auscheckens; alte Kopie zu %s umbenannt"
+" - gehen Sie zu Submodul (%s) und mergen Sie entweder Commit %s\n"
+" oder aktualisieren Sie zu einem bestehenden Commit, der diese Änderungen "
+"zusammengeführt hat\n"
+
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"Das rekursive Zusammenführen mit Submodulen unterstützt derzeit nur triviale "
+"Fälle.\n"
+"Bitte führen Sie die Zusammenführung der einzelnen konfliktbehafteten "
+"Submodule manuell durch.\n"
+"Dies kann mit den folgenden Schritten erreicht werden:\n"
+"%s - zurück zum Hauptprojekt und dann ausführen:\n"
+"\n"
+" git add %s\n"
+"\n"
+" um die obige Zusammenführung oder Aktualisierung aufzuzeichnen\n"
+" - lösen Sie alle anderen Konflikte im Hauptprojekt\n"
+" - committen Sie den resultierenden Index in das Hauptprojekt\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -17053,6 +17181,22 @@ msgid "Found a possible merge resolution for the submodule:\n"
msgstr "Mögliche Auflösung des Merges für Submodul gefunden:\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Falls das korrekt ist, fügen Sie es einfach der Staging-Area, zum Beispiel "
+"mit:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"hinzu, um diesen Vorschlag zu akzeptieren.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Fehler beim Merge von Submodul %s (mehrere Merges gefunden)"
@@ -17128,8 +17272,8 @@ msgstr ""
#, c-format
msgid ""
-"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename "
-"\"%s\"->\"%s\" in \"%s\"%s"
+"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
+"\"->\"%s\" in \"%s\"%s"
msgstr ""
"KONFLIKT (umbenennen/umbenennen): Benenne um \"%s\"->\"%s\" in Branch \"%s\" "
"und \"%s\"->\"%s\" in Branch \"%s\"%s"
@@ -17593,6 +17737,22 @@ msgid "confused by unstable object source data for %s"
msgstr "Fehler wegen instabilen Objektquelldaten für %s"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "stream-Objekt schreiben %ld!= %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "neues Objekt kann nicht aus Stream entpackt werden (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "deflateEnd auf Stream-Objekt fehlgeschlagen (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "Verzeichnis %s kann nicht erstellt werden"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "Kann Objekt für %s nicht lesen."
@@ -17657,7 +17817,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"
@@ -17666,7 +17826,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.
@@ -17682,7 +17842,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]"
@@ -17823,6 +17983,58 @@ msgstr "Konnte Objekt '%s' nicht parsen."
msgid "hash mismatch %s"
msgstr "Hash stimmt nicht mit %s überein."
+msgid "trying to write commit not in index"
+msgstr "Versuch, einen Commit zu schreiben, der nicht im Index steht"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "bitmap-Index kann nicht geladen werden (beschädigt?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "beschädigter Bitmap-Index (zu klein)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "beschädigte Bitmap-Indexdatei (falscher Header)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "nicht unterstützte Version '%d' für Bitmap-Indexdatei"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr ""
+"beschädigte Bitmap-Indexdatei (zu kurz, um in den Hash-Cache zu passen)"
+
+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)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "duplizierter Eintrag im Bitmap-Index: '%s'"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "fehlerhafte ewah-Bitmap: abgeschnittener Header für Eintrag %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "fehlerhafte ewah-Bitmap: Commit-Index %u außerhalb des Bereichs"
+
+msgid "corrupted bitmap pack index"
+msgstr "beschädigter Bitmap-Pack-Index"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "ungültiger XOR-Offset im Bitmap-Pack-Index"
+
+msgid "cannot fstat bitmap file"
+msgstr "kann Bitmap-Datei nicht lesen"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "ignoriere zusätzliche Bitmap-Datei: '%s'"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "Prüfsumme stimmt in MIDX und Bitmap nicht überein"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "Multi-Pack-Bitmap fehlt erforderlicher Reverse-Index"
@@ -17834,9 +18046,60 @@ msgstr "konnte Paket '%s' nicht öffnen"
msgid "preferred pack (%s) is invalid"
msgstr "bevorzugtes Paket (%s) ist ungültig"
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "Bitmap-Lookup-Tabelle beschädigt: Triplet-Position außerhalb des Index"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr ""
+"fehlerhafte Bitmap-Lookup-Tabelle: XOR-Kette überschreitet die Anzahl der "
+"Einträge"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr ""
+"Bitmap-Lookup-Tabelle beschädigt: Commit-Index %u außerhalb des Bereichs"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr ""
+"fehlerhafte ewah-Bitmap: abgeschnittener Header für Bitmap des Commits \"%s\""
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "Objekt '%s' nicht im Typ Bitmaps gefunden"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "das Objekt '%s' hat keinen eindeutigen Typ"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "Objekt '%s': reeller Typ '%s', erwartet: '%s'"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "Objekt nicht in Bitmap: '%s'"
+
+msgid "failed to load bitmap indexes"
+msgstr "Bitmap-Indizes konnten nicht geladen werden"
+
+msgid "you must specify exactly one commit to test"
+msgstr "Sie müssen genau einen Commit zum Testen angeben"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "Commit '%s' hat keine indizierte Bitmap"
+
+msgid "mismatch in bitmap results"
+msgstr "Unstimmigkeiten bei Bitmap-Ergebnissen"
+
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "konnte %s nicht in Paket %s bei Offset %<PRIuMAX> finden"
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "konnte '%s' in Paket '%s' bei Offset %<PRIuMAX> nicht finden"
+
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "Festplattennutzung von '%s' kann nicht abgerufen werden"
#, c-format
msgid "mtimes file %s is too small"
@@ -17963,6 +18226,9 @@ msgstr "Meinten Sie `--%s` (mit zwei Strichen)?"
msgid "alias of --%s"
msgstr "Alias für --%s"
+msgid "need a subcommand"
+msgstr "benötige einen Unterbefehl"
+
#, c-format
msgid "unknown option `%s'"
msgstr "Unbekannte Option: `%s'"
@@ -18405,9 +18671,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -18429,11 +18698,16 @@ msgstr ""
"l, label <Label> = aktuellen HEAD mit Label versehen\n"
"t, reset <Label> = HEAD zu einem Label umsetzen\n"
"m, merge [-C <Commit> | -c <Commit>] <Label> [# <eineZeile>]\n"
-". Merge-Commit mit der originalen Merge-Commit-Beschreibung erstellen\n"
-". (oder die eine Zeile, wenn keine originale Merge-Commit-"
+" Merge-Commit mit der originalen Merge-Commit-Beschreibung erstellen\n"
+" (oder die eine Zeile, wenn keine originale Merge-Commit-"
"Beschreibung\n"
-". spezifiziert ist). Benutzen Sie -c <Commit> zum Bearbeiten der\n"
-". Commit-Beschreibung.\n"
+" spezifiziert ist). Benutzen Sie -c <Commit> zum Bearbeiten der\n"
+" Commit-Beschreibung.\n"
+"u, update-ref <Referenz>= einen Platzhalter für die zu aktualisierende "
+"<Referenz>\n"
+" zu dieser Position in den neuen Commits erstellen. Die "
+"<Referenz>wird\n"
+" am Ende des Rebase aktualisiert\n"
"\n"
"Diese Zeilen können umsortiert werden; sie werden von oben nach unten\n"
"ausgeführt.\n"
@@ -18908,6 +19182,13 @@ msgstr "Protokollfehler: SHA-1/Referenz erwartet, '%s' bekommen"
msgid "http transport does not support %s"
msgstr "HTTP-Transport unterstützt nicht %s"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "Protokollfehler: erwartet '<url> <path>', fehlendes Leerzeichen"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "Datei unter URL '%s' konnte nicht heruntergeladen werden"
+
msgid "git-http-push failed"
msgstr "\"git-http-push\" fehlgeschlagen"
@@ -19258,6 +19539,14 @@ msgstr "Konnte HEAD-Commit nicht bestimmen."
msgid "failed to find tree of %s"
msgstr "Fehler beim Finden des \"Tree\"-Objektes von %s."
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo zeichnet `%s` auf, das fehlt"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "konnte kein Commit für das Argument ancestry-path %s erhalten"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<Pack-Datei> wird nicht länger unterstützt"
@@ -19278,6 +19567,174 @@ msgstr "-L unterstützt noch keine anderen Diff-Formate außer -p und -s"
msgid "cannot create async thread: %s"
msgstr "Konnte Thread für async nicht erzeugen: %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' existiert nicht."
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "konnte nicht zu '%s' wechseln"
+
+msgid "need a working directory"
+msgstr "Arbeitsverzeichnis benötigt"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "Skalare Eintragungen erfordern ein Arbeitsverzeichnis"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "konnte %s=%s nicht konfigurieren"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "konnte log.excludeDecoration nicht konfigurieren"
+
+msgid "could not add enlistment"
+msgstr "konnte keine Eintragung hinzufügen"
+
+msgid "could not set recommended config"
+msgstr "konnte die empfohlene Konfiguration nicht setzen"
+
+msgid "could not turn on maintenance"
+msgstr "konnte die Wartung nicht einschalten"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "konnte den FSMonitor-Daemon nicht starten"
+
+msgid "could not turn off maintenance"
+msgstr "konnte die Wartung nicht abschalten"
+
+msgid "could not remove enlistment"
+msgstr "konnte die Eintragung nicht aufheben"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "externer HEAD ist kein Branch: '%.*s'"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"Fehler beim Abfragen des Standard-Branchnamens vom Remote-Repository; nutze "
+"lokalen Standardwert"
+
+msgid "failed to get default branch name"
+msgstr "Fehler beim Abfragen des Standard-Branchnamens"
+
+msgid "failed to unregister repository"
+msgstr "Fehler beim Austragen des Repositories"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "der FSMonitor-Daemon konnte nicht gestoppt werden"
+
+msgid "failed to delete enlistment directory"
+msgstr "Fehler beim Löschen des Eintragungs-Verzeichnisses"
+
+msgid "branch to checkout after clone"
+msgstr "Branch, der nach dem Klonen ausgecheckt werden soll"
+
+msgid "when cloning, create full working directory"
+msgstr "vollständiges Arbeitsverzeichnis beim Klonen erstellen"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "lade nur Metadaten des Branches herunter, der ausgecheckt wird"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<Optionen>] [--] <Repository> [<Verzeichnis>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "konnte Name für Arbeitsverzeichnis nicht von '%s' ableiten"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "Verzeichnis '%s' existiert bereits"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "Fehler beim Abfragen des Default-Branches für '%s'"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "konnte Remote-Repository in '%s' nicht konfigurieren"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "konnte '%s' nicht konfigurieren"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "partielles Klonen fehlgeschlagen; versuche vollständiges Klonen"
+
+msgid "could not configure for full clone"
+msgstr "konnte nicht für vollständiges Klonen konfigurieren"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<Eintragung>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` akzeptiert keine Argumente"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<Eintragung>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "alle registrierten Eintragungen neu konfigurieren"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <Eintragung>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all oder <Eintragung>, aber nicht beides"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "Git-Repository entfernt in '%s'"
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <Aufgabe> [<Eintragung>]\n"
+"Aufgaben:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "Aufgabe nicht gefunden: '%s'"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<Eintragung>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <Eintragung>"
+
+msgid "refusing to delete current working directory"
+msgstr "Löschen des aktuellen Arbeitsverzeichnisses wurde verweigert"
+
+msgid "include Git version"
+msgstr "Git-Version einbeziehen"
+
+msgid "include Git's build options"
+msgstr "Build-Optionen von Git einbeziehen"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C erfordert ein <Verzeichnis>"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "konnte nicht zu '%s' wechseln"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c benötigt ein <Schlüssel>=<Wert> Argument"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <Verzeichnis>] [-c <Schlüssel>=<Wert>] <Befehl> [<Optionen>]\n"
+"\n"
+"Befehle:\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr "Unerwartetes Flush-Paket beim Lesen des Remote-Unpack-Status."
@@ -19403,10 +19860,6 @@ msgid "commit your changes or stash them to proceed."
msgstr ""
"Committen Sie Ihre Änderungen oder benutzen Sie \"stash\", um fortzufahren."
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: Vorspulen"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -19900,6 +20353,28 @@ msgstr "konnte nicht einmal versuchen '%.*s' zu mergen"
msgid "merge: Unable to write new index file"
msgstr "merge: Konnte neue Index-Datei nicht schreiben."
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr ""
+"ein weiterer 'rebase'-Prozess scheint zu laufen; '%s.lock' existiert bereits"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Die folgenden Referenzen wurden mit %s aktualisiert:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Die Aktualisierung der folgenden Referenzen mit %s ist fehlgeschlagen:\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "Kann automatischen Stash nicht erzeugen"
@@ -20071,6 +20546,10 @@ msgid "the script was already rearranged."
msgstr "Das Script wurde bereits umgeordnet."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "update-refs-Datei bei '%s' ist ungültig"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "'%s' liegt außerhalb des Repositories von '%s'"
@@ -20192,17 +20671,22 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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 ""
-"unsicheres Repository ('%s' gehört jemand anderem)\n"
-"Um eine Ausnahme für dieses Repository hinzuzufügen, führen Sie aus:\n"
+"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')"
+
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -21091,6 +21575,18 @@ msgstr "ungültige Portnummer"
msgid "invalid '..' path segment"
msgstr "ungültiges '..' Pfadsegment"
+msgid "usage: "
+msgstr "Verwendung: "
+
+msgid "fatal: "
+msgstr "Schwerwiegend: "
+
+msgid "error: "
+msgstr "Fehler: "
+
+msgid "warning: "
+msgstr "Warnung: "
+
msgid "Fetching objects"
msgstr "Anfordern der Objekte"
@@ -21474,8 +21970,8 @@ msgstr "Sie führen gerade \"cherry-pick\" von Commit %s aus."
msgid " (fix conflicts and run \"git cherry-pick --continue\")"
msgstr ""
-" (beheben Sie die Konflikte und führen Sie dann \"git cherry-pick --"
-"continue\" aus)"
+" (beheben Sie die Konflikte und führen Sie dann \"git cherry-pick --continue"
+"\" aus)"
msgid " (run \"git cherry-pick --continue\" to continue)"
msgstr " (Führen Sie \"git cherry-pick --continue\" aus, um weiterzumachen)"
@@ -21948,23 +22444,6 @@ msgstr ""
msgid "ignoring unmerged: %s\n"
msgstr "ignoriere nicht zusammengeführte Datei: %s\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "Modusänderung auf Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Löschung auf Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Ergänzung auf Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-"Diesen Patch-Block auf das Arbeitsverzeichnis anwenden [y,n,q,a,d%s,?]? "
-
msgid "No other hunks to goto\n"
msgstr "Keine anderen Patch-Blöcke verbleibend\n"
diff --git a/po/es.po b/po/es.po
index b2190476799..1ff5ff3911d 100644
--- a/po/es.po
+++ b/po/es.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: 2022-06-16 08:28-0600\n"
-"PO-Revision-Date: 2021-11-07 18:53-0500\n"
+"POT-Creation-Date: 2022-09-27 21:02-0600\n"
+"PO-Revision-Date: 2022-09-27 22:56-0600\n"
"Last-Translator: Alex Henrie <alexhenrie24@gmail.com>\n"
"Language-Team: CodeLabora <codelabora@gmail.com>\n"
"Language: es\n"
@@ -16,7 +16,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.0\n"
+"X-Generator: Poedit 3.1\n"
#, c-format
msgid "Huh (%s)?"
@@ -420,6 +420,22 @@ msgstr ""
"a - aplicar este fragmento y todos los posteriores en el archivo\n"
"d - no aplicar este fragmento ni ninguno de los siguientes en este archivo\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "¿Aplicar cambio de modo al árbol de trabajo [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "¿Aplicar eliminación al árbol de trabajo [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "¿Aplicar adición al árbol de trabajo [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "¿Aplicar este fragmento al árbol de trabajo [y,n,q,a,d,/%s,?]? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -437,10 +453,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "no se puede analizar hunk header '%.*s'"
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "no se puede analizar hunk header '%.*s'"
-
msgid "could not parse diff"
msgstr "no se puede analizar diff"
@@ -496,7 +508,6 @@ msgstr ""
"Para eliminar '%c' líneas, bórrelas.\n"
"Líneas comenzando con %c serán eliminadas.\n"
-#. #-#-#-#-# git-add--interactive.perl.po #-#-#-#-#
#. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
msgid ""
"If it does not apply cleanly, you will be given an opportunity to\n"
@@ -514,14 +525,12 @@ msgstr "no se puede analizar hunk header"
msgid "'git apply --cached' failed"
msgstr "falló 'git apply --cached'"
-#. #-#-#-#-# add-patch.c.po #-#-#-#-#
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input at this point.
#. Consider translating (saying "no" discards!) as
#. (saying "n" for "no" discards!) if the translation
#. of the word "no" does not start with n.
#.
-#. #-#-#-#-# git-add--interactive.perl.po #-#-#-#-#
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input
#. at this point.
@@ -731,6 +740,25 @@ msgstr ""
"false\n"
"\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Las rutas siguientes se han movido fuera de la definición\n"
+"de sparse-checkout pero no son escasas a causa de\n"
+"modificaciones locales.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Para corregir la escasez de estas rutas, haz lo siguiente:\n"
+"* Usa \"git add --sparse <rutas>\" para actualizar el índice\n"
+"* Usa \"git sparse-checkout reapply\" para aplicar las reglas de escasez"
+
msgid "cmdline ends with \\"
msgstr "cmdline termina en \\"
@@ -745,13 +773,13 @@ msgstr "opción de espacios en blanco no reconocida '%s'"
msgid "unrecognized whitespace ignore option '%s'"
msgstr "opción de ignorar espacios en blanco no reconocida '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "options '%s' and '%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '%s' y '%s' no pueden ser usados juntos"
-#, fuzzy, c-format
+#, c-format
msgid "'%s' outside a repository"
-msgstr "--3way está fuera de un repositorio"
+msgstr "'%s' fuera de un repositorio"
#, c-format
msgid "Cannot prepare timestamp regexp %s"
@@ -836,7 +864,7 @@ msgstr "parche corrupto en la línea %d"
#, c-format
msgid "new file %s depends on old contents"
-msgstr "nuevo archivo %s depende en contenidos viejos"
+msgstr "nuevo archivo %s depende de contenidos viejos"
#, c-format
msgid "deleted file %s still has contents"
@@ -844,7 +872,7 @@ msgstr "el archivo borrado %s todavía tiene contenido"
#, c-format
msgid "** warning: file %s becomes empty but is not deleted"
-msgstr "** peligro: el archivo %s está vacío pero no es borrado"
+msgstr "** advertencia: el archivo %s se volverá vacío pero no se borrará"
#, c-format
msgid "corrupt binary patch at line %d: %.*s"
@@ -1113,7 +1141,7 @@ msgid "Skipped patch '%s'."
msgstr "Parche '%s' saltado."
msgid "No valid patches in input (allow with \"--allow-empty\")"
-msgstr ""
+msgstr "No hay parches válidos en la entrada (permitir con \"--allow-empty\")"
msgid "unable to read index file"
msgstr "no es posible leer el archivo índice"
@@ -1240,7 +1268,7 @@ msgid "prepend <root> to all filenames"
msgstr "anteponer <root> a todos los nombres de archivos"
msgid "don't return error for empty patches"
-msgstr ""
+msgstr "no devolver error por parches vacíos"
#, c-format
msgid "cannot stream blob %s"
@@ -1251,6 +1279,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "modo de archivo no soportado: 0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "error al desinflar (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "no se puede comenzar filtro '%s'"
@@ -1270,21 +1302,17 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "ruta demasiada larga (%d chars, SHA1: %s): %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "error al desinflar (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "timestamp demasiado grande para este sistema: %<PRIuMAX>"
msgid "git archive [<options>] <tree-ish> [<path>...]"
-msgstr "git archive [<opciones>] <parte-del-árbol> [<ruta>...]"
+msgstr "git archive [<opciones>] <árbol-ismo> [<ruta>...]"
msgid ""
"git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]"
msgstr ""
-"git archive --remote <repo> [--exec <comando> ] [<opciones>] <parte-del-"
-"árbol> [<ruta>...]"
+"git archive --remote <repositorio> [--exec <comando> ] [<opciones>] <árbol-"
+"ismo> [<ruta>...]"
msgid "git archive --remote <repo> [--exec <cmd>] --list"
msgstr "git archive --remote <repo> [--exec <comando>] --list"
@@ -1320,17 +1348,17 @@ msgstr "Archivo no encontrado: %s"
msgid "Not a regular file: %s"
msgstr "No es un archivo regular: %s"
-#, fuzzy, c-format
+#, c-format
msgid "unclosed quote: '%s'"
-msgstr "comillas incompletas"
+msgstr "comilla sin pareja: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "missing colon: '%s'"
-msgstr "valor faltante para '%s'"
+msgstr "falta un colon: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "empty file name: '%s'"
-msgstr "mbox vacío: '%s'"
+msgstr "nombre vacío de archivo: '%s'"
msgid "fmt"
msgstr "fmt"
@@ -1350,9 +1378,8 @@ msgstr "archivo"
msgid "add untracked file to archive"
msgstr "incluir archivos sin seguimiento a la crónica"
-#, fuzzy
msgid "path:content"
-msgstr "contenido"
+msgstr "ruta:contenido"
msgid "write the archive to this file"
msgstr "escribe la crónica en este archivo"
@@ -1384,9 +1411,9 @@ msgstr "ruta para el comando git-upload-archive remoto"
msgid "Unexpected option --remote"
msgstr "Opción inesperada --remote"
-#, fuzzy, c-format
+#, c-format
msgid "the option '%s' requires '%s'"
-msgstr "opción `%s' requiere un valor"
+msgstr "la opción `%s' requiere '%s'"
msgid "Unexpected option --output"
msgstr "Opción inesperada --output"
@@ -1548,68 +1575,64 @@ msgid ""
"cannot inherit upstream tracking configuration of multiple refs when "
"rebasing is requested"
msgstr ""
+"no se puede heredar la configuración de rastreo upstream de múltiples "
+"referencias cuando se pide rebasar"
-#, fuzzy, c-format
+#, c-format
msgid "not setting branch '%s' as its own upstream"
-msgstr "La rama %s no se configura como su propio upstream."
+msgstr "no configurando la rama %s como su propio upstream"
-#, fuzzy, c-format
+#, c-format
msgid "branch '%s' set up to track '%s' by rebasing."
-msgstr ""
-"Rama '%s' configurada para hacer seguimiento a la referencia local '%s' por "
-"rebase."
+msgstr "rama '%s' configurada para rastrear '%s' por rebase."
-#, fuzzy, c-format
+#, c-format
msgid "branch '%s' set up to track '%s'."
-msgstr ""
-"Rama '%s' configurada para hacer seguimiento a la referencia local '%s'."
+msgstr "rama '%s' configurada para rastrear '%s'."
-#, fuzzy, c-format
+#, c-format
msgid "branch '%s' set up to track:"
-msgstr ""
-"Rama '%s' configurada para hacer seguimiento a la referencia local '%s'."
+msgstr "rama '%s' configurada para rastrear:"
-#, fuzzy
msgid "unable to write upstream branch configuration"
-msgstr "No es posible escribir la configuración de la rama upstream"
+msgstr "no es posible escribir la configuración de la rama upstream"
-#, fuzzy
msgid ""
"\n"
"After fixing the error cause you may try to fix up\n"
"the remote tracking information by invoking:"
msgstr ""
"\n"
-"Tras arreglar la causa del error puedes intentar arreglar\n"
-"la información del rastreo remoto invocando\n"
-"\"git branch --set-upstream-to=%s%s%s\"."
+"Tras arreglar la causa del error puedes intentar\n"
+"arreglar la información de rastreo remoto invocando:"
#, c-format
msgid "asked to inherit tracking from '%s', but no remote is set"
msgstr ""
+"se pidió heredar el rastreo de '%s', pero no se ha configurado ningún remoto"
#, c-format
msgid "asked to inherit tracking from '%s', but no merge configuration is set"
msgstr ""
+"se pidió heredar el rastreo de '%s', pero no se ha configurado ninguna "
+"configuración de fusión"
-#, fuzzy, c-format
+#, c-format
msgid "not tracking: ambiguous information for ref '%s'"
-msgstr "No rastreando: información ambigua para la referencia %s"
+msgstr "no rastreando: información ambigua para la referencia '%s'"
-#. #-#-#-#-# branch.c.po #-#-#-#-#
#. TRANSLATORS: This is a line listing a remote with duplicate
#. refspecs in the advice message below. For RTL languages you'll
#. probably want to swap the "%s" and leading " " space around.
#.
-#. #-#-#-#-# object-name.c.po #-#-#-#-#
#. TRANSLATORS: This is line item of ambiguous object output
#. from describe_ambiguous_object() above. For RTL languages
#. you'll probably want to swap the "%s" and leading " " space
#. around.
#.
-#, fuzzy, c-format
+#, c-format
msgid " %s\n"
-msgstr " %s"
+msgstr " %s\n"
#. TRANSLATORS: The second argument is a \n-delimited list of
#. duplicate refspecs, composed above.
@@ -1625,24 +1648,34 @@ msgid ""
"different remotes' fetch refspecs map into different\n"
"tracking namespaces."
msgstr ""
+"Hay múltiples remotos cuyas especificaciones de referencia de\n"
+"fetch corresponden a la referencia de rastreo remoto '%s':\n"
+"%s\n"
+"Esto es típicamente un error de configuración.\n"
+"\n"
+"Para soportar configuración de ramas que rastrean, asegura que\n"
+"las especificationes de referencia de fetch de remotos distintos\n"
+"mapeen a espacios de nombres de rastreo distintos."
-#, fuzzy, c-format
+#, c-format
msgid "'%s' is not a valid branch name"
-msgstr "'%s' no es un nombre válido de rama."
+msgstr "'%s' no es un nombre válido de rama"
-#, fuzzy, c-format
+#, c-format
msgid "a branch named '%s' already exists"
-msgstr "Una rama llamada '%s' ya existe."
+msgstr "una rama llamada '%s' ya existe"
-#, fuzzy, c-format
+#, c-format
msgid "cannot force update the branch '%s' checked out at '%s'"
-msgstr "No se puede borrar rama '%s' que cuenta con checkout en '%s'"
+msgstr ""
+"no se puede actualizar la rama '%s' a la fuerza que cuenta con checkout en "
+"'%s'"
-#, fuzzy, c-format
+#, c-format
msgid "cannot set up tracking information; starting point '%s' is not a branch"
msgstr ""
-"No se puede configurar el rastreo de información; el punto de partida '%s' "
-"no es una rama."
+"no se puede configurar la información de rastreo; el punto de partida '%s' "
+"no es una rama"
#, c-format
msgid "the requested upstream branch '%s' does not exist"
@@ -1672,27 +1705,29 @@ msgstr ""
msgid "not a valid object name: '%s'"
msgstr "nombre de objeto no válido: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "ambiguous object name: '%s'"
-msgstr "Nombre de objeto ambiguo: '%s'."
+msgstr "nombre de objeto ambiguo: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "not a valid branch point: '%s'"
-msgstr "Punto de rama no válido: '%s'."
+msgstr "punto de bifurcación no válido: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "submodule '%s': unable to find submodule"
-msgstr "submódulo '%s' tiene un índice corrupto"
+msgstr "submódulo '%s': incapaz de encontrar el submódulo"
#, c-format
msgid ""
"You may try updating the submodules using 'git checkout %s && git submodule "
"update --init'"
msgstr ""
+"Se puede intentar actualizar los submódulos usando 'git checkout %s && git "
+"submodule update --init'"
-#, fuzzy, c-format
+#, c-format
msgid "submodule '%s': cannot create branch '%s'"
-msgstr "submódulo '%s' no puede agregar alterno: %s"
+msgstr "submódulo '%s': no se puede crear la rama '%s'"
#, c-format
msgid "'%s' is already checked out at '%s'"
@@ -1850,9 +1885,10 @@ msgstr "falló al agregar archivos"
msgid "--chmod param '%s' must be either -x or +x"
msgstr "El parámetro '%s' para --chmod debe ser -x o +x"
-#, fuzzy, c-format
+#, c-format
msgid "'%s' and pathspec arguments cannot be used together"
-msgstr "-x y -X no pueden ser usadas juntas"
+msgstr ""
+"'%s' y los argumentos de especificación de ruta no pueden ser usados juntos"
#, c-format
msgid "Nothing specified, nothing added.\n"
@@ -1874,9 +1910,9 @@ msgstr "archivo índice corrompido"
msgid "bad action '%s' for '%s'"
msgstr "mala acción '%s' para '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "invalid value for '%s': '%s'"
-msgstr "valor inválido para %s: %s"
+msgstr "valor inválido para '%s': '%s'"
#, c-format
msgid "could not read '%s'"
@@ -1946,10 +1982,11 @@ msgstr "Cuando hayas resuelto este problema, ejecuta \"%s --continue\"."
msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
msgstr "Si prefieres saltar este parche, ejecuta \"%s --skip\"."
-#, fuzzy, c-format
+#, c-format
msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
msgstr ""
-"Para restaurar la rama original y detener el parcheo, ejecuta \"%s --abort\"."
+"Para registrar el parche vacío como un commit vacío, ejecuta \"%s --allow-"
+"empty\"."
#, c-format
msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -2025,13 +2062,13 @@ msgstr "no es posible escribir el archivo índice"
msgid "Dirty index: cannot apply patches (dirty: %s)"
msgstr "Ãndice sucio: no se puede aplicar parches (sucio: %s)"
-#, fuzzy, c-format
+#, c-format
msgid "Skipping: %.*s"
-msgstr "Aplicando: %.*s"
+msgstr "Saltando: %.*s"
-#, fuzzy, c-format
+#, c-format
msgid "Creating an empty commit: %.*s"
-msgstr "mantener commits redundantes, vacíos"
+msgstr "Creando un commit vacío: %.*s"
msgid "Patch is empty."
msgstr "El parche está vacío."
@@ -2050,9 +2087,8 @@ msgstr "El parche falló en %s %.*s"
msgid "Use 'git am --show-current-patch=diff' to see the failed patch"
msgstr "Usa 'git am --show-current-patch=diff' para ver el parche fallido"
-#, fuzzy
msgid "No changes - recorded it as an empty commit."
-msgstr "no se agregaron cambios al commit\n"
+msgstr "Sin cambios - se ha registrado como un commit vacío."
msgid ""
"No changes - did you forget to use 'git add'?\n"
@@ -2096,9 +2132,9 @@ msgstr ""
msgid "failed to read '%s'"
msgstr "falló al leer '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "options '%s=%s' and '%s=%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '%s=%s' y '%s=%s' no pueden ser usadas juntas"
msgid "git am [<options>] [(<mbox> | <Maildir>)...]"
msgstr "git am [<opciones>] [(<mbox> | <Directorio-de-correo>)...]"
@@ -2180,7 +2216,7 @@ msgid "show the patch being applied"
msgstr "mostrar el parche siendo aplicado"
msgid "record the empty patch as an empty commit"
-msgstr ""
+msgstr "registrar el parche vacío como un commit vacío"
msgid "lie about committer date"
msgstr "mentir sobre la fecha del committer"
@@ -2194,9 +2230,8 @@ msgstr "key-id"
msgid "GPG-sign commits"
msgstr "firmar los commits con GPG"
-#, fuzzy
msgid "how to handle empty patches"
-msgstr "mostrar el parche actual"
+msgstr "cómo manejar parches vacíos"
msgid "(internal use for git-rebase)"
msgstr "(uso interno para git-rebase)"
@@ -2366,16 +2401,16 @@ msgid "Are you sure [Y/n]? "
msgstr "¿Estás seguro [Y/n]? "
msgid "status: waiting for both good and bad commits\n"
-msgstr ""
+msgstr "estado: esperando ambos commits buenos y malos\n"
#, c-format
msgid "status: waiting for bad commit, %d good commit known\n"
msgid_plural "status: waiting for bad commit, %d good commits known\n"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "estado: esperando commit malo, %d commit bueno conocido\n"
+msgstr[1] "estado: esperando commit malo, %d commits buenos conocidos\n"
msgid "status: waiting for good commit(s), bad commit known\n"
-msgstr ""
+msgstr "estado: esperando commit bueno, commit malo conocido\n"
msgid "no terms defined"
msgstr "no hay términos definidos"
@@ -2475,13 +2510,13 @@ msgstr "ejecutando %s\n"
msgid "bisect run failed: no command provided."
msgstr "bisect falló: no se proveyó comando."
-#, fuzzy, c-format
+#, c-format
msgid "unable to verify '%s' on good revision"
-msgstr "no es posible escribir el archivo '%s' modo %o"
+msgstr "no se puede verificar '%s' en la revisión buena"
#, c-format
msgid "bogus exit code %d for good revision"
-msgstr ""
+msgstr "código de salida malogrado %d de la revisión buena"
#, c-format
msgid "bisect run failed: exit code %d from '%s' is < 0 or >= 128"
@@ -2540,9 +2575,8 @@ msgstr "saltar algunos commits para checkout"
msgid "visualize the bisection"
msgstr "visualizar bisección"
-#, fuzzy
msgid "use <cmd>... to automatically bisect"
-msgstr "use <cmd>... para aplicar bisección automática."
+msgstr "usa <cmd>... para bisecar automáticamente"
msgid "no log for BISECT_WRITE"
msgstr "no hay log para BISECT_WRITE"
@@ -2695,15 +2729,15 @@ msgstr "Blaming a líneas"
msgid "git branch [<options>] [-r | -a] [--merged] [--no-merged]"
msgstr "git branch [<opciones>] [-r | -a] [--merged] [--no-merged]"
-#, fuzzy
msgid ""
"git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-"
"point>]"
-msgstr "git branch [<opciones>] [-l] [-f] <nombre-de-rama> [<punto-inicial>]"
+msgstr ""
+"git branch [<opciones>] [-l] [-f] [--recurse-submodules] <nombre-de-rama> "
+"[<punto-de-partida>]"
-#, fuzzy
msgid "git branch [<options>] [-l] [<pattern>...]"
-msgstr "git for-each-ref [<opciones>] [<patrón>]"
+msgstr "git branch [<opciones>] [-l] [<patrón>...]"
msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..."
msgstr "git branch [<opciones>] [-r] (-d | -D) <nombre-de-rama>..."
@@ -2852,9 +2886,8 @@ msgstr "mostrar hash y tema, dar dos veces para rama upstream"
msgid "suppress informational messages"
msgstr "suprimir mensajes informativos"
-#, fuzzy
msgid "set branch tracking configuration"
-msgstr "mostrar información de la rama"
+msgstr "configurar rastreo de rama"
msgid "do not use"
msgstr "no usar"
@@ -2953,9 +2986,11 @@ msgid ""
"branch with --recurse-submodules can only be used if submodule."
"propagateBranches is enabled"
msgstr ""
+"branch con --recurse-submodules solo se puede usar si submodule."
+"propagateBranches está habilitado"
msgid "--recurse-submodules can only be used to create branches"
-msgstr ""
+msgstr "--recurse-submodules solo se puede usar para crear ramas"
msgid "branch name required"
msgstr "se necesita el nombre de la rama"
@@ -3040,9 +3075,12 @@ msgstr "información de libc: "
msgid "not run from a git repository - no hooks to show\n"
msgstr "no ejecutado desde un repositorio git - no hay hooks para mostrar\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
msgstr ""
-"git bugreport [-o|--output-directory <archivo>] [-s|--suffix <formato>]"
+"git bugreport [-o|--output-directory <archivo>] [-s|--suffix <formato>] [--"
+"diagnose[=<modo>]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3079,17 +3117,30 @@ msgstr ""
"Por favor revisa el resto del reporte abajo.\n"
"Puedes borrar cualquier línea que no desees compartir.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "especificar el destino para el archivo de reporte de bug"
+msgid "mode"
+msgstr "modo"
-msgid "specify a strftime format suffix for the filename"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
msgstr ""
-"especificar el sufijo de formato de strftime para el nombre del archivo"
+"crear una crónica zip adicional con diagnósticos detallados (por defecto "
+"'stats')"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "especificar un destino para los archivos de reporte de bug"
+
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr ""
+"especificar un sufijo de formato de strftime para los nombres de los archivos"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "no se pudo crear directorios principales para '%s'"
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "no se puede crear la crónica diagnóstica %s"
+
msgid "System Info"
msgstr "Información del sistema"
@@ -3148,83 +3199,76 @@ msgid "Unbundling objects"
msgstr "Desagrupando objetos"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Sub-comando desconocido: %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "no se puede leer el objeto %s '%s'"
msgid "flush is only for --buffer mode"
-msgstr ""
+msgstr "flush solo es para el modo --buffer"
-#, fuzzy
msgid "empty command in input"
-msgstr "comando exec vacío"
+msgstr "comando vacío en la entrada"
-#, fuzzy, c-format
+#, c-format
msgid "whitespace before command: '%s'"
-msgstr "editar mensaje antes de realizar commit"
+msgstr "espacio en blanco antes del comando: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "%s requires arguments"
-msgstr "-n requiere un argumento"
+msgstr "%s requiere argumentos"
-#, fuzzy, c-format
+#, c-format
msgid "%s takes no arguments"
-msgstr "%s no toma valores"
+msgstr "%s no toma argumentos"
-#, fuzzy, c-format
+#, c-format
msgid "unknown command: '%s'"
-msgstr "comando desconocido: %d"
+msgstr "comando desconocido: '%s'"
msgid "only one batch option may be specified"
msgstr "solo se puede especificar una opción batch"
-#, fuzzy
msgid "git cat-file <type> <object>"
-msgstr "git notes edit [<objeto>]"
+msgstr "git cat-file <tipo> <objeto>"
-#, fuzzy
msgid "git cat-file (-e | -p) <object>"
-msgstr "git notes edit [<objeto>]"
+msgstr "git cat-file (-e | -p) <objeto>"
msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>"
-msgstr ""
+msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objeto>"
-#, fuzzy
msgid ""
"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
"objects]\n"
" [--buffer] [--follow-symlinks] [--unordered]\n"
" [--textconv | --filters]"
msgstr ""
-"git cat-file (--batch[=<formato>] | --batch-check[=<formato>]) [--follow-"
-"symlinks] [--textconv | --filters]"
+"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
+"objects]\n"
+" [--buffer] [--follow-symlinks] [--unordered]\n"
+" [--textconv | --filters]"
msgid ""
"git cat-file (--textconv | --filters)\n"
" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"
msgstr ""
+"git cat-file (--textconv | --filters)\n"
+" [<revisión>:<ruta|árbol-ismo> | --path=<ruta|árbol-ismo> "
+"<revisión>]"
-#, fuzzy
msgid "Check object existence or emit object contents"
-msgstr "para objetos blob, ejecuta textconv en el contenido del objeto"
+msgstr "Comprobar la existencia de un objeto o emitir el contenido del objeto"
-#, fuzzy
msgid "check if <object> exists"
-msgstr "Revisando objetos"
+msgstr "comprobar si <objeto> existe"
-#, fuzzy
msgid "pretty-print <object> content"
-msgstr "realizar pretty-print del contenido del objeto"
+msgstr "realizar pretty-print del contenido de <objeto>"
msgid "Emit [broken] object attributes"
-msgstr ""
+msgstr "Emitir atributos de objeto [broken]"
-#, fuzzy
msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"
-msgstr "<tipo> puede ser: blob, tree, commit, tag"
+msgstr "mostrar tipo de objeto (uno de 'blob', 'tree', 'commit', 'tag' ...)"
msgid "show object size"
msgstr "mostrar el tamaño del objeto"
@@ -3232,91 +3276,91 @@ msgstr "mostrar el tamaño del objeto"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "permita que -s y -t funcionen con objetos rotos o corruptos"
+msgid "use mail map file"
+msgstr "usar archivo de mapa de correo"
+
msgid "Batch objects requested on stdin (or --batch-all-objects)"
-msgstr ""
+msgstr "Hacer batch a los objecos solicitados en stdin (o --batch-all-objects)"
msgid "show full <object> or <rev> contents"
-msgstr ""
+msgstr "mostrar el contenido completo de <objeto> o <revisión>"
msgid "like --batch, but don't emit <contents>"
-msgstr ""
+msgstr "como --batch, pero no emitir <contenido>"
+
+msgid "stdin is NUL-terminated"
+msgstr "stdin es terminada con NUL"
-#, fuzzy
msgid "read commands from stdin"
-msgstr "leer packs de stdin"
+msgstr "leer comandos de stdin"
msgid "with --batch[-check]: ignores stdin, batches all known objects"
msgstr ""
+"con --batch[-check]: ignora stdin, hace batch a todos los objetos conocidos"
msgid "Change or optimize batch output"
-msgstr ""
+msgstr "Cambia o optimiza la salida de batch"
msgid "buffer --batch output"
msgstr "salida buffer --batch"
-#, fuzzy
msgid "follow in-tree symlinks"
-msgstr "no se pudo leer el symlink %s"
+msgstr "seguir symlinks en el árbol"
-#, fuzzy
msgid "do not order objects before emitting them"
-msgstr "no se pudo leer el objeto %s para el symlink %s"
+msgstr "no ordenar objetos antes de emitirlos"
msgid ""
"Emit object (blob or tree) with conversion or filter (stand-alone, or with "
"batch)"
msgstr ""
+"Emitir objeto (blob o árbol) con conversión o filtro (independiente, o con "
+"batch)"
-#, fuzzy
msgid "run textconv on object's content"
-msgstr "para objetos blob, ejecuta textconv en el contenido del objeto"
+msgstr "ejecuta textconv en el contenido del objeto"
-#, fuzzy
msgid "run filters on object's content"
-msgstr "para objetos blob, ejecuta filters en el contenido del objeto"
+msgstr "ejecuta filtros en el contenido del objeto"
-#, fuzzy
msgid "blob|tree"
-msgstr "blob"
+msgstr "blob|árbol"
-#, fuzzy
msgid "use a <path> for (--textconv | --filters); Not with 'batch'"
-msgstr "usar una ruta específica para --textconv/--filters"
+msgstr "usar una <ruta> para (--textconv | --filters); No con 'batch'"
#, c-format
msgid "'%s=<%s>' needs '%s' or '%s'"
-msgstr ""
+msgstr "'%s=<%s>' necesita '%s' o '%s'"
-#, fuzzy
msgid "path|tree-ish"
-msgstr "árbol-ismo"
+msgstr "ruta|árbol-ismo"
-#, fuzzy, c-format
+#, c-format
msgid "'%s' requires a batch mode"
-msgstr "%s requiere un valor"
+msgstr "'%s' requiere un modo de batch"
-#, fuzzy, c-format
+#, c-format
msgid "'-%c' is incompatible with batch mode"
-msgstr "%s es incompatible con %s"
+msgstr "'-%c' es incompatible con el modo de batch"
-#, fuzzy
msgid "batch modes take no arguments"
-msgstr "esta opción no requiere argumentos"
+msgstr "los modos de batch no toman argumentos"
#, c-format
msgid "<rev> required with '%s'"
-msgstr ""
+msgstr "se requiere <revisión> con '%s'"
#, c-format
msgid "<object> required with '-%c'"
-msgstr ""
+msgstr "<objeto> requerido con '-%c'"
msgid "too many arguments"
msgstr "demasiados argumentos"
#, c-format
msgid "only two arguments allowed in <type> <object> mode, not %d"
-msgstr ""
+msgstr "solo se permiten dos argumentos en modo de <objeto> de <tipo>, no %d"
msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..."
msgstr "git check-attr [-a | --all | <attr>...] [--] <nombre-de-ruta>..."
@@ -3395,7 +3439,7 @@ msgid "check out all files in the index"
msgstr "revisar todos los archivos en el índice"
msgid "do not skip files with skip-worktree set"
-msgstr ""
+msgstr "no saltar archivos con skip-worktree configurado"
msgid "force overwrite of existing files"
msgstr "forzar sobreescritura de los archivos existentes"
@@ -3555,12 +3599,12 @@ msgid_plural ""
"\n"
"%s\n"
msgstr[0] ""
-"Peligro: estás dejando %d commit atrás, no está conectado\n"
+"Advertencia: estás dejando %d commit atrás, no está conectado\n"
"a ninguna rama:\n"
"\n"
"%s\n"
msgstr[1] ""
-"Peligro: estás dejando %d commits atrás, no están conectados\n"
+"Advertencia: estás dejando %d commits atrás, no están conectados\n"
"a ninguna rama:\n"
"\n"
"%s\n"
@@ -3618,7 +3662,7 @@ msgid ""
"one remote, e.g. the 'origin' remote, consider setting\n"
"checkout.defaultRemote=origin in your config."
msgstr ""
-"Si querías hacer un check out a una rama rastreada remota, como 'origin',\n"
+"Si querías hacer un check out a una rama remota rastreada, como 'origin',\n"
"puedes hacerlo proporcionando el nombre completo con la opción --track:\n"
"\n"
" git checkout --track origin/<nombre>\n"
@@ -3665,6 +3709,8 @@ msgstr "se espera una rama, se obtuvo commit '%s'"
msgid ""
"If you want to detach HEAD at the commit, try again with the --detach option."
msgstr ""
+"Si quieres desacoplar HEAD al commit, intenta de nuevo con la opción --"
+"detach."
msgid ""
"cannot switch branch while merging\n"
@@ -3732,9 +3778,8 @@ msgstr "realizar una fusión de tres vías con la rama nueva"
msgid "style"
msgstr "estilo"
-#, fuzzy
msgid "conflict style (merge, diff3, or zdiff3)"
-msgstr "estilo de conflictos (merge o diff3)"
+msgstr "estilo de conflictos (merge, diff3 o zdiff3)"
msgid "detach HEAD at named commit"
msgstr "desacoplar HEAD en el commit nombrado"
@@ -3763,9 +3808,9 @@ msgstr "hacer checkout a su versión para los archivos sin fusionar"
msgid "do not limit pathspecs to sparse entries only"
msgstr "no limitar pathspecs a entradas escasas solamente"
-#, fuzzy, c-format
+#, c-format
msgid "options '-%c', '-%c', and '%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '-%c', '-%c' y '%s' no pueden ser usadas juntas"
msgid "--track needs a branch name"
msgstr "--track necesita el nombre de una rama"
@@ -3873,13 +3918,11 @@ msgstr "falló al borrar %s"
msgid "could not lstat %s\n"
msgstr "no se pudo lstat %s\n"
-#, fuzzy
msgid "Refusing to remove current working directory\n"
-msgstr "no es posible obtener el directorio de trabajo actual"
+msgstr "Rehusando eliminar el directorio de trabajo actual\n"
-#, fuzzy
msgid "Would refuse to remove current working directory\n"
-msgstr "no es posible obtener el directorio de trabajo actual"
+msgstr "Se rehusaría eliminar el directorio de trabajo actual\n"
#, c-format
msgid ""
@@ -3923,7 +3966,7 @@ msgstr "Ingresa los patrones que ignorar>> "
#, c-format
msgid "WARNING: Cannot find items matched by: %s"
-msgstr "PELIGRO: No se puede encontrar objetos que concuerden con: %s"
+msgstr "ADVERTENCIA: No se puede encontrar objetos que concuerden con: %s"
msgid "Select items to delete"
msgstr "Seleccionar objetos para borrar"
@@ -4108,7 +4151,7 @@ msgid "use IPv6 addresses only"
msgstr "solo usar direcciones IPv6"
msgid "apply partial clone filters to submodules"
-msgstr ""
+msgstr "aplicar filtros de clonación parcial a los submódulos"
msgid "any cloned submodules will use their remote-tracking branch"
msgstr "cualquier submódulo clonado usará su branch de rastreo remoto"
@@ -4117,6 +4160,13 @@ msgid "initialize sparse-checkout file to include only files at root"
msgstr ""
"inicializar archivo sparse-checkout para incluir solo archivos en la raíz"
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr ""
+"un URI para descargar bundles antes de hacer fetch del remoto de origen"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: No se pudo agregar un alterno para '%s': %s\n"
@@ -4176,9 +4226,10 @@ msgstr "incapaz de actualizar %s"
msgid "failed to initialize sparse-checkout"
msgstr "falló al inicializar sparse-checkout"
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
msgstr ""
-"remoto HEAD refiere a un ref inexistente, no se puede hacer checkout.\n"
+"la HEAD remota refiere a una referencia inexistente, no se puede hacer "
+"checkout"
msgid "unable to checkout working tree"
msgstr "no es posible realizar checkout en el árbol de trabajo"
@@ -4198,9 +4249,15 @@ msgstr "Demasiados argumentos."
msgid "You must specify a repository to clone."
msgstr "Tienes que especificar un repositorio para clonar."
-#, fuzzy, c-format
+#, c-format
msgid "options '%s' and '%s %s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '%s' y '%s %s' no pueden ser usadas juntas"
+
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri es incompatible con --depth, --shallow-since y --shallow-exclude"
#, c-format
msgid "repository '%s' does not exist"
@@ -4274,7 +4331,14 @@ msgid "--local is ignored"
msgstr "--local es ignorado"
msgid "cannot clone from filtered bundle"
-msgstr ""
+msgstr "no se puede clonar de un bundle filtrado"
+
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "falló al inicializar el repositorio, saltando el URI de bundle"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "falló al hacer fetch de objetos del URI de bundle '%s'"
msgid "remote transport reported error"
msgstr "transporte remoto reportó error"
@@ -4389,10 +4453,6 @@ msgstr "usa como máximo uno de --reachable, --stdin-commits, o --stdin-packs"
msgid "Collecting commits from input"
msgstr "Recolectando commits del input"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "subcomando desconocido: %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -4569,9 +4629,9 @@ msgstr "no se pudo leer log desde standard input"
msgid "could not read log file '%s'"
msgstr "no se pudo leer el log '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "options '%s' and '%s:%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '%s' y '%s:%s' no pueden ser usadas juntas"
msgid "could not read SQUASH_MSG"
msgstr "no se pudo leer SQUASH_MSG"
@@ -4694,13 +4754,13 @@ msgstr "Estás en medio de una fusión -- no se puede refrasear."
msgid "You are in the middle of a cherry-pick -- cannot reword."
msgstr "Estás en medio de un cherry-pick -- no se puede refrasear."
-#, fuzzy, c-format
+#, c-format
msgid "reword option of '%s' and path '%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "la opción reword de '%s' y la ruta '%s' no pueden ser usadas juntas"
-#, fuzzy, c-format
+#, c-format
msgid "reword option of '%s' and '%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "la opción reword de '%s' y '%s' no pueden ser usadas juntas"
msgid "You have nothing to amend."
msgstr "No tienes nada que enmendar."
@@ -4749,9 +4809,6 @@ msgstr "mostrar status en formato largo (default)"
msgid "terminate entries with NUL"
msgstr "terminar entradas con NUL"
-msgid "mode"
-msgstr "modo"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
"mostrar archivos sin seguimiento, modos opcionales: all, normal, no. "
@@ -5342,9 +5399,26 @@ msgstr "adjuntar <marca> en un árbol de trabajo roto (default: \"-broken\")"
msgid "No names found, cannot describe anything."
msgstr "No se encontraron nombres, no se puede describir nada."
-#, fuzzy, c-format
+#, c-format
msgid "option '%s' and commit-ishes cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "la opción '%s' y los commit-ismos no pueden ser usados juntos"
+
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <ruta>] [-s|--suffix <formato>] [--"
+"mode=<modo>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "especificar un destino para la crónica diagnóstica"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr ""
+"especificar el sufijo de formato de strftime para el nombre del archivo"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "especificar el contenido de la crónica diagnóstica"
msgid "--merge-base only works with two commits"
msgstr "--merge-base solo funciona con dos commits"
@@ -5488,9 +5562,8 @@ msgid ""
msgstr ""
"opción `--default' espera un valor unsigned long con `--type=ulong`, no `%s`"
-#, fuzzy
msgid "git fast-export [<rev-list-opts>]"
-msgstr "git fast-export [rev-list-opts]"
+msgstr "git fast-export [<opciones-de-rev-list>]"
msgid "Error: Cannot export nested tags unless --mark-tags is specified."
msgstr ""
@@ -5669,7 +5742,7 @@ msgid "convert to a complete repository"
msgstr "convertir a un repositorio completo"
msgid "re-fetch without negotiating common commits"
-msgstr ""
+msgstr "hacer fetch de nuevo sin negociar commits en común"
msgid "prepend this to submodule path output"
msgstr "anteponer esto a la salida de ruta del submódulo"
@@ -5688,15 +5761,15 @@ msgid "refmap"
msgstr "refmap"
msgid "specify fetch refmap"
-msgstr "especificar extracción de refmap"
+msgstr "especificar el mapa de referencias de fetch"
msgid "report that we have only objects reachable from this object"
msgstr "reportar que solo tenemos objetos alcanzables de este objeto"
msgid "do not fetch a packfile; instead, print ancestors of negotiation tips"
msgstr ""
-"no realizar fetch al packfile; en lugar de eso, mostrar los ancestros de las "
-"puntas de negociación"
+"no realizar fetch de un archivo de pack; en lugar de eso, mostrar los "
+"ancestros de las puntas de negociación"
msgid "run 'maintenance --auto' after fetching"
msgstr "ejecutar 'maintenance --auto' después de buscar"
@@ -5710,9 +5783,8 @@ msgstr "escribir commit-graph luego del fetch"
msgid "accept refspecs from stdin"
msgstr "aceptar refspecs de stdin"
-#, fuzzy
msgid "couldn't find remote ref HEAD"
-msgstr "No se pudo encontrar ref remota HEAD"
+msgstr "no se pudo encontrar la referencia remota HEAD"
#, c-format
msgid "object %s not found"
@@ -5724,12 +5796,8 @@ msgstr "[actualizado]"
msgid "[rejected]"
msgstr "[rechazado]"
-msgid "can't fetch in current branch"
-msgstr "no se puede traer en la rama actual"
-
-#, fuzzy
-msgid "checked out in another worktree"
-msgstr "buscar en el índice en lugar del árbol de trabajo"
+msgid "can't fetch into checked-out branch"
+msgstr "no se puede hacer fetch a la rama actual"
msgid "[tag update]"
msgstr "[actualización de tag]"
@@ -5759,25 +5827,24 @@ msgstr "avance no rápido"
msgid "cannot open '%s'"
msgstr "no se puede abrir '%s'"
-#, fuzzy
msgid ""
"fetch normally indicates which branches had a forced update,\n"
"but that check has been disabled; to re-enable, use '--show-forced-updates'\n"
"flag or run 'git config fetch.showForcedUpdates true'"
msgstr ""
-"Fetch normalmente incida qué branches han tenido un update forzado,\n"
+"fetch normalmente indica cuáles ramas han tenido una actualización forzada,\n"
"pero esa validación ha sido deshabilitada. Para activarla de nuevo usa '--"
"show-forced-updates'\n"
-"o ejecuta 'git config fetch.showForcedUpdates true'."
+"o ejecuta 'git config fetch.showForcedUpdates true'"
-#, fuzzy, c-format
+#, c-format
msgid ""
"it took %.2f seconds to check forced updates; you can use\n"
"'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates "
"false'\n"
"to avoid this check\n"
msgstr ""
-"Tomó %.2f segundos validar los updates forzados. Puedes usar\n"
+"tomó %.2f segundos validar las actualizaciones forzadas. Se puede usar\n"
"'--no-show-forced-updates' o ejecutar 'git config fetch.showForcedUpdates "
"false'\n"
"para evitar esta validación.\n"
@@ -5816,17 +5883,17 @@ msgstr "[eliminado]"
msgid "(none)"
msgstr "(nada)"
-#, fuzzy, c-format
+#, c-format
msgid "refusing to fetch into branch '%s' checked out at '%s'"
-msgstr "No se puede borrar rama '%s' que cuenta con checkout en '%s'"
+msgstr "rehusando hacer fetch a la rama '%s' que cuenta con checkout en '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "option \"%s\" value \"%s\" is not valid for %s"
-msgstr "Valor \"%2$s\" de opción \"%1$s\" no es válido para %3$s"
+msgstr "el valor \"%2$s\" de la opción \"%1$s\" no es válido para %3$s"
-#, fuzzy, c-format
+#, c-format
msgid "option \"%s\" is ignored for %s\n"
-msgstr "Opción \"%s\" es ignorada por %s\n"
+msgstr "la opción \"%s\" es ignorada por %s\n"
#, c-format
msgid "%s is not a valid object"
@@ -5839,13 +5906,13 @@ msgstr "el objeto %s no existe"
msgid "multiple branches detected, incompatible with --set-upstream"
msgstr "múltiples ramas detectadas, incompatible con --set-upstream"
-#, fuzzy, c-format
+#, c-format
msgid ""
"could not set upstream of HEAD to '%s' from '%s' when it does not point to "
"any branch."
msgstr ""
-"no se pudo configurar upstream de HEAD a %s cuando este no apunta a ninguna "
-"rama."
+"no se pudo cambiar el upstream de HEAD de '%s' a '%s' cuando este no apunta "
+"a ninguna rama."
msgid "not setting upstream for a remote remote-tracking branch"
msgstr "no configurar upstream para una rama de rastreo remoto"
@@ -5856,45 +5923,40 @@ msgstr "no configurar upstream para un tag remoto"
msgid "unknown branch type"
msgstr "tipo de branch desconocido"
-#, fuzzy
msgid ""
"no source branch found;\n"
"you need to specify exactly one branch with the --set-upstream option"
msgstr ""
"no se encontró rama fuente.\n"
-"tienes que especificar exactamente una rama con la opción --set-upstream."
+"hay que especificar exactamente una rama con la opción --set-upstream"
#, c-format
msgid "Fetching %s\n"
msgstr "Extrayendo %s\n"
-#, fuzzy, c-format
+#, c-format
msgid "could not fetch %s"
-msgstr "No se pudo extraer %s"
+msgstr "no se pudo hacer fetch de %s"
#, c-format
msgid "could not fetch '%s' (exit code: %d)\n"
msgstr "no se pudo hacer fetch a '%s' (código de salida: %d)\n"
-#, fuzzy
msgid ""
"no remote repository specified; please specify either a URL or a\n"
"remote name from which new revisions should be fetched"
msgstr ""
-"No hay repositorio remoto especificado. Por favor, especifica un URL o un\n"
-"nombre remoto del cual las nuevas revisiones deben ser extraídas."
+"no hay repositorio remoto especificado. Por favor, especifica un URL o un\n"
+"nombre remoto del cual hacer fetch de las nuevas revisiones"
-#, fuzzy
msgid "you need to specify a tag name"
-msgstr "Tienes que especificar un nombre de tag."
+msgstr "hay que especificar un nombre de etiqueta"
-#, fuzzy
msgid "--negotiate-only needs one or more --negotiation-tip=*"
-msgstr "--negotiate-only necesita uno o más --negotiate-tip=*"
+msgstr "--negotiate-only necesita uno o más --negotiation-tip=*"
-#, fuzzy
msgid "negative depth in --deepen is not supported"
-msgstr "Profundidad negativa en --deepen no soportada"
+msgstr "profundidad negativa en --deepen no es soportada"
msgid "--unshallow on a complete repository does not make sense"
msgstr "--unshallow no tiene sentido en un repositorio completo"
@@ -5905,20 +5967,20 @@ msgstr "fetch --all no toma un argumento de repositorio"
msgid "fetch --all does not make sense with refspecs"
msgstr "fetch --all no tiene sentido con refspecs"
-#, fuzzy, c-format
+#, c-format
msgid "no such remote or remote group: %s"
-msgstr "No existe el remoto o grupo remoto: %s"
+msgstr "no existe tal remoto o grupo remoto: %s"
-#, fuzzy
msgid "fetching a group and specifying refspecs does not make sense"
-msgstr "Extraer un grupo y especificar refspecs no tiene sentido"
+msgstr ""
+"hacer fetch de un grupo y especificar especificaciones de referencia no "
+"tiene sentido"
msgid "must supply remote when using --negotiate-only"
msgstr "tiene que proveer un remoto cuando usa --negotiate-only"
-#, fuzzy
msgid "protocol does not support --negotiate-only, exiting"
-msgstr "Protocolo no soporta --negotiate-only, saliendo."
+msgstr "el protocolo no soporta --negotiate-only, saliendo"
msgid ""
"--filter can only be used with the remote configured in extensions."
@@ -5950,9 +6012,8 @@ msgstr "texto"
msgid "use <text> as start of message"
msgstr "usar <text> como comienzo de mensaje"
-#, fuzzy
msgid "use <name> instead of the real target branch"
-msgstr "usar <nombre> en lugar de 'origin' para rastrear upstream"
+msgstr "usar <nombre> en lugar de la rama de destino real"
msgid "file to read from"
msgstr "archivo del cual leer"
@@ -6025,7 +6086,7 @@ msgstr "error en %s %s: %s"
#. TRANSLATORS: e.g. warning in tree 01bfda: <more explanation>
#, c-format
msgid "warning in %s %s: %s"
-msgstr "peligro en %s %s: %s"
+msgstr "advertencia en %s %s: %s"
#, c-format
msgid "broken link from %7s %s"
@@ -6093,11 +6154,11 @@ msgstr "tagged %s %s (%s) en %s"
#, c-format
msgid "%s: object corrupt or missing"
-msgstr "%s: objecto corrupto o faltante"
+msgstr "%s: objeto corrupto o faltante"
#, c-format
msgid "%s: invalid reflog entry %s"
-msgstr "%s: referencia inválida %s"
+msgstr "%s: entrada de log de referencias inválida %s"
#, c-format
msgid "Checking reflog %s->%s"
@@ -6170,6 +6231,10 @@ msgstr "%s: puntero inválido sha1 en cache-tree"
msgid "non-tree in cache-tree"
msgstr "non-tree en cache-tree"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s: puntero inválido sha1 en resolve-undo"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<opciones>] [<objeto>...]"
@@ -6220,79 +6285,73 @@ msgstr "%s: objeto faltante"
msgid "invalid parameter: expected sha1, got '%s'"
msgstr "parámetro inválido: sha1 esperado, se obtuvo '%s'"
-#, fuzzy
msgid "git fsmonitor--daemon start [<options>]"
-msgstr "git stash list [<opciones>]"
+msgstr "git fsmonitor--daemon start [<opciones>]"
-#, fuzzy
msgid "git fsmonitor--daemon run [<options>]"
-msgstr "git notes prune [<opciones>]"
+msgstr "git fsmonitor--daemon run [<opciones>]"
msgid "git fsmonitor--daemon stop"
-msgstr ""
+msgstr "git fsmonitor--daemon stop"
msgid "git fsmonitor--daemon status"
-msgstr ""
+msgstr "git fsmonitor--daemon status"
-#, fuzzy, c-format
+#, c-format
msgid "value of '%s' out of range: %d"
-msgstr "largo de abreviatura fuera de rango: %d"
+msgstr "valor de '%s' fuera de rango: %d"
-#, fuzzy, c-format
+#, c-format
msgid "value of '%s' not bool or int: %d"
-msgstr "valor es --bool o --int"
+msgstr "valor de '%s' no bool ni int: %d"
#, c-format
msgid "fsmonitor-daemon is watching '%s'\n"
-msgstr ""
+msgstr "fsmonitor-daemon está vigilando '%s'\n"
#, c-format
msgid "fsmonitor-daemon is not watching '%s'\n"
-msgstr ""
+msgstr "fsmonitor-daemon no está vigilando '%s'\n"
-#, fuzzy, c-format
+#, c-format
msgid "could not create fsmonitor cookie '%s'"
-msgstr "no se pudo crear el archivo '%s'"
+msgstr "no se pudo crear la galleta de fsmonitor '%s'"
#, c-format
msgid "fsmonitor: cookie_result '%d' != SEEN"
-msgstr ""
+msgstr "fsmonitor: cookie_result '%d' != SEEN"
-#, fuzzy, c-format
+#, c-format
msgid "could not start IPC thread pool on '%s'"
-msgstr "no se pudo iniciar el servidor en: '%s'"
+msgstr "no se pudo iniciar el pool de hilos IPC en '%s'"
-#, fuzzy
msgid "could not start fsmonitor listener thread"
-msgstr "no se pudo comenzar ls-files en .."
+msgstr "no se pudo iniciar el hilo escuchante de fsmonitor"
-#, fuzzy
msgid "could not start fsmonitor health thread"
-msgstr "no se pudo iniciar el accept_thread '%s'"
+msgstr "no se pudo iniciar el hilo de salud de fsmonitor"
-#, fuzzy
msgid "could not initialize listener thread"
-msgstr "no se pudo guardar el árbol de índice"
+msgstr "no se pudo inicializar el hilo escuchante"
-#, fuzzy
msgid "could not initialize health thread"
-msgstr "no se pudo normalizar la ruta %s"
+msgstr "no se pudo inicializar el hilo de salud"
-#, fuzzy, c-format
+#, c-format
msgid "could not cd home '%s'"
-msgstr "no se pudo cerrar '%s'"
+msgstr "no se pudo cambiar al directorio personal '%s'"
#, c-format
msgid "fsmonitor--daemon is already running '%s'"
-msgstr ""
+msgstr "fsmonitor--daemon ya está ejecutando '%s'"
#, c-format
msgid "running fsmonitor-daemon in '%s'\n"
-msgstr ""
+msgstr "ejecutando fsmonitor-daemon en '%s'\n"
-#, fuzzy, c-format
+#, c-format
msgid "starting fsmonitor-daemon in '%s'\n"
-msgstr "Probando mtime en '%s' "
+msgstr "iniciando fsmonitor-daemon en '%s'\n"
msgid "daemon failed to start"
msgstr "falló al iniciar demonio"
@@ -6300,32 +6359,28 @@ msgstr "falló al iniciar demonio"
msgid "daemon not online yet"
msgstr "demonio no está en línea todavía"
-#, fuzzy
msgid "daemon terminated"
-msgstr "no hay términos definidos"
+msgstr "demonio terminado"
-#, fuzzy
msgid "detach from console"
-msgstr "HEAD desacoplada de "
+msgstr "desacoplar de la consola"
-#, fuzzy
msgid "use <n> ipc worker threads"
-msgstr "usar <n> hilos de trabajo"
+msgstr "usar <n> hilos de trabajo ipc"
-#, fuzzy
msgid "max seconds to wait for background daemon startup"
-msgstr "segundos a esperar para que el dominio empiece o se detenga"
+msgstr "segundos máximos a esperar el inicio del demonio de fondo"
-#, fuzzy, c-format
+#, c-format
msgid "invalid 'ipc-threads' value (%d)"
-msgstr "valor --stat inválido: %s"
+msgstr "valor 'ipc-threads' inválido (%d)"
-#, fuzzy, c-format
+#, c-format
msgid "Unhandled subcommand '%s'"
-msgstr "subcomando no válido: %s"
+msgstr "Subcomando no manejado '%s'"
msgid "fsmonitor--daemon not supported on this platform"
-msgstr ""
+msgstr "fsmonitor--daemon no es soportado en este plataforma"
msgid "git gc [<options>]"
msgstr "git gc [<opciones>]"
@@ -6359,9 +6414,8 @@ msgstr ""
msgid "prune unreferenced objects"
msgstr "recortar objetos no referenciados"
-#, fuzzy
msgid "pack unreferenced objects separately"
-msgstr "recortar objetos no referenciados"
+msgstr "empacar separadamente objetos no referenciados"
msgid "be more thorough (increased runtime)"
msgstr "ser más exhaustivo (aumentar runtime)"
@@ -6376,8 +6430,8 @@ msgid "repack all other packs except the largest pack"
msgstr "reempaquetar todos los otros paquetes excepto el paquete más grande"
#, c-format
-msgid "failed to parse gc.logexpiry value %s"
-msgstr "falló al analizar valor %s de gc.logexpiry"
+msgid "failed to parse gc.logExpiry value %s"
+msgstr "falló al analizar el valor %s de gc.logExpiry"
#, c-format
msgid "failed to parse prune expiry value %s"
@@ -6514,13 +6568,16 @@ msgid "failed to run 'crontab -l'; your system might not support 'cron'"
msgstr ""
"no se pudo ejecutar 'crontab -l'; es posible que su sistema no soporte 'cron'"
+msgid "failed to create crontab temporary file"
+msgstr "falló al crear el archivo temporal de crontab"
+
+msgid "failed to open temporary file"
+msgstr "falló al abrir un archivo temporal"
+
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr ""
"no se pudo ejecutar 'crontab'; es posible que su sistema no soporte 'cron'"
-msgid "failed to open stdin of 'crontab'"
-msgstr "no se pudo abrir stdin de 'crontab'"
-
msgid "'crontab' died"
msgstr "'crontab' murió"
@@ -6567,10 +6624,6 @@ msgstr "no se pudo agregar el repositorio a la configuración global"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <subcomando> [<opciones>]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "subcomando no válido: %s"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<opciones>] [-e] <patrón> [<rev>...] [[--] <ruta>...]"
@@ -6582,7 +6635,6 @@ msgstr "grep: falló al crear el hilo: %s"
msgid "invalid number of threads specified (%d) for %s"
msgstr "número inválido de hilos especificado (%d) para %s"
-#. #-#-#-#-# grep.c.po #-#-#-#-#
#. TRANSLATORS: %s is the configuration
#. variable for tweaking threads, currently
#. grep.threads
@@ -6745,6 +6797,9 @@ msgstr "mostrar archivos concordantes en el paginador"
msgid "allow calling of grep(1) (ignored by this build)"
msgstr "permitir el llamado de grep(1) (ignorado por esta build)"
+msgid "maximum number of results per file"
+msgstr "número máximo de resultados por archivo"
+
msgid "no pattern given"
msgstr "no se ha entregado ningún patrón"
@@ -6808,13 +6863,11 @@ msgstr "procesar el archivo como si fuera de esta ruta"
msgid "print all available commands"
msgstr "mostrar todos los comandos disponibles"
-#, fuzzy
msgid "show external commands in --all"
-msgstr "Comandos externos"
+msgstr "mostrar comandos externos en --all"
-#, fuzzy
msgid "show aliases in --all"
-msgstr "mostrar lista de tags en columnas"
+msgstr "mostrar aliases en --all"
msgid "exclude guides"
msgstr "excluir las guias"
@@ -6834,14 +6887,21 @@ msgstr "imprimir descripción del comando"
msgid "print list of useful guides"
msgstr "mostrar una lista de guías útiles"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr ""
+"imprimir lista de interfaces de repositorio, comando y archivo orientadas al "
+"usuario"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr ""
+"imprimir lista de formatos de archivos, protocolos y otras interfaces para "
+"el desarrollador"
+
msgid "print all configuration variable names"
msgstr "imprimir todos los nombres de variables de configuración"
-#, fuzzy
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr ""
-"git help [-a|--all] [--[no-]verbose]]\n"
-" [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<comando>|<documento>]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -6895,13 +6955,15 @@ msgstr "'%s' tiene el alias '%s'"
msgid "bad alias.%s string: %s"
msgstr "mal alias.%s string: %s"
-#, fuzzy, c-format
+#, c-format
msgid "the '%s' option doesn't take any non-option arguments"
-msgstr "esta opción no requiere argumentos"
+msgstr "la opción '%s' no toma ningún argumento aparte de opciones"
msgid ""
"the '--no-[external-commands|aliases]' options can only be used with '--all'"
msgstr ""
+"las opciones '--no-[external-commands|aliases]' solo pueden ser usadas con "
+"'--all'"
#, c-format
msgid "usage: %s%s"
@@ -6912,9 +6974,10 @@ msgstr "'git help config' para más información"
msgid "git hook run [--ignore-missing] <hook-name> [-- <hook-args>]"
msgstr ""
+"git hook run [--ignore-missing] <nombre-de-hook> [-- <argumentos-de-hook>]"
msgid "silently ignore missing requested <hook-name>"
-msgstr ""
+msgstr "ignorar silenciosamente <nombre-de-hook> solicitado y faltante"
#, c-format
msgid "object type mismatch at %s"
@@ -6946,9 +7009,9 @@ msgstr "se usaron más bytes de los disponibles"
msgid "pack too large for current definition of off_t"
msgstr "paquete demasiado grande para la definición actual de off_t"
-#, fuzzy, c-format
+#, c-format
msgid "pack exceeds maximum allowed size (%s)"
-msgstr "paquete excede el máximo tamaño permitido"
+msgstr "el pack excede el tamaño máximo permitido (%s)"
msgid "pack signature mismatch"
msgstr "firma del paquete no concuerda"
@@ -6981,8 +7044,8 @@ msgstr "no se puede hacer pread en el paquete"
#, c-format
msgid "premature end of pack file, %<PRIuMAX> byte missing"
msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
-msgstr[0] "final prematuro de archivo de paquete, %<PRIuMAX> byte faltante"
-msgstr[1] "final prematuro de archivo de paquete, %<PRIuMAX> bytes faltantes"
+msgstr[0] "fin prematuro de archivo de paquete, %<PRIuMAX> byte faltante"
+msgstr[1] "fin prematuro de archivo de paquete, %<PRIuMAX> bytes faltantes"
msgid "serious inflate inconsistency"
msgstr "inconsistencia seria en inflate"
@@ -7089,8 +7152,8 @@ msgid "error while closing pack file"
msgstr "error mientras se cerraba el archivo paquete"
#, c-format
-msgid "bad pack.indexversion=%<PRIu32>"
-msgstr "mal pack.indexversion=%<PRIu32>"
+msgid "bad pack.indexVersion=%<PRIu32>"
+msgstr "mal pack.indexVersion=%<PRIu32>"
#, c-format
msgid "Cannot open existing pack file '%s'"
@@ -7311,8 +7374,8 @@ msgstr "suprimir salida de diff"
msgid "show source"
msgstr "mostrar fuente"
-msgid "use mail map file"
-msgstr "usar archivo de mapa de mail"
+msgid "clear all previously-defined decoration filters"
+msgstr "limpiar todos los filtros de decoración previamente definidos"
msgid "only decorate refs that match <pattern>"
msgstr "solo decorar refs que concuerden con <patrón>"
@@ -7341,9 +7404,8 @@ msgstr "-L<rango>:<archivo> no se puede usar con pathspec"
msgid "Final output: %d %s\n"
msgstr "Salida final: %d %s\n"
-#, fuzzy
msgid "unable to create temporary object directory"
-msgstr "no es posible crear un archivo temporal"
+msgstr "incapaz de crear directorio temporal de objetos"
#, c-format
msgid "git show %s: bad file"
@@ -7572,6 +7634,9 @@ msgstr "mostrar cambios contra <refspec> en cover letter o en un solo parche"
msgid "percentage by which creation is weighted"
msgstr "porcentaje por el cual la creación es pesada"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "mostrar From: en el cuerpo aunque sea idéntico a la cabecera de e-mail"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "línea de identificación inválida: %s"
@@ -7585,9 +7650,8 @@ msgstr "--name-status no tiene sentido"
msgid "--check does not make sense"
msgstr "--check no tiene sentido"
-#, fuzzy
msgid "--remerge-diff does not make sense"
-msgstr "--name-only no tiene sentido"
+msgstr "--remerge-diff no tiene sentido"
#, c-format
msgid "could not create directory '%s'"
@@ -7633,6 +7697,18 @@ msgstr ""
"No se pudo encontrar una rama remota rastreada, por favor especifica "
"<upstream> manualmente.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "formato malo de ls-files: el elemento '%s' no comienza con '('"
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "formato malo de ls-files: el elemento '%s' no termina en ')'"
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "formato malo de ls-files: %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<opciones>] [<archivo>...]"
@@ -7716,9 +7792,15 @@ msgstr "mostrar data de debug"
msgid "suppress duplicate entries"
msgstr "suprimir entradas duplicadas"
-#, fuzzy
msgid "show sparse directories in the presence of a sparse index"
-msgstr "activar el uso de un índice sparse"
+msgstr "mostrar directorios escasos en la presencia de un índice escaso"
+
+msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format no puede ser usado con -s, -o, -k, -t, --resolve-undo, --"
+"deduplicate, --eol"
msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -7759,21 +7841,21 @@ msgstr "mostrar ref subyacente en adición al objeto apuntado por él"
msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
msgstr "git ls-tree [<opciones>] <árbol-ismo> [<ruta>...]"
-#, fuzzy, c-format
+#, c-format
msgid "could not get object info about '%s'"
-msgstr "no se pudo analizar el objeto '%s'"
+msgstr "no se pudo averiguar información sobre el objeto '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "el nombre del archivo de paquete '%s' no termina con '.%s'"
+msgstr "formato malo de ls-tree: el elemento '%s' no comienza con '('"
-#, fuzzy, c-format
+#, c-format
msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "el nombre del archivo de paquete '%s' no termina con '.%s'"
+msgstr "formato malo de ls-tree: el elemento '%s' no termina en ')'"
-#, fuzzy, c-format
+#, c-format
msgid "bad ls-tree format: %%%.*s"
-msgstr "formato inválido: %s"
+msgstr "formato malo de ls-tree: %%%.*s"
msgid "only show trees"
msgstr "solo mostrar árboles"
@@ -7793,9 +7875,8 @@ msgstr "incluir tamaño de objeto"
msgid "list only filenames"
msgstr "listar solo nombres de archivos"
-#, fuzzy
msgid "list only objects"
-msgstr "Escribiendo objetos"
+msgstr "listar solo objetos"
msgid "use full path names"
msgstr "usar rutas completas"
@@ -7804,9 +7885,9 @@ msgid "list entire tree; not just current directory (implies --full-name)"
msgstr ""
"mostrar todo el árbol; no solo el directorio actual (implica --full-name)"
-#, fuzzy
msgid "--format can't be combined with other format-altering options"
-msgstr "--mirror no puede ser combinado con refspecs"
+msgstr ""
+"--format no se puede combinar con otras opciones que alteren el formato"
#. TRANSLATORS: keep <> in "<" mail ">" info.
msgid "git mailinfo [<options>] <msg> <patch> < mail >info"
@@ -7845,9 +7926,8 @@ msgstr "actión cuando se encuentra un CR citado"
msgid "use headers in message's body"
msgstr "usar cabeceras en el cuerpo del mensaje"
-#, fuzzy
msgid "reading patches from stdin/tty..."
-msgstr "leer actualizaciones de stdin"
+msgstr "leyendo parches de stdin/tty..."
#, c-format
msgid "empty mbox: '%s'"
@@ -7896,9 +7976,8 @@ msgstr "mandar resultados a standard output"
msgid "use a diff3 based merge"
msgstr "usar una fusión basada en diff3"
-#, fuzzy
msgid "use a zealous diff3 based merge"
-msgstr "usar una fusión basada en diff3"
+msgstr "usar una fusión celosa basada en diff3"
msgid "for conflicts, use our version"
msgstr "por conflictos, usar nuestra versión"
@@ -7943,6 +8022,39 @@ msgstr "no se pudo resolver ref '%s'"
msgid "Merging %s with %s\n"
msgstr "Fusionando %s con %s\n"
+msgid "not something we can merge"
+msgstr "no es nada que se pueda fusionar"
+
+msgid "refusing to merge unrelated histories"
+msgstr "rehusando fusionar historias no relacionadas"
+
+msgid "failure to merge"
+msgstr "falló al fusionar"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<opciones>] <rama1> <rama2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <árbol-base> <rama1> <rama2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "hacer una fusión real en vez de una fusión trivial"
+
+msgid "do a trivial merge only"
+msgstr "hacer solo una fusión trivial"
+
+msgid "also show informational/conflict messages"
+msgstr "también mostrar mensajes informativos o de conflictos"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "listar nombres de archivo sin modos/oids/etapas"
+
+msgid "allow merging unrelated histories"
+msgstr "permitir fusionar historias no relacionadas"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge es incompatible con cualquier otra opción"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<opciones>] [<commit>...]"
@@ -8012,9 +8124,8 @@ msgstr "opción para la estrategia de fusión seleccionada"
msgid "merge commit message (for a non-fast-forward merge)"
msgstr "fusionar mensaje de commit (para una fusión no fast-forward)"
-#, fuzzy
msgid "use <name> instead of the real target"
-msgstr "usar <nombre> en lugar de 'origin' para rastrear upstream"
+msgstr "usar <nombre> en lugar del destino real"
msgid "abort the current in-progress merge"
msgstr "abortar la fusión en progreso actual"
@@ -8025,9 +8136,6 @@ msgstr "--abort pero no tocar el índice ni el árbol de trabajo"
msgid "continue the current in-progress merge"
msgstr "continuar la fusión en progreso actual"
-msgid "allow merging unrelated histories"
-msgstr "permitir fusionar historias no relacionadas"
-
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "hacer un bypass a hooks pre-merge-commit y commit-msg"
@@ -8149,9 +8257,6 @@ msgstr "no se pudo cerrar '%s'"
msgid "not something we can merge in %s: %s"
msgstr "nada que podamos fusionar en %s: %s"
-msgid "not something we can merge"
-msgstr "nada que podamos fusionar"
-
msgid "--abort expects no arguments"
msgstr "--abort no espera argumentos"
@@ -8201,14 +8306,20 @@ msgstr "%s - nada que podamos fusionar"
msgid "Can merge only exactly one commit into empty head"
msgstr "Solo se puede fusionar exactamente un commit en un head vacío"
-msgid "refusing to merge unrelated histories"
-msgstr "rehusando fusionar historias no relacionadas"
-
#, c-format
msgid "Updating %s..%s\n"
msgstr "Actualizando %s..%s\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Los cambios locales a los archivos siguientes serían sobreescritos al "
+"fusionar:\n"
+" %s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Intentando fusión en índice realmente trivial...\n"
@@ -8242,8 +8353,13 @@ msgstr ""
"Fusión automática fue bien; detenida antes del commit como se solicitó\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr ""
+"Cuando esté terminado, aplica los cambios en stash con `git stash pop`\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
-msgstr "peligro: información de tag no pasa fsck: %s"
+msgstr "advertencia: la información de etiqueta no pasa fsck: %s"
#, c-format
msgid "error: tag input does not pass fsck: %s"
@@ -8298,9 +8414,8 @@ msgstr "git multi-pack-index [<opciones>] expire"
msgid "git multi-pack-index [<options>] repack [--batch-size=<size>]"
msgstr "git multi-pack-index [<opciones>] repack [--batch-size=<tamaño>]"
-#, fuzzy
msgid "directory"
-msgstr "archivo/directorio"
+msgstr "directorio"
msgid "object directory containing set of packfile and pack-index pairs"
msgstr ""
@@ -8361,6 +8476,9 @@ msgstr "Revisando cambio de nombre de '%s' a '%s'\n"
msgid "bad source"
msgstr "mala fuente"
+msgid "destination exists"
+msgstr "el destino existe"
+
msgid "can not move directory into itself"
msgstr "no se puede mover un directorio en sí mismo"
@@ -8376,9 +8494,6 @@ msgstr "no se encuentra bajo control de versiones"
msgid "conflicted"
msgstr "en conflicto"
-msgid "destination exists"
-msgstr "destino existe"
-
#, c-format
msgid "overwriting '%s'"
msgstr "sobrescribiendo '%s'"
@@ -8392,6 +8507,9 @@ msgstr "múltiples fuentes para el mismo destino"
msgid "destination directory does not exist"
msgstr "el directorio de destino no existe"
+msgid "destination exists in the index"
+msgstr "el destino existe en el índice"
+
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, fuente=%s, destino=%s"
@@ -8410,9 +8528,8 @@ msgstr "git name-rev [<opciones>] <commit>..."
msgid "git name-rev [<options>] --all"
msgstr "git name-rev [<opciones>] --all"
-#, fuzzy
msgid "git name-rev [<options>] --annotate-stdin"
-msgstr "git name-rev [<opciones>] --stdin"
+msgstr "git name-rev [<opciones>] --annotate-stdin"
msgid "print only ref-based names (no object names)"
msgstr "imprimir solo nombres basados en referencias (sin nombres de objetos)"
@@ -8429,12 +8546,11 @@ msgstr "ignorar refs que concuerden con <patrón>"
msgid "list all commits reachable from all refs"
msgstr "listar todos los commits alcanzables desde todas las referencias"
-msgid "deprecated: use annotate-stdin instead"
-msgstr ""
+msgid "deprecated: use --annotate-stdin instead"
+msgstr "deprecado: usa --annotate-stdin en su lugar"
-#, fuzzy
msgid "annotate text from stdin"
-msgstr "leer el objeto de stdin"
+msgstr "anotar el texto de stdin"
msgid "allow to print `undefined` names (default)"
msgstr "permitir imprimir nombres `undefined` (predeterminado)"
@@ -8753,8 +8869,8 @@ msgid "use notes from <notes-ref>"
msgstr "usar notas desde <referencia-de-notas>"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "subcomando desconocido: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "subcomando desconocido: '%s'"
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -8896,21 +9012,18 @@ msgstr "no se puede obtener el tipo de objeto %s en pack %s"
msgid "could not find pack '%s'"
msgstr "no se pudo encontrar pack '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "packfile %s cannot be accessed"
-msgstr "objeto %s no puede ser mapeado %s"
+msgstr "no se puede acceder al archivo de pack %s"
-#, fuzzy
msgid "Enumerating cruft objects"
-msgstr "Enumerando objetos"
+msgstr "Enumerando objetos inalcanzables"
-#, fuzzy
msgid "unable to add cruft objects"
-msgstr "incapaz de añadir objetos recientes"
+msgstr "incapaz de añadir objetos inalcanzables"
-#, fuzzy
msgid "Traversing cruft objects"
-msgstr "Comprimiendo objetos"
+msgstr "Atravesando objetos inalcanzables"
#, c-format
msgid ""
@@ -8928,9 +9041,8 @@ msgstr ""
"se esperaba ID de objeto, se obtuvo basura:\n"
"%s"
-#, fuzzy
msgid "could not load cruft pack .mtimes"
-msgstr "no se pudo cargar pack"
+msgstr "no se pudo cargar el .mtimes del pack de inalcanzables"
msgid "cannot open pack index"
msgstr "no se puede abrir índice de paquetes"
@@ -8940,7 +9052,7 @@ msgid "loose object at %s could not be examined"
msgstr "objeto suelto en %s no pudo ser examinado"
msgid "unable to force loose object"
-msgstr "incapaz de forzar que el objecto se suelte"
+msgstr "incapaz de forzar que el objeto se suelte"
#, c-format
msgid "not a rev '%s'"
@@ -9034,13 +9146,11 @@ msgstr "empaquetar objetos sueltos inalcanzables"
msgid "unpack unreachable objects newer than <time>"
msgstr "desempaquetar objetos inalcanzables más nuevos que <tiempo>"
-#, fuzzy
msgid "create a cruft pack"
-msgstr "crear paquetes delgados"
+msgstr "crear un pack de inalcanzables"
-#, fuzzy
msgid "expire cruft objects older than <time>"
-msgstr "caducar objetos más viejos a <tiempo>"
+msgstr "caducar objetos inalcanzables más viejos a <tiempo>"
msgid "use the sparse reachability algorithm"
msgstr "usar el algoritmo sparse reachability"
@@ -9119,19 +9229,16 @@ msgid "cannot use --filter with --stdin-packs"
msgstr "no se puede usar --filter con --stdin-packs"
msgid "cannot use internal rev list with --stdin-packs"
-msgstr "no se puede usar un lista interna de rev con --stdin-packs"
+msgstr "no se puede usar un lista interna de revisiones con --stdin-packs"
-#, fuzzy
msgid "cannot use internal rev list with --cruft"
-msgstr "no se puede usar un lista interna de rev con --stdin-packs"
+msgstr "no se puede usar un lista interna de revisiones con --cruft"
-#, fuzzy
msgid "cannot use --stdin-packs with --cruft"
-msgstr "no se puede usar -a con -d"
+msgstr "no se puede usar --stdin-packs con --cruft"
-#, fuzzy
msgid "cannot use --max-pack-size with --cruft"
-msgstr "no se puede usar -a con -d"
+msgstr "no se puede usar --max-pack-size con --cruft"
msgid "Enumerating objects"
msgstr "Enumerando objetos"
@@ -9197,9 +9304,8 @@ msgstr "incorporar cambios por rebase en lugar de fusión"
msgid "allow fast-forward"
msgstr "permitir fast-forward"
-#, fuzzy
msgid "control use of pre-merge-commit and commit-msg hooks"
-msgstr "hacer un bypass a hooks pre-merge-commit y commit-msg"
+msgstr "controlar el uso de los hooks pre-merge-commit y commit-msg"
msgid "automatically stash/stash pop before and after"
msgstr "ejecutar automáticamente stash/stash pop antes y después"
@@ -9283,7 +9389,6 @@ msgstr "no es posible acceder al commit %s"
msgid "ignoring --verify-signatures for rebase"
msgstr "ignorando --verify-signatures para rebase"
-#, fuzzy
msgid ""
"You have divergent branches and need to specify how to reconcile them.\n"
"You can do so by running one of the following commands sometime before\n"
@@ -9299,18 +9404,18 @@ msgid ""
"or --ff-only on the command line to override the configured default per\n"
"invocation.\n"
msgstr ""
-"Hacer un pull sin especificar cómo reconciliar las ramas es poco\n"
-"recomendable. Puedes eliminar este mensaje usando uno de los\n"
-"siguientes comandos antes de tu siguiente pull:\n"
+"Las ramas se han divergido y hay que especificar cómo reconciliarlas.\n"
+"Se puede hacerlo ejecutando uno de los comandos siguiente antes del\n"
+"próximo pull:\n"
"\n"
-" git config pull.rebase false # hacer merge (estrategia por defecto)\n"
-" git config pull.rebase true # aplicar rebase\n"
-" git config pull.ff only # aplicar solo fast-forward\n"
+" git config pull.rebase false # fusionar\n"
+" git config pull.rebase true # rebasar\n"
+" git config pull.ff only # solo avance rápido\n"
"\n"
-"Puedes reemplazar \"git config\" con \"git config --global\" para aplicar\n"
-"la preferencia en todos los repositorios. Puedes también pasar --rebase,\n"
-"--no-rebase, o --ff-only en el comando para sobrescribir la configuración\n"
-"por defecto en cada invocación.\n"
+"Se puede reemplazar \"git config\" con \"git config --global\" para aplicar\n"
+"la preferencia en todos los repositorios. También se puede pasar\n"
+"--rebase, --no-rebase o --ff-only en el comando para sobrescribir la\n"
+"configuración por defecto en cada invocación.\n"
msgid "Updating an unborn branch with changes added to the index."
msgstr "Actualizando una rama no nacida con cambios agregados al índice."
@@ -9373,14 +9478,13 @@ msgstr "taquigrafía de tag sin <tag>"
msgid "--delete only accepts plain target ref names"
msgstr "--delete solo acepta como objetivos nombres de ref planos"
-#, fuzzy
msgid ""
"\n"
"To choose either option permanently, see push.default in 'git help config'.\n"
msgstr ""
"\n"
-"Para elegir si la opción es permanente, mira push.default en 'git help "
-"config'."
+"Para elegir una de las opciones permanentemente, mira push.default en 'git "
+"help config'.\n"
msgid ""
"\n"
@@ -9389,8 +9493,12 @@ msgid ""
"autoSetupMerge\n"
"in 'git help config'.\n"
msgstr ""
+"\n"
+"Para evitar configurar una rama upstream automáticamente cuando su nombre\n"
+"no coincida con el de la rama local, mira la opción 'simple' de\n"
+"branch.autoSetupMerge en 'git help config'.\n"
-#, fuzzy, c-format
+#, c-format
msgid ""
"The upstream branch of your current branch does not match\n"
"the name of your current branch. To push to the upstream branch\n"
@@ -9412,7 +9520,7 @@ msgstr ""
"Para empujar a la rama del mismo nombre en el remoto, ejecuta\n"
"\n"
" git push %s HEAD\n"
-"%s"
+"%s%s"
#, c-format
msgid ""
@@ -9433,8 +9541,11 @@ msgid ""
"To have this happen automatically for branches without a tracking\n"
"upstream, see 'push.autoSetupRemote' in 'git help config'.\n"
msgstr ""
+"\n"
+"Para hacer que esto pase automáticamente para las ramas que no rastrean\n"
+"un upstream, mira 'push.autoSetupRemote' en 'git help config'.\n"
-#, fuzzy, c-format
+#, c-format
msgid ""
"The current branch %s has no upstream branch.\n"
"To push the current branch and set the remote as upstream, use\n"
@@ -9445,7 +9556,8 @@ msgstr ""
"La rama actual %s no tiene una rama upstream.\n"
"Para empujar la rama actual y configurar el remoto como upstream, usa\n"
"\n"
-"\tgit push --set-upstream %s %s\n"
+" git push --set-upstream %s %s\n"
+"%s"
#, c-format
msgid "The current branch %s has multiple upstream branches, refusing to push."
@@ -9536,9 +9648,9 @@ msgstr "Empujando a %s\n"
msgid "failed to push some refs to '%s'"
msgstr "falló el empuje de algunas referencias a '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "invalid value for '%s'"
-msgstr "valor inválido para %s"
+msgstr "valor inválido para '%s'"
msgid "repository"
msgstr "repositorio"
@@ -9658,11 +9770,16 @@ msgid "only emit output related to the second range"
msgstr "solo emite salida relacionada con el segundo rango"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "no es una revisión: '%s'"
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "no es un rango de commit: '%s'"
-msgid "single arg format must be symmetric range"
-msgstr "argumento único de formato debe ser un rango simétrico"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "no es un rango simétrico: '%s'"
msgid "need two commit ranges"
msgstr "se necesitan dos rangos de commits"
@@ -9923,9 +10040,8 @@ msgstr "usar estrategias de fusión para el rebase"
msgid "let the user edit the list of commits to rebase"
msgstr "permitir al usuario editar la lista de commits para rebasar"
-#, fuzzy
msgid "(REMOVED) was: try to recreate merges instead of ignoring them"
-msgstr "(DEPRECADO) intentar recrear merges en lugar de ignorarlos"
+msgstr "(DEPRECADO) era: intentar recrear fusiones en lugar de ignorarlas"
msgid "how to handle commits that become empty"
msgstr "como manejar commits que se vuelven vacíos"
@@ -9936,6 +10052,9 @@ msgstr "mantener commits que comiencen con vacío"
msgid "move commits that begin with squash!/fixup! under -i"
msgstr "mover commits que comiencen con squash!/fixup! bajo -i"
+msgid "update branches that point to commits that are being rebased"
+msgstr "actualizar ramas que apuntan a commits que se rebasan"
+
msgid "add exec lines after each commit of the editable list"
msgstr "agregar líneas exec tras cada commit de la lista editable"
@@ -9976,12 +10095,19 @@ msgid ""
"Use `git rebase --abort` to terminate current rebase.\n"
"Or downgrade to v2.33, or earlier, to complete the rebase."
msgstr ""
+"`rebase --preserve-merges` (-p) ya no es soportado.\n"
+"Usa `git rebase --abort` para terminar la rebase actual.\n"
+"O regresa a v2.33, o más antes, para completar la rebase."
msgid ""
"--preserve-merges was replaced by --rebase-merges\n"
-"Note: Your `pull.rebase` configuration may also be set to 'preserve',\n"
+"Note: Your `pull.rebase` configuration may also be set to 'preserve',\n"
"which is no longer supported; use 'merges' instead"
msgstr ""
+"--rebase-merges ha reemplazado --preserve-merges\n"
+"Nota: Tu configuración de `pull.rebase` también podría estar\n"
+"configurada a 'preserve', el cual ya no es soportado; usa 'merges' en\n"
+"su lugar"
msgid "No rebase in progress?"
msgstr "¿No hay rebase en progreso?"
@@ -10037,9 +10163,10 @@ msgstr "Modo desconocido: %s"
msgid "--strategy requires --merge or --interactive"
msgstr "--strategy requiere --merge o --interactive"
-#, fuzzy
msgid "apply options and merge options cannot be used together"
-msgstr "Opciones --add-file y --remote no pueden ser usadas juntas"
+msgstr ""
+"las opciones de aplicación y las opciones de fusión no pueden ser usadas "
+"juntas"
#, c-format
msgid "Unknown rebase backend: %s"
@@ -10176,82 +10303,80 @@ msgstr ""
msgid "quiet"
msgstr "silencioso"
-#, fuzzy
msgid "you must specify a directory"
-msgstr "Se tiene que especificar un directorio."
+msgstr "hay que especificar un directorio"
-#, fuzzy
msgid "git reflog [show] [<log-options>] [<ref>]"
-msgstr "git remote show [<opciones>] <nombre>"
+msgstr "git reflog [show] [<opciones-de-log>] [<referencia>]"
-#, fuzzy
msgid ""
"git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
" [--rewrite] [--updateref] [--stale-fix]\n"
" [--dry-run | -n] [--verbose] [--all [--single-worktree] | "
"<refs>...]"
msgstr ""
-"git reflog expire [--expire=<tiempo>] [--expire-unreachable=<tiempo>] [--"
-"rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] "
-"<refs>..."
+"git reflog expire [--expire=<tiempo>] [--expire-unreachable=<tiempo>]\n"
+" [--rewrite] [--updateref] [--stale-fix]\n"
+" [--dry-run | -n] [--verbose] [--all [--single-worktree] | "
+"<referencias>...]"
-#, fuzzy
msgid ""
"git reflog delete [--rewrite] [--updateref]\n"
" [--dry-run | -n] [--verbose] <ref>@{<specifier>}..."
msgstr ""
-"git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] "
-"<refs>..."
+"git reflog delete [--rewrite] [--updateref]\n"
+" [--dry-run | -n] [--verbose] "
+"<referencia>@{<especificador>}..."
msgid "git reflog exists <ref>"
-msgstr "git reflog existe <ref>"
+msgstr "git reflog exists <referencia>"
-#, fuzzy, c-format
+#, c-format
msgid "invalid timestamp '%s' given to '--%s'"
-msgstr "regex inválido para -I: '%s'"
+msgstr "marca de tiempo inválida '%s' pasada a '--%s'"
-#, fuzzy
msgid "do not actually prune any entries"
-msgstr "no tocar entradas index-only"
+msgstr "no recortar de verdad ninguna entrada"
msgid ""
"rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"
msgstr ""
+"reescribir el SHA1 antiguo con el SHA1 nuevo de la entrada que ya lo precede"
msgid "update the reference to the value of the top reflog entry"
-msgstr ""
+msgstr "actualizar la referencia al valor de la entrada superior del reflog"
-#, fuzzy
msgid "print extra information on screen"
-msgstr "Información de output en cada ref"
+msgstr "imprimir información extra a la pantalla"
-#, fuzzy
msgid "timestamp"
-msgstr "timestamp inválido"
+msgstr "marca de tiempo"
-#, fuzzy
msgid "prune entries older than the specified time"
-msgstr "caducar árboles de trabajo más viejos a <tiempo>"
+msgstr "recortar entradas más viejas al tiempo especificado"
msgid ""
"prune entries older than <time> that are not reachable from the current tip "
"of the branch"
msgstr ""
+"recortar entradas más viejas de <tiempo> que están inalcanzables de la punta "
+"actual de la rama"
-#, fuzzy
msgid "prune any reflog entries that point to broken commits"
-msgstr "mostrar solo ramas que contengan el commit"
+msgstr ""
+"recortar cualquier entrada del log de referencias que apunte a un commit roto"
-#, fuzzy
msgid "process the reflogs of all references"
-msgstr "forzar sobrescritura de referencia local"
+msgstr "procesar los logs de referencias de todas las referencias"
msgid "limits processing to reflogs from the current worktree only"
msgstr ""
+"limita procesamiento a solo los logs de referencias del árbol de trabajo "
+"actual"
#, c-format
msgid "Marking reachable objects..."
-msgstr "Marcando objectos alcanzables..."
+msgstr "Marcando objetos alcanzables..."
#, c-format
msgid "%s points nowhere!"
@@ -10271,9 +10396,8 @@ msgstr ""
"git remote add [-t <rama>] [-m <master>] [-f] [--tags | --no-tags] [--"
"mirror=<fetch|push>] <nombre> <url>"
-#, fuzzy
msgid "git remote rename [--[no-]progress] <old> <new>"
-msgstr "git remote rename <viejo> <nuevo>"
+msgstr "git remote rename [--[no-]progress] <viejo> <nuevo>"
msgid "git remote remove <name>"
msgstr "git remote remove <nombre>"
@@ -10431,9 +10555,8 @@ msgstr ""
"\t%s\n"
"\tPor favor actualiza la configuración manualmente si es necesario."
-#, fuzzy
msgid "Renaming remote references"
-msgstr "no se pudo eliminar la referencia %s"
+msgstr "Renombrando referencias remotas"
#, c-format
msgid "deleting '%s' failed"
@@ -10468,6 +10591,9 @@ msgstr " nuevo (siguiente fetch se guardará en remotes/%s)"
msgid " tracked"
msgstr " rastreada"
+msgid " skipped"
+msgstr "saltado"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " viejo (usa 'git remote prune' para eliminar)"
@@ -10696,10 +10822,11 @@ msgstr "git repack [<opciones>]"
msgid ""
"Incremental repacks are incompatible with bitmap indexes. Use\n"
-"--no-write-bitmap-index or disable the pack.writebitmaps configuration."
+"--no-write-bitmap-index or disable the pack.writeBitmaps configuration."
msgstr ""
-"Reempaquetados incrementales son incompatibles con índices bitmap. Usa\n"
-"--no-write-bitmap-index o deshabilita la configuración pack.writebitmaps."
+"Los reempaquetados incrementales son incompatibles con las índices de "
+"bitmap.\n"
+"Usa --no-write-bitmap-index o deshabilita la configuración pack.writeBitmaps."
msgid "could not start pack-objects to repack promisor objects"
msgstr "no se puede iniciar pack-objects para reempaquetar objetos promisores"
@@ -10739,16 +10866,14 @@ msgstr "empaquetar todo en un único paquete"
msgid "same as -a, and turn unreachable objects loose"
msgstr "lo mismo que -a, y soltar objetos inalcanzables"
-#, fuzzy
msgid "same as -a, pack unreachable cruft objects separately"
-msgstr "lo mismo que -a, y soltar objetos inalcanzables"
+msgstr "lo mismo que -a, empacar objetos inalcanzables separadamente"
msgid "approxidate"
msgstr "approxidate"
-#, fuzzy
msgid "with -C, expire objects older than this"
-msgstr "caducar objetos más viejos a <tiempo>"
+msgstr "con -C, caducar objetos más viejos a esto"
msgid "remove redundant packs, and run git-prune-packed"
msgstr "eliminar paquetes redundantes, y ejecutar git-prune-packed"
@@ -10815,9 +10940,9 @@ msgstr "no se pueden borrar paquetes en un repositorio de objetos preciosos"
msgid "Nothing new to pack."
msgstr "Nada nuevo para empaquetar."
-#, fuzzy, c-format
+#, c-format
msgid "pack prefix %s does not begin with objdir %s"
-msgstr "el nombre del archivo de paquete '%s' no termina con '.%s'"
+msgstr "el prefijo %s de pack no comienza con el objdir %s"
#, c-format
msgid "missing required file: %s"
@@ -11081,7 +11206,7 @@ msgid "be quiet, only report errors"
msgstr "ser silencioso, solo reportar errores"
msgid "skip refreshing the index after reset"
-msgstr ""
+msgstr "saltar refrescar el índice después de hacer reset"
msgid "reset HEAD and index"
msgstr "reiniciar HEAD e índice"
@@ -11121,14 +11246,13 @@ msgstr "%s reset no está permitido en un repositorio vacío"
msgid "Unstaged changes after reset:"
msgstr "Cambios fuera del área de stage tras el reset:"
-#, fuzzy, c-format
+#, c-format
msgid ""
"It took %.2f seconds to refresh the index after reset. You can use\n"
"'--no-refresh' to avoid this."
msgstr ""
-"\n"
-"Tomó %.2f segundos para calcular los valores anterior/posterior del branch.\n"
-"Puedes usar '--no-ahead-behind' para evitar esto.\n"
+"Tomó %.2f segundos para refrescar el índice después de reiniciar.\n"
+"Se puede usar '--no-refresh' para evitar esto."
#, c-format
msgid "Could not reset index file to revision '%s'."
@@ -11141,12 +11265,16 @@ msgstr "No se puede escribir un nuevo archivo índice."
msgid "unable to get disk usage of %s"
msgstr "no se puede obtener el uso de disco de %s"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "valor inválido para '%s': '%s', el único formato permitido es '%s'"
+
msgid "rev-list does not support display of notes"
msgstr "rev-list no soporta mostrar notas"
-#, fuzzy, c-format
+#, c-format
msgid "marked counting and '%s' cannot be used together"
-msgstr "--reject y --3way no se pueden utilizar juntas."
+msgstr "el conteo marcado y '%s' no pueden ser usados juntos"
msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
msgstr "git rev-parse --parseopt [<opciones>] -- [<args>...]"
@@ -11166,6 +11294,9 @@ msgstr "fin de input prematuro"
msgid "no usage string given before the `--' separator"
msgstr "no se ha entregado cadena antes del separador`--'"
+msgid "missing opt-spec before option flags"
+msgstr "falta opt-spec antes de los flags de opción"
+
msgid "Needed a single revision"
msgstr "Se necesitó una revisión singular"
@@ -11283,7 +11414,7 @@ msgid "keep redundant, empty commits"
msgstr "mantener commits redundantes, vacíos"
msgid "use the 'reference' format to refer to commits"
-msgstr ""
+msgstr "usar el formato 'de referencia' para referir a los commits"
msgid "revert failed"
msgstr "falló al revertir"
@@ -11573,9 +11704,8 @@ msgstr "mostrar refs de stdin que no estén en el repositorio local"
msgid "git sparse-checkout (init|list|set|add|reapply|disable) <options>"
msgstr "git sparse-checkout (init|list|set|add|reapply|disable) <opciones>"
-#, fuzzy
msgid "this worktree is not sparse"
-msgstr "HEAD del árbol de trabajo %s no está actualizada"
+msgstr "este árbol de trabajo no es escaso"
msgid "this worktree is not sparse (sparse-checkout file may not exist)"
msgstr ""
@@ -11597,9 +11727,8 @@ msgstr "falló al borrar directorio '%s'"
msgid "failed to create directory for sparse-checkout file"
msgstr "falló al crear directorio para el archivo sparse-checkout"
-#, fuzzy
msgid "failed to initialize worktree config"
-msgstr "falló al inicializar sparse-checkout"
+msgstr "falló al inicializar la configuración del árbol de trabajo"
msgid "failed to modify sparse-index config"
msgstr "falló al modificar la configuración del índice sparse"
@@ -11629,61 +11758,70 @@ msgstr "no es posible dequote la cadena de estilo C '%s'"
msgid "unable to load existing sparse-checkout patterns"
msgstr "no se pudo cargar patrones de sparse-checkout existentes"
-#, fuzzy
msgid "existing sparse-checkout patterns do not use cone mode"
-msgstr "no se pudo cargar patrones de sparse-checkout existentes"
+msgstr "los patrones de checkout escaso existentes no usan el modo de cono"
msgid "please run from the toplevel directory in non-cone mode"
-msgstr ""
+msgstr "por favor ejecuta desde el directorio superior en el modo no de cono"
msgid "specify directories rather than patterns (no leading slash)"
-msgstr ""
+msgstr "especificar directorios en vez de patrones (sin slash inicial)"
msgid ""
"specify directories rather than patterns. If your directory starts with a "
"'!', pass --skip-checks"
msgstr ""
+"especificar directorios en vez de patrones. Si el directorio comienza con "
+"un '!', se necesita --skip-checks también"
msgid ""
"specify directories rather than patterns. If your directory really has any "
"of '*?[]\\' in it, pass --skip-checks"
msgstr ""
+"especificar directorios en vez de patrones. Si el directorio realmente "
+"lleva cualquier de '*?[]\\', se necesita --skip-checks también"
#, c-format
msgid ""
"'%s' is not a directory; to treat it as a directory anyway, rerun with --"
"skip-checks"
msgstr ""
+"'%s' no es un directorio; para tratarlo como directorio de todas maneras, "
+"ejecuta otra vez con --skip-checks"
#, c-format
msgid ""
"pass a leading slash before paths such as '%s' if you want a single file "
"(see NON-CONE PROBLEMS in the git-sparse-checkout manual)."
msgstr ""
+"pasa un slash inicial antes de rutas como '%s' si quieres un archivo soltero "
+"(mira NON-CONE PROBLEMS en el manual de git-sparse-checkout)."
-#, fuzzy
msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"
-msgstr "git sparse-checkout (set|add) (--stdin | <patrones>)"
+msgstr "git sparse-checkout add [--skip-checks] (--stdin | <patrones>)"
msgid ""
"skip some sanity checks on the given paths that might give false positives"
msgstr ""
+"saltar algunas pruebas de sensatez en las rutas proporcionadas que podrían "
+"resultar en positivos falsos"
msgid "read patterns from standard in"
msgstr "leer patrones de standard in"
-#, fuzzy
msgid "no sparse-checkout to add to"
-msgstr "git sparse-checkout list"
+msgstr "no hay checkout escaso a que añadir"
-#, fuzzy
msgid ""
"git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] "
"(--stdin | <patterns>)"
-msgstr "git sparse-checkout init [--cone] [--[no-]sparse-index]"
+msgstr ""
+"git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] "
+"(--stdin | <patrones>)"
msgid "must be in a sparse-checkout to reapply sparsity patterns"
msgstr ""
+"hay que estar en un checkout escaso para volver a aplicar patrones de escasez"
msgid "error while refreshing working directory"
msgstr "error al refrescar directorio de trabajo"
@@ -11703,7 +11841,6 @@ msgstr "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]"
msgid "git stash branch <branchname> [<stash>]"
msgstr "git stash branch <nombre-de-rama> [<stash>]"
-#, fuzzy
msgid ""
"git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
"quiet]\n"
@@ -11711,18 +11848,19 @@ msgid ""
" [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
" [--] [<pathspec>...]]"
msgstr ""
-"git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
+"git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
+"quiet]\n"
" [-u|--include-untracked] [-a|--all] [-m|--message <mensaje>]\n"
" [--pathspec-from-file=<archivo> [--pathspec-file-nul]]\n"
" [--] [<pathspec>...]]"
-#, fuzzy
msgid ""
"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
"quiet]\n"
" [-u|--include-untracked] [-a|--all] [<message>]"
msgstr ""
-"git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
+"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
+"quiet]\n"
" [-u|--include-untracked] [-a|--all] [<mensaje>]"
msgid "git stash pop [--index] [-q|--quiet] [<stash>]"
@@ -11845,9 +11983,8 @@ msgstr "mensaje de stash"
msgid "\"git stash store\" requires one <commit> argument"
msgstr "\"git stash store\" requiere un argumento <commit>"
-#, fuzzy
msgid "No staged changes"
-msgstr "Sin cambios"
+msgstr "No hay cambios en stage"
msgid "No changes selected"
msgstr "Sin cambios seleccionados"
@@ -11864,9 +12001,8 @@ msgstr "No se pueden guardar los archivos no rastreados"
msgid "Cannot save the current worktree state"
msgstr "No se puede guardar el estado actual del árbol de trabajo"
-#, fuzzy
msgid "Cannot save the current staged state"
-msgstr "No se puede guardar el estado actual del índice"
+msgstr "No se puede guardar el estado actualmente en stage"
msgid "Cannot record working tree state"
msgstr "No se puede grabar el estado del árbol de trabajo"
@@ -11874,9 +12010,9 @@ msgstr "No se puede grabar el estado del árbol de trabajo"
msgid "Can't use --patch and --include-untracked or --all at the same time"
msgstr "No se puede usar --patch y --include-untracked o --all al mismo tiempo"
-#, fuzzy
msgid "Can't use --staged and --include-untracked or --all at the same time"
-msgstr "No se puede usar --patch y --include-untracked o --all al mismo tiempo"
+msgstr ""
+"No se puede usar --staged y --include-untracked o --all al mismo tiempo"
msgid "Did you forget to 'git add'?"
msgstr "¿Olvidaste 'git add'?"
@@ -11901,7 +12037,7 @@ msgid "keep index"
msgstr "mantener index"
msgid "stash staged changes only"
-msgstr ""
+msgstr "hacer stash a solo los cambios en stage"
msgid "stash in patch mode"
msgstr "stash en modo patch"
@@ -11927,6 +12063,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "Se esperaba un nombre de ref completo, se obtuvo %s"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "no se pudo conseguir un handle de repositorio para el submódulo '%s'"
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -11934,12 +12074,6 @@ msgstr ""
"no se pudo encontrar configuración '%s'. Asumiendo que este repositorio es "
"su propio upstream autoritario."
-msgid "alternative anchor for relative paths"
-msgstr "ancho alternativo para rutas relativas"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<ruta>] [<ruta>...]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "No se encontró url para la ruta del submódulo '%s' en .gitmodules"
@@ -11972,12 +12106,12 @@ msgstr "suprime la salida de inicializar cada comando de submódulo"
msgid "recurse into nested submodules"
msgstr "recursar en submódulos anidados"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <comando>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <comando>"
#, c-format
msgid "Failed to register url for submodule path '%s'"
-msgstr "Falló al registrar el url para la ruta del submódulo '%s'"
+msgstr "Falló al registrar el url para la ruta de submódulo '%s'"
#, c-format
msgid "Submodule '%s' (%s) registered for path '%s'\n"
@@ -11986,7 +12120,8 @@ msgstr "Submódulo '%s' (%s) registrado para ruta '%s'\n"
#, c-format
msgid "warning: command update mode suggested for submodule '%s'\n"
msgstr ""
-"peligro: modo de actualización de comandos sugerido para el submódulo '%s'\n"
+"advertencia: modo de actualización de comandos sugerido para el submódulo "
+"'%s'\n"
#, c-format
msgid "Failed to register update mode for submodule path '%s'"
@@ -11996,8 +12131,8 @@ msgstr ""
msgid "suppress output for initializing a submodule"
msgstr "suprime la salida de inicializar un submódulo"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<opciones>] [<path>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<opciones>] [<ruta>]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -12025,9 +12160,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<ruta>...]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <ruta>"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submodule)"
@@ -12064,8 +12196,8 @@ msgstr "omitir submódulos con el valor 'ignore_config' establecido en 'all'"
msgid "limit the summary size"
msgstr "limitar el tamaño de resumen"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<opciones>] [<commit>] [--] [<ruta>]"
msgid "could not fetch a revision for HEAD"
msgstr "no se puede obtener la revisión para HEAD"
@@ -12076,29 +12208,25 @@ msgstr "Sincronizando url del submódulo para '%s'\n"
#, c-format
msgid "failed to register url for submodule path '%s'"
-msgstr "falló al registrar el url para la ruta del submódulo '%s'"
-
-#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "error al conseguir el remoto por defecto para el submódulo '%s'"
+msgstr "falló al registrar el url para la ruta de submódulo '%s'"
#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "error al actualizar el remoto para el submódulo '%s'"
msgid "suppress output of synchronizing submodule url"
-msgstr "suprime la salida de sincronizar el url del submódulo"
+msgstr "suprimir la salida de sincronizar el url del submódulo"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<ruta>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<ruta>]"
-#, fuzzy, c-format
+#, c-format
msgid ""
"Submodule work tree '%s' contains a .git directory. This will be replaced "
"with a .git file by using absorbgitdirs."
msgstr ""
-"El árbol de trabajo de submódulo '%s' contiene un directorio .git (usa 'rm -"
-"rf' si realmente quieres eliminarlo incluyendo todo en su historia)"
+"El árbol de trabajo de submódulo '%s' contiene un directorio .git. Este será "
+"reemplazado con un archivo .git usando absorbgitdirs."
#, c-format
msgid ""
@@ -12153,6 +12281,11 @@ msgstr ""
"'--reference-if-able' en lugar de '--reference'."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr ""
+"no se pudo conseguir un handle de repositorio para el directorio de git '%s'"
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "submódulo '%s' no puede agregar alterno: %s"
@@ -12180,6 +12313,9 @@ msgstr "directorio no está vacío: '%s'"
msgid "could not get submodule directory for '%s'"
msgstr "no se pudo obtener el directorio de submódulo para '%s'"
+msgid "alternative anchor for relative paths"
+msgstr "ancla alternativa para rutas relativas"
+
msgid "where the new submodule will be cloned to"
msgstr "a donde el nuevo submódulo será clonado"
@@ -12198,19 +12334,14 @@ msgstr "forzar el proceso de clonación"
msgid "disallow cloning into non-empty directory"
msgstr "no permitir clonar en directorios no vacíos"
-#, fuzzy
msgid ""
"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
"<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter "
"<filter-spec>] --url <url> --path <path>"
msgstr ""
"git submodule--helper clone [--prefix=<ruta>] [--quiet] [--reference "
-"<repositorio>] [--name <nombre>] [--depth <profundidad>] [--single-branch] --"
-"url <url> --path <ruta>"
-
-#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Modo de actualización inválido '%s' para ruta de submódulo '%s'"
+"<repositorio>] [--name <nombre>] [--depth <profundidad>] [--single-branch] "
+"[--filter <especificación-de-filtro>] --url <url> --path <ruta>"
#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
@@ -12287,6 +12418,10 @@ msgstr ""
"directo del commit falló."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "no se pudo inicializar el submódulo a la ruta '%s'"
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -12295,42 +12430,32 @@ msgstr ""
"el superproyecto no está en ninguna rama"
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "no se pudo conseguir un handle de repositorio para el submódulo '%s'"
-
-#, fuzzy, c-format
msgid "Unable to find current revision in submodule path '%s'"
-msgstr ""
-"No se pudo encontrar la revisión actual en la ruta de submódulo "
-"'$displaypath'"
+msgstr "Incapaz de encontrar la revisión actual en la ruta de submódulo '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "Unable to fetch in submodule path '%s'"
-msgstr "No es posible realizar fetch en la ruta de submódulo '$sm_path'"
+msgstr "Incapaz de realizar fetch en la ruta de submódulo '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "Unable to find %s revision in submodule path '%s'"
-msgstr ""
-"No se pudo encontrar la revisión actual en la ruta de submódulo "
-"'$displaypath'"
+msgstr "Incapaz de encontrar la revisión %s en la ruta de submódulo '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "Failed to recurse into submodule path '%s'"
-msgstr "falló al recursar en el submódulo '%s'"
+msgstr "Falló al recursar en la ruta de submódulo '%s'"
msgid "force checkout updates"
msgstr "forzar actualizaciones de checkout"
-#, fuzzy
msgid "initialize uninitialized submodules before update"
-msgstr "inicializar submódulos en el clon"
+msgstr "inicializar submódulos no inicializados antes de actualizar"
-#, fuzzy
msgid "use SHA-1 of submodule's remote tracking branch"
-msgstr "cualquier submódulo clonado usará su branch de rastreo remoto"
+msgstr "usar el SHA-1 de la rama remota que el submódulo rastrea"
msgid "traverse submodules recursively"
-msgstr ""
+msgstr "atravesar los submódulos recursivamente"
msgid "don't fetch new objects from the remote site"
msgstr "no recuperar objetos nuevos del sitio remoto"
@@ -12338,11 +12463,14 @@ msgstr "no recuperar objetos nuevos del sitio remoto"
msgid "path into the working tree"
msgstr "ruta al árbol de trabajo"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "ruta al árbol de trabajo, a través de fronteras de submódulos anidados"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "usar la estrategia de actualización 'checkout' (por defecto)"
-msgid "rebase, merge, checkout or none"
-msgstr "rebase, merge, checkout o none"
+msgid "use the 'merge' update strategy"
+msgstr "usar la estrategia de actualización 'merge'"
+
+msgid "use the 'rebase' update strategy"
+msgstr "usar la estrategia de actualización 'rebase'"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr "crea un clon superficial truncado al número especificado de revisiones"
@@ -12356,21 +12484,25 @@ msgstr "si el clon inicial debe seguir la recomendación de superficialidad"
msgid "don't print cloning progress"
msgstr "no mostrar el progreso de clonación"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "no permitir clonar en directorios no vacíos, implica --init"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
"shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] "
"[--] [<path>...]"
msgstr ""
-
-msgid "bad value for update parameter"
-msgstr "mal valor para parámetro update"
+"git submodule [--quiet] update [--init [--filter=<especificación-de-"
+"filtro>]] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--"
+"rebase] [--[no-]recommend-shallow] [--reference <repositorio>] [--recursive] "
+"[--[no-]single-branch] [--] [<ruta>...]"
msgid "recurse into submodules"
msgstr "recurrir a submódulos"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<opciones>] [<path>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<opciones>] [<ruta>...]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr "revisar si es seguro escribir al archivo .gitmodules"
@@ -12391,8 +12523,8 @@ msgstr ""
msgid "suppress output for setting url of a submodule"
msgstr "suprime la salida de inicializar la url de un submódulo"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <ruta> <nueva url>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <ruta> <url-nuevo>"
msgid "set the default tracking branch to master"
msgstr "configurar la rama de rastreo por defecto a master"
@@ -12400,13 +12532,11 @@ msgstr "configurar la rama de rastreo por defecto a master"
msgid "set the default tracking branch"
msgstr "configurar la rama de rastreo por defecto"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <ruta>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <ruta>"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <rama> <ruta>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <rama> <ruta>"
msgid "--branch or --default required"
msgstr "--branch o --default requerido"
@@ -12415,20 +12545,21 @@ msgid "print only error messages"
msgstr "mostrar solo mensajes de error"
msgid "force creation"
-msgstr ""
+msgstr "forzar creación"
-#, fuzzy
msgid "show whether the branch would be created"
-msgstr "mostrar lo que sería incluido en el commit"
+msgstr "mostrar si la rama sería creada"
msgid ""
"git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--"
"quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"
msgstr ""
+"git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--"
+"quiet] [-t|--track] [-n|--dry-run] <nombre> <oid-inicial> <nombre-inicial>"
-#, fuzzy, c-format
+#, c-format
msgid "creating branch '%s'"
-msgstr "Reiniciar rama '%s'\n"
+msgstr "creando la rama '%s'"
#, c-format
msgid "Adding existing repo at '%s' to the index\n"
@@ -12497,16 +12628,15 @@ msgstr "permitir agregar una ruta de submódulo que de otro modo se ignora"
msgid "borrow the objects from reference repositories"
msgstr "prestar los objetos de los repositorios de referencia"
-#, fuzzy
msgid ""
"sets the submodule's name to the given string instead of defaulting to its "
"path"
msgstr ""
-"configura el nombre del submódulo para el string dado en lugar de ir a la "
-"ruta por defecto"
+"configura el nombre del submódulo a la cadena proporcionada en lugar de usar "
+"por defecto la ruta suya"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<options>] [--] <repository> [<path>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<opciones>] [--] <repositorio> [<ruta>]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr ""
@@ -12690,9 +12820,9 @@ msgstr "solo imprimir las tags que no estén fusionadas"
msgid "print only tags of the object"
msgstr "solo imprimir tags del objeto"
-#, fuzzy, c-format
+#, c-format
msgid "the '%s' option is only allowed in list mode"
-msgstr "opción -n solo es permitida en modo lista"
+msgstr "la opción '%s' solo es permitida en el modo de lista"
#, c-format
msgid "'%s' is not a valid tag name."
@@ -12713,6 +12843,16 @@ msgstr "Etiqueta '%s' actualizada (era %s)\n"
msgid "pack exceeds maximum allowed size"
msgstr "paquete excede el máximo tamaño permitido"
+msgid "failed to write object in stream"
+msgstr "falló al escribir objeto al stream"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "inflate devolvió (%d)"
+
+msgid "invalid blob object from stream"
+msgstr "objeto blob inválido del stream"
+
msgid "Unpacking objects"
msgstr "Desempaquetando objetos"
@@ -13000,9 +13140,8 @@ msgstr "git worktree prune [<opciones>]"
msgid "git worktree remove [<options>] <worktree>"
msgstr "git worktree remove [<opciones>] <worktree>"
-#, fuzzy
msgid "git worktree repair [<path>...]"
-msgstr "git worktree prune [<opciones>]"
+msgstr "git worktree repair [<ruta>...]"
msgid "git worktree unlock <path>"
msgstr "git worktree unlock <ruta>"
@@ -13045,14 +13184,16 @@ msgstr ""
#, c-format
msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly"
msgstr ""
+"falló al copiar '%s' a '%s'; puede que el checkout escaso no funcione "
+"correctamente"
-#, fuzzy, c-format
+#, c-format
msgid "failed to copy worktree config from '%s' to '%s'"
-msgstr "falló al copiar notas de '%s' a '%s'"
+msgstr "falló al copiar la configuración del árbol de trabajo de '%s' a '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "failed to unset '%s' in '%s'"
-msgstr "falló al mover '%s' a '%s'"
+msgstr "falló al desconfigurar '%s' en '%s'"
#, c-format
msgid "could not create directory of '%s'"
@@ -13104,9 +13245,9 @@ msgid "try to match the new branch name with a remote-tracking branch"
msgstr ""
"intentar emparejar el nuevo nombre de rama con una rama de rastreo remoto"
-#, fuzzy, c-format
+#, c-format
msgid "options '%s', '%s', and '%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '%s', '%s' y '%s' no pueden ser usadas juntas"
msgid "added with --lock"
msgstr "agregado con --lock"
@@ -13121,9 +13262,8 @@ msgid "add 'prunable' annotation to worktrees older than <time>"
msgstr ""
"agregar la anotación 'podable' a los árboles de trabajo anteriores a <tiempo>"
-#, fuzzy
msgid "terminate records with a NUL character"
-msgstr "terminar registros de entrada y salida con un carácter NUL"
+msgstr "terminar registros con un carácter NUL"
#, c-format
msgid "'%s' is not a working tree"
@@ -13238,6 +13378,27 @@ msgstr "escribir objeto de árbol para un subdirectorio <prefijo>"
msgid "only useful for debugging"
msgstr "solo útil para depurar"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch no es soportado en este plataforma"
+
+msgid "failed to create temporary file"
+msgstr "falló al crear archivo temporal"
+
+msgid "insufficient capabilities"
+msgstr "capacidades insuficientes"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "falló al descargar bundle del URI '%s'"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "el archivo al URI '%s' no es un bundle"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "falló al extraer bundle del URI '%s'"
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
msgstr "algoritmo bundle hash desconocido %s"
@@ -13260,20 +13421,20 @@ msgstr "Al repositorio le faltan estos commits prerrequisitos:"
msgid "need a repository to verify a bundle"
msgstr "se necesita un repositorio para verificar un bundle"
-#, fuzzy, c-format
+#, c-format
msgid "The bundle contains this ref:"
msgid_plural "The bundle contains these %<PRIuMAX> refs:"
msgstr[0] "El bundle contiene esta referencia:"
-msgstr[1] "El bundle contiene estas %d referencias:"
+msgstr[1] "El bundle contiene estas %<PRIuMAX> referencias:"
msgid "The bundle records a complete history."
msgstr "El bundle registra una historia completa."
-#, fuzzy, c-format
+#, c-format
msgid "The bundle requires this ref:"
msgid_plural "The bundle requires these %<PRIuMAX> refs:"
msgstr[0] "El bundle requiere esta referencia:"
-msgstr[1] "El bundle requiere estas %d referencias:"
+msgstr[1] "El bundle requiere estas %<PRIuMAX> referencias:"
msgid "unable to dup bundle descriptor"
msgstr "incapaz de duplicar bundle descriptor"
@@ -13445,6 +13606,9 @@ msgstr ""
"Dar a un objeto un nombre legible por humanos basado en una referencia "
"disponible"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Generar una crónica zip de información diagnóstica"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr "Mostrar los cambios entre commits, commit y árbol de trabajo, etc"
@@ -13512,7 +13676,7 @@ msgid "Display help information about Git"
msgstr "Mostrar información de ayuda sobre Git"
msgid "Run git hooks"
-msgstr ""
+msgstr "Ejecutar hooks de git"
msgid "Server side implementation of Git over HTTP"
msgstr "Implementación de lado de servidor de Git por HTTP"
@@ -13574,8 +13738,8 @@ msgstr "Ejecutar una fusión para archivos que la necesiten"
msgid "The standard helper program to use with git-merge-index"
msgstr "El programa de ayuda estándar para usar con git-merge-index"
-msgid "Show three-way merge without touching index"
-msgstr "Mostrar fusión de tres vías sin tocar el índice"
+msgid "Perform merge without touching index or working tree"
+msgstr "Realizar fusión sin tocar el índice o el árbol de trabajo"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr ""
@@ -13709,9 +13873,8 @@ msgstr "Mostrar el índice de crónica empaquetado"
msgid "List references in a local repository"
msgstr "Listar referencias en el repositorio local"
-#, fuzzy
msgid "Reduce your working tree to a subset of tracked files"
-msgstr " (usa la opción -u para mostrar los archivos sin seguimiento)"
+msgstr "Reducir el árbol de trabajo a un subconjunto de archivos rastreados"
msgid "Add file contents to the staging area"
msgstr "Agregar contenidos de un archivo al área de staging"
@@ -13776,6 +13939,9 @@ msgstr "Validar crónicas Git empaquetadas"
msgid "Check the GPG signature of tags"
msgstr "Verificar la firma GPG de etiquetas"
+msgid "Display version information about Git"
+msgstr "Mostrar información de versión sobre Git"
+
msgid "Show logs with difference each commit introduces"
msgstr "Mostrar logs con las diferencias que cada commit introduce"
@@ -13809,6 +13975,24 @@ msgstr "Un conjunto mínimo útil de comandos cotidianos de Git"
msgid "Frequently asked questions about using Git"
msgstr "Preguntas frecuentes sobre el uso de Git"
+msgid "The bundle file format"
+msgstr "Formato de archivo de bundle"
+
+msgid "Chunk-based file formats"
+msgstr "Formatos de archivo basados en fragmentos"
+
+msgid "Git commit graph format"
+msgstr "Formato de grafo de commits de Git"
+
+msgid "Git index format"
+msgstr "Formato de índice de Git"
+
+msgid "Git pack format"
+msgstr "Formato de pack de Git"
+
+msgid "Git cryptographic signature formats"
+msgstr "Formatos de firma criptográfica de Git"
+
msgid "A Git Glossary"
msgstr "Un Glosario de Git"
@@ -13832,6 +14016,21 @@ msgstr "Definir las propiedades de submódulo"
msgid "Git namespaces"
msgstr "Namespaces de Git"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Capacidades de los protocolos v0 y v1"
+
+msgid "Things common to various protocols"
+msgstr "Cosas en común entre varios protocolos"
+
+msgid "Git HTTP-based protocols"
+msgstr "Protocolos de Git basados en HTTP"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Cómo los packs se transfieren en el alambre"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Protocolo de alambre de Git, versión 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Programas de ayuda para interactuar con repositorios remotos"
@@ -13856,6 +14055,9 @@ msgstr "Interfaz web Git (interfaz web para repositorios Git)"
msgid "An overview of recommended workflows with Git"
msgstr "Una visión general de flujos de trabajo recomendados con Git"
+msgid "A tool for managing large Git repositories"
+msgstr "Una herramienta para gestionar repositorios de Git grandes"
+
msgid "commit-graph file is too small"
msgstr "archivo commit-graph es demasiado pequeño"
@@ -13921,11 +14123,11 @@ msgstr "Calculando números de generación de commit graph"
msgid "Collecting referenced commits"
msgstr "Recolectando commits referenciados"
-#, fuzzy, c-format
+#, c-format
msgid "Finding commits for commit graph in %<PRIuMAX> pack"
msgid_plural "Finding commits for commit graph in %<PRIuMAX> packs"
-msgstr[0] "Encontrando commits para commit graph en %d pack"
-msgstr[1] "Encontrando commits para commit graph en %d packs"
+msgstr[0] "Encontrando commits para el grafo de commits en %<PRIuMAX> pack"
+msgstr[1] "Encontrando commits para el grafo de commits en %<PRIuMAX> packs"
#, c-format
msgid "error adding pack %s"
@@ -14087,12 +14289,12 @@ msgstr "El commit %s tiene una buena firma GPG por %s\n"
msgid ""
"Warning: commit message did not conform to UTF-8.\n"
"You may want to amend it after fixing the message, or set the config\n"
-"variable i18n.commitencoding to the encoding your project uses.\n"
+"variable i18n.commitEncoding to the encoding your project uses.\n"
msgstr ""
-"Peligro: el mensaje del commit no se ajusta a UTF-8.\n"
+"Advertencia: el mensaje del commit no se ajusta a UTF-8.\n"
"Tal vez quieras enmendarlo después de arreglar el mensaje, o arreglar la\n"
-"variable de configuración i18n.commitencoding para la codificación que use "
-"tu proyecto.\n"
+"variable de configuración i18n.commitEncoding para la codificación que el "
+"proyecto use.\n"
msgid "no compiler information available\n"
msgstr "no hay información disponible del compilador\n"
@@ -14100,138 +14302,140 @@ msgstr "no hay información disponible del compilador\n"
msgid "no libc information available\n"
msgstr "no hay información disponible de libc\n"
-#, fuzzy, c-format
+#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "no se pudo determinar el espacio de disco libre de '%s'"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "no se pudo averiguar la información de '%s'"
+
+#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
-msgstr "no se pudo abrir '%s'"
+msgstr "[GLE %ld] el hilo de salud no pudo abrir '%ls'"
#, c-format
msgid "[GLE %ld] health thread getting BHFI for '%ls'"
-msgstr ""
+msgstr "[GLE %ld] hilo de salud averiguando BHFI de '%ls'"
-#, fuzzy, c-format
+#, c-format
msgid "could not convert to wide characters: '%s'"
-msgstr ""
-"no se pudo convertir el siguiente graft(s):\n"
-"%s"
+msgstr "no se pudo convertir a caracteres anchos: '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "BHFI changed '%ls'"
-msgstr "no se puede cambiar a '%s'"
+msgstr "BHFI cambió '%ls'"
#, c-format
msgid "unhandled case in 'has_worktree_moved': %d"
-msgstr ""
+msgstr "caso no manejado en 'has_worktree_moved': %d"
#, c-format
msgid "health thread wait failed [GLE %ld]"
-msgstr ""
+msgstr "falló la espera del hilo de salud [GLE %ld]"
-#, fuzzy
msgid "Unable to create FSEventStream."
-msgstr "no es posible crear hilo: %s"
+msgstr "Incapaz de crear FSEventStream."
-#, fuzzy
msgid "Failed to start the FSEventStream"
-msgstr "Falló al iniciar emacsclient."
+msgstr "Falló al iniciar el FSEventStream"
#, c-format
msgid "[GLE %ld] could not convert path to UTF-8: '%.*ls'"
-msgstr ""
+msgstr "[GLE %ld] no se pudo convertir la ruta a UTF-8: '%.*ls'"
-#, fuzzy, c-format
+#, c-format
msgid "[GLE %ld] could not watch '%s'"
-msgstr "no se pudo hacer stat en '%s'"
+msgstr "[GLE %ld] no se pudo vigilar '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "[GLE %ld] could not get longname of '%s'"
-msgstr "no se pudo conseguir 'onto': '%s'"
+msgstr "[GLE %ld] no se pudo averiguar el nombre largo de '%s'"
#, c-format
msgid "ReadDirectoryChangedW failed on '%s' [GLE %ld]"
-msgstr ""
+msgstr "Falló ReadDirectoryChangedW en '%s' [GLE %ld]"
#, c-format
msgid "GetOverlappedResult failed on '%s' [GLE %ld]"
-msgstr ""
+msgstr "Falló GetOverlappedResult en '%s' [GLE %ld]"
-#, fuzzy, c-format
+#, c-format
msgid "could not read directory changes [GLE %ld]"
-msgstr "no se pudo crear directorios para %s"
+msgstr "no se pudo leer los cambios de directorio [GLE %ld]"
+
+#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] incapaz de abrir para leer '%ls'"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] incapaz de averiguar la información de protocolo de '%ls'"
-#, fuzzy, c-format
+#, c-format
msgid "failed to copy SID (%ld)"
-msgstr "falló al copiar archivo a '%s'"
+msgstr "falló al copiar SID (%ld)"
-#, fuzzy, c-format
+#, c-format
msgid "failed to get owner for '%s' (%ld)"
-msgstr "falló al iterar sobre '%s'"
+msgstr "falló al averiguar el propietario de '%s' (%ld)"
msgid "memory exhausted"
msgstr "memoria agotada"
msgid "Success"
-msgstr ""
+msgstr "Éxito"
msgid "No match"
-msgstr ""
+msgstr "Ninguna coincidencia"
-#, fuzzy
msgid "Invalid regular expression"
-msgstr "usar expresiones regulares POSIX extendidas"
+msgstr "Expresión regular inválida"
-#, fuzzy
msgid "Invalid collation character"
-msgstr "carácter lastre"
+msgstr "Carácter de colación inválido"
-#, fuzzy
msgid "Invalid character class name"
-msgstr "carácter inválido en el nombre del host"
+msgstr "Nombre de clase de carácter inválido"
msgid "Trailing backslash"
-msgstr ""
+msgstr "Backslash al final"
-#, fuzzy
msgid "Invalid back reference"
-msgstr "referencia inválida: %s"
+msgstr "Referencia atrás inválida"
msgid "Unmatched [ or [^"
-msgstr ""
+msgstr "[ o [^ sin pareja"
msgid "Unmatched ( or \\("
-msgstr ""
+msgstr "( o \\( sin pareja"
msgid "Unmatched \\{"
-msgstr ""
+msgstr "\\{ sin pareja"
-#, fuzzy
msgid "Invalid content of \\{\\}"
-msgstr "contenido inválido: '%s'"
+msgstr "Contenido inválido de \\{\\}"
-#, fuzzy
msgid "Invalid range end"
-msgstr "codificación de transferencia inválida"
+msgstr "Fin inválido de rango"
-#, fuzzy
msgid "Memory exhausted"
-msgstr "memoria agotada"
+msgstr "Memoria agotada"
-#, fuzzy
msgid "Invalid preceding regular expression"
-msgstr "usar expresiones regulares POSIX extendidas"
+msgstr "Expresión regular precedente inválida"
-#, fuzzy
msgid "Premature end of regular expression"
-msgstr "usar expresiones regulares POSIX extendidas"
+msgstr "Fin prematuro de expresión regular"
msgid "Regular expression too big"
-msgstr ""
+msgstr "Expresión regular demasiada larga"
msgid "Unmatched ) or \\)"
-msgstr ""
+msgstr ") o \\) sin pareja"
-#, fuzzy
msgid "No previous regular expression"
-msgstr "usar expresiones regulares compatibles con Perl"
+msgstr "No hay expresión regular previa"
msgid "could not send IPC command"
msgstr "no se pudo enviar el comando IPC"
@@ -14247,28 +14451,27 @@ msgstr "no se pudo iniciar el accept_thread '%s'"
msgid "could not start worker[0] for '%s'"
msgstr "no se pudo iniciar el worker[0] para '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "ConnectNamedPipe failed for '%s' (%lu)"
-msgstr "uname() falló con error '%s' (%d)\n"
+msgstr "ConnectNamedPipe falló en '%s' (%lu)"
-#, fuzzy, c-format
+#, c-format
msgid "could not create fd from pipe for '%s'"
-msgstr "no se pudo crear directorios para %s"
+msgstr "no se pudo crear descriptor de archivo del pipe para '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "could not start thread[0] for '%s'"
-msgstr "no se pudo iniciar el worker[0] para '%s'"
+msgstr "no se pudo iniciar thread[0] para '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "wait for hEvent failed for '%s'"
-msgstr "Autenticación falló para '%s'"
+msgstr "espera de hEvent falló en '%s'"
msgid "cannot resume in the background, please use 'fg' to resume"
-msgstr ""
+msgstr "no se puede resumir en el fondo, por favor usa 'fg' para resumir"
-#, fuzzy
msgid "cannot restore terminal settings"
-msgstr "no se puede guardar el archivo índice"
+msgstr "no se puede restaurar la configuración de terminal"
#, c-format
msgid ""
@@ -14299,6 +14502,8 @@ msgid ""
"remote URLs cannot be configured in file directly or indirectly included by "
"includeIf.hasconfig:remote.*.url"
msgstr ""
+"no se pueden configurar URLs remotos en archivo incluido directa o "
+"indirectamente por includeIf.hasconfig:remote.*.url"
#, c-format
msgid "invalid config format: %s"
@@ -14415,13 +14620,13 @@ msgstr ""
msgid "bad numeric config value '%s' for '%s' in %s: %s"
msgstr "mal valor de config numérico '%s' para '%s' en %s: %s"
-#, fuzzy, c-format
+#, c-format
msgid "invalid value for variable %s"
-msgstr "valor inválido para %s"
+msgstr "valor inválido para la variable %s"
#, c-format
msgid "ignoring unknown core.fsync component '%s'"
-msgstr ""
+msgstr "ignorando componente desconocido de core.fsync '%s'"
#, c-format
msgid "bad boolean config value '%s' for '%s'"
@@ -14448,10 +14653,10 @@ msgstr "core.commentChar debería tener solo un carácter"
#, c-format
msgid "ignoring unknown core.fsyncMethod value '%s'"
-msgstr ""
+msgstr "ignorando valor desconocido de core.fsyncMethod '%s'"
msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead"
-msgstr ""
+msgstr "core.fsyncObjectFiles es deprecado; usa core.fsync en su lugar"
#, c-format
msgid "invalid mode for object creation: %s"
@@ -14708,190 +14913,6 @@ msgid "failed to close rev-list's stdin"
msgstr "falló al cerrar la entrada standard de rev-list"
#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' no existe"
-
-#, fuzzy
-msgid "need a working directory"
-msgstr "Incapaz de leer el directorio de trabajo actual"
-
-#, fuzzy
-msgid "could not find enlistment root"
-msgstr "no se pudo encontrar commit %s"
-
-#, fuzzy, c-format
-msgid "could not switch to '%s'"
-msgstr "no se pudo cambiar a %s"
-
-#, fuzzy, c-format
-msgid "could not configure %s=%s"
-msgstr "no se pudo bloquear archivo de configuración %s"
-
-msgid "could not configure log.excludeDecoration"
-msgstr ""
-
-msgid "Scalar enlistments require a worktree"
-msgstr ""
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "no se pudo abrir el directorio '%s'"
-
-#, fuzzy, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "destino '%s' no es un directorio"
-
-#, fuzzy, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "no se pudo crear un árbol de trabajo '%s'"
-
-#, fuzzy, c-format
-msgid "could not get info for '%s'"
-msgstr "no se pudo leer el log para '%s'"
-
-#, fuzzy, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr " Rama HEAD: %s"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-
-#, fuzzy
-msgid "failed to get default branch name"
-msgstr "falló al formatear el valor por defecto de configuración: %s"
-
-#, fuzzy
-msgid "failed to unregister repository"
-msgstr "falló al crear directorio %s"
-
-#, fuzzy
-msgid "failed to delete enlistment directory"
-msgstr "falló al eliminar directorio %s"
-
-msgid "branch to checkout after clone"
-msgstr ""
-
-#, fuzzy
-msgid "when cloning, create full working directory"
-msgstr "no es posible obtener el directorio de trabajo actual"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr ""
-
-#, fuzzy
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "git clone [<opciones>] [--] <repo> [<directorio>]"
-
-#, fuzzy, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "No se puede acceder al árbol de trabajo '%s'"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr ""
-
-#, fuzzy, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "error al conseguir el remoto por defecto para el submódulo '%s'"
-
-#, fuzzy, c-format
-msgid "could not configure remote in '%s'"
-msgstr "no se pudo crear el archivo '%s'"
-
-#, fuzzy, c-format
-msgid "could not configure '%s'"
-msgstr "no se pudo cerrar '%s'"
-
-msgid "partial clone failed; attempting full clone"
-msgstr ""
-
-#, fuzzy
-msgid "could not configure for full clone"
-msgstr "no se pudo bloquear archivo de configuración %s"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr ""
-
-#, fuzzy, c-format
-msgid "could not create directory for '%s'"
-msgstr "No se pudo crear el directorio para '%s'"
-
-#, fuzzy
-msgid "could not duplicate stdout"
-msgstr "no se puede actualizar %s"
-
-#, fuzzy
-msgid "failed to write archive"
-msgstr "falló al leer la cache"
-
-#, fuzzy
-msgid "`scalar list` does not take arguments"
-msgstr "%%(rest) no toma ningún argumento"
-
-msgid "scalar register [<enlistment>]"
-msgstr ""
-
-msgid "reconfigure all registered enlistments"
-msgstr ""
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr ""
-
-msgid "--all or <enlistment>, but not both"
-msgstr ""
-
-#, fuzzy, c-format
-msgid "git repository gone in '%s'"
-msgstr "no es un repositorio git: '%s'"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-
-#, fuzzy, c-format
-msgid "no such task: '%s'"
-msgstr "no existe tal rama: '%s'"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr ""
-
-msgid "scalar delete <enlistment>"
-msgstr ""
-
-#, fuzzy
-msgid "refusing to delete current working directory"
-msgstr "no es posible obtener el directorio de trabajo actual"
-
-#, fuzzy
-msgid "include Git version"
-msgstr "versión de hash inválida"
-
-msgid "include Git's build options"
-msgstr ""
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr ""
-
-#, fuzzy
-msgid "-C requires a <directory>"
-msgstr "--stdin requiere un repositorio git"
-
-#, fuzzy, c-format
-msgid "could not change to '%s'"
-msgstr "no se puede cambiar a '%s'"
-
-#, fuzzy
-msgid "-c requires a <key>=<value> argument"
-msgstr "-n requiere un argumento"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "crlf_action %d ilegal"
@@ -14904,6 +14925,8 @@ msgid ""
"in the working copy of '%s', CRLF will be replaced by LF the next time Git "
"touches it"
msgstr ""
+"en la copia de trabajo de '%s', CRLF será reemplazado con LF la próxima vez "
+"que Git la toque"
#, c-format
msgid "LF would be replaced by CRLF in %s"
@@ -14914,6 +14937,8 @@ msgid ""
"in the working copy of '%s', LF will be replaced by CRLF the next time Git "
"touches it"
msgstr ""
+"en la copia de trabajo de '%s', LF será reemplazado con CRLF la próxima vez "
+"que Git la toque"
#, c-format
msgid "BOM is prohibited in '%s' if encoded as %s"
@@ -15092,6 +15117,32 @@ msgstr "regex isla de config tiene demasiados grupos de captura (max=%d)"
msgid "Marked %d islands, done.\n"
msgstr "%d islas marcadas, listo.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "valor de --%s inválido '%s'"
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "no se pudo archivar el directorio faltante '%s'"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "no se pudo abrir el directorio '%s'"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "saltando '%s', el cual no es ni archivo ni directorio"
+
+msgid "could not duplicate stdout"
+msgstr "no se pudo duplicar stdout"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "no se pudo añadir el directorio '%s' al cronista"
+
+msgid "failed to write archive"
+msgstr "falló al escribir crónica"
+
msgid "--merge-base does not work with ranges"
msgstr "--merge-base no funciona con rangos"
@@ -15165,18 +15216,21 @@ msgstr ""
msgid "external diff died, stopping at %s"
msgstr "diff externo murió, deteniendo en %s"
-#, fuzzy, c-format
+#, c-format
msgid "options '%s', '%s', '%s', and '%s' cannot be used together"
-msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
+msgstr "las opciones '%s', '%s', '%s' y '%s' no pueden ser usadas juntas"
-#, fuzzy, c-format
+#, c-format
msgid "options '%s' and '%s' cannot be used together, use '%s' with '%s'"
-msgstr "'%s' o '%s' no puede ser usado con %s"
+msgstr ""
+"las opciones '%s' y '%s' no pueden ser usadas juntas, usa '%s' con '%s'"
-#, fuzzy, c-format
+#, c-format
msgid ""
"options '%s' and '%s' cannot be used together, use '%s' with '%s' and '%s'"
-msgstr "'%s' o '%s' no puede ser usado con %s"
+msgstr ""
+"las opciones '%s' y '%s' no pueden ser usadas juntas, usa '%s' con '%s' y "
+"'%s'"
msgid "--follow requires exactly one pathspec"
msgstr "--follow requiere exactamente un pathspec"
@@ -15596,9 +15650,8 @@ msgstr "seleccionar archivos por tipo de diff"
msgid "<file>"
msgstr "<archivo>"
-#, fuzzy
msgid "output to a specific file"
-msgstr "Output a un archivo específico"
+msgstr "emitir a un archivo específico"
msgid "exhaustive rename detection was skipped due to too many files."
msgstr ""
@@ -15714,6 +15767,9 @@ msgstr "git fetch-pack: se esperaba ACK/NAK, se obtuvo '%s'"
msgid "unable to write to remote"
msgstr "no se puede escribir al remoto"
+msgid "Server supports filter"
+msgstr "El servidor soporta filtración"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "línea shallow inválida: %s"
@@ -15824,9 +15880,6 @@ msgstr "el servidor no soporta el algoritmo '%s'"
msgid "Server does not support shallow requests"
msgstr "El servidor no soporta peticiones superficiales"
-msgid "Server supports filter"
-msgstr "El servidor soporta filtración"
-
msgid "unable to write request to remote"
msgstr "no se puede escribir request al remoto"
@@ -15834,9 +15887,9 @@ msgstr "no se puede escribir request al remoto"
msgid "expected '%s', received '%s'"
msgstr "se esperaba '%s', se recibió '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "expected '%s'"
-msgstr "línea inesperada: '%s'"
+msgstr "se esperó '%s'"
#, c-format
msgid "unexpected acknowledgment line: '%s'"
@@ -15849,16 +15902,17 @@ msgstr "error al procesar acks: %d"
#. TRANSLATORS: The parameter will be 'ready', a protocol
#. keyword.
#.
-#, fuzzy, c-format
+#, c-format
msgid "expected packfile to be sent after '%s'"
-msgstr "se esperaba que el packfile fuera enviado luego del 'listo'"
+msgstr "se esperaba que el archivo de pack fuera enviado luego del '%s'"
#. TRANSLATORS: The parameter will be 'ready', a protocol
#. keyword.
#.
-#, fuzzy, c-format
+#, c-format
msgid "expected no other sections to be sent after no '%s'"
-msgstr "se esperaba que ninguna otra sección fuera enviada luego del 'listo'"
+msgstr ""
+"se esperaba que ninguna otra sección fuera enviada luego de la falta de '%s'"
#, c-format
msgid "error processing shallow info: %d"
@@ -15895,41 +15949,42 @@ msgstr "El servidor no permite solicitudes de objetos inadvertidos %s"
#, c-format
msgid "fsmonitor_ipc__send_query: invalid path '%s'"
-msgstr ""
+msgstr "fsmonitor_ipc__send_query: ruta inválida '%s'"
#, c-format
msgid "fsmonitor_ipc__send_query: unspecified error on '%s'"
-msgstr ""
+msgstr "fsmonitor_ipc__send_query: error no especificado en '%s'"
msgid "fsmonitor--daemon is not running"
-msgstr ""
+msgstr "fsmonitor--daemon no está ejecutándose"
-#, fuzzy, c-format
+#, c-format
msgid "could not send '%s' command to fsmonitor--daemon"
-msgstr "no se pudo enviar el comando IPC"
+msgstr "no se pudo enviar el comando '%s' a fsmonitor--daemon"
-#, fuzzy, c-format
+#, c-format
msgid "bare repository '%s' is incompatible with fsmonitor"
-msgstr "%s es incompatible con %s"
+msgstr "el repositorio desnudo '%s es incompatible con fsmonitor"
#, c-format
msgid "repository '%s' is incompatible with fsmonitor due to errors"
-msgstr ""
+msgstr "el repositorio '%s' es incompatible con fsmonitor a causa de errores"
-#, fuzzy, c-format
+#, c-format
msgid "remote repository '%s' is incompatible with fsmonitor"
-msgstr "%s es incompatible con %s"
+msgstr "el repositorio remoto '%s' es incompatible con fsmonitor"
-#, fuzzy, c-format
+#, c-format
msgid "virtual repository '%s' is incompatible with fsmonitor"
-msgstr "%s es incompatible con %s"
+msgstr "el repositorio virtual '%s' es incompatible con fsmonitor"
#, c-format
msgid ""
"repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"
msgstr ""
+"el repositorio '%s' es incompatible con fsmonitor a causa de falta de "
+"sockets de Unix"
-#, fuzzy
msgid ""
"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
@@ -15939,14 +15994,14 @@ msgid ""
" [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
" <command> [<args>]"
msgstr ""
-"git [--version] [--help] [-C <ruta>] [-c <nombre>=<valor>]\n"
-" [--exec-path [= <path>]] [--html-path] [--man-path] [--info-"
-"path]\n"
-" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"git [-v | --version] [-h | --help] [-C <ruta>] [-c <nombre>=<valor>]\n"
+" [--exec-path[=<ruta>]] [--html-path] [--man-path] [--info-path]\n"
+" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
"bare]\n"
-" [--git-dir=<ruta>] [--work-tree=<ruta>] [--namespace=<nombre>]\n"
-" [--super-prefix=<ruta>] [--config-env=<nombre>=<envvar>]\n"
-" <comando> [<args>]"
+" [--git-dir=<ruta>] [--work-tree=<ruta>] [--namespace=<nombre>]\n"
+" [--super-prefix=<ruta>] [--config-env=<nombre>=<variable-de-"
+"entorno>]\n"
+" <comando> [<argumentos>]"
msgid ""
"'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -15963,9 +16018,9 @@ msgstr ""
msgid "unsupported command listing type '%s'"
msgstr "tipo de listado de comandos no soportado '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "no directory given for '%s' option\n"
-msgstr "no se entregó directorio para -C\n"
+msgstr "no se entregó un directorio para la opción '%s'\n"
#, c-format
msgid "no namespace given for --namespace\n"
@@ -16090,8 +16145,8 @@ msgstr "gpg.ssh.defaultKeyCommand falló: %s %s"
msgid "gpg failed to sign the data"
msgstr "gpg falló al firmar los datos"
-msgid "user.signingkey needs to be set for ssh signing"
-msgstr "user.signingkey necesita ser configurado para firmar con ssh"
+msgid "user.signingKey needs to be set for ssh signing"
+msgstr "user.signingKey necesita ser configurado para firmar con ssh"
#, c-format
msgid "failed writing ssh signing key to '%s'"
@@ -16170,6 +16225,14 @@ msgstr "Comandos de bajo nivel / Sincronización de repositorios"
msgid "Low-level Commands / Internal Helpers"
msgstr "Comandos de bajo nivel / Auxiliares internos"
+msgid "User-facing repository, command and file interfaces"
+msgstr "Interfaces de repositorio, comando y archivo orientadas al usuario"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr ""
+"Formatos de archivo, protocolos e otras interfaces orientados al "
+"desarrollador"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "comandos disponibles de git en '%s'"
@@ -16183,6 +16246,13 @@ msgstr "Estos son comandos comunes de Git usados en varias situaciones:"
msgid "The Git concept guides are:"
msgstr "Las guías de conceptos de Git son:"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Interfaces de repositorio, comando y archivo orientadas al usuario:"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr ""
+"Formatos de archivo, protocolos y otras interfaces para el desarrollador:"
+
msgid "External commands"
msgstr "Comandos externos"
@@ -16209,15 +16279,15 @@ msgstr "Oh oh. Tu sistema no reporta ningún comando de Git."
#, c-format
msgid "WARNING: You called a Git command named '%s', which does not exist."
-msgstr "PELIGRO: Has llamado a un comando de Git '%s', el cual no existe."
+msgstr "ADVERTENCIA: Has llamado a un comando de Git '%s', el cual no existe."
#, c-format
msgid "Continuing under the assumption that you meant '%s'."
msgstr "Continuando asumiendo que quisiste decir '%s'."
-#, fuzzy, c-format
+#, c-format
msgid "Run '%s' instead [y/N]? "
-msgstr "Ejecutar '%s' en su lugar? (y/N)"
+msgstr "¿Ejecutar '%s' en su lugar [y/N]? "
#, c-format
msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
@@ -16264,10 +16334,6 @@ msgstr ""
"El hook '%s' fue ignorado porque no ha sido configurado como ejecutable.\n"
"Puedes desactivar esta advertencia con `git config advice.ignoredHook false`."
-#, fuzzy, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "No se pudo hacer stat en '%s'"
-
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
msgstr "argumento para --packfile tiene que se un hash válido (se obtuvo '%s')"
@@ -16276,8 +16342,8 @@ msgid "not a git repository"
msgstr "no es un repositorio git"
#, c-format
-msgid "negative value for http.postbuffer; defaulting to %d"
-msgstr "valor negativo para http.postbuffer; poniendo el default %d"
+msgid "negative value for http.postBuffer; defaulting to %d"
+msgstr "valor negativo de http.postBuffer; usando el valor por defecto %d"
msgid "Delegation control is not supported with cURL < 7.22.0"
msgstr "Delegación de control no es soportada con cURL < 7.22.0"
@@ -16454,19 +16520,14 @@ msgid "quoted CRLF detected"
msgstr "CRLF con comillas detectado"
#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Los cambios locales de los siguientes archivos serán sobreescritos por "
-"merge:\n"
-" %s"
-
-#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Falló al fusionar el submódulo %s (no revisado)"
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "Falló al fusionar el submódulo %s (no hay base de fusión)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
msgstr "Falló al fusionar el submódulo %s (commits no presentes)"
@@ -16484,28 +16545,10 @@ msgstr "Falló al fusionar el submódulo %s"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
msgstr ""
-"Falló al fusionar el submódulo %s, pero existen posibles soluciones de "
-"fusión:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Si esto es correcto simplemente agrégalo al índice por ejemplo\n"
-"usando:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"el cual aceptará esta sugerencia.\n"
+"Falló al fusionar el submódulo %s, pero existe una solución de fusión "
+"posible: %s"
#, c-format
msgid ""
@@ -16559,7 +16602,7 @@ msgid ""
"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
"renamed."
msgstr ""
-"PELIGRO: Evitando aplicar %s -> %s renombrado a %s, porque %s mismo fue "
+"ADVERTENCIA: Evitando aplicar %s -> %s renombrado a %s, porque %s mismo fue "
"renombrado."
#, c-format
@@ -16671,13 +16714,45 @@ msgstr ""
"CONFLICTO (modificar / eliminar): %s eliminado en %s y modificado en %s. "
"Versión %s de %s restante en el árbol."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
msgstr ""
-"Nota: %s no está actualizado y en conflicto con la versión; la copia antigua "
-"fue renombrada a %s"
+" - ve al submódulo (%s), y después o fusiona el commit %s\n"
+" o actualiza a un commit existente en que ya se han fusionado esos "
+"cambios\n"
+
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"La fusión recursiva con submódulos actualmente solo soporta casos "
+"triviales.\n"
+"Por favor, maneja manualmente la fusión de cada submódulo en conflicto.\n"
+"Esto se puede lograr con los pasos siguientes:\n"
+"%s - volver al superproyecto y ejecutar:\n"
+"\n"
+" git add %s\n"
+"\n"
+" para registrar la fusión de arriba o actualizar\n"
+" - resolver cualquier otro conflicto en el superproyecto\n"
+" - hace commit al índice resultante en el superproyecto\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -16750,6 +16825,22 @@ msgid "Found a possible merge resolution for the submodule:\n"
msgstr "Se encontró una posible solución de fusión para el submódulo:\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Si esto es correcto simplemente agrégalo al índice por ejemplo\n"
+"usando:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"el cual aceptará esta sugerencia.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Falló al fusionar el submódulo %s (múltiples fusiones encontradas)"
@@ -17020,9 +17111,8 @@ msgstr "pack de referencia '% s' ha expirado"
msgid "no pack files to index."
msgstr "no hay archivos pack para indexar."
-#, fuzzy
msgid "refusing to write multi-pack .bitmap without any objects"
-msgstr "no se pudo escribir bitmap multi-paquete"
+msgstr "rehusando escribir .bitmap de multi-pack sin ningún objeto"
msgid "could not write multi-pack bitmap"
msgstr "no se pudo escribir bitmap multi-paquete"
@@ -17283,6 +17373,22 @@ msgid "confused by unstable object source data for %s"
msgstr "confundido por fuente de data de objetos inestable para %s"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "objeto de stream de escritura %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "incapaz de desinflar dinamicamente el objeto nuevo (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "deflateEnd en el objeto de stream falló (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "incapaz de crear directorio %s"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "no se pudo leer el objeto para %s"
@@ -17340,23 +17446,23 @@ msgstr "no es posible desempaquetar contenidos de %s"
#. output shown when we cannot look up or parse the
#. object in question. E.g. "deadbeef [bad object]".
#.
-#, fuzzy, c-format
+#, c-format
msgid "%s [bad object]"
-msgstr "tipo de objeto erróneo."
+msgstr "%s [mal objeto]"
#. 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"
#.
-#, fuzzy, c-format
+#, c-format
msgid "%s commit %s - %s"
-msgstr "%s: %s - %s"
+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.
@@ -17364,33 +17470,33 @@ msgstr "%s: %s - %s"
#. The third argument is the "tag" string
#. from object.c.
#.
-#, fuzzy, c-format
+#, c-format
msgid "%s tag %s - %s"
-msgstr "%s: %s - %s"
+msgstr "%s etiqueta %s - %s"
#. TRANSLATORS: This is a line of ambiguous
#. 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]"
#.
-#, fuzzy, c-format
+#, c-format
msgid "%s [bad tag, could not parse it]"
-msgstr "%s: no se pudo analizar objeto: %s"
+msgstr "%s [mala etiqueta, no se pudo analizar]"
#. TRANSLATORS: This is a line of ambiguous <type>
#. object output. E.g. "deadbeef tree".
#.
-#, fuzzy, c-format
+#, c-format
msgid "%s tree"
-msgstr "hilo %s falló"
+msgstr "árbol %s"
#. TRANSLATORS: This is a line of ambiguous <type>
#. object output. E.g. "deadbeef blob".
#.
-#, fuzzy, c-format
+#, c-format
msgid "%s blob"
-msgstr "blob"
+msgstr "blob %s"
#, c-format
msgid "short object ID %s is ambiguous"
@@ -17400,11 +17506,13 @@ msgstr "el ID de objeto corto %s es ambiguo"
#. objects composed in show_ambiguous_object(). See
#. its "TRANSLATORS" comments for details.
#.
-#, fuzzy, c-format
+#, c-format
msgid ""
"The candidates are:\n"
"%s"
-msgstr "Los candidatos son:"
+msgstr ""
+"Los candidatos son:\n"
+"%s"
msgid ""
"Git normally never creates a ref that ends with 40 hex characters\n"
@@ -17482,7 +17590,7 @@ msgstr ""
#, c-format
msgid "<object>:<path> required, only <object> '%s' given"
-msgstr ""
+msgstr "<objeto>:<ruta> requerido, solo <objeto> '%s' proporcionado"
#, c-format
msgid "invalid object name '%.*s'."
@@ -17508,40 +17616,144 @@ msgstr "incapaz de analizar objeto: %s"
msgid "hash mismatch %s"
msgstr "hash no concuerda %s"
+msgid "trying to write commit not in index"
+msgstr "intentando escribir un commit que no está en el índice"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "falló al cargar el índice de bitmap (¿corrupto?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "índice de bitmap corrupto (demasiado pequeño)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "archivo de índice de bitmap corrupto (cabecera errónea)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "versión no soportada '%d' de archivo de índice de bitmap"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr ""
+"archivo de índice de bitmap corrupto (demasiado corto para el cache de hash)"
+
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr ""
+"archivo de índice de bitmap corrupto (demasiado corto para la tabla de "
+"consultación)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "entrada duplicada en el índice de bitmap: '%s'"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "bitmap ewah corrupto: cabecera truncada en la entrada %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "bitmap ewah corrupto: índice de commit %u fuera de rango"
+
+msgid "corrupted bitmap pack index"
+msgstr "índice de pack de bitmap corrupto"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "offset XOR inválido en el índice de pack de bitmap"
+
+msgid "cannot fstat bitmap file"
+msgstr "no se puede hacer fstat en el archivo de bitmap"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "ignorando el archivo extra de bitmap: '%s'"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "no se concuerden los checksums del MIDX y del bitmap"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "a multi-pack-index le falta un índice reveretido"
-#, fuzzy, c-format
+#, c-format
msgid "could not open pack %s"
-msgstr "no se pudo abrir '%s'"
+msgstr "no se pudo abrir el pack %s"
-#, fuzzy, c-format
+#, c-format
msgid "preferred pack (%s) is invalid"
-msgstr "pack de referencia '% s' ha expirado"
+msgstr "el pack preferido (%s) es inválido"
+
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "tabla de consultación corrupta: posición de trillizo fuera del índice"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr ""
+"tabla de consultación de bitmap corrupta: la cadena xor excede el número de "
+"entradas"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr ""
+"tabla de consultación de bitmap corrupta: índice de commit %u fuera de rango"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr "bitmap ewah corrupto: cabecera truncada del bitmap del commit \"%s\""
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "objeto '%s' no encontrado en bitmaps de tipo"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "el objeto '%s' no tiene un tipo único"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "objeto '%s': tipo real '%s', esperado: '%s'"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "objeto no en bitmap: '%s'"
+
+msgid "failed to load bitmap indexes"
+msgstr "falló en cargar índices de bitmap"
+
+msgid "you must specify exactly one commit to test"
+msgstr "hay que especificar exactamente un commit para probar"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "el commit '%s' no tiene un bitmap indexado"
+
+msgid "mismatch in bitmap results"
+msgstr "discordancia en los resultados de bitmap"
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "no se pudo encontrar %s en paquete %s en el offset %<PRIuMAX>"
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "no se pudo encontrar '%s' en el pack '%s' al offset %<PRIuMAX>"
-#, fuzzy, c-format
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "incapaz de obtener el uso de disco de '%s'"
+
+#, c-format
msgid "mtimes file %s is too small"
-msgstr "el archivo multi-pack-index %s es demasiado pequeño"
+msgstr "el archivo de mtimes %s es demasiado pequeño"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s has unknown signature"
-msgstr "el archivo de índice inverso %s tiene una firma desconocida"
+msgstr "el archivo de mtimes %s tiene una firma desconocida"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s has unsupported version %<PRIu32>"
-msgstr "archivo reverse-index %s tiene una versión no soportada %<PRIu32>"
+msgstr "el archivo de mtimes %s tiene una versión no soportada %<PRIu32>"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s has unsupported hash id %<PRIu32>"
-msgstr "archivo reverse-index %s tiene un id de hash no soportado %<PRIu32>"
+msgstr ""
+"el archivo de mtimes %s tiene un identificador de hash no soportado %<PRIu32>"
-#, fuzzy, c-format
+#, c-format
msgid "mtimes file %s is corrupt"
-msgstr "el archivo de índice inverso %s está dañado"
+msgstr "el archivo de mtimes %s es corrupto"
#, c-format
msgid "reverse-index file %s is too small"
@@ -17557,11 +17769,13 @@ msgstr "el archivo de índice inverso %s tiene una firma desconocida"
#, c-format
msgid "reverse-index file %s has unsupported version %<PRIu32>"
-msgstr "archivo reverse-index %s tiene una versión no soportada %<PRIu32>"
+msgstr "el archivo reverse-index %s tiene la versión no soportada %<PRIu32>"
#, c-format
msgid "reverse-index file %s has unsupported hash id %<PRIu32>"
-msgstr "archivo reverse-index %s tiene un id de hash no soportado %<PRIu32>"
+msgstr ""
+"el archivo reverse-index %s tiene el identificador de hash no soportado "
+"%<PRIu32>"
msgid "cannot both write and verify reverse index"
msgstr "no puede escribir y verificar el índice inverso"
@@ -17607,9 +17821,9 @@ msgstr "opción `%s' puede usar \"always\", \"auto\", o \"never\""
msgid "malformed object name '%s'"
msgstr "nombre de objeto mal formado '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "option `%s' expects \"%s\" or \"%s\""
-msgstr "opción `%s' puede usar \"always\", \"auto\", o \"never\""
+msgstr "la opción `%s' espera \"%s\" o \"%s\""
#, c-format
msgid "%s requires a value"
@@ -17647,6 +17861,9 @@ msgstr "¿quisiste decir `--%s` (con dos guiones)?"
msgid "alias of --%s"
msgstr "alias de --%s"
+msgid "need a subcommand"
+msgstr "se necesita un subcomando"
+
#, c-format
msgid "unknown option `%s'"
msgstr "opción `%s' desconocida"
@@ -18025,9 +18242,8 @@ msgstr "no se pudo refrescar el índice compartido '%s'"
msgid "broken index, expect %s in %s, got %s"
msgstr "index roto, se esperaba %s en %s, se obtuvo %s"
-#, fuzzy
msgid "cannot write split index for a sparse index"
-msgstr "activar el uso de un índice sparse"
+msgstr "no se puede escribir un índice dividido para un índice escaso"
msgid "failed to convert to a sparse-index"
msgstr "falló al convertir a un índice sparse"
@@ -18084,9 +18300,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -18096,20 +18315,23 @@ msgstr ""
"r, reword <commit> = usar commit, pero refrasear el mensaje de commit\n"
"e, edit <commit> = usar commit, pero parar para enmendar\n"
"s, squash <commit> = usar commit, pero aplastarlo en el commit previo\n"
-"f, fixup <commit> = como \"squash\", pero descarta el mensaje del log de "
-"este commit\n"
-"\t, a menos que se use -C, en cuyo caso\n"
-"\tmantiene solo el mensaje del commit; -c es lo mismo que -C\n"
-"\tpero abre el editor\n"
+"f, fixup [-C | -c] <commit> = como \"squash\", pero descarta el mensaje del\n"
+" log de este commit, a menos que se use -C, en cuyo caso\n"
+" mantiene solo el mensaje del commit; -c es lo mismo que\n"
+" -C pero abre el editor\n"
"x, exec <commit> = ejecutar comando (el resto de la línea) usando un shell\n"
"b, break = parar aquí (continuar rebase luego con 'git rebase --continue')\n"
"d, drop <commit> = eliminar commit\n"
"l, label <label> = poner label al HEAD actual con un nombre\n"
"t, reset <label> = reiniciar HEAD al label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". crear un commit de fusión usando el mensaje original de\n"
-". fusión (o la línea de oneline, si no se especifica un mensaje\n"
-". de commit). Use -c <commit> para reescribir el mensaje del commit.\n"
+" crear un commit de fusión usando el mensaje original de\n"
+" fusión (o la línea de oneline, si no se especifica un mensaje\n"
+" de commit). Use -c <commit> para reescribir el mensaje del commit.\n"
+"u, update-ref <referencia> = rasrear un marcador de posición para que la\n"
+" <referencia> sea actualizada a esta posición\n"
+" en los commits nuevos. Se actualiza la\n"
+" <referencia> al fin de la rebase\n"
"\n"
"Estas líneas pueden ser reordenadas; son ejecutadas desde arriba hacia "
"abajo.\n"
@@ -18165,7 +18387,8 @@ msgid ""
"Warning: some commits may have been dropped accidentally.\n"
"Dropped commits (newer to older):\n"
msgstr ""
-"Peligro: algunos commits pueden haber sido descartados de forma accidental.\n"
+"Advertencia: algunos commits pueden haber sido descartados de forma "
+"accidental.\n"
"Commits descartados (empezando con el más nuevo):\n"
#, c-format
@@ -18291,9 +18514,9 @@ msgstr ""
"no es un repositorio git, pero el campo '%.*s' requiere acceso a los datos "
"de objeto"
-#, fuzzy, c-format
+#, c-format
msgid "format: %%(%s) atom used without a %%(%s) atom"
-msgstr "formato: átomo %%(else) usado sin un átomo %%(if)"
+msgstr "formato: átomo %%(%s) usado sin un átomo %%(%s)"
#, c-format
msgid "format: %%(then) atom used more than once"
@@ -18584,6 +18807,13 @@ msgstr "error de protocolo: se esperaba sha/ref, se obtuvo '%s'"
msgid "http transport does not support %s"
msgstr "http transport no soporta %s"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "error de protocolo: se esperaba '<url> <ruta>', falta el espacio"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "falló al descargar el archivo al URL '%s'"
+
msgid "git-http-push failed"
msgstr "git-http-push falló"
@@ -18610,13 +18840,13 @@ msgstr "más de un receivepack dado, usando el primero"
msgid "more than one uploadpack given, using the first"
msgstr "más de un uploadpack dado, usando el primero"
-#, fuzzy, c-format
-msgid "unrecognized value fetch.credentialsInURL: '%s'"
-msgstr "patrón desconocido: '%s'"
+#, c-format
+msgid "unrecognized value transfer.credentialsInUrl: '%s'"
+msgstr "valor desconocido de transfer.credentialsInUrl: '%s'"
#, c-format
msgid "URL '%s' uses plaintext credentials"
-msgstr ""
+msgstr "El URL '%s' usa credenciales de texto claro"
#, c-format
msgid "Cannot fetch both %s and %s to %s"
@@ -18925,6 +19155,14 @@ msgstr "no se pudo determinar revisión HEAD"
msgid "failed to find tree of %s"
msgstr "falló al encontrar árbol de %s"
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo registra '%s' el cual falta"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "no se pudo determinar el commit del argumento de ancestry-path %s"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<packfile> ya no es soportado"
@@ -18945,6 +19183,174 @@ msgstr "-L no soporta todavía formatos de diff fuera de -p y -s"
msgid "cannot create async thread: %s"
msgstr "no es posible crear hilo async: %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' no existe"
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "no se pudo cambiar a '%s'"
+
+msgid "need a working directory"
+msgstr "se necesita un directorio de trabajo"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "alistamientos de Scalar requieren un árbol de trabajo"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "no se pudo configurar %s=%s"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "no se pudo configurar log.excludeDecoration"
+
+msgid "could not add enlistment"
+msgstr "no se pudo añadir alistamiento"
+
+msgid "could not set recommended config"
+msgstr "no se pudo establecer la configuración recomendada"
+
+msgid "could not turn on maintenance"
+msgstr "no se pudo activar mantenimiento"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "no se pudo iniciar el demonio de FSMonitor"
+
+msgid "could not turn off maintenance"
+msgstr "no se pudo desactivar mantenimiento"
+
+msgid "could not remove enlistment"
+msgstr "no se pudo eliminar alistamiento"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "la HEAD remota no es una rama: '%.*s'"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"falló al obtener el nombre de rama por defecto del remoto; usando el valor "
+"local por defecto"
+
+msgid "failed to get default branch name"
+msgstr "falló al determinar el nombre de rama por defecto"
+
+msgid "failed to unregister repository"
+msgstr "falló al desregistrar repositorio"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "falló al parar el demonio de FSMonitor"
+
+msgid "failed to delete enlistment directory"
+msgstr "falló al eliminar el directorio de alistamiento"
+
+msgid "branch to checkout after clone"
+msgstr "rama a que cambiar después de clonar"
+
+msgid "when cloning, create full working directory"
+msgstr "cuando se clona, crear un directorio pleno de trabajo"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "solo descargar metadatos de la rama a que cambiar"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<opciones>] [--] <repositorio> [<directorio>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "no se puede deducir de '%s' el nombre del árbol de trabajo"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "el directorio '%s' ya existe"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "falló al determinar la rama por defecto para '%s'"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "no se pudo configurar el remoto en '%s'"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "no se pudo configurar '%s'"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "falló la clonación parcial; intentando clonación plena"
+
+msgid "could not configure for full clone"
+msgstr "no se pudo configurar para una clonación plena"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<alistamiento>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` no toma ningún argumento"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<alistamiento>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "reconfigurar todos los alistamientos registrados"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <alistamiento>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all o <alistamiento>, pero no los dos"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "el repositorio de git en '%s' ya no está"
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <tarea> [<alistamiento>]\n"
+"Tareas:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "no existe tal tarea: '%s'"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<alistamiento>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <alistamiento>"
+
+msgid "refusing to delete current working directory"
+msgstr "rehusando eliminar el directorio de trabajo actual"
+
+msgid "include Git version"
+msgstr "incluir la versión de Git"
+
+msgid "include Git's build options"
+msgstr "incluir las opciones de compilación de Git"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C requiere un <directorio>"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "no se pudo cambiar a '%s'"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c requiere un argumento <clave>=<valor>"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <directorio>] [-c <clave>=<valor>] <comando> [<opciones>]\n"
+"\n"
+"Comandos:\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr ""
"flush packet inesperado mientras se leía estatus de desempaquetado remoto"
@@ -19067,10 +19473,6 @@ msgstr "tus cambios locales serán sobreescritos por %s."
msgid "commit your changes or stash them to proceed."
msgstr "realiza un commit con tus cambios o haz un stash para proceder."
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: avance rápido"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -19421,7 +19823,7 @@ msgstr "final de archivo inesperado"
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
-msgstr "archivo HEAD '%s' guardado antes de cherry-pick está corrupto"
+msgstr "archivo HEAD '%s' guardado antes de cherry-pick está corrupto"
msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
msgstr "Parece que se ha movido HEAD. No se hace rebobinado, ¡revisa tu HEAD!"
@@ -19555,6 +19957,28 @@ msgstr "ni se pudo intentar fusionar '%.*s'"
msgid "merge: Unable to write new index file"
msgstr "fusión: No se puede escribir el nuevo archivo índice"
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr ""
+"parece que otro proceso 'rebase' ya se está ejecutando; '%s.lock' ya existe"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Se han actualizado las referencias siguientes con %s:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Falló al abrir las referencias siguientes con %s:\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "No se puede ejecutar autostash"
@@ -19723,6 +20147,10 @@ msgid "the script was already rearranged."
msgstr "este script ya fue reorganizado."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "el archivo de update-refs a '%s' es inválido"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "'%s' está fuera del repositorio en '%s'"
@@ -19845,11 +20273,20 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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 ""
+"posesión dudosa detectada en el repositorio a '%s'\n"
+"%sPara añadir una excepción para este directorio, ejecuta:\n"
+"\n"
+"\tgit config --global --add safe.directory %s"
+
+#, c-format
+msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
+msgstr ""
+"no se puede usar el repositorio desnudo '%s' (safe.bareRepository es '%s')"
#, c-format
msgid ""
@@ -19869,9 +20306,8 @@ msgstr "falló setsid"
msgid "index entry is a directory, but not sparse (%08x)"
msgstr "la entrada de índice es un directorio, pero no escaso (%08x)"
-#, fuzzy
msgid "cannot use split index with a sparse index"
-msgstr "no se puede leer el índice"
+msgstr "no se puede usar un índice dividido con un índice escaso"
#. TRANSLATORS: IEC 80000-13:2008 gibibyte
#, c-format
@@ -19925,8 +20361,8 @@ msgstr "no se pudo editar '%s'"
msgid "ignoring suspicious submodule name: %s"
msgstr "ignorando nombre de submódulo sospechoso: %s"
-msgid "negative values not allowed for submodule.fetchjobs"
-msgstr "no se permiten valores negativos para submodule.fetchjobs"
+msgid "negative values not allowed for submodule.fetchJobs"
+msgstr "no se permiten valores negativos para submodule.fetchJobs"
#, c-format
msgid "ignoring '%s' which may be interpreted as a command-line option: %s"
@@ -20006,13 +20442,13 @@ msgstr "Haciendo fetch al submódulo %s%s\n"
msgid "Could not access submodule '%s'\n"
msgstr "No se pudo acceder al submódulo '%s'\n"
-#, fuzzy, c-format
+#, c-format
msgid "Could not access submodule '%s' at commit %s\n"
-msgstr "No se pudo acceder al submódulo '%s'\n"
+msgstr "No se pudo acceder al submódulo '%s' al commit %s\n"
-#, fuzzy, c-format
+#, c-format
msgid "Fetching submodule %s%s at commit %s\n"
-msgstr "Haciendo fetch al submódulo %s%s\n"
+msgstr "Haciendo fetch al submódulo %s%s al commit %s\n"
#, c-format
msgid ""
@@ -20158,7 +20594,7 @@ msgid "number of threads in server thread pool"
msgstr "número de hilos en el pool de hilos del servidor"
msgid "seconds to wait for daemon to start or stop"
-msgstr "segundos a esperar para que el dominio empiece o se detenga"
+msgstr "segundos a esperar que el demonio se inicie o se detenga"
msgid "number of bytes"
msgstr "número de bytes"
@@ -20519,11 +20955,13 @@ msgstr ""
"seguimiento en ellos:\n"
"%s"
-#, fuzzy, c-format
+#, c-format
msgid ""
"Refusing to remove the current working directory:\n"
"%s"
-msgstr "no es posible obtener el directorio de trabajo actual"
+msgstr ""
+"Rehusando eliminar el directorio de trabajo actual:\n"
+"%s"
#, c-format
msgid ""
@@ -20712,7 +21150,7 @@ msgid "expected flush after fetch arguments"
msgstr "se espera flush tras argumentos fetch"
msgid "invalid URL scheme name or missing '://' suffix"
-msgstr "nombre de URL inválido o sufijo '://' faltante"
+msgstr "nombre de URL inválido o sufijo '://' faltante"
#, c-format
msgid "invalid %XX escape sequence"
@@ -20728,11 +21166,23 @@ msgid "invalid characters in host name"
msgstr "carácter inválido en el nombre del host"
msgid "invalid port number"
-msgstr "número de puerto inválido"
+msgstr "número de puerto inválido"
msgid "invalid '..' path segment"
msgstr "segmento de ruta '..' inválido"
+msgid "usage: "
+msgstr "uso: "
+
+msgid "fatal: "
+msgstr "fatal: "
+
+msgid "error: "
+msgstr "error: "
+
+msgid "warning: "
+msgstr "advertencia: "
+
msgid "Fetching objects"
msgstr "Haciendo fetch a objetos"
@@ -20807,13 +21257,13 @@ msgstr "archivo gitdir inválido"
msgid "gitdir file points to non-existent location"
msgstr "archivo gitdir apunta a una ubicación inexistente"
-#, fuzzy, c-format
+#, c-format
msgid "unable to set %s in '%s'"
-msgstr "incapaz de hacer stat en '%s'"
+msgstr "incapaz de configurar %s en '%s'"
-#, fuzzy, c-format
+#, c-format
msgid "unable to unset %s in '%s'"
-msgstr "no se pudo poner permisos a '%s'"
+msgstr "incapaz de desconfigurar %s en '%s'"
msgid "failed to set extensions.worktreeConfig setting"
msgstr "falló al configurar opción extensions.worktreeConfig"
@@ -20893,7 +21343,7 @@ msgstr ""
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
msgstr ""
-" (usa \"git %s <archivo>...\" para incluirlo a lo que se será confirmado)"
+" (usa \"git %s <archivo>...\" para incluirlo a lo que será confirmado)"
msgid "both deleted:"
msgstr "borrados por ambos:"
@@ -21005,10 +21455,11 @@ msgstr " (arregla los conflictos y luego ejecuta \"git am --continue\""
msgid " (use \"git am --skip\" to skip this patch)"
msgstr " (usa \"git am --skip\" para saltar este parche)"
-#, fuzzy
msgid ""
" (use \"git am --allow-empty\" to record this patch as an empty commit)"
-msgstr " (usa \"git commit --amend\" para enmendar el commit actual)"
+msgstr ""
+" (usa \"git am --allow-empty\" para registrar este parche como un commit "
+"vacío)"
msgid " (use \"git am --abort\" to restore the original branch)"
msgstr " (usa \"git am --abort\" para restaurar la rama original)"
@@ -21019,11 +21470,11 @@ msgstr "git-rebase-todo no está presente."
msgid "No commands done."
msgstr "No se realizaron los comandos."
-#, fuzzy, c-format
+#, c-format
msgid "Last command done (%<PRIuMAX> command done):"
msgid_plural "Last commands done (%<PRIuMAX> commands done):"
-msgstr[0] "El último comando realizado (%d comando realizado):"
-msgstr[1] "Los últimos comandos realizados (%d comandos realizados):"
+msgstr[0] "El último comando realizado (%<PRIuMAX> comando realizado):"
+msgstr[1] "Los últimos comandos realizados (%<PRIuMAX> comandos realizados):"
#, c-format
msgid " (see more in file %s)"
@@ -21032,11 +21483,11 @@ msgstr " (ver más en el archivo %s)"
msgid "No commands remaining."
msgstr "No quedan más comandos."
-#, fuzzy, c-format
+#, c-format
msgid "Next command to do (%<PRIuMAX> remaining command):"
msgid_plural "Next commands to do (%<PRIuMAX> remaining commands):"
-msgstr[0] "Siguiente comando a realizar (%d comando restante):"
-msgstr[1] "Siguientes comandos a realizar (%d comandos faltantes):"
+msgstr[0] "Siguiente comando a realizar (%<PRIuMAX> comando restante):"
+msgstr[1] "Siguientes comandos a realizar (%<PRIuMAX> comandos faltantes):"
msgid " (use \"git rebase --edit-todo\" to view and edit)"
msgstr " (usa \"git rebase --edit-todo\" para ver y editar)"
@@ -21547,22 +21998,6 @@ msgstr "¡Los hunks seleccionados no aplican al índice!\n"
msgid "ignoring unmerged: %s\n"
msgstr "ignorando lo no fusionado: %s\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "¿Aplicar cambio de modo al árbol de trabajo [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "¿Aplicar eliminación al árbol de trabajo [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "¿Aplicar adición al árbol de trabajo [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "¿Aplicar este fragmento al árbol de trabajo [y,n,q,a,d,/%s,?]? "
-
msgid "No other hunks to goto\n"
msgstr "No hay más fragmentos a que ir\n"
@@ -21693,11 +22128,11 @@ msgstr "Configuración --confirm desconocida: '%s'\n"
#, perl-format
msgid "warning: sendmail alias with quotes is not supported: %s\n"
-msgstr "peligro: alias de sendmail con comillas no es soportado: %s\n"
+msgstr "advertencia: alias de sendmail con comillas no es soportado: %s\n"
#, perl-format
msgid "warning: `:include:` not supported: %s\n"
-msgstr "peligro: `:include:` no soportado: %s\n"
+msgstr "advertencia: `:include:` no soportado: %s\n"
#, perl-format
msgid "warning: `/file` or `|pipe` redirection not supported: %s\n"
@@ -21929,15 +22364,15 @@ msgstr "no se puede mandar mensaje como 7bit"
msgid "invalid transfer encoding"
msgstr "codificación de transferencia inválida"
-#, fuzzy, perl-format
+#, perl-format
msgid ""
"fatal: %s: rejected by %s hook\n"
"%s\n"
"warning: no patches were sent\n"
msgstr ""
-"fatal: %s: rechazado por hook sendmail-validate\n"
+"fatal: %s: rechazado por el hook %s\n"
"%s\n"
-"peligro: no se mandaron parches\n"
+"advertencia: no se mandó ningún parche\n"
#, perl-format
msgid "unable to open %s: %s\n"
@@ -21949,7 +22384,7 @@ msgid ""
"warning: no patches were sent\n"
msgstr ""
"fatal: %s: %d es más grande que 998 caracteres\n"
-"peligro: no se mandaron parches\n"
+"advertencia: no se mandó ningún parche\n"
#, perl-format
msgid "Skipping %s with backup suffix '%s'.\n"
diff --git a/po/fr.po b/po/fr.po
index f601f406363..b29d3410020 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -78,8 +78,8 @@ msgid ""
msgstr ""
"Project-Id-Version: git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-24 21:43+0200\n"
-"PO-Revision-Date: 2022-06-24 21:58+0200\n"
+"POT-Creation-Date: 2022-09-28 21:43+0200\n"
+"PO-Revision-Date: 2022-09-28 21:45+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"
@@ -491,6 +491,23 @@ msgstr ""
"a - appliquer cette section et toutes les suivantes de ce fichier\n"
"d - ne pas appliquer cette section ni les suivantes de ce fichier\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr ""
+"Appliquer le changement de mode dans l'arbre de travail [y,n,q,a,d%s,?] ? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Appliquer la suppression dans l'arbre de travail [y,n,q,a,d%s,?] ? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Appliquer l'ajout dans l'arbre de travail [y,n,q,a,d%s,?] ? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Appliquer la section à l'arbre de travail [y,n,q,a,d%s,?] ? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -508,10 +525,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "impossible d'analyser l'entête de section '%.*s'"
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "impossible d'analyser l'entête coloré de section '%.*s'"
-
msgid "could not parse diff"
msgstr "impossible d'analyser la diff"
@@ -803,6 +816,25 @@ msgstr ""
"detachedHead à false\n"
"\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Les chemins suivants ont été déplacés hors de\n"
+"la définition d'extraction clairsemée mai ne sont pas\n"
+"clairsemés à cause de modifications locales\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Pour corriger l'état clairsemé de ces chemins, faites ceci :\n"
+"* Lancez \"git add --sparse <chemins>\" pour mettre l'index à jour\n"
+"* Lancez \"git sparse-checkout reapply\" pour réappliquer les règles"
+
msgid "cmdline ends with \\"
msgstr "cmdline se termine par \\"
@@ -1323,6 +1355,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "mode de fichier non supporté :0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "erreur de compression (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "impossible de démarrer le filtre '%s'"
@@ -1342,10 +1378,6 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "le chemin est trop long (%d caractères, SHA1 : %s) : %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "erreur de compression (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "l'horodatage est trop grand pour ce système : %<PRIuMAX>"
@@ -3143,8 +3175,12 @@ msgstr "info libc : "
msgid "not run from a git repository - no hooks to show\n"
msgstr "lancé hors d'un dépôt git - aucun crochet à montrer\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <fichier>] [-s|--suffix <format>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <fichier>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3182,16 +3218,29 @@ msgstr ""
"Veuillez relire le rapport de bogue ci-dessous.\n"
"Vous pouvez supprimer toute ligne que vous ne souhaitez pas envoyer.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "spécifier la destination du fichier de rapport de bogue"
+msgid "mode"
+msgstr "mode"
+
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr ""
+"créer une archive zip supplémentaire de diagnostique détaillé (par défaut "
+"'stats')"
-msgid "specify a strftime format suffix for the filename"
-msgstr "spécifier une suffixe au format strftime pour le nom de fichier"
+msgid "specify a destination for the bugreport file(s)"
+msgstr "spécifier la destination du/des fichier(s) de rapport de bogue"
+
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "spécifier une suffixe au format strftime pour le(s) nom(s) de fichier"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "impossible de créer les répertoires de premier niveau pour '%s'"
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "impossible de créer l'archive de diagnostique %s"
+
msgid "System Info"
msgstr "Info système"
@@ -3250,10 +3299,6 @@ msgid "Unbundling objects"
msgstr "Dépaquetage d'objets"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Sous-commande inconnue : %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "impossible de lire l'objet %s '%s'"
@@ -3330,6 +3375,9 @@ msgstr "afficher la taille de l'objet"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "autoriser -s et -t à travailler sur des objets cassés/corrompus"
+msgid "use mail map file"
+msgstr "utiliser le fichier de correspondance de mail"
+
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr "Traiter par lot les objets demandés sur stdin (ou --batch-all-objects)"
@@ -3339,6 +3387,9 @@ msgstr "afficher tout le contenu de <objet> ou <rev>"
msgid "like --batch, but don't emit <contents>"
msgstr "comme --batch, mais ne pas émettre <contenu>"
+msgid "stdin is NUL-terminated"
+msgstr "l'entrée se termine par NUL"
+
msgid "read commands from stdin"
msgstr "lire les commandes depuis l'entrée standard"
@@ -4225,6 +4276,14 @@ msgstr ""
"initialiser le fichier d'extraction clairsemée pour n'inclure que les "
"fichiers à la racine"
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr ""
+"un URI pour télécharger des paquets avant de récupérer depuis le distant "
+"d'origine"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info : impossible d'ajouter une alternative pour '%s' : %s\n"
@@ -4284,10 +4343,10 @@ msgstr "impossible de mettre à jour %s"
msgid "failed to initialize sparse-checkout"
msgstr "échec lors de l'initialisation l'extraction clairsemée"
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
msgstr ""
"la HEAD distante réfère à une référence non existante, impossible de "
-"l'extraire.\n"
+"l'extraire"
msgid "unable to checkout working tree"
msgstr "impossible d'extraire la copie de travail"
@@ -4311,6 +4370,13 @@ msgstr "Vous devez spécifier un dépôt à cloner."
msgid "options '%s' and '%s %s' cannot be used together"
msgstr "les options '%s' et '%s %s' ne peuvent pas être utilisées ensemble"
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri est incompatible avec --depth, --shallow-since, et --shallow-"
+"exclude"
+
#, c-format
msgid "repository '%s' does not exist"
msgstr "le dépôt '%s' n'existe pas"
@@ -4388,6 +4454,13 @@ msgstr "--local est ignoré"
msgid "cannot clone from filtered bundle"
msgstr "impossible de cloner depuis un colis filtré"
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "échec lors de l'initialisation du dépôt, URI du paquet ignoré"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "impossible de récupérer les objets depuis l'URI de paquet '%s'"
+
msgid "remote transport reported error"
msgstr "le transport distant a retourné une erreur"
@@ -4504,10 +4577,6 @@ msgstr "utilisez un seul parmi --reachable, --stdin-commits ou --stdin-packs"
msgid "Collecting commits from input"
msgstr "Collecte des commits depuis l'entrée"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "sous-commande non reconnue : %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -4869,9 +4938,6 @@ msgstr "afficher l'état en format long (par défaut)"
msgid "terminate entries with NUL"
msgstr "terminer les éléments par NUL"
-msgid "mode"
-msgstr "mode"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
"afficher les fichiers non suivis, \"mode\" facultatif : all (tous), normal, "
@@ -5476,6 +5542,22 @@ msgid "option '%s' and commit-ishes cannot be used together"
msgstr ""
"l'option '%s' et des commit-esques ne peuvent pas être utilisées ensemble"
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <fichier>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "spécifier la destination de l'archive de diagnostique"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr "spécifier une suffixe au format strftime pour le nom de fichier"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "spécifier le contenu de l'archive de diagnostique"
+
msgid "--merge-base only works with two commits"
msgstr "--merge-base ne fonctionne qu'avec deux commits"
@@ -5865,11 +5947,8 @@ msgstr "[à jour]"
msgid "[rejected]"
msgstr "[rejeté]"
-msgid "can't fetch in current branch"
-msgstr "impossible de récupérer dans la branche actuelle"
-
-msgid "checked out in another worktree"
-msgstr "extrait dans un autre arbre de travail"
+msgid "can't fetch into checked-out branch"
+msgstr "impossible de récupérer dans la branche extraite"
msgid "[tag update]"
msgstr "[mise à jour de l'étiquette]"
@@ -6303,6 +6382,10 @@ msgstr "%s : pointer sha1 invalide dans l'arbre de cache"
msgid "non-tree in cache-tree"
msgstr "non-arbre dans l'arbre de cache"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s : pointeur sha1 invalide dans resolve-undo"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<options>] [<objet>...]"
@@ -6640,14 +6723,17 @@ msgstr ""
"echec du lancement de 'crontab -l' ; votre système n'a pas l'air de fournir "
"'cron'"
+msgid "failed to create crontab temporary file"
+msgstr "impossible de créer un fichier crontab temporaire"
+
+msgid "failed to open temporary file"
+msgstr "impossible d'ouvrir un fichier temporaire"
+
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr ""
"echec du lancement de 'crontab' ; votre système n'a pas l'air de fournir "
"'cron'"
-msgid "failed to open stdin of 'crontab'"
-msgstr "échec à l'ouverture de stdin de 'crontab'"
-
msgid "'crontab' died"
msgstr "'crontab' est mort"
@@ -6696,10 +6782,6 @@ msgstr "échec de l'ajout du dépôt à la config globale"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <subcommand> [<options>]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "sous-commande invalide : %s"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<options>] [-e] <motif> [<révision>...] [[--] <chemin>...]"
@@ -6877,6 +6959,9 @@ msgstr "afficher les fichiers correspondant dans le pagineur"
msgid "allow calling of grep(1) (ignored by this build)"
msgstr "permettre l'appel de grep(1) (ignoré par ce build)"
+msgid "maximum number of results per file"
+msgstr "nombre maximum de résultats par fichier"
+
msgid "no pattern given"
msgstr "aucun motif fourni"
@@ -6965,11 +7050,19 @@ msgstr "afficher la description de la commande"
msgid "print list of useful guides"
msgstr "afficher une liste de guides utiles"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr "afficher les liste des dépôts publics, des commandes et des interfaces"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr ""
+"afficher la liste des formats de fichier, des protocoles et des autres "
+"interfaces pour développeur"
+
msgid "print all configuration variable names"
msgstr "afficher tous les noms de variables de configuration"
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<commande>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<commande>|<doc>]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -7442,8 +7535,8 @@ msgstr "supprimer la sortie des différences"
msgid "show source"
msgstr "afficher la source"
-msgid "use mail map file"
-msgstr "utiliser le fichier de correspondance de mail"
+msgid "clear all previously-defined decoration filters"
+msgstr "effacer tous les filtres de décoration précédemment définis"
msgid "only decorate refs that match <pattern>"
msgstr "décorer seulement les références correspondant à <motif>"
@@ -7711,6 +7804,11 @@ msgstr ""
msgid "percentage by which creation is weighted"
msgstr "pourcentage par lequel la création est pondérée"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr ""
+"montrer les From: inclus même s'ils sont identiques à celui de l'entête du "
+"courriel"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "ligne d'identification invalide : %s"
@@ -7771,6 +7869,18 @@ msgstr ""
"Impossible de trouver une branche distante suivie, merci de spécifier "
"<branche_amont> manuellement.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "mauvais format ls-files : l'élément '%s' ne commence pas par '('"
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "mauvais format ls-files : l'élément '%s' ne se termine pas par ')'"
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "mauvais format ls-files : %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<options>] [<fichier>...]"
@@ -7859,6 +7969,13 @@ msgid "show sparse directories in the presence of a sparse index"
msgstr "afficher les répertoires clairsemés en présence d'un index clairsemé"
msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format ne peut pas être utilisé avec -s, -o, -k, -t, --resolve-undo, --"
+"deduplicate, --eol"
+
+msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url]\n"
" [--symref] [<repository> [<refs>...]]"
@@ -8082,6 +8199,39 @@ msgstr "impossible de résoudre la référence '%s'"
msgid "Merging %s with %s\n"
msgstr "Fusion de %s avec %s\n"
+msgid "not something we can merge"
+msgstr "pas possible de fusionner ceci"
+
+msgid "refusing to merge unrelated histories"
+msgstr "refus de fusionner des historiques sans relation"
+
+msgid "failure to merge"
+msgstr "échec de la fusion"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<options>] <branche1> <branche2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <arbre-de-base> <branche1> <branche2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "faire une fusion réelle au lieu d'une fusion triviale"
+
+msgid "do a trivial merge only"
+msgstr "faire seulement une fusion triviale"
+
+msgid "also show informational/conflict messages"
+msgstr "afficher aussi les messages d'information/de conflit"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "lister les noms de fichier sans modes/oids/indexation"
+
+msgid "allow merging unrelated histories"
+msgstr "permettre la fusion d'historiques sans rapport"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge est incompatible avec d'autres options"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<options>] [<commit>...]"
@@ -8164,9 +8314,6 @@ msgstr "--abort mais laisser l'index et l'arbre de travail inchangés"
msgid "continue the current in-progress merge"
msgstr "continuer la fusion en cours"
-msgid "allow merging unrelated histories"
-msgstr "permettre la fusion d'historiques sans rapport"
-
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "ne pas utiliser les crochets pre-merge-commit et commit-msg"
@@ -8289,9 +8436,6 @@ msgstr "impossible de fermer '%s'"
msgid "not something we can merge in %s: %s"
msgstr "pas possible de fusionner ceci dans %s : %s"
-msgid "not something we can merge"
-msgstr "pas possible de fusionner ceci"
-
msgid "--abort expects no arguments"
msgstr "--abort n'accepte pas d'argument"
@@ -8342,14 +8486,20 @@ msgid "Can merge only exactly one commit into empty head"
msgstr ""
"Possible de fusionner exactement une seule validation dans une tête vide"
-msgid "refusing to merge unrelated histories"
-msgstr "refus de fusionner des historiques sans relation"
-
#, c-format
msgid "Updating %s..%s\n"
msgstr "Mise à jour %s..%s\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Vos modifications locales aux fichiers suivants seraient écrasées par la "
+"fusion :\n"
+" %s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Essai de fusion vraiment triviale dans l'index...\n"
@@ -8383,6 +8533,11 @@ msgstr ""
"La fusion automatique a réussi ; stoppée avant la validation comme demandé\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr ""
+"Une fois terminé, appliquer les modifications remisées avec `git stash pop`\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
msgstr "attention : l'entrée d'étiquette ne passe pas fsck : %s"
@@ -8502,6 +8657,9 @@ msgstr "Vérification du renommage de '%s' en '%s'\n"
msgid "bad source"
msgstr "mauvaise source"
+msgid "destination exists"
+msgstr "la destination existe"
+
msgid "can not move directory into itself"
msgstr "impossible de déplacer un répertoire dans lui-même"
@@ -8517,9 +8675,6 @@ msgstr "pas sous le contrôle de version"
msgid "conflicted"
msgstr "en conflit"
-msgid "destination exists"
-msgstr "la destination existe"
-
#, c-format
msgid "overwriting '%s'"
msgstr "écrasement de '%s'"
@@ -8533,6 +8688,9 @@ msgstr "multiples sources pour la même destination"
msgid "destination directory does not exist"
msgstr "le répertoire de destination n'existe pas"
+msgid "destination exists in the index"
+msgstr "la destination existe dans l'index"
+
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, source=%s, destination=%s"
@@ -8894,8 +9052,8 @@ msgid "use notes from <notes-ref>"
msgstr "utiliser les notes depuis <références-notes>"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "sous-commande inconnue : %s"
+msgid "unknown subcommand: `%s'"
+msgstr "sous-commande inconnue : `%s'"
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -9442,7 +9600,7 @@ msgstr ""
"les réconcilier. Vous pouvez le faire en lançant une des\n"
"commandes suivantes avant votre prochain tirage :\n"
"\n"
-" git config pull.rebase false # fusion (stratégie par défaut)\n"
+" git config pull.rebase false # fusion\n"
" git config pull.rebase true # rebasage\n"
" git config pull.ff only # avance rapide seulement\n"
"\n"
@@ -9823,11 +9981,16 @@ msgid "only emit output related to the second range"
msgstr "afficher seulement les sorties liées à la deuxième plage"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "'%s' n'est pas une révision"
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "pas une plage de commit : '%s'"
-msgid "single arg format must be symmetric range"
-msgstr "un format d'argument unique doit être une plage symétrique"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "pas une plage symétrique : '%s'"
msgid "need two commit ranges"
msgstr "plage entre deux commits requise"
@@ -10103,6 +10266,11 @@ msgstr "conserver les commits qui commencent vides"
msgid "move commits that begin with squash!/fixup! under -i"
msgstr "déplace les commits qui commencent par squash!/fixup! sous -i"
+msgid "update branches that point to commits that are being rebased"
+msgstr ""
+"mettre à jour les branches qui pointent sur les commits qui sont en cours de "
+"rebasage"
+
msgid "add exec lines after each commit of the editable list"
msgstr "ajouter les lignes exec après chaque commit de la liste éditable"
@@ -10639,6 +10807,9 @@ msgstr " nouveau (le prochain rapatriement (fetch) stockera dans remotes/%s)"
msgid " tracked"
msgstr " suivi"
+msgid " skipped"
+msgstr " sauté"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " dépassé (utilisez 'git remote prune' pour supprimer)"
@@ -11322,6 +11493,10 @@ msgstr "Impossible d'écrire le nouveau fichier d'index."
msgid "unable to get disk usage of %s"
msgstr "impossible de récupérer l'utilisation du disque de %s"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "valeur invalide pour '%s' : '%s', le seul format permis est '%s'"
+
msgid "rev-list does not support display of notes"
msgstr "rev-list ne supporte l'affichage des notes"
@@ -11347,6 +11522,9 @@ msgstr "fin prématurée de l'entrée"
msgid "no usage string given before the `--' separator"
msgstr "pas de chaîne d'usage fournie avant le séparateur `--'"
+msgid "missing opt-spec before option flags"
+msgstr "opt-spec manquant avant les drapeaux d'option"
+
msgid "Needed a single revision"
msgstr "Une seule révision attendue"
@@ -12133,6 +12311,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "Nom de référence complet attendu, %s obtenu"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "impossible de trouver une poignée de dépôt pour le sous-module '%s'"
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -12140,12 +12322,6 @@ msgstr ""
"impossible de trouver la configuration '%s'. Ce dépôt est considéré comme "
"son propre amont d'autorité."
-msgid "alternative anchor for relative paths"
-msgstr "ancre alternative pour les chemins relatifs"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<chemin>] [<chemin>...]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "URL non trouvée pour le chemin de sous-module '%s' dans .gitmodules"
@@ -12179,8 +12355,8 @@ msgstr ""
msgid "recurse into nested submodules"
msgstr "parcourir récursivement les sous-modules"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <commande>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <commande>"
#, c-format
msgid "Failed to register url for submodule path '%s'"
@@ -12205,8 +12381,8 @@ msgstr ""
msgid "suppress output for initializing a submodule"
msgstr "supprimer la sortie lors de l'initialisation d'un sous-module"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<options>] [<chemin>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<options>] [<chemin>]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -12235,9 +12411,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<chemin>...]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper <nom> <chemin>"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submodule)"
@@ -12271,8 +12444,8 @@ msgstr "sauter les sous-modules avec la valeur 'ignore_config' à 'all'"
msgid "limit the summary size"
msgstr "limiter la taille du résumé"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<options>] [<commit>] [--] [<chemin>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<options>] [<commit>] [--] [<chemin>]"
msgid "could not fetch a revision for HEAD"
msgstr "impossible de récupérer une révision pour HEAD"
@@ -12286,10 +12459,6 @@ msgid "failed to register url for submodule path '%s'"
msgstr "échec d'enregistrement de l'URL pour le chemin de sous-module '%s'"
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "échec d'obtention du dépôt distant par défaut pour le sous-module '%s'"
-
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "échec de mise à jour du dépôt distant pour le sous-module '%s'"
@@ -12297,8 +12466,8 @@ msgid "suppress output of synchronizing submodule url"
msgstr ""
"supprimer la sortie lors de la synchronisation de l'URL d'un sous-module"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<chemin>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<chemin>]"
#, c-format
msgid ""
@@ -12361,6 +12530,10 @@ msgstr ""
"clonez avec '--reference-if-able' au lieu de '--reference'."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "impossible de trouver une poignée de dépôt pour le répertoire git '%s'"
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "le sous-module '%s' ne peut pas ajouter d'alternative : %s"
@@ -12390,6 +12563,9 @@ msgstr "le répertoire n'est pas vide : '%s'"
msgid "could not get submodule directory for '%s'"
msgstr "impossible de créer le répertoire de sous-module pour '%s'"
+msgid "alternative anchor for relative paths"
+msgstr "ancre alternative pour les chemins relatifs"
+
msgid "where the new submodule will be cloned to"
msgstr "emplacement où le sous-module sera cloné"
@@ -12418,10 +12594,6 @@ msgstr ""
"<spécificateur-de-filtre>]--url <url> --path <chemin>"
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Mode de mise à jour '%s' invalide pour le chemin de sous-module '%s'"
-
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr ""
"Mode de mise à jour '%s'invalide configuré pour le chemin de sous-module '%s'"
@@ -12496,6 +12668,10 @@ msgstr ""
"récupération directe de ce commit a échoué."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "impossible d'initialiser le sous-module dans le chemin '%s'"
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -12504,10 +12680,6 @@ msgstr ""
"superprojet, mais le superprojet n'est sur aucune branche"
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "impossible de trouver une poignée de dépôt pour le sous-module '%s'"
-
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr ""
"Impossible de trouver la révision actuelle dans le chemin de sous-module '%s'"
@@ -12543,12 +12715,14 @@ msgstr "ne pas récupérer les nouveaux objets depuis le site distant"
msgid "path into the working tree"
msgstr "chemin dans la copie de travail"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr ""
-"chemin dans la copie de travail, traversant les frontières de sous-modules"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "utiliser la stratégie de mise à jour 'checkout' (valeur par défaut)"
+
+msgid "use the 'merge' update strategy"
+msgstr "utiliser la stratégie de mise à jour par fusion"
-msgid "rebase, merge, checkout or none"
-msgstr "valeurs possibles : rebase, merge, checkout ou none"
+msgid "use the 'rebase' update strategy"
+msgstr "utiliser la stratégie de mise à jour par rebasage"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr "créer un clone superficiel tronqué au nombre de révisions spécifié"
@@ -12562,6 +12736,9 @@ msgstr "spécifie si le clonage initial doit être aussi superficiel"
msgid "don't print cloning progress"
msgstr "ne pas afficher la progression du clonage"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "interdire de cloner dans un répertoire non-vide, implique --init"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12573,14 +12750,11 @@ msgstr ""
"[no-]recommend-shallow] [--reference <dépôt>] [--recursive] [--[no-]single-"
"branch] [--] [<chemin>...]"
-msgid "bad value for update parameter"
-msgstr "valeur invalide pour la mise à jour du paramètre"
-
msgid "recurse into submodules"
msgstr "parcourir récursivement les sous-modules"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<options>] [<chemin>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<options>] [<chemin>...]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr "vérifier si écrire dans le fichier .gitmodules est sur"
@@ -12601,8 +12775,8 @@ msgstr ""
msgid "suppress output for setting url of a submodule"
msgstr "supprimer la sortie lors du paramétrage de l'url d'un sous-module"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper sync [--quiet] <chemin> <nouvelle-url>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <chemin> <nouvelle-url>"
msgid "set the default tracking branch to master"
msgstr "régler la branche de suivi par défaut à master"
@@ -12610,14 +12784,11 @@ msgstr "régler la branche de suivi par défaut à master"
msgid "set the default tracking branch"
msgstr "régler la branche de suivi par défaut"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <chemin>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <chemin>"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branche> "
-"<chemin>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <branche> <chemin>"
msgid "--branch or --default required"
msgstr "--branch ou --default requis"
@@ -12716,8 +12887,8 @@ msgstr ""
"configurer le nom du sous-module avec la chaîne passée au lieu d'utiliser "
"par défaut son chemin"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<options>] [--] <dépôt> [<chemin>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<options>] [--] <dépôt> [<chemin>]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr ""
@@ -12927,6 +13098,16 @@ msgstr "Étiquette '%s' mise à jour (elle était sur %s)\n"
msgid "pack exceeds maximum allowed size"
msgstr "le paquet dépasse la taille maximale permise"
+msgid "failed to write object in stream"
+msgstr "impossible d'écrire l'objet dans le flux"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "la décompression (inflate) a retourné (%d)"
+
+msgid "invalid blob object from stream"
+msgstr "objet blob invalide depuis le flux"
+
msgid "Unpacking objects"
msgstr "Dépaquetage des objets"
@@ -13470,6 +13651,27 @@ msgstr "écrire l'objet arbre pour un sous-répertoire <préfixe>"
msgid "only useful for debugging"
msgstr "seulement utile pour le débogage"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch non géré sur cette plateforme"
+
+msgid "failed to create temporary file"
+msgstr "impossible de créer un fichier temporaire"
+
+msgid "insufficient capabilities"
+msgstr "capacités insuffisantes"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "impossible de télécharger le colis depuis l'URI '%s'"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "le fichier à l'URI '%s' n'est pas un colis"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "échec pour ouvrir le colis de l'URI '%s'"
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
msgstr "algorithme d'empreinte du colis inconnu : %s"
@@ -13679,6 +13881,9 @@ msgid "Give an object a human readable name based on an available ref"
msgstr ""
"Baptiser un objet avec un nom lisible à partir d'une référence disponible"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Générer une archive zip d'information de diagnostic"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr ""
"Afficher les changements entre les validations, entre validation et copie de "
@@ -13815,8 +14020,8 @@ msgstr "Lancer une fusion à 3 points pour les fichiers à fusionner"
msgid "The standard helper program to use with git-merge-index"
msgstr "Le programme assistant standard à utiliser avec git-merge-index"
-msgid "Show three-way merge without touching index"
-msgstr "Afficher la fusion à trois points sans modifier l'index"
+msgid "Perform merge without touching index or working tree"
+msgstr "effectuer la fusion sans toucher à l'index ni à l'arbre de travail"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr ""
@@ -14018,6 +14223,9 @@ msgstr "Valider des fichiers d'archive Git empaquetés"
msgid "Check the GPG signature of tags"
msgstr "Vérifier la signature GPG d'étiquettes"
+msgid "Display version information about Git"
+msgstr "Afficher l'information de version à propos de Git"
+
msgid "Show logs with difference each commit introduces"
msgstr "Afficher les journaux avec la différence que chaque commit introduit"
@@ -14051,6 +14259,24 @@ msgstr "Un ensemble minimal utile des commandes de Git pour tous les jours"
msgid "Frequently asked questions about using Git"
msgstr "Foire aux questions sur l'utilisation de Git"
+msgid "The bundle file format"
+msgstr "le format du fichier de colis"
+
+msgid "Chunk-based file formats"
+msgstr "format de fichier avec des sections"
+
+msgid "Git commit graph format"
+msgstr "format de graphe de commit de Gti"
+
+msgid "Git index format"
+msgstr "format d'index Git"
+
+msgid "Git pack format"
+msgstr "format de paquet Git"
+
+msgid "Git cryptographic signature formats"
+msgstr "formats de signature cryptographique Git"
+
msgid "A Git Glossary"
msgstr "Un glossaire Git"
@@ -14073,6 +14299,21 @@ msgstr "Définition des propriétés de sous-module"
msgid "Git namespaces"
msgstr "Espaces de nom de Git"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Capacités des protocoles v0 et v1"
+
+msgid "Things common to various protocols"
+msgstr "Choses communes aux différents protocoles"
+
+msgid "Git HTTP-based protocols"
+msgstr "protocoles Git basés sur HTTP"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Comment les paquets sont transférés sur le réseau"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Protocole réseau Git, version 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Programmes assistants pour interagir avec des dépôts distants"
@@ -14097,6 +14338,9 @@ msgstr "Interface web de Git"
msgid "An overview of recommended workflows with Git"
msgstr "Un aperçu des flux de travail recommandés avec Git"
+msgid "A tool for managing large Git repositories"
+msgstr "Un outil pour gérer les grands dépôts Git"
+
msgid "commit-graph file is too small"
msgstr "le graphe de commit est trop petit"
@@ -14359,6 +14603,14 @@ msgid "no libc information available\n"
msgstr "aucune information de libc disponible\n"
#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "impossible de déterminer l'espace libre du disque pour '%s'"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "impossible d'avoir des informations pour '%s'"
+
+#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
msgstr "[GLE %ld] le fil de santé n'a pas pu ouvrir '%ls'"
@@ -14413,6 +14665,14 @@ msgid "could not read directory changes [GLE %ld]"
msgstr "impossible de lire les modifications du répertoire [GLE %ld]"
#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] impossible d'ouvrir pour lire '%ls'"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] impossible d'obtenir l'information de protocole pour '%ls'"
+
+#, c-format
msgid "failed to copy SID (%ld)"
msgstr "échec de la copie du SID (%ld)"
@@ -14970,182 +15230,6 @@ msgid "failed to close rev-list's stdin"
msgstr "impossible de fermer l'entrée standard du rev-list"
#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' n'existe pas"
-
-msgid "need a working directory"
-msgstr "répertoire de travail nécessaire"
-
-msgid "could not find enlistment root"
-msgstr "impossible de trouver la racine d'enrôlement"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "impossible de basculer vers '%s'"
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "impossible de configurer %s=%s"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "impossible de configurer log.excludeDecoration"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "Les enrôlements scalaires requièrent un arbre de travail"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "impossible d'ouvrir le répertoire '%s'"
-
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "'%s' sauté, qui n'est ni un fichier ni un répertoire"
-
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "impossible de déterminer l'espace libre du disque pour '%s'"
-
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "impossible d'avoir des informations pour '%s'"
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "la HEAD distante n'est pas une branche : '%.*s'"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-"échec de récupération de la branche par défaut depuis le distant ; "
-"utilisation de la valeur par défaut locale"
-
-msgid "failed to get default branch name"
-msgstr "échec de l'obtention du nom de branche par défaut"
-
-msgid "failed to unregister repository"
-msgstr "échec du désenregistrement du dépôt"
-
-msgid "failed to delete enlistment directory"
-msgstr "échec de la suppression du répertoire d'enrôlement"
-
-msgid "branch to checkout after clone"
-msgstr "branche à extraire après le clonage"
-
-msgid "when cloning, create full working directory"
-msgstr "lors d'un clonage, créer un répertoire de travail complet"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "ne télécharger les méta-données que pour la branche qui sera extraite"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<options>] [--] <dépôt> [<répertoire>]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "impossible de déduire le nom de l'arbre de travail depuis '%s'"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "le répertoire '%s' existe déjà"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "échec d'obtention de la branche par défaut pour '%s'"
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "impossible de paramétrer le distant dans '%s'"
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "impossible de configurer '%s'"
-
-msgid "partial clone failed; attempting full clone"
-msgstr "échec du clonage partiel ; tentative de clonage complet"
-
-msgid "could not configure for full clone"
-msgstr "impossible de configurer pour le clonage complet"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<enrôlement>]"
-
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "impossible de créer le répertoire pour '%s'"
-
-msgid "could not duplicate stdout"
-msgstr "impossible de dupliquer stdout"
-
-msgid "failed to write archive"
-msgstr "impossible d'écrire l'archive"
-
-msgid "`scalar list` does not take arguments"
-msgstr "`scalar list` n'accepte pas d'argument"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<enrôlement>]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "reconfigurer tous les enrôlements enregistrés"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scala reconfigure [--all|<enrôlement>]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "--all ou <enrôlement>, mais pas les deux"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "dépôt git parti dans '%s'"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <tâche> [<enrôlement>]\n"
-"Tâches :\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "pas de tâche : '%s'"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<enrôlement>]"
-
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <enrôlement>"
-
-msgid "refusing to delete current working directory"
-msgstr "refus de la suppression du répertoire de travail actuel"
-
-msgid "include Git version"
-msgstr "inclure la version Git"
-
-msgid "include Git's build options"
-msgstr "inclure les options de construction de Git"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "-C requiert un <répertoire>"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "échec de modification en '%s'"
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c exige un argument <clé>=<valeur>"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <répertoire>] [-c <clé>=<valeur>] <commande> [<options>]\n"
-"\n"
-"Commandes :\n"
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "crlf_action illégal %d"
@@ -15357,6 +15441,32 @@ msgstr ""
msgid "Marked %d islands, done.\n"
msgstr "Marquage de %d îlots, fait.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "valeur invalide de --%s : %s"
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "impossible d'archiver le répertoire manquant '%s'"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "impossible d'ouvrir le répertoire '%s'"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "'%s' sauté, qui n'est ni un fichier ni un répertoire"
+
+msgid "could not duplicate stdout"
+msgstr "impossible de dupliquer stdout"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "impossible d'ajouter le répertoire '%s' à l'archiveur"
+
+msgid "failed to write archive"
+msgstr "impossible d'écrire l'archive"
+
msgid "--merge-base does not work with ranges"
msgstr "--merge-base ne fonctionne pas avec des plages"
@@ -16000,6 +16110,9 @@ msgstr "git fetch-pack : ACK/NACK attendu, '%s' reçu"
msgid "unable to write to remote"
msgstr "impossible d'écrire sur un distant"
+msgid "Server supports filter"
+msgstr "Le serveur supporte filter"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "ligne de superficiel invalide : %s"
@@ -16110,9 +16223,6 @@ msgstr "le serveur ne supporte pas l'algorithme '%s'"
msgid "Server does not support shallow requests"
msgstr "Le serveur ne supporte pas les requêtes superficielles"
-msgid "Server supports filter"
-msgstr "Le serveur supporte filter"
-
msgid "unable to write request to remote"
msgstr "impossible d'écrire la requête sur le distant"
@@ -16458,6 +16568,12 @@ msgstr "Commandes bas niveau / Synchronisation de dépôts"
msgid "Low-level Commands / Internal Helpers"
msgstr "Commandes bas niveau / Assistants internes"
+msgid "User-facing repository, command and file interfaces"
+msgstr "dépôts publics, commandes et interfaces de fichier"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Formats de fichier, protocoles et interfaces de niveau développeur"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "commandes git disponibles dans '%s'"
@@ -16471,6 +16587,12 @@ msgstr "Ci-dessous les commandes Git habituelles dans diverses situations :"
msgid "The Git concept guides are:"
msgstr "Les guides des concepts de Git sont :"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Dépôts publics, commandes et interfaces de fichier :"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "formats de fichiers, protocoles et interfaces de niveau développeur :"
+
msgid "External commands"
msgstr "Commandes externes"
@@ -16558,10 +16680,6 @@ msgstr ""
"false`."
#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "impossible de démarrer le crochet '%s'\n"
-
-#, 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)"
@@ -16750,19 +16868,14 @@ msgid "quoted CRLF detected"
msgstr "CRLF citées détectées"
#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Vos modifications locales aux fichiers suivants seraient écrasées par la "
-"fusion :\n"
-" %s"
-
-#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Échec de la fusion du sous-module %s (non extrait)"
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "Échec de la fusion du sous-module %s (pas de base de fusion)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
msgstr "Échec de fusion du sous-module %s (commits non présents)"
@@ -16782,28 +16895,10 @@ msgstr "Échec de la fusion du sous-module %s"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
msgstr ""
"Échec de fusion du sous-module %s mais une résolution possible de fusion "
-"existe :\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Si c'est correct, ajoutez le simplement à l'index\n"
-"en utilisant par exemple :\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"qui acceptera cette suggestion.\n"
+"existe : %s"
#, c-format
msgid ""
@@ -16968,13 +17063,46 @@ msgstr ""
"CONFLIT (modification/suppression) : %s supprimé dans %s et modifié dans %s. "
"Version %s de %s laissée dans l'arbre."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
+#, c-format
+msgid ""
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
+msgstr ""
+" - aller au sous-module (%s), et soit fusionner le commit %s,\n"
+" soit mettre à jour vers un commit exstant qui intègre déjà ces "
+"modifications\n"
+
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
msgstr ""
-"Note :%s pas à jour et au milieu de l'extraction d'une version "
-"conflictuelle ; la vielle copie a été renommée en %s"
+"La fusion récursive des sous-modules ne gère actuellement que les cas "
+"triviaux.\n"
+"Veuillez procéder à la fusion manuellement pour chaque sous-module en "
+"conflit.\n"
+"Ceci peut être réalisé par les étapes suivantes :\n"
+"%s - revenir au super-projet et lancer :\n"
+"\n"
+" git add %s\n"
+"\n"
+" pour enregistrer la fusion ci-dessus et mettre à jour\n"
+" - résoudre tous les autres conflits dans le super-projet\n"
+" - valider l'index résultant dans le super-projet\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -17046,6 +17174,22 @@ msgid "Found a possible merge resolution for the submodule:\n"
msgstr "Résolution possible de fusion trouvée pour le sous-module :\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Si c'est correct, ajoutez le simplement à l'index\n"
+"en utilisant par exemple :\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"qui acceptera cette suggestion.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Échec de fusion du sous-module %s (plusieurs fusions trouvées)"
@@ -17572,6 +17716,22 @@ msgid "confused by unstable object source data for %s"
msgstr "données de source d'objet instable pour %s"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "écrire l'objet de flux %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "impossible de compresser le nouvel objet dans le flux (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "échec de deflateEnd sur l'objet (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "échec de la création du répertoire %s"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "impossible de lire l'objet pour %s"
@@ -17801,6 +17961,60 @@ msgstr "impossible d'analyser l'objet : %s"
msgid "hash mismatch %s"
msgstr "incohérence de hachage %s"
+msgid "trying to write commit not in index"
+msgstr "échec de l'écriture de l'objet commit absent de l'index"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "échec du chargement de l'index en bitmap (corruption ?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "index en bitmap corrompu (trop court)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "fichier d'index en bitmap corrompu (mauvais entête)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "version non gérée '%d' pour le fichier d'index en bitmap"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr ""
+"fichier d'index en bitmap corrompu (trop court pour correspondre à un cache "
+"d'empreinte)"
+
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr ""
+"fichier d'index en bitmap corrompu (trop court pour correspondre à une table "
+"de recherche)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "entrée dupliquée dans l'index en bitmap : '%s'"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "bitmap ewah corrompu : entête tronqué pour l'entrée %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "bitmap ewah corrompu : index de commit %u hors plage"
+
+msgid "corrupted bitmap pack index"
+msgstr "index de paquet en bitmap corrompu"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "décalage XOR invalide dans l'index de paquet en bitmap"
+
+msgid "cannot fstat bitmap file"
+msgstr "impossible d'obtenir le statut (fstat) du fichier de bitmap"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "fichier bitmap extra ignoré : '%s'"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "la somme de contrôle ne correspond pas entre MIDX et bitmap"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "l'index inverse requis manque dans l'index multi-paquet"
@@ -17812,9 +18026,59 @@ msgstr "impossible d'ouvrir le paquet '%s'"
msgid "preferred pack (%s) is invalid"
msgstr "le paquet préféré (%s) est invalide"
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr ""
+"table de recherche en bitmap corrompue : position de triplet hors d'index"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr ""
+"table de recherche en bitmap corrompue : la chaîne de xor dépasse le nombre "
+"d'entrées"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr "table de recherche en bitmap corrompue : index de commit %u hors plage"
+
#, 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>"
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr "bitmap ewah corrompue : entête tronqué pour la bitmap du commit '%s'"
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "objet '%s' non trouvé dans les bitmaps de type"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "l'objet '%s' n'a pas un type unique"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "objet '%s' : type réel '%s', attendu : '%s'"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "objet non trouvé dans la bitmap : '%s'"
+
+msgid "failed to load bitmap indexes"
+msgstr "échec de chargement des index de bitmap"
+
+msgid "you must specify exactly one commit to test"
+msgstr "vous devez spécifier un seul commit à tester"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "le commit '%s' n'a pas de bitmap indexée"
+
+msgid "mismatch in bitmap results"
+msgstr "décalage dans le résultats de bitmap"
+
+#, 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>"
+
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "impossible de récupérer l'utilisation du disque de '%s'"
#, c-format
msgid "mtimes file %s is too small"
@@ -17939,6 +18203,9 @@ msgstr "vouliez-vous dire `--%s` (avec deux signes moins)?"
msgid "alias of --%s"
msgstr "alias pour --%s"
+msgid "need a subcommand"
+msgstr "sous-commande requise"
+
#, c-format
msgid "unknown option `%s'"
msgstr "option inconnue « %s »"
@@ -18385,9 +18652,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -18415,6 +18685,11 @@ msgstr ""
" créer un commit de fusion utilisant le message de fusion original\n"
" (ou l'uniligne, si aucun commit de fusion n'a été spécifié).\n"
" Utilisez -c <commit> pour reformuler le message de validation.\n"
+" u, update-ref <réf> = suivre un espace réservé pour la <réf> à mettre à "
+"jour\n"
+" à cette position dans les nouveaux commits. La <réf> "
+"est\n"
+" mise à jour à la fin du rebasage\n"
"\n"
"Vous pouvez réordonner ces lignes ; elles sont exécutées de haut en bas.\n"
@@ -18886,6 +19161,13 @@ msgstr "erreur de protocole : sha/ref attendu, '%s' trouvé"
msgid "http transport does not support %s"
msgstr "le transport http ne supporte pas %s"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "erreur de protocole : '<url> <chemin>' attendu, espace manquant"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "échec du téléchargement du fichier à l'URL '%s'"
+
msgid "git-http-push failed"
msgstr "échec de git-http-push"
@@ -19236,6 +19518,15 @@ msgstr "impossible de déterminer la révision HEAD"
msgid "failed to find tree of %s"
msgstr "impossible de trouver l'arbre de %s"
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo enregistre `%s` qui manque"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr ""
+"impossible de récupérer le commit pour l'argument de chemin d'ascendance %s"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<fichier-paquet> n'est plus géré"
@@ -19256,6 +19547,174 @@ msgstr "-L ne supporte pas encore les formats de diff autres que -p et -s"
msgid "cannot create async thread: %s"
msgstr "impossible de créer un fil asynchrone : %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' n'existe pas"
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "impossible de basculer vers '%s'"
+
+msgid "need a working directory"
+msgstr "répertoire de travail nécessaire"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "Les enrôlements scalaires requièrent un arbre de travail"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "impossible de configurer %s=%s"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "impossible de configurer log.excludeDecoration"
+
+msgid "could not add enlistment"
+msgstr "impossible d'ajouter l'enrôlement"
+
+msgid "could not set recommended config"
+msgstr "impossible de réglér la configuration recommandée"
+
+msgid "could not turn on maintenance"
+msgstr "impossible d'activer la maintenance"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "impossible de démarrer le daemon FSMonitor"
+
+msgid "could not turn off maintenance"
+msgstr "impossible de désactiver la maintenance"
+
+msgid "could not remove enlistment"
+msgstr "impossible de supprimer l'enrôlement"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "la HEAD distante n'est pas une branche : '%.*s'"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"échec de récupération de la branche par défaut depuis le distant ; "
+"utilisation de la valeur par défaut locale"
+
+msgid "failed to get default branch name"
+msgstr "échec de l'obtention du nom de branche par défaut"
+
+msgid "failed to unregister repository"
+msgstr "échec du désenregistrement du dépôt"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "Échec de l'arrêt de FSEVEntStream"
+
+msgid "failed to delete enlistment directory"
+msgstr "échec de la suppression du répertoire d'enrôlement"
+
+msgid "branch to checkout after clone"
+msgstr "branche à extraire après le clonage"
+
+msgid "when cloning, create full working directory"
+msgstr "lors d'un clonage, créer un répertoire de travail complet"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "ne télécharger les méta-données que pour la branche qui sera extraite"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<options>] [--] <dépôt> [<répertoire>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "impossible de déduire le nom de l'arbre de travail depuis '%s'"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "le répertoire '%s' existe déjà"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "échec d'obtention de la branche par défaut pour '%s'"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "impossible de paramétrer le distant dans '%s'"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "impossible de configurer '%s'"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "échec du clonage partiel ; tentative de clonage complet"
+
+msgid "could not configure for full clone"
+msgstr "impossible de configurer pour le clonage complet"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<enrôlement>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` n'accepte pas d'argument"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<enrôlement>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "reconfigurer tous les enrôlements enregistrés"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scala reconfigure [--all|<enrôlement>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all ou <enrôlement>, mais pas les deux"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "dépôt git parti dans '%s'"
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <tâche> [<enrôlement>]\n"
+"Tâches :\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "pas de tâche : '%s'"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<enrôlement>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <enrôlement>"
+
+msgid "refusing to delete current working directory"
+msgstr "refus de la suppression du répertoire de travail actuel"
+
+msgid "include Git version"
+msgstr "inclure la version Git"
+
+msgid "include Git's build options"
+msgstr "inclure les options de construction de Git"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C requiert un <répertoire>"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "échec de modification en '%s'"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c exige un argument <clé>=<valeur>"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <répertoire>] [-c <clé>=<valeur>] <commande> [<options>]\n"
+"\n"
+"Commandes :\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr ""
"paquet de nettoyage inattendu pendant la lecture de l'état de dépaquetage "
@@ -19379,10 +19838,6 @@ msgstr "vos modifications locales seraient écrasées par %s."
msgid "commit your changes or stash them to proceed."
msgstr "validez vos modifications ou les remiser pour continuer."
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s : avance rapide"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -19872,6 +20327,27 @@ msgstr "impossible de seulement essayer de fusionner '%.*s'"
msgid "merge: Unable to write new index file"
msgstr "fusion : Impossible d'écrire le nouveau fichier index"
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "un processu 'rebase' semble déjà lancé; '%s.lock' existe déjà"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Les références suivantes ont été mises à jour avec %s :\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Échec des mises à jour des références suivantes avec %s :\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "Autoremisage impossible"
@@ -20039,6 +20515,10 @@ msgid "the script was already rearranged."
msgstr "le script a déjà été réarrangé."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "le fichier update-refs %s est invalide"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "'%s' est hors du dépôt à '%s'"
@@ -20164,17 +20644,21 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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 ""
-"dépôt non sécurisé ('%s' appartient à quelqu'un d'autre)\n"
-"Pour ajouter une exception pour ce dépôt, lancez :\n"
+"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')"
+
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -21061,6 +21545,18 @@ msgstr "numéro de port invalide"
msgid "invalid '..' path segment"
msgstr "segment de chemin '..' invalide"
+msgid "usage: "
+msgstr "usage : "
+
+msgid "fatal: "
+msgstr "fatal : "
+
+msgid "error: "
+msgstr "erreur : "
+
+msgid "warning: "
+msgstr "avertissement : "
+
msgid "Fetching objects"
msgstr "Récupération des objets"
@@ -21502,7 +21998,7 @@ msgid "HEAD detached from "
msgstr "HEAD détachée depuis "
msgid "Not currently on any branch."
-msgstr "Actuellement sur aucun branche."
+msgstr "Actuellement sur aucune branche."
msgid "Initial commit"
msgstr "Validation initiale"
@@ -21874,23 +22370,6 @@ msgstr "Les sections sélectionnées ne s'applique pas à l'index !\n"
msgid "ignoring unmerged: %s\n"
msgstr "fichier non-fusionné ignoré : %s\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-"Appliquer le changement de mode dans l'arbre de travail [y,n,q,a,d%s,?] ? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Appliquer la suppression dans l'arbre de travail [y,n,q,a,d%s,?] ? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Appliquer l'ajout dans l'arbre de travail [y,n,q,a,d%s,?] ? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "Appliquer la section à l'arbre de travail [y,n,q,a,d%s,?] ? "
-
msgid "No other hunks to goto\n"
msgstr "Aucune autre section à atteindre\n"
@@ -22289,5 +22768,87 @@ 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] : "
+#~ msgid "(stats|all)"
+#~ msgstr "(stats|all)"
+
+#~ msgid "git maintenance register"
+#~ msgstr "git maintenance register"
+
+#~ msgid "git maintenance unregister"
+#~ msgstr "git maintenance unregister"
+
+#~ msgid "git maintenance stop"
+#~ msgstr "git maintenance stop"
+
+#, c-format
+#~ msgid "could not parse colored hunk header '%.*s'"
+#~ msgstr "impossible d'analyser l'entête coloré de section '%.*s'"
+
+#, c-format
+#~ msgid "Unknown subcommand: %s"
+#~ msgstr "Sous-commande inconnue : %s"
+
+#~ msgid "checked out in another worktree"
+#~ msgstr "extrait dans un autre arbre de travail"
+
+#~ msgid "failed to open stdin of 'crontab'"
+#~ msgstr "échec à l'ouverture de stdin de 'crontab'"
+
+#, c-format
+#~ msgid "invalid subcommand: %s"
+#~ msgstr "sous-commande invalide : %s"
+
+#~ msgid "single arg format must be symmetric range"
+#~ msgstr "un format d'argument unique doit être une plage symétrique"
+
+#~ msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
+#~ msgstr "git submodule--helper list [--prefix=<chemin>] [<chemin>...]"
+
+#~ msgid "git submodule--helper name <path>"
+#~ msgstr "git submodule--helper <nom> <chemin>"
+
+#, c-format
+#~ msgid "failed to get the default remote for submodule '%s'"
+#~ msgstr ""
+#~ "échec d'obtention du dépôt distant par défaut pour le sous-module '%s'"
+
+#, c-format
+#~ msgid "Invalid update mode '%s' for submodule path '%s'"
+#~ msgstr ""
+#~ "Mode de mise à jour '%s' invalide pour le chemin de sous-module '%s'"
+
+#~ msgid "path into the working tree, across nested submodule boundaries"
+#~ msgstr ""
+#~ "chemin dans la copie de travail, traversant les frontières de sous-modules"
+
+#~ msgid "rebase, merge, checkout or none"
+#~ msgstr "valeurs possibles : rebase, merge, checkout ou none"
+
+#~ msgid "bad value for update parameter"
+#~ msgstr "valeur invalide pour la mise à jour du paramètre"
+
+#~ msgid "Show three-way merge without touching index"
+#~ msgstr "Afficher la fusion à trois points sans modifier l'index"
+
+#, c-format
+#~ msgid "could not create directory for '%s'"
+#~ msgstr "impossible de créer le répertoire pour '%s'"
+
+#, c-format
+#~ msgid "Couldn't start hook '%s'\n"
+#~ msgstr "impossible de démarrer le crochet '%s'\n"
+
+#, c-format
+#~ msgid ""
+#~ "Note: %s not up to date and in way of checking out conflicted version; "
+#~ "old copy renamed to %s"
+#~ msgstr ""
+#~ "Note :%s pas à jour et au milieu de l'extraction d'une version "
+#~ "conflictuelle ; la vielle copie a été renommée en %s"
+
+#, c-format
+#~ msgid "%s: fast-forward"
+#~ msgstr "%s : avance rapide"
+
#~ msgid "--preserve-merges was replaced by --rebase-merges"
#~ msgstr "--preserve-merges a été remplacé par --rebase-merges"
diff --git a/po/id.po b/po/id.po
index 794bf8f1c56..7ce5acb674c 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: 2022-06-21 20:20+0000\n"
-"PO-Revision-Date: 2022-06-18 16:30+0700\n"
+"POT-Creation-Date: 2022-09-28 14:31+0700\n"
+"PO-Revision-Date: 2022-09-28 14:50+0700\n"
"Last-Translator: Bagas Sanjaya <bagasdotme@gmail.com>\n"
"Language-Team: Indonesian\n"
"Language: id\n"
@@ -22,7 +22,7 @@ msgstr ""
msgid "Huh (%s)?"
msgstr "Huh (%s)?"
-#: add-interactive.c builtin/rebase.c reset.c sequencer.c
+#: add-interactive.c builtin/merge.c builtin/rebase.c reset.c sequencer.c
msgid "could not read index"
msgstr "tidak dapat membaca indeks"
@@ -203,8 +203,8 @@ msgid "unstaged"
msgstr "tak tergelar"
#: add-interactive.c apply.c builtin/am.c builtin/bugreport.c builtin/clone.c
-#: builtin/fetch.c builtin/merge.c builtin/pull.c builtin/submodule--helper.c
-#: git-add--interactive.perl
+#: builtin/diagnose.c builtin/fetch.c builtin/merge.c builtin/pull.c
+#: builtin/submodule--helper.c git-add--interactive.perl
msgid "path"
msgstr "jalur"
@@ -464,22 +464,22 @@ msgstr ""
#: add-patch.c git-add--interactive.perl
#, c-format, perl-format
msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Terapkan perubahan mode ke indeks dan pohon kerja [y,n,q,a,d%s,?]? "
+msgstr "Terapkan perubahan mode pada indeks dan pohon kerja [y,n,q,a,d%s,?]? "
#: add-patch.c git-add--interactive.perl
#, c-format, perl-format
msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Terapkan penghapusan ke indeks dan pohon kerja [y,n,q,a,d%s,?]? "
+msgstr "Terapkan penghapusan pada indeks dan pohon kerja [y,n,q,a,d%s,?]? "
#: add-patch.c git-add--interactive.perl
#, c-format, perl-format
msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Terapkan penambahan ke indeks dan pohon kerja [y,n,q,a,d%s,?]? "
+msgstr "Terapkan penambahan pada indeks dan pohon kerja [y,n,q,a,d%s,?]? "
#: add-patch.c git-add--interactive.perl
#, c-format, perl-format
msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Terapkan bingkah ini ke indeks dan pohon kerja [y,n,q,a,d%s,?]? "
+msgstr "Terapkan bingkah ini pada indeks dan pohon kerja [y,n,q,a,d%s,?]? "
#: add-patch.c
msgid ""
@@ -495,6 +495,26 @@ msgstr ""
"a - terapkan bingkah ini dan semua bingkah selanjutnya dalam berkas\n"
"d - jangan terapkan bingkah ini atau bingkah selanjutnya dalam berkas\n"
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "Terapkan perubahan mode pada pohon kerja [y,n,q,a,d%s,?]?"
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Terapkan penghapusan pada pohon kerja [y,n,q,a,d%s,?]?"
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Terapkan penambahan pada pohon kerja [y,n,q,a,d%s,?]?"
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Terapkan bingkah ini pada pohon kerja [y,n,q,a,d%s,?]?"
+
#: add-patch.c
msgid ""
"y - apply this hunk to worktree\n"
@@ -515,11 +535,6 @@ msgid "could not parse hunk header '%.*s'"
msgstr "tidak dapat menguraikan kepala bingkah '%.*s'"
#: add-patch.c
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "tidak dapat menguraikan kepala bingkah berwarna '%.*s'"
-
-#: add-patch.c
msgid "could not parse diff"
msgstr "tidak dapat menguraikan diff"
@@ -626,11 +641,11 @@ msgstr ""
#: add-patch.c
msgid "The selected hunks do not apply to the index!"
-msgstr "Bingkah yang dipilih tidak diterapkan ke indeks!"
+msgstr "Bingkah yang dipilih tidak diterapkan pada indeks!"
#: add-patch.c git-add--interactive.perl
msgid "Apply them to the worktree anyway? "
-msgstr "Tetap terapkan itu ke pohon kerja? "
+msgstr "Tetap terapkan pada pohon kerja? "
#: add-patch.c git-add--interactive.perl
msgid "Nothing was applied.\n"
@@ -857,6 +872,26 @@ msgstr ""
"ke false\n"
"\n"
+#: advice.c
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Jalur berikut sudah dipindahkan di luar definisi sparse-checkout\n"
+"tetapi bukan jarang karena perubahan lokal.\n"
+
+#: advice.c
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Untuk memperbaiki kejarangan jalur tersebut, lakukan hal-hal berikut:\n"
+"* Gunakan \"git add --sparse <jalur>\" untuk memperbarui indeks\n"
+"* Gunakan \"git sparse-checkout reapply\" untuk menerapkan aturan kejarangan"
+
#: alias.c
msgid "cmdline ends with \\"
msgstr "baris perintah diakhiri dengan \\"
@@ -1097,7 +1132,7 @@ msgstr ""
msgid "patch failed: %s:%ld"
msgstr "tambalan gagal: %s:%ld"
-#: apply.c
+#: apply.c builtin/mv.c
#, c-format
msgid "cannot checkout %s"
msgstr "tidak dapat men-checkout %s"
@@ -1495,6 +1530,11 @@ msgstr "tidak dapat mengaruskan blob %s"
msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "mode berkas tidak didukung: 0%o (SHA1: %s)"
+#: archive-tar.c archive-zip.c builtin/pack-objects.c
+#, c-format
+msgid "deflate error (%d)"
+msgstr "kesalahan deflasi (%d)"
+
#: archive-tar.c
#, c-format
msgid "unable to start '%s' filter"
@@ -1519,11 +1559,6 @@ msgstr "jalur bukan UTF-8 valid: %s"
msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "jalur terlalu panjang (%d karakter, SHA1: %s): %s"
-#: archive-zip.c builtin/pack-objects.c
-#, c-format
-msgid "deflate error (%d)"
-msgstr "kesalahan deflasi (%d)"
-
#: archive-zip.c
#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
@@ -1841,8 +1876,8 @@ msgstr ""
"--reverse dan --first-parent bersama-sama butuh komit terbaru yang disebutkan"
#: blame.c builtin/commit.c builtin/log.c builtin/merge.c
-#: builtin/pack-objects.c builtin/shortlog.c bundle.c midx.c ref-filter.c
-#: remote.c sequencer.c submodule.c
+#: builtin/pack-objects.c builtin/shortlog.c bundle.c midx.c pack-bitmap.c
+#: ref-filter.c remote.c sequencer.c submodule.c
msgid "revision walk setup failed"
msgstr "persiapan jalan revisi gagal"
@@ -1937,7 +1972,7 @@ msgstr "tak melacak: informasi ambigu untuk referensi '%s'"
#: branch.c object-name.c
#, c-format
msgid " %s\n"
-msgstr ""
+msgstr " %s\n"
#. TRANSLATORS: The second argument is a \n-delimited list of
#. duplicate refspecs, composed above.
@@ -1954,6 +1989,13 @@ msgid ""
"different remotes' fetch refspecs map into different\n"
"tracking namespaces."
msgstr ""
+"Ada banyak remote yang spek referensi pengambilan terpetakan ke referensi\n"
+"pelacak remote '%s'\n"
+"%s\n"
+"Hal ini biasanya merupakan kesalahan konfigurasi.\n"
+"\n"
+"Untuk mendukung menyetel cabang pelacakan, pastikan bahwa spek referensi\n"
+"remote yang berbeda terpetakan ke ruang nama pelacakan yang berbeda."
#: branch.c
#, c-format
@@ -1993,6 +2035,14 @@ msgid ""
"will track its remote counterpart, you may want to use\n"
"\"git push -u\" to set the upstream config as you push."
msgstr ""
+"\n"
+"Jika Anda berencana mendasarkan karya Anda pada sebuah cabang hulu\n"
+"yang sudah ada pada remote, Anda mungkin perlu menjalankan\n"
+"\"git fetch\" untuk mendapatkannya.\n"
+"\n"
+"Jika Anda berencana mendorong sebuah cabang lokal baru yang akan melacak\n"
+"pasangan remotenya, Anda dapat menggunakan \"git push -u\" untuk menyetel\n"
+"konfigurasi hulu saat Anda dorong."
#: branch.c builtin/replace.c
#, c-format
@@ -2248,19 +2298,19 @@ msgstr ""
#: builtin/reset.c builtin/rm.c builtin/submodule--helper.c read-cache.c
#: rerere.c submodule.c
msgid "index file corrupt"
-msgstr ""
+msgstr "berkas indeks rusak"
#: builtin/am.c builtin/mailinfo.c mailinfo.c
#, c-format
msgid "bad action '%s' for '%s'"
-msgstr ""
+msgstr "tindakan jelek '%s' untuk '%s'"
#: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c
#: builtin/pull.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 ""
+msgstr "nilai tidak valid untuk '%s': '%s'"
#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c
#, c-format
@@ -2274,7 +2324,7 @@ msgstr "tidak dapat mengurai skrip pengarang"
#: builtin/am.c builtin/replace.c commit.c sequencer.c
#, c-format
msgid "could not parse %s"
-msgstr ""
+msgstr "tidak dapat menguraikan %s"
#: builtin/am.c
#, c-format
@@ -2300,7 +2350,7 @@ msgstr "fseek gagal"
msgid "could not open '%s' for reading"
msgstr "tidak dapat membuka '%s' untuk dibaca"
-#: builtin/am.c builtin/rebase.c strbuf.c wrapper.c
+#: builtin/am.c builtin/rebase.c sequencer.c strbuf.c wrapper.c
#, c-format
msgid "could not open '%s' for writing"
msgstr "tidak dapat membuka '%s' untuk ditulis"
@@ -2384,7 +2434,7 @@ msgstr "baris identitas tidak valid: %.*s"
#: builtin/am.c builtin/checkout.c builtin/clone.c commit-graph.c
#, c-format
msgid "unable to parse commit %s"
-msgstr ""
+msgstr "tidak dapat menguraikan komit %s"
#: builtin/am.c
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
@@ -2618,8 +2668,8 @@ msgid "n"
msgstr "n"
#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
-#: builtin/for-each-ref.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c
+#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c
msgid "format"
msgstr "format"
@@ -2723,7 +2773,7 @@ msgstr "mode interaktif butuh tambalan pada baris perintah"
msgid "git apply [<options>] [<patch>...]"
msgstr "git apply [<opsi>] [<tambalan>...]"
-#: builtin/archive.c contrib/scalar/scalar.c
+#: builtin/archive.c diagnose.c
msgid "could not redirect output"
msgstr "tidak dapat mengalihkan keluaran"
@@ -3611,8 +3661,8 @@ msgstr "pengurutan dan penyaringan tak peka kapital"
msgid "recurse through submodules"
msgstr "rekursi melalui submodul"
-#: builtin/branch.c builtin/for-each-ref.c builtin/ls-tree.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/branch.c builtin/for-each-ref.c builtin/ls-files.c builtin/ls-tree.c
+#: builtin/tag.c builtin/verify-tag.c
msgid "format to use for the output"
msgstr "format yang digunakan untuk keluaran"
@@ -3721,28 +3771,34 @@ msgstr ""
#: builtin/bugreport.c
msgid "git version:\n"
-msgstr ""
+msgstr "versi git:\n"
#: builtin/bugreport.c
#, c-format
msgid "uname() failed with error '%s' (%d)\n"
-msgstr ""
+msgstr "uname() gagal dengan kesalahan '%s' (%d)\n"
#: builtin/bugreport.c
msgid "compiler info: "
-msgstr ""
+msgstr "info pengompilasi: "
#: builtin/bugreport.c
msgid "libc info: "
-msgstr ""
+msgstr "info pustaka c: "
#: builtin/bugreport.c
msgid "not run from a git repository - no hooks to show\n"
msgstr ""
+"tidak dijalankan dari sebuah repositori git - tidak ada kait yang "
+"diperlihatkan\n"
#: builtin/bugreport.c
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
msgstr ""
+"git bugreport [-o|--output-directory <berkas>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]]"
#: builtin/bugreport.c
msgid ""
@@ -3762,37 +3818,67 @@ msgid ""
"Please review the rest of the bug report below.\n"
"You can delete any lines you don't wish to share.\n"
msgstr ""
+"Terima kasih telah mengisi laporan bug Git!\n"
+"Mohon jawab pertanyaan berikut untuk membantu memahami masalah Anda.\n"
+"\n"
+"Apa yang Anda lakukan sebelum bug terjadi? (Tahap-tahap untuk mereproduksi "
+"masalah Anda)\n"
+"Apa yang Anda harapkan? (Perilaku yang diharapkan)\n"
+"\n"
+"Apa yang terjadi? (Perilaku sebenarnya)\n"
+"\n"
+"Apa yang berbeda antara apa yang Anda harapkan dan yang sebenarnya terjadi?\n"
+"\n"
+"Apalagi yang Anda ingin tambahkan?\n"
+"\n"
+"Mohon tinjau sisa laporan bug di bawah ini.\n"
+"Anda dapat menghapus baris-baris yang Anda tidak ingin dibagi.\n"
+
+#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c
+#: parse-options.h
+msgid "mode"
+msgstr "mode"
#: builtin/bugreport.c
-msgid "specify a destination for the bugreport file"
-msgstr ""
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr "buat arsip zip tambahan dari diagnostik terperinci (asali 'stats')"
#: builtin/bugreport.c
-msgid "specify a strftime format suffix for the filename"
-msgstr ""
+msgid "specify a destination for the bugreport file(s)"
+msgstr "sebutkan tujuan untuk berkas(-berkas) laporan bug"
#: builtin/bugreport.c
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "sebutkan akhiran format strftime untuk nama(-nama) berkas"
+
+#: builtin/bugreport.c builtin/diagnose.c
#, c-format
msgid "could not create leading directories for '%s'"
-msgstr ""
+msgstr "tidak dapat membuat direktori utama untuk '%s'"
+
+#: builtin/bugreport.c builtin/diagnose.c
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "tidak dapat membuat arsip diagnostik %s"
#: builtin/bugreport.c
msgid "System Info"
-msgstr ""
+msgstr "Informasi Sistem"
#: builtin/bugreport.c
msgid "Enabled Hooks"
-msgstr ""
+msgstr "Kait Aktif"
#: builtin/bugreport.c
#, c-format
msgid "unable to write to %s"
-msgstr ""
+msgstr "tidak dapat menulis ke %s"
#: builtin/bugreport.c
#, c-format
msgid "Created new report at '%s'.\n"
-msgstr ""
+msgstr "Laporan baru dibuat pada '%s'.\n"
#: builtin/bundle.c
msgid "git bundle create [<options>] <file> <git-rev-list args>"
@@ -3851,11 +3937,6 @@ msgstr "Perlu sebuah repositori untuk membongkar bundel."
msgid "Unbundling objects"
msgstr "Membongkar bundel objek"
-#: builtin/bundle.c builtin/remote.c
-#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Subperintah tidak dikenal: %s"
-
#: builtin/cat-file.c merge-recursive.c
#, c-format
msgid "cannot read object %s '%s'"
@@ -3954,6 +4035,10 @@ msgstr "perlihatkan ukuran objek"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "perbolehkan -s dan -t bekerja dengan objek rusak"
+#: builtin/cat-file.c builtin/log.c
+msgid "use mail map file"
+msgstr "gunakan berkas peta surat"
+
#: builtin/cat-file.c
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr "Objek batch diminta pada masukan standar (atau --batch-all-objects)"
@@ -3967,6 +4052,10 @@ msgid "like --batch, but don't emit <contents>"
msgstr "seperti --batch, tapi jangan keluarkan <isi>"
#: builtin/cat-file.c
+msgid "stdin is NUL-terminated"
+msgstr "stdin diakhiri dengan NUL"
+
+#: builtin/cat-file.c
msgid "read commands from stdin"
msgstr "baca perintah dari masukan standar"
@@ -4062,137 +4151,139 @@ msgstr ""
#: builtin/check-attr.c
msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..."
-msgstr ""
+msgstr "git check-attr [-a | --all | <atribut>...] [--] <nama jalur>..."
#: builtin/check-attr.c
msgid "git check-attr --stdin [-z] [-a | --all | <attr>...]"
-msgstr ""
+msgstr "git check-attr --stdin [-z] [-a | --all | <attribut>...]"
#: builtin/check-attr.c
msgid "report all attributes set on file"
-msgstr ""
+msgstr "laporkan semua atribut yang disetel pada berkas"
#: builtin/check-attr.c
msgid "use .gitattributes only from the index"
-msgstr ""
+msgstr "hanya gunakan .gitattributes dari indeks"
#: builtin/check-attr.c builtin/check-ignore.c builtin/hash-object.c
msgid "read file names from stdin"
-msgstr ""
+msgstr "baca nama berkas dari masukan standar"
#: builtin/check-attr.c builtin/check-ignore.c
msgid "terminate input and output records by a NUL character"
-msgstr ""
+msgstr "akhiri masukan dan keluarkan rekaman oleh sebuah karakter NUL"
#: builtin/check-ignore.c builtin/checkout.c builtin/gc.c builtin/worktree.c
msgid "suppress progress reporting"
-msgstr ""
+msgstr "padamkan pelaporan kemajuan"
#: builtin/check-ignore.c
msgid "show non-matching input paths"
-msgstr ""
+msgstr "perlihatkan jalur input yang tak cocok"
#: builtin/check-ignore.c
msgid "ignore index when checking"
-msgstr ""
+msgstr "abaikan indeks ketika memeriksa"
#: builtin/check-ignore.c
msgid "cannot specify pathnames with --stdin"
-msgstr ""
+msgstr "tidak dapat menyebutkan nama jalur dengan --stdin"
#: builtin/check-ignore.c
msgid "-z only makes sense with --stdin"
-msgstr ""
+msgstr "-z hanya masuk akal dengan --stdin"
#: builtin/check-ignore.c
msgid "no path specified"
-msgstr ""
+msgstr "tidak ada jalur yang disebutkan"
#: builtin/check-ignore.c
msgid "--quiet is only valid with a single pathname"
-msgstr ""
+msgstr "--quiet hanya valid dengan satu nama jalur"
#: builtin/check-ignore.c
msgid "cannot have both --quiet and --verbose"
-msgstr ""
+msgstr "tidak dapat punya baik --quiet dan --verbose"
#: builtin/check-ignore.c
msgid "--non-matching is only valid with --verbose"
-msgstr ""
+msgstr "--non-matching hanya valid dengan --verbose"
#: builtin/check-mailmap.c
msgid "git check-mailmap [<options>] <contact>..."
-msgstr ""
+msgstr "git check-mailmap [<opsi>] <kontak>..."
#: builtin/check-mailmap.c
msgid "also read contacts from stdin"
-msgstr ""
+msgstr "juga baca kontak dari masukan standar"
#: builtin/check-mailmap.c
#, c-format
msgid "unable to parse contact: %s"
-msgstr ""
+msgstr "tidak dapat menguraikan kontak: %s"
#: builtin/check-mailmap.c
msgid "no contacts specified"
-msgstr ""
+msgstr "tidak ada kontak yang disebutkan"
#: builtin/checkout--worker.c
msgid "git checkout--worker [<options>]"
-msgstr ""
+msgstr "git checkout--worker [<opsi>]"
#: builtin/checkout--worker.c builtin/checkout-index.c builtin/column.c
#: builtin/submodule--helper.c builtin/worktree.c
msgid "string"
-msgstr ""
+msgstr "untai"
#: builtin/checkout--worker.c builtin/checkout-index.c
msgid "when creating files, prepend <string>"
-msgstr ""
+msgstr "saat membuat berkas, awali dengan <string>"
#: builtin/checkout-index.c
msgid "git checkout-index [<options>] [--] [<file>...]"
-msgstr ""
+msgstr "git checkout-index [<opsi>] [--] [<berkas>...]"
#: builtin/checkout-index.c
msgid "stage should be between 1 and 3 or all"
-msgstr ""
+msgstr "tahap seharusnya antara 1 dan 3 atau semua"
#: builtin/checkout-index.c
msgid "check out all files in the index"
-msgstr ""
+msgstr "check out semua berkas di dalam indeks"
#: builtin/checkout-index.c
msgid "do not skip files with skip-worktree set"
-msgstr ""
+msgstr "jangan lewatkan berkas dengan skip-worktree tersetel"
#: builtin/checkout-index.c
msgid "force overwrite of existing files"
-msgstr ""
+msgstr "paksa timpa berkas yang ada"
#: builtin/checkout-index.c
msgid "no warning for existing files and files not in index"
msgstr ""
+"tanpa peringatan untuk berkas yang ada dan berkas yang tidak ada di dalam "
+"indeks"
#: builtin/checkout-index.c
msgid "don't checkout new files"
-msgstr ""
+msgstr "jangan checkout berkas baru"
#: builtin/checkout-index.c
msgid "update stat information in the index file"
-msgstr ""
+msgstr "perbarui informasi stat di dalam berkas indeks"
#: builtin/checkout-index.c
msgid "read list of paths from the standard input"
-msgstr ""
+msgstr "baca daftar jalur dari masukan standar"
#: builtin/checkout-index.c
msgid "write the content to temporary files"
-msgstr ""
+msgstr "tulis isi ke berkas sementara"
#: builtin/checkout-index.c
msgid "copy out the files from named stage"
-msgstr ""
+msgstr "salin berkas dari tahap bernama"
#: builtin/checkout.c
msgid "git checkout [<options>] <branch>"
@@ -5063,6 +5154,14 @@ msgstr ""
"inisialisasi berkas checkout tipis agar memasukkan hanya berkas pada akar"
#: builtin/clone.c
+msgid "uri"
+msgstr "URI"
+
+#: builtin/clone.c
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "sebuah URI untuk mengunduh bundel sebelum mengambil dari remote asal"
+
+#: builtin/clone.c
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: Tidak dapat menambahkan alternatif untuk '%s': %s\n"
@@ -5136,9 +5235,8 @@ msgid "failed to initialize sparse-checkout"
msgstr "gagal menginisalisasi checkout tipis"
#: builtin/clone.c
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr ""
-"HEAD remote merujuk pada ref yang tidak ada, tidak dapat men-checkout.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
+msgstr "HEAD remote merujuk pada ref yang tidak ada, tidak dapat men-checkout"
#: builtin/clone.c
msgid "unable to checkout working tree"
@@ -5160,7 +5258,7 @@ msgstr "tidak dapat batal-taut berkas alternatif sementara"
msgid "Too many arguments."
msgstr "Terlalu banyak argumen."
-#: builtin/clone.c contrib/scalar/scalar.c
+#: builtin/clone.c scalar.c
msgid "You must specify a repository to clone."
msgstr "Anda harus sebutkan repositori untuk diklon."
@@ -5170,6 +5268,14 @@ msgid "options '%s' and '%s %s' cannot be used together"
msgstr "opsi '%s' dan '%s %s' tidak dapat digunakan bersamaan"
#: builtin/clone.c
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri tidak kompatibel dengan --depth, --shallow-since, dan --shallow-"
+"exclude"
+
+#: builtin/clone.c
#, c-format
msgid "repository '%s' does not exist"
msgstr "repositori '%s' tidak ada"
@@ -5262,6 +5368,15 @@ msgid "cannot clone from filtered bundle"
msgstr "tidak dapat mengkloning dari bundel tersaring"
#: builtin/clone.c
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "gagal menginisialisasi repo, melewatkan URI bundel"
+
+#: builtin/clone.c
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "gagal mengambil objek dari URI bundel '%s'"
+
+#: builtin/clone.c
msgid "remote transport reported error"
msgstr "transportasi remote melaporkan kesalahan"
@@ -5276,40 +5391,42 @@ msgstr "Anda tampaknya mengklon repositori kosong."
#: builtin/column.c
msgid "git column [<options>]"
-msgstr ""
+msgstr "git column [<opsi>]"
#: builtin/column.c
msgid "lookup config vars"
-msgstr ""
+msgstr "cari variabel konfigurasi"
#: builtin/column.c
msgid "layout to use"
-msgstr ""
+msgstr "layout yang digunakan"
#: builtin/column.c
msgid "maximum width"
-msgstr ""
+msgstr "lebar maksimum"
#: builtin/column.c
msgid "padding space on left border"
-msgstr ""
+msgstr "bantalan spasi pada perbatasan kiri"
#: builtin/column.c
msgid "padding space on right border"
-msgstr ""
+msgstr "bantalan spasi pada perbatasan kanan"
#: builtin/column.c
msgid "padding space between columns"
-msgstr ""
+msgstr "bantalan spasi di antara kolom"
#: builtin/column.c
msgid "--command must be the first argument"
-msgstr ""
+msgstr "--command harus menjadi argumen pertama"
#: builtin/commit-graph.c
msgid ""
"git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"
msgstr ""
+"git commit-graph verify [--object-dir <direktori objek>] [--shallow] [--"
+"[no-]progress]"
#: builtin/commit-graph.c
msgid ""
@@ -5317,96 +5434,96 @@ msgid ""
"split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] [--changed-"
"paths] [--[no-]max-new-filters <n>] [--[no-]progress] <split options>"
msgstr ""
+"git commit-graph write [--object-dir <direktori objek>] [--append] [--"
+"split[=<strategi>]] [--reachable|--stdin-packs|--stdin-commits] [--changed-"
+"paths] [--[no-]max-new-filters <n>] [--[-no-]progrss] <opsi pemisah>"
#: builtin/commit-graph.c builtin/fetch.c builtin/log.c
msgid "dir"
-msgstr ""
+msgstr "direktori"
#: builtin/commit-graph.c
msgid "the object directory to store the graph"
-msgstr ""
+msgstr "direktori objek untuk menyimpan grafik"
#: builtin/commit-graph.c
msgid "if the commit-graph is split, only verify the tip file"
-msgstr ""
+msgstr "jika grafik komit terpisah, hanya verifikasi berkas ujung"
#: builtin/commit-graph.c
#, c-format
msgid "Could not open commit-graph '%s'"
-msgstr ""
+msgstr "Tidak dapat membuka grafik komit '%s'"
#: builtin/commit-graph.c
#, c-format
msgid "unrecognized --split argument, %s"
-msgstr ""
+msgstr "argumen --split tidak dikenal, %s"
#: builtin/commit-graph.c
#, c-format
msgid "unexpected non-hex object ID: %s"
-msgstr ""
+msgstr "ID objek non-heks tidak diharapkan: %s"
#: builtin/commit-graph.c
#, c-format
msgid "invalid object: %s"
-msgstr ""
+msgstr "objek tidak valid: %s"
#: builtin/commit-graph.c parse-options-cb.c
#, c-format
msgid "option `%s' expects a numerical value"
-msgstr ""
+msgstr "opsi `%s' mengharapkan nilai numerik"
#: builtin/commit-graph.c
msgid "start walk at all refs"
-msgstr ""
+msgstr "mulai berjalan pada semua referensi"
#: builtin/commit-graph.c
msgid "scan pack-indexes listed by stdin for commits"
-msgstr ""
+msgstr "pindai indeks pak yang disebutkan oleh masukan standar untuk komit"
#: builtin/commit-graph.c
msgid "start walk at commits listed by stdin"
-msgstr ""
+msgstr "mulai berjalan pada komit yang disebutkan oleh masukan standar"
#: builtin/commit-graph.c
msgid "include all commits already in the commit-graph file"
-msgstr ""
+msgstr "masukkan semua komit yang sudah ada di dalam berkas grafik komit"
#: builtin/commit-graph.c
msgid "enable computation for changed paths"
-msgstr ""
+msgstr "aktifkan perhitungan perubahan jalur"
#: builtin/commit-graph.c
msgid "allow writing an incremental commit-graph file"
-msgstr ""
+msgstr "perbolehkan menulis berkas grafik komit bertambah"
#: builtin/commit-graph.c
msgid "maximum number of commits in a non-base split commit-graph"
-msgstr ""
+msgstr "jumlah komit maksimal di dalam grafik komit terpisah non-dasar"
#: builtin/commit-graph.c
msgid "maximum ratio between two levels of a split commit-graph"
-msgstr ""
+msgstr "rasio maksimum di antara dua tingkat grafik komit terpisah"
#: builtin/commit-graph.c
msgid "only expire files older than a given date-time"
msgstr ""
+"hanya kadaluarsakan berkas yang lebih tua dari tanggal-waktu yang diberikan"
#: builtin/commit-graph.c
msgid "maximum number of changed-path Bloom filters to compute"
-msgstr ""
+msgstr "jumlah penyaring Bloom berubah jalur maksimum yang dihitung"
#: builtin/commit-graph.c
msgid "use at most one of --reachable, --stdin-commits, or --stdin-packs"
msgstr ""
+"gunakan hanya satu dari --reachable, --stdin-commits, atau --stdin-packs"
#: builtin/commit-graph.c
msgid "Collecting commits from input"
-msgstr ""
-
-#: builtin/commit-graph.c builtin/multi-pack-index.c
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr ""
+msgstr "Mengumpulkan komit dari masukan"
#: builtin/commit-tree.c
msgid ""
@@ -5842,10 +5959,6 @@ msgstr "perlihatkan status dalam format panjang (asali)"
msgid "terminate entries with NUL"
msgstr "akhiri entri dengan NUL"
-#: builtin/commit.c builtin/fast-export.c builtin/rebase.c parse-options.h
-msgid "mode"
-msgstr "mode"
-
#: builtin/commit.c
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
@@ -6416,23 +6529,28 @@ msgid ""
"\n"
"\tchmod 0700 %s"
msgstr ""
+"Perizinan pada direktori soket Anda terlalu longgar; pengguna lainnya\n"
+"dapat membaca kredensial tertembolok Anda. Pertimbangkan menjalankan:\n"
+"\n"
+"\tchmod 0700 %s"
#: builtin/credential-cache--daemon.c
msgid "print debugging messages to stderr"
-msgstr ""
+msgstr "cetak pesan penirkutuan ke kesalahan standar"
#: builtin/credential-cache--daemon.c
msgid "credential-cache--daemon unavailable; no unix socket support"
-msgstr ""
+msgstr "credential-cache--daemon tidak tersedia; tidak ada dukungan soket unix"
#: builtin/credential-cache.c
msgid "credential-cache unavailable; no unix socket support"
-msgstr ""
+msgstr "credential-cache tidak tersedia; tidak ada dukungan soket unix"
#: builtin/credential-store.c
#, c-format
msgid "unable to get credential storage lock in %d ms"
msgstr ""
+"tidak dapat mendapatkan kunci penyimpanan kredensial dalam %d milidetik"
#: builtin/describe.c
msgid "git describe [<options>] [<commit-ish>...]"
@@ -6593,6 +6711,26 @@ msgstr "Tidak ada nama yang ditemukan, tidak dapat menjelaskan apapun."
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "opsi '%s' dan mirip-komit tidak dapat digunakan bersamaan"
+#: builtin/diagnose.c
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <jalur>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+
+#: builtin/diagnose.c
+msgid "specify a destination for the diagnostics archive"
+msgstr "sebutkan tujuan untuk arsip diagnostik"
+
+#: builtin/diagnose.c
+msgid "specify a strftime format suffix for the filename"
+msgstr "sebutkan akhiran format strftime untuk nama berkas"
+
+#: builtin/diagnose.c
+msgid "specify the content of the diagnostic archive"
+msgstr "sebutkan isi arsip diagnostik"
+
#: builtin/diff-tree.c
msgid "--merge-base only works with two commits"
msgstr "--merge-base hanya bekerja dengan dua komit"
@@ -6749,20 +6887,22 @@ msgstr "tidak ada <perintah> yang diberikan untuk --extcmd=<perintah>"
#: builtin/env--helper.c
msgid "git env--helper --type=[bool|ulong] <options> <env-var>"
-msgstr ""
+msgstr "git env--helper --type=[bool|ulong] <opsi> <variabel lingkungan>"
#: builtin/env--helper.c
msgid "default for git_env_*(...) to fall back on"
-msgstr ""
+msgstr "asali untuk git_env_*(...) agar kembali"
#: builtin/env--helper.c
msgid "be quiet only use git_env_*() value as exit code"
-msgstr ""
+msgstr "jadi diam; hanya gunakan nilai git_env_*() sebagai kode keluar"
#: builtin/env--helper.c
#, c-format
msgid "option `--default' expects a boolean value with `--type=bool`, not `%s`"
msgstr ""
+"opsi `--default' mengharapkan sebuah nilai boolean dengan `--type=bool`, "
+"bukan `%s`"
#: builtin/env--helper.c
#, c-format
@@ -6770,6 +6910,8 @@ msgid ""
"option `--default' expects an unsigned long value with `--type=ulong`, not `"
"%s`"
msgstr ""
+"opsi `--default' mengharapkan sebuah nilai unsigned long dengan `--"
+"type=ulong`, bukan `%s`"
#: builtin/fast-export.c
msgid "git fast-export [<rev-list-opts>]"
@@ -7074,12 +7216,8 @@ msgid "[rejected]"
msgstr "[tertolak]"
#: builtin/fetch.c
-msgid "can't fetch in current branch"
-msgstr "tidak dapat mengambil di cabang saat ini"
-
-#: builtin/fetch.c
-msgid "checked out in another worktree"
-msgstr "ter-check out di dalam pohon kerja lainnya"
+msgid "can't fetch into checked-out branch"
+msgstr "tidak dapat mengambil ke dalam cabang ter-checkout"
#: builtin/fetch.c
msgid "[tag update]"
@@ -7327,106 +7465,107 @@ msgstr "--stdin hanya dapat digunakan saat mengambil dari satu remote"
msgid ""
"git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"
msgstr ""
+"git fmt-merge-msg [-m <pesan>] [--log[=<n>] | --no-log] [--file <berkas>]"
#: builtin/fmt-merge-msg.c
msgid "populate log with at most <n> entries from shortlog"
-msgstr ""
+msgstr "isi log dengan paling banyak <n> entri dari shortlog"
#: builtin/fmt-merge-msg.c
msgid "alias for --log (deprecated)"
-msgstr ""
+msgstr "alias untuk --log (usang)"
#: builtin/fmt-merge-msg.c
msgid "text"
-msgstr ""
+msgstr "teks"
#: builtin/fmt-merge-msg.c
msgid "use <text> as start of message"
-msgstr ""
+msgstr "gunakan <teks> sebagai awal pesan"
#: builtin/fmt-merge-msg.c
msgid "use <name> instead of the real target branch"
-msgstr ""
+msgstr "gunakan <nama> daripada cabang target sebenarnya"
#: builtin/fmt-merge-msg.c
msgid "file to read from"
-msgstr ""
+msgstr "berkas untuk dibaca"
#: builtin/for-each-ref.c
msgid "git for-each-ref [<options>] [<pattern>]"
-msgstr ""
+msgstr "git for-each-ref [<opsi>] [<pola>]"
#: builtin/for-each-ref.c
msgid "git for-each-ref [--points-at <object>]"
-msgstr ""
+msgstr "git for-each-ref [--points-at <objek>]"
#: builtin/for-each-ref.c
msgid "git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]"
-msgstr ""
+msgstr "git for-each-ref [--merged [<komit>]] [--no-merged [<komit>]]"
#: builtin/for-each-ref.c
msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"
-msgstr ""
+msgstr "git for-each-ref [--contains [<komit>]] [--no-contains [<komit>]]"
#: builtin/for-each-ref.c
msgid "quote placeholders suitably for shells"
-msgstr ""
+msgstr "kutip tempat penampung yang sesuai untuk cangkang"
#: builtin/for-each-ref.c
msgid "quote placeholders suitably for perl"
-msgstr ""
+msgstr "kutip tempat penampung yang sesuai untuk perl"
#: builtin/for-each-ref.c
msgid "quote placeholders suitably for python"
-msgstr ""
+msgstr "kutip tempat penampung yang sesuai untuk python"
#: builtin/for-each-ref.c
msgid "quote placeholders suitably for Tcl"
-msgstr ""
+msgstr "kutip tempat penampung yang sesuai untuk Tcl"
#: builtin/for-each-ref.c
msgid "show only <n> matched refs"
-msgstr ""
+msgstr "hanya perlihatkan <n> referensi yang cocok"
#: builtin/for-each-ref.c builtin/tag.c
msgid "respect format colors"
-msgstr ""
+msgstr "hargai warna format"
#: builtin/for-each-ref.c
msgid "print only refs which points at the given object"
-msgstr ""
+msgstr "hanya cetak referensi yang menunjuk pada objek yang diberikan"
#: builtin/for-each-ref.c
msgid "print only refs that are merged"
-msgstr ""
+msgstr "hanya cetak referensi yang tergabung"
#: builtin/for-each-ref.c
msgid "print only refs that are not merged"
-msgstr ""
+msgstr "hanya cetak referensi yang tidak tergabung"
#: builtin/for-each-ref.c
msgid "print only refs which contain the commit"
-msgstr ""
+msgstr "hanya cetak referensi yang berisi komit"
#: builtin/for-each-ref.c
msgid "print only refs which don't contain the commit"
-msgstr ""
+msgstr "hanya cetak referensi yang tidak berisi komit"
#: builtin/for-each-repo.c
msgid "git for-each-repo --config=<config> <command-args>"
-msgstr ""
+msgstr "git for-each-repo --config=<konfigurasi> <argumen perintah>"
#: builtin/for-each-repo.c
msgid "config"
-msgstr ""
+msgstr "konfigurasi"
#: builtin/for-each-repo.c
msgid "config key storing a list of repository paths"
-msgstr ""
+msgstr "kunci konfigurasi yang menampung daftar jalur repositori"
#: builtin/for-each-repo.c
msgid "missing --config=<config>"
-msgstr ""
+msgstr "kehilangan --config=<config>"
#: builtin/fsck.c
msgid "unknown"
@@ -7626,6 +7765,11 @@ msgid "non-tree in cache-tree"
msgstr "bukan pohon pada pohon tembolok"
#: builtin/fsck.c
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s: penunjuk sha1 tidak valid di resolve-undo"
+
+#: builtin/fsck.c
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<opsi>] [<objek>...]"
@@ -7693,128 +7837,129 @@ msgstr "parameter tidak valid: sha1 diharapkan, dapat '%s'"
#: builtin/fsmonitor--daemon.c
msgid "git fsmonitor--daemon start [<options>]"
-msgstr ""
+msgstr "git fsmonitor--daemon start [<opsi>]"
#: builtin/fsmonitor--daemon.c
msgid "git fsmonitor--daemon run [<options>]"
-msgstr ""
+msgstr "git fsmonitor--daemon run [<opsi>]"
#: builtin/fsmonitor--daemon.c
msgid "git fsmonitor--daemon stop"
-msgstr ""
+msgstr "git fsmonitor--daemon stop"
#: builtin/fsmonitor--daemon.c
msgid "git fsmonitor--daemon status"
-msgstr ""
+msgstr "git fsmonitor--daemon status"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "value of '%s' out of range: %d"
-msgstr ""
+msgstr "nilai '%s' di luar jangkauan: %d"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "value of '%s' not bool or int: %d"
-msgstr ""
+msgstr "nilai '%s' bukan bool atau int: %d"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "fsmonitor-daemon is watching '%s'\n"
-msgstr ""
+msgstr "fsmonitor-daemon mengawasi '%s'\n"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "fsmonitor-daemon is not watching '%s'\n"
-msgstr ""
+msgstr "fsmonitor-daemon tidak mengawasi '%s'\n"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "could not create fsmonitor cookie '%s'"
-msgstr ""
+msgstr "tidak dapat membuat kuki fsmonitor '%s'"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "fsmonitor: cookie_result '%d' != SEEN"
-msgstr ""
+msgstr "fsmonitor: cookie_result '%d' != SEEN"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "could not start IPC thread pool on '%s'"
-msgstr ""
+msgstr "tidak dapat memulai lubuk utas IPC pada '%s'"
#: builtin/fsmonitor--daemon.c
msgid "could not start fsmonitor listener thread"
-msgstr ""
+msgstr "tidak dapat memulai utas pendengar fsmonitor"
#: builtin/fsmonitor--daemon.c
msgid "could not start fsmonitor health thread"
-msgstr ""
+msgstr "tidak dapat memulai utas kesehatan fsmonitor"
#: builtin/fsmonitor--daemon.c
msgid "could not initialize listener thread"
-msgstr ""
+msgstr "tidak dapat menginisialisasi utas pendengar"
#: builtin/fsmonitor--daemon.c
msgid "could not initialize health thread"
-msgstr ""
+msgstr "tidak dapat menginisialisasi utas kesehatan"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "could not cd home '%s'"
-msgstr ""
+msgstr "tidak dapat berganti direktori ke rumah '%s'"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "fsmonitor--daemon is already running '%s'"
-msgstr ""
+msgstr "fsmonitor--daemon sudah berjalan '%s'"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "running fsmonitor-daemon in '%s'\n"
-msgstr ""
+msgstr "menjalankan fsmonitor-daemon di '%s'\n"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "starting fsmonitor-daemon in '%s'\n"
-msgstr ""
+msgstr "menjalankan fsmonitor-daemon di '%s'\n"
#: builtin/fsmonitor--daemon.c
msgid "daemon failed to start"
-msgstr ""
+msgstr "daemon gagal dijalankan"
#: builtin/fsmonitor--daemon.c
msgid "daemon not online yet"
-msgstr ""
+msgstr "daemon belum daring"
#: builtin/fsmonitor--daemon.c
msgid "daemon terminated"
-msgstr ""
+msgstr "daemon berhenti"
#: builtin/fsmonitor--daemon.c
msgid "detach from console"
-msgstr ""
+msgstr "lepas dari konsol"
#: builtin/fsmonitor--daemon.c
msgid "use <n> ipc worker threads"
-msgstr ""
+msgstr "gunakan <n> utas pekerja ipc"
#: builtin/fsmonitor--daemon.c
msgid "max seconds to wait for background daemon startup"
msgstr ""
+"maksimal waktu (detik) untuk menunggu dimulainya daemon dari balik layar"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "invalid 'ipc-threads' value (%d)"
-msgstr ""
+msgstr "nilai 'ipc-threads' tidak valid (%d)"
#: builtin/fsmonitor--daemon.c
#, c-format
msgid "Unhandled subcommand '%s'"
-msgstr ""
+msgstr "Subperintah tidak tertangani '%s'"
#: builtin/fsmonitor--daemon.c
msgid "fsmonitor--daemon not supported on this platform"
-msgstr ""
+msgstr "fsmonitor--daemon tidak didukung pada platform ini"
#: builtin/gc.c
msgid "git gc [<options>]"
@@ -8048,15 +8193,19 @@ msgstr ""
"gagal menjalankan 'crontab -l'; sistem Anda mungkin tidak mendukung 'cron'"
#: builtin/gc.c
+msgid "failed to create crontab temporary file"
+msgstr "tidak dapat membuat berkas crontab sementara"
+
+#: builtin/gc.c
+msgid "failed to open temporary file"
+msgstr "tidak dapat membuka berkas sementara"
+
+#: builtin/gc.c
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr ""
"gagal menjalankan 'crontab'; sistem Anda mungkin tidak mendukung 'cron'"
#: builtin/gc.c
-msgid "failed to open stdin of 'crontab'"
-msgstr "gagal membuka masukan standar dari 'crontab'"
-
-#: builtin/gc.c
msgid "'crontab' died"
msgstr "'crontab' mati"
@@ -8116,11 +8265,6 @@ msgstr "gagal menambahkan repositori ke konfigurasi global"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <subperintah> [<opsi>]"
-#: builtin/gc.c
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "subperintah tidak valid: %s"
-
#: builtin/grep.c
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<opsi>] [-e] <pola> [<revisi>...] [[--] <pola>...]"
@@ -8346,6 +8490,10 @@ msgid "allow calling of grep(1) (ignored by this build)"
msgstr "perbolehkan pemanggilan grep(1) (diabaikan oleh bangunan ini)"
#: builtin/grep.c
+msgid "maximum number of results per file"
+msgstr "jumlah hasil maksimum tiap berkas"
+
+#: builtin/grep.c
msgid "no pattern given"
msgstr "tidak ada pola yang diberikan"
@@ -8458,12 +8606,23 @@ msgid "print list of useful guides"
msgstr "cetak daftar panduan berguna"
#: builtin/help.c
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr ""
+"cetak daftar repositori, perintah, dan antarmuka berkas yang menghadap "
+"pengguna"
+
+#: builtin/help.c
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr "cetak daftar format berkas, protokol, dan antarmuka pengembang lainnya"
+
+#: builtin/help.c
msgid "print all configuration variable names"
msgstr "cetak semua nama variabel konfigurasi"
#: builtin/help.c
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<perintah>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr ""
+"git help [[-i|--info] [-m|--man] [-w|--web]] [<perintah>|<dokumentasi>]"
#: builtin/help.c
#, c-format
@@ -8538,6 +8697,7 @@ msgstr "opsi '%s' tidak mengambil argumen bukan opsi"
msgid ""
"the '--no-[external-commands|aliases]' options can only be used with '--all'"
msgstr ""
+"opsi '--no-[external-commands|aliases]' hanya dapat digunakan dengan '--all'"
#: builtin/help.c
#, c-format
@@ -8550,11 +8710,11 @@ msgstr "'git help config' untuk informasi lebih lanjut"
#: builtin/hook.c
msgid "git hook run [--ignore-missing] <hook-name> [-- <hook-args>]"
-msgstr ""
+msgstr "git hook run [--ignore-missing] <nama kait> [-- <argumen kait>]"
#: builtin/hook.c
msgid "silently ignore missing requested <hook-name>"
-msgstr ""
+msgstr "diam-diam abaikan <nama kait> yang diminta yang hilang"
#: builtin/index-pack.c
#, c-format
@@ -8980,58 +9140,60 @@ msgid ""
"git interpret-trailers [--in-place] [--trim-empty] [(--trailer "
"<token>[(=|:)<value>])...] [<file>...]"
msgstr ""
+"git interpret-trailers [--in-place] [--trim-empty] [(--trailer "
+"<token>[(=|:)<nilai>])...] [<berkas>...]"
#: builtin/interpret-trailers.c
msgid "edit files in place"
-msgstr ""
+msgstr "sunting berkas di tempat"
#: builtin/interpret-trailers.c
msgid "trim empty trailers"
-msgstr ""
+msgstr "pangkas trailer kosong"
#: builtin/interpret-trailers.c
msgid "where to place the new trailer"
-msgstr ""
+msgstr "dimana trailer baru ditempatkan"
#: builtin/interpret-trailers.c
msgid "action if trailer already exists"
-msgstr ""
+msgstr "tindakan jika trailer sudah ada"
#: builtin/interpret-trailers.c
msgid "action if trailer is missing"
-msgstr ""
+msgstr "tindakan jika trailer hilang"
#: builtin/interpret-trailers.c
msgid "output only the trailers"
-msgstr ""
+msgstr "keluarkan hanya trailer"
#: builtin/interpret-trailers.c
msgid "do not apply config rules"
-msgstr ""
+msgstr "jangan terapkan aturan konfigurasi"
#: builtin/interpret-trailers.c
msgid "join whitespace-continued values"
-msgstr ""
+msgstr "gabungkan nilai yang dilanjutkan oleh spasi"
#: builtin/interpret-trailers.c
msgid "set parsing options"
-msgstr ""
+msgstr "setel opsi penguraian"
#: builtin/interpret-trailers.c
msgid "do not treat --- specially"
-msgstr ""
+msgstr "jangan memperlakukan khusus ---"
#: builtin/interpret-trailers.c
msgid "trailer(s) to add"
-msgstr ""
+msgstr "trailer untuk ditambah"
#: builtin/interpret-trailers.c
msgid "--trailer with --only-input does not make sense"
-msgstr ""
+msgstr "--trailer dengan --only-input tidak masuk akal"
#: builtin/interpret-trailers.c
msgid "no input file given for in-place editing"
-msgstr ""
+msgstr "tidak ada berkas masukan yang diberikan untuk penyuntingan di tempat"
#: builtin/log.c
msgid "git log [<options>] [<revision-range>] [[--] <path>...]"
@@ -9055,8 +9217,8 @@ msgid "show source"
msgstr "perlihatkan sumber"
#: builtin/log.c
-msgid "use mail map file"
-msgstr "gunakan berkas peta surat"
+msgid "clear all previously-defined decoration filters"
+msgstr "bersihkan semua penyaring dekorasi yang sebelumnya didefinisikan"
#: builtin/log.c
msgid "only decorate refs that match <pattern>"
@@ -9390,6 +9552,10 @@ msgid "percentage by which creation is weighted"
msgstr "persentase dimana pembuatan tertimbang"
#: builtin/log.c
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "perlihatkan From: dalam tubuh bahkan jika sama dengan kepala surel"
+
+#: builtin/log.c
#, c-format
msgid "invalid ident line: %s"
msgstr "baris identitas tidak valid: %s"
@@ -9467,10 +9633,25 @@ msgstr ""
"secara manual.\n"
#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "format ls-files jelek: elemen '%s' tidak dimulai dengan '('"
+
+#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "format ls-files jelek: elemen '%s' tidak diakhiri dengan ')'"
+
+#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "format ls-files jelek: %%%.*s"
+
+#: builtin/ls-files.c
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<opsi>] [<berkas>...]"
-#: builtin/ls-files.c
+#: builtin/ls-files.c builtin/merge-tree.c
msgid "separate paths with the NUL character"
msgstr "pisahkan jalur dengan karakter NUL"
@@ -9579,6 +9760,14 @@ msgstr "hapus entri duplikat"
msgid "show sparse directories in the presence of a sparse index"
msgstr "perlihatkan direktori tipis di hadapan indeks tipis"
+#: builtin/ls-files.c
+msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format tidak dapat digunakan dengan -s, -o, -k, -t, --resolve-undo, --"
+"deduplicate, --eol"
+
#: builtin/ls-remote.c
msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -9695,60 +9884,60 @@ msgstr "--format tidak dapat digabungkan opsi pengubah format lainnya"
#. TRANSLATORS: keep <> in "<" mail ">" info.
#: builtin/mailinfo.c
msgid "git mailinfo [<options>] <msg> <patch> < mail >info"
-msgstr ""
+msgstr "git mailinfo [<opsi>] <pesan> <tambalan> < surat >info"
#: builtin/mailinfo.c
msgid "keep subject"
-msgstr ""
+msgstr "pertahankan subjek"
#: builtin/mailinfo.c
msgid "keep non patch brackets in subject"
-msgstr ""
+msgstr "pertahankan tanda kurung non tambalan dalam subjek"
#: builtin/mailinfo.c
msgid "copy Message-ID to the end of commit message"
-msgstr ""
+msgstr "salin Message-ID pada akhir pesan komit"
#: builtin/mailinfo.c
msgid "re-code metadata to i18n.commitEncoding"
-msgstr ""
+msgstr "kodekan ulang metadata ke i18n.commitEncoding"
#: builtin/mailinfo.c
msgid "disable charset re-coding of metadata"
-msgstr ""
+msgstr "nonaktifkan pengkodean ulang set karakter metadata"
#: builtin/mailinfo.c
msgid "encoding"
-msgstr ""
+msgstr "pengkodean"
#: builtin/mailinfo.c
msgid "re-code metadata to this encoding"
-msgstr ""
+msgstr "kodekan ulang metadata ke pengkodean ini"
#: builtin/mailinfo.c
msgid "use scissors"
-msgstr ""
+msgstr "gunakan gunting"
#: builtin/mailinfo.c
msgid "<action>"
-msgstr ""
+msgstr "<tindakan>"
#: builtin/mailinfo.c
msgid "action when quoted CR is found"
-msgstr ""
+msgstr "bertindak ketika CR terkutip ditemukan"
#: builtin/mailinfo.c
msgid "use headers in message's body"
-msgstr ""
+msgstr "gunakan kepala di dalam badan pesan"
#: builtin/mailsplit.c
msgid "reading patches from stdin/tty..."
-msgstr ""
+msgstr "membaca tambalan dari masukan standar/tty..."
#: builtin/mailsplit.c
#, c-format
msgid "empty mbox: '%s'"
-msgstr ""
+msgstr "mbox kosong: '%s'"
#: builtin/merge-base.c
msgid "git merge-base [-a | --all] <commit> <commit>..."
@@ -9795,73 +9984,119 @@ msgid ""
"git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> "
"<orig-file> <file2>"
msgstr ""
+"git merge-file [<opsi>] [-L <nama 1> [-L <asli> [-L <nama 2>]]] <berkas 1> "
+"<berkas asli> <berkas 2>"
#: builtin/merge-file.c
msgid "send results to standard output"
-msgstr ""
+msgstr "kirim hasil ke keluaran standar"
#: builtin/merge-file.c
msgid "use a diff3 based merge"
-msgstr ""
+msgstr "gunakan penggabungan berdasarkan diff3"
#: builtin/merge-file.c
msgid "use a zealous diff3 based merge"
-msgstr ""
+msgstr "gunakan penggabungan berdasarkan diff3 yang bersemangat"
#: builtin/merge-file.c
msgid "for conflicts, use our version"
-msgstr ""
+msgstr "untuk konflik, gunakan versi kami"
#: builtin/merge-file.c
msgid "for conflicts, use their version"
-msgstr ""
+msgstr "untuk konflik, gunakan versi mereka"
#: builtin/merge-file.c
msgid "for conflicts, use a union version"
-msgstr ""
+msgstr "untuk konflik, gunakan versi bersatu"
#: builtin/merge-file.c
msgid "for conflicts, use this marker size"
-msgstr ""
+msgstr "untuk konflik, gunakan ukuran penanda ini"
#: builtin/merge-file.c
msgid "do not warn about conflicts"
-msgstr ""
+msgstr "jangan peringatkan tentang konflik"
#: builtin/merge-file.c
msgid "set labels for file1/orig-file/file2"
-msgstr ""
+msgstr "setel label untuk file1/orig-file/file2"
#: builtin/merge-recursive.c
#, c-format
msgid "unknown option %s"
-msgstr ""
+msgstr "opsi tidak dikenal %s"
#: builtin/merge-recursive.c
#, c-format
msgid "could not parse object '%s'"
-msgstr ""
+msgstr "tidak dapat menguraikan objek '%s'"
#: builtin/merge-recursive.c
#, c-format
msgid "cannot handle more than %d base. Ignoring %s."
msgid_plural "cannot handle more than %d bases. Ignoring %s."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "tidak dapat menangani lebih dari %d dasar. Mengabaikan %s."
+msgstr[1] "tidak dapat menangani lebih dari %d dasar. Mengabaikan %s."
#: builtin/merge-recursive.c
msgid "not handling anything other than two heads merge."
-msgstr ""
+msgstr "tidak menangani apapun selain penggabungan dua kepala"
#: builtin/merge-recursive.c
#, c-format
msgid "could not resolve ref '%s'"
-msgstr ""
+msgstr "tidak dapat menguraikan referensi '%s'"
#: builtin/merge-recursive.c
#, c-format
msgid "Merging %s with %s\n"
-msgstr ""
+msgstr "Menggabungkan %s dengan %s\n"
+
+#: builtin/merge-tree.c builtin/merge.c
+msgid "not something we can merge"
+msgstr "bukan sesuatu yang kami bisa gabungkan"
+
+#: builtin/merge-tree.c builtin/merge.c
+msgid "refusing to merge unrelated histories"
+msgstr "menolak menggabungkan riwayat tak terkait"
+
+#: builtin/merge-tree.c
+msgid "failure to merge"
+msgstr "kegagalan penggabungan"
+
+#: builtin/merge-tree.c
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<opsi>] <cabang 1> <cabang 2>"
+
+#: builtin/merge-tree.c
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <pohon dasar> <cabang 1> <cabang 2>"
+
+#: builtin/merge-tree.c
+msgid "do a real merge instead of a trivial merge"
+msgstr "lakukan penggabungan sebenarnya daripada penggabungan sepele"
+
+#: builtin/merge-tree.c
+msgid "do a trivial merge only"
+msgstr "hanya lakukan penggabungan sepele"
+
+#: builtin/merge-tree.c
+msgid "also show informational/conflict messages"
+msgstr "perlihatkan juga pesan informasi/konflik"
+
+#: builtin/merge-tree.c
+msgid "list filenames without modes/oids/stages"
+msgstr "daftar nama berkas tanpa mode/oid/tahap"
+
+#: builtin/merge-tree.c builtin/merge.c builtin/pull.c
+msgid "allow merging unrelated histories"
+msgstr "perbolehkan penggabungan riwayat yang tak terkait"
+
+#: builtin/merge-tree.c
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge tidak kompatibel dengan semua opsi lainnya"
#: builtin/merge.c
msgid "git merge [<options>] [<commit>...]"
@@ -9969,10 +10204,6 @@ msgstr "--abort tapi biarkan indeks dan pohon kerja"
msgid "continue the current in-progress merge"
msgstr "lanjutkan penggabungan yang sedang berlangsung saat ini"
-#: builtin/merge.c builtin/pull.c
-msgid "allow merging unrelated histories"
-msgstr "perbolehkan penggabungan riwayat yang tak terkait"
-
#: builtin/merge.c
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "lewati kail pre-merge-commit dan commit-msg"
@@ -10114,7 +10345,7 @@ msgstr "Nilai jelek '%s' dalam lingkungan '%s'"
#: builtin/merge.c read-cache.c strbuf.c wrapper.c
#, c-format
msgid "could not close '%s'"
-msgstr ""
+msgstr "tidak dapat menutup '%s'"
#: builtin/merge.c
#, c-format
@@ -10122,10 +10353,6 @@ msgid "not something we can merge in %s: %s"
msgstr "bukan sesuatu yang kami bisa gabungkan di %s: %s"
#: builtin/merge.c
-msgid "not something we can merge"
-msgstr "bukan sesuatu yang kami bisa gabungkan"
-
-#: builtin/merge.c
msgid "--abort expects no arguments"
msgstr "--abort harap tanpa argumen"
@@ -10188,14 +10415,20 @@ msgid "Can merge only exactly one commit into empty head"
msgstr "Hanya bisa menggabungkan tepantnya satu komit ke kepala kosong"
#: builtin/merge.c
-msgid "refusing to merge unrelated histories"
-msgstr "menolak menggabungkan riwayat tak terkait"
-
-#: builtin/merge.c
#, c-format
msgid "Updating %s..%s\n"
msgstr "Memperbarui %s..%s\n"
+#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c
+#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh "
+"penggabungan:\n"
+" %s"
+
#: builtin/merge.c
#, c-format
msgid "Trying really trivial in-index merge...\n"
@@ -10238,30 +10471,35 @@ msgstr ""
"Penggabungan otomatis berjalan baik; berhenti sebelum mengkomit seperti yang "
"diminta\n"
+#: builtin/merge.c
+#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "Ketika selesai, terapkan perubahan terstase dengan `git stash pop`\n"
+
#: builtin/mktag.c
#, c-format
msgid "warning: tag input does not pass fsck: %s"
-msgstr ""
+msgstr "peringatan: masukan tag tidak lolos fsck: %s"
#: builtin/mktag.c
#, c-format
msgid "error: tag input does not pass fsck: %s"
-msgstr ""
+msgstr "kesalahan: masukan tag tidak lolos fsck: %s"
#: builtin/mktag.c
#, c-format
msgid "%d (FSCK_IGNORE?) should never trigger this callback"
-msgstr ""
+msgstr "%d (FSCK_IGNORE?) seharusnya tidak pernah memicu pemanggilan balik ini"
#: builtin/mktag.c
#, c-format
msgid "could not read tagged object '%s'"
-msgstr ""
+msgstr "tidak dapat membaca objek tertag '%s'"
#: builtin/mktag.c
#, c-format
msgid "object '%s' tagged as '%s', but is a '%s' type"
-msgstr ""
+msgstr "objek '%s' ditag sebagai '%s', tetapi bertipe '%s'"
#: builtin/mktag.c imap-send.c trailer.c
msgid "could not read from stdin"
@@ -10269,27 +10507,27 @@ msgstr "tidak dapat membaca dari masukan standar"
#: builtin/mktag.c
msgid "tag on stdin did not pass our strict fsck check"
-msgstr ""
+msgstr "tag pada masukan standar tidak lolos pemeriksaan fsck ketat kami"
#: builtin/mktag.c
msgid "tag on stdin did not refer to a valid object"
-msgstr ""
+msgstr "tag pada masukan standar tidak merujuk pada objek valid"
#: builtin/mktag.c builtin/tag.c
msgid "unable to write tag file"
-msgstr ""
+msgstr "tidak dapat menulis berkas tag"
#: builtin/mktree.c
msgid "input is NUL terminated"
-msgstr ""
+msgstr "masukan diakhiri dengan NUL"
#: builtin/mktree.c builtin/write-tree.c
msgid "allow missing objects"
-msgstr ""
+msgstr "perbolehkan objek hilang"
#: builtin/mktree.c
msgid "allow creation of more than one tree"
-msgstr ""
+msgstr "perbolehkan pembuatan lebih dari satu pohon"
#: builtin/multi-pack-index.c
msgid ""
@@ -10388,6 +10626,10 @@ msgid "bad source"
msgstr "sumber jelek"
#: builtin/mv.c
+msgid "destination exists"
+msgstr "tujuan ada"
+
+#: builtin/mv.c
msgid "can not move directory into itself"
msgstr "tidak dapat memindahkan direktori ke dirinya sendiri"
@@ -10408,10 +10650,6 @@ msgid "conflicted"
msgstr "terkonflik"
#: builtin/mv.c
-msgid "destination exists"
-msgstr "tujuan ada"
-
-#: builtin/mv.c
#, c-format
msgid "overwriting '%s'"
msgstr "menimpa '%s'"
@@ -10429,6 +10667,10 @@ msgid "destination directory does not exist"
msgstr "direktori tujuan tidak ada"
#: builtin/mv.c
+msgid "destination exists in the index"
+msgstr "tujuan ada dalam indeks"
+
+#: builtin/mv.c
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, source=%s, destination=%s"
@@ -10882,10 +11124,10 @@ msgstr "referensi catatan"
msgid "use notes from <notes-ref>"
msgstr "gunakan catatan dari <referensi catatan>"
-#: builtin/notes.c builtin/stash.c
+#: builtin/notes.c builtin/remote.c parse-options.c
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "subperintah tidak dikenal: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "subperintah tidak dikenal: `%s'"
#: builtin/pack-objects.c
msgid ""
@@ -11371,6 +11613,11 @@ msgid ""
"and let us know you still use it by sending an e-mail\n"
"to <git@vger.kernel.org>. Thanks.\n"
msgstr ""
+"'git pack-redundant' dinominasikan untuk dihapus.\n"
+"Jika Anda masih menggunakan perintah ini, mohon tambahkan sebuah opsi\n"
+"ekstra, '--i-still-use-this', pada baris perintah dan beri tahu kami jika\n"
+"Anda masih menggunakannya dengan mengirimkan surel ke\n"
+"<git@vger.kernel.org>. Terima kasih.\n"
#: builtin/pack-refs.c
msgid "git pack-refs [<options>]"
@@ -11498,7 +11745,7 @@ msgstr "Lihat git-pull(1) untuk selengkapnya."
msgid "<remote>"
msgstr "<remote>"
-#: builtin/pull.c contrib/scalar/scalar.c
+#: builtin/pull.c scalar.c
msgid "<branch>"
msgstr "<cabang>"
@@ -11944,47 +12191,54 @@ msgstr "opsi dorong harus tidak ada karakter baris baru"
#: builtin/range-diff.c
msgid "git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"
msgstr ""
+"git range-diff [<opsi>] <dasar lama>..<ujung lama> <dasar-baru>..<ujung baru>"
#: builtin/range-diff.c
msgid "git range-diff [<options>] <old-tip>...<new-tip>"
-msgstr ""
+msgstr "git range-diff [<opsi>] <ujung lama>...<ujung baru>"
#: builtin/range-diff.c
msgid "git range-diff [<options>] <base> <old-tip> <new-tip>"
-msgstr ""
+msgstr "git range-diff [<opsi>] <dasar> <ujung lama> <ujung baru>"
#: builtin/range-diff.c
msgid "use simple diff colors"
-msgstr ""
+msgstr "gunakan warna diff sederhana"
#: builtin/range-diff.c
msgid "notes"
-msgstr ""
+msgstr "catatan"
#: builtin/range-diff.c
msgid "passed to 'git log'"
-msgstr ""
+msgstr "lewatkan ke 'git log'"
#: builtin/range-diff.c
msgid "only emit output related to the first range"
-msgstr ""
+msgstr "hanya keluarkan keluaran relatif terhadap rentang pertama"
#: builtin/range-diff.c
msgid "only emit output related to the second range"
-msgstr ""
+msgstr "hanya keluarkan keluaran relatif terhadap rentang kedua"
+
+#: builtin/range-diff.c
+#, c-format
+msgid "not a revision: '%s'"
+msgstr "bukan sebuah revisi: '%s'"
#: builtin/range-diff.c
#, c-format
msgid "not a commit range: '%s'"
-msgstr ""
+msgstr "bukan sebuah rentang komit '%s'"
#: builtin/range-diff.c
-msgid "single arg format must be symmetric range"
-msgstr ""
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "bukan sebuah rentang simetris: '%s'"
#: builtin/range-diff.c
msgid "need two commit ranges"
-msgstr ""
+msgstr "butuh dua rentang komit"
#: builtin/read-tree.c
msgid ""
@@ -12323,6 +12577,10 @@ msgid "move commits that begin with squash!/fixup! under -i"
msgstr "pindahakan komit yang diawali dengan squash!/fixup! di bawah -i"
#: builtin/rebase.c
+msgid "update branches that point to commits that are being rebased"
+msgstr "perbarui cabang yang menunjuk pada komit yang akan didasarkan ulang"
+
+#: builtin/rebase.c
msgid "add exec lines after each commit of the editable list"
msgstr ""
"tambahkan baris exec setelah setiap komit dari daftar yang bisa disunting"
@@ -12373,6 +12631,9 @@ msgid ""
"Use `git rebase --abort` to terminate current rebase.\n"
"Or downgrade to v2.33, or earlier, to complete the rebase."
msgstr ""
+"`rebase --preserve-merges` (-p) tidak lagi didukung.\n"
+"Gunakan `git rebase --abort` untuk menghentikan pendasaran ulang saat ini.\n"
+"Atau turun ke v2.33 atau lebih awal untuk menyelesaikan pendasaran ulang."
#: builtin/rebase.c
msgid ""
@@ -12380,6 +12641,9 @@ msgid ""
"Note: Your `pull.rebase` configuration may also be set to 'preserve',\n"
"which is no longer supported; use 'merges' instead"
msgstr ""
+"--preserve-merges diganti oleh --rebase-merges\n"
+"Catatan: Konfigurasi `pull.rebase` Anda mungkin juga disetel ke 'preserve',\n"
+"yang tidak lagi didukung; gunakan 'merges' sebagai gantinya"
#: builtin/rebase.c
msgid "No rebase in progress?"
@@ -12956,6 +13220,10 @@ msgid " tracked"
msgstr " dilacak"
#: builtin/remote.c
+msgid " skipped"
+msgstr " dilewati"
+
+#: builtin/remote.c
msgid " stale (use 'git remote prune' to remove)"
msgstr " basi (gunakan 'git remote prune' untuk hapus)"
@@ -13412,23 +13680,23 @@ msgstr "tidak dapat membatal taut: %s"
#: builtin/replace.c
msgid "git replace [-f] <object> <replacement>"
-msgstr ""
+msgstr "git replace [-f] <objek> <pengganti>"
#: builtin/replace.c
msgid "git replace [-f] --edit <object>"
-msgstr ""
+msgstr "git replace [-f] --edit <objek>"
#: builtin/replace.c
msgid "git replace [-f] --graft <commit> [<parent>...]"
-msgstr ""
+msgstr "git replace [-f] --graft <komit> [<induk>...]"
#: builtin/replace.c
msgid "git replace -d <object>..."
-msgstr ""
+msgstr "git replace -d <objek>..."
#: builtin/replace.c
msgid "git replace [--format=<format>] [-l [<pattern>]]"
-msgstr ""
+msgstr "git replace [--format=<format>] [-l [<pola>]]"
#: builtin/replace.c
#, c-format
@@ -13436,26 +13704,28 @@ msgid ""
"invalid replace format '%s'\n"
"valid formats are 'short', 'medium' and 'long'"
msgstr ""
+"format penggantian '%s' tidak valid\n"
+"yang valid adalah 'short', 'medium' dan 'long'"
#: builtin/replace.c
#, c-format
msgid "replace ref '%s' not found"
-msgstr ""
+msgstr "referensi penggantian '%s' tidak ditemukan"
#: builtin/replace.c
#, c-format
msgid "Deleted replace ref '%s'"
-msgstr ""
+msgstr "Referensi penggantian '%s' dihapus"
#: builtin/replace.c
#, c-format
msgid "'%s' is not a valid ref name"
-msgstr ""
+msgstr "'%s' bukan nama referensi valid"
#: builtin/replace.c
#, c-format
msgid "replace ref '%s' already exists"
-msgstr ""
+msgstr "referensi penggantian '%s' sudah ada"
#: builtin/replace.c
#, c-format
@@ -13464,74 +13734,77 @@ msgid ""
"'%s' points to a replaced object of type '%s'\n"
"while '%s' points to a replacement object of type '%s'."
msgstr ""
+"Objek harus bertipe sama.\n"
+"'%s' menunjuk pada objek yang diganti bertipe '%s'\n"
+"sedangkan '%s' menunjuk pada objek pengganti bertipe '%s'."
#: builtin/replace.c
#, c-format
msgid "unable to open %s for writing"
-msgstr ""
+msgstr "tidak dapat membuka %s untuk ditulis"
#: builtin/replace.c
msgid "cat-file reported failure"
-msgstr ""
+msgstr "cat-file melaporkan kegagalan"
#: builtin/replace.c
#, c-format
msgid "unable to open %s for reading"
-msgstr ""
+msgstr "tidak dapat membuka %s untuk dibaca"
#: builtin/replace.c
msgid "unable to spawn mktree"
-msgstr ""
+msgstr "tidak dapat memunculkan mktree"
#: builtin/replace.c
msgid "unable to read from mktree"
-msgstr ""
+msgstr "tidak dapat membaca dari mktree"
#: builtin/replace.c
msgid "mktree reported failure"
-msgstr ""
+msgstr "mktree melaporkan kegagalan"
#: builtin/replace.c
msgid "mktree did not return an object name"
-msgstr ""
+msgstr "mktree tidak mengembalikan sebuah nama objek"
#: builtin/replace.c
#, c-format
msgid "unable to fstat %s"
-msgstr ""
+msgstr "tidak dapat men-fstat %s"
#: builtin/replace.c
msgid "unable to write object to database"
-msgstr ""
+msgstr "tidak dapat menulis objek ke basis data"
#: builtin/replace.c
#, c-format
msgid "unable to get object type for %s"
-msgstr ""
+msgstr "tidak dapat mendapatkan tipe objek untuk %s"
#: builtin/replace.c
msgid "editing object file failed"
-msgstr ""
+msgstr "gagal menyunting berkas objek"
#: builtin/replace.c
#, c-format
msgid "new object is the same as the old one: '%s'"
-msgstr ""
+msgstr "objek baru sama dengan objek lama: '%s'"
#: builtin/replace.c
#, c-format
msgid "could not parse %s as a commit"
-msgstr ""
+msgstr "tidak dapat menguraikan %s sebagai sebuah komit"
#: builtin/replace.c
#, c-format
msgid "bad mergetag in commit '%s'"
-msgstr ""
+msgstr "tag penggabungan jelek pada komit '%s'"
#: builtin/replace.c
#, c-format
msgid "malformed mergetag in commit '%s'"
-msgstr ""
+msgstr "tag penggabungan rusak pada komit '%s'"
#: builtin/replace.c
#, c-format
@@ -13539,30 +13812,32 @@ msgid ""
"original commit '%s' contains mergetag '%s' that is discarded; use --edit "
"instead of --graft"
msgstr ""
+"komit asal '%s' berisi tag penggabungan '%s' yang dibuang; gunakan --edit "
+"daripada --graft"
#: builtin/replace.c
#, c-format
msgid "the original commit '%s' has a gpg signature"
-msgstr ""
+msgstr "komit asal '%s' punya tandatangan gpg"
#: builtin/replace.c
msgid "the signature will be removed in the replacement commit!"
-msgstr ""
+msgstr "tandatangan akan dihapus di dalam komit pengganti!"
#: builtin/replace.c
#, c-format
msgid "could not write replacement commit for: '%s'"
-msgstr ""
+msgstr "tidak dapat menulis komit pengganti untuk: '%s'"
#: builtin/replace.c
#, c-format
msgid "graft for '%s' unnecessary"
-msgstr ""
+msgstr "cangkuk untuk '%s' tidak diperlukan"
#: builtin/replace.c
#, c-format
msgid "new commit is the same as the old one: '%s'"
-msgstr ""
+msgstr "komit baru sama dengan komit lama: '%s'"
#: builtin/replace.c
#, c-format
@@ -13570,91 +13845,93 @@ msgid ""
"could not convert the following graft(s):\n"
"%s"
msgstr ""
+"tidak dapat mengkonversi cangkuk berikut:\n"
+"%s"
#: builtin/replace.c
msgid "list replace refs"
-msgstr ""
+msgstr "daftar referensi penggantian"
#: builtin/replace.c
msgid "delete replace refs"
-msgstr ""
+msgstr "hapus referensi penggantian"
#: builtin/replace.c
msgid "edit existing object"
-msgstr ""
+msgstr "sunting objek yang ada"
#: builtin/replace.c
msgid "change a commit's parents"
-msgstr ""
+msgstr "ubah induk sebuah komit"
#: builtin/replace.c
msgid "convert existing graft file"
-msgstr ""
+msgstr "konversi berkas cangkuk yang anda"
#: builtin/replace.c
msgid "replace the ref if it exists"
-msgstr ""
+msgstr "ganti referensi jika ada"
#: builtin/replace.c
msgid "do not pretty-print contents for --edit"
-msgstr ""
+msgstr "jangan cetak cantik isi untuk --edit"
#: builtin/replace.c
msgid "use this format"
-msgstr ""
+msgstr "gunakan format ini"
#: builtin/replace.c
msgid "--format cannot be used when not listing"
-msgstr ""
+msgstr "--format tidak dapat digunakan ketika mendaftar"
#: builtin/replace.c
msgid "-f only makes sense when writing a replacement"
-msgstr ""
+msgstr "-f hanya masuk akal ketika menulis pengganti"
#: builtin/replace.c
msgid "--raw only makes sense with --edit"
-msgstr ""
+msgstr "--raw hanya masuk akal dengan --edit"
#: builtin/replace.c
msgid "-d needs at least one argument"
-msgstr ""
+msgstr "-d butuh setidaknya satu argumen"
#: builtin/replace.c
msgid "bad number of arguments"
-msgstr ""
+msgstr "jumlah argumen jelek"
#: builtin/replace.c
msgid "-e needs exactly one argument"
-msgstr ""
+msgstr "-e butuh tepat satu argumen"
#: builtin/replace.c
msgid "-g needs at least one argument"
-msgstr ""
+msgstr "-g butuh setidaknya satu argumen"
#: builtin/replace.c
msgid "--convert-graft-file takes no argument"
-msgstr ""
+msgstr "--convert-graft-file tidak mengambil argumen"
#: builtin/replace.c
msgid "only one pattern can be given with -l"
-msgstr ""
+msgstr "hanya satu pola yang dapat diberikan dengan -l"
#: builtin/rerere.c
msgid "git rerere [clear | forget <path>... | status | remaining | diff | gc]"
-msgstr ""
+msgstr "git rerere [clear | forge <jalur>... | status | remaining | diff | gc]"
#: builtin/rerere.c
msgid "register clean resolutions in index"
-msgstr ""
+msgstr "daftar resolusi bersih di dalam indeks"
#: builtin/rerere.c
msgid "'git rerere forget' without paths is deprecated"
-msgstr ""
+msgstr "'git rerere forget' tanpa jalur usang"
#: builtin/rerere.c
#, c-format
msgid "unable to generate diff for '%s'"
-msgstr ""
+msgstr "tidak dapat membuat diff untuk '%s'"
#: builtin/reset.c
msgid ""
@@ -13725,7 +14002,7 @@ msgstr "diam, hanya laporkan kesalahan"
#: builtin/reset.c
msgid "skip refreshing the index after reset"
-msgstr ""
+msgstr "lewati penyegaran indeks setelah reset"
#: builtin/reset.c
msgid "reset HEAD and index"
@@ -13794,10 +14071,16 @@ msgstr "Tidak dapat menyetel ulang berkas indeks ke revisi '%s'."
msgid "Could not write new index file."
msgstr "Tidak dapat menulis berkas indeks baru."
-#: builtin/rev-list.c pack-bitmap.c
+#: builtin/rev-list.c
#, c-format
msgid "unable to get disk usage of %s"
+msgstr "tidak dapat mendapatkan penggunaan disk %s"
+
+#: builtin/rev-list.c
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
msgstr ""
+"nilai tidak valid untuk '%s': '%s', format yang diperbolehkan hanyalah '%s'"
#: builtin/rev-list.c
msgid "rev-list does not support display of notes"
@@ -13833,6 +14116,10 @@ msgid "no usage string given before the `--' separator"
msgstr "tidak ada untai penggunaan yang diberikan sebelum pemisah `--'"
#: builtin/rev-parse.c
+msgid "missing opt-spec before option flags"
+msgstr "kehilangan spek opsi sebelum bendera opsi"
+
+#: builtin/rev-parse.c
msgid "Needed a single revision"
msgstr "Butuh satu revisi"
@@ -13982,7 +14269,7 @@ msgstr "simpan komit kosong mubazir"
#: builtin/revert.c
msgid "use the 'reference' format to refer to commits"
-msgstr ""
+msgstr "gunakan format 'reference' untuk merujuk pada komit"
#: builtin/revert.c
msgid "revert failed"
@@ -14392,10 +14679,10 @@ msgstr "inisialisasi checkout tipis dalam mode kerucut"
msgid "toggle the use of a sparse index"
msgstr "gunakan indeks tipis"
-#: builtin/sparse-checkout.c commit-graph.c midx.c
+#: builtin/sparse-checkout.c commit-graph.c midx.c sequencer.c
#, c-format
msgid "unable to create leading directories of %s"
-msgstr ""
+msgstr "tidak dapat membuat direktori utama dari %s"
#: builtin/sparse-checkout.c
#, c-format
@@ -14787,11 +15074,11 @@ msgstr "masukkan berkas ignore"
#: builtin/stripspace.c
msgid "skip and remove all lines starting with comment character"
-msgstr ""
+msgstr "lewati dan hapus semua baris yang diawali dengan karakter komentar"
#: builtin/stripspace.c
msgid "prepend comment character and space to each line"
-msgstr ""
+msgstr "tambahkan karakter komentar dan spasi di awal setiap baris"
#: builtin/submodule--helper.c
#, c-format
@@ -14800,6 +15087,11 @@ msgstr "Mengharapkan nama referensi penuh, dapat %s"
#: builtin/submodule--helper.c
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "tidak dapat mendapat pegangan repositori untuk submodul '%s'"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -14808,14 +15100,6 @@ msgstr ""
"hulu otoritatif tersendiri."
#: builtin/submodule--helper.c
-msgid "alternative anchor for relative paths"
-msgstr "jangkar alternatif untuk jalur relatif"
-
-#: builtin/submodule--helper.c
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<jalur>] [<jalur>...]"
-
-#: builtin/submodule--helper.c
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "Tidak ada url yang ditemukan untuk jalur submodul '%s' di .gitmodules"
@@ -14854,9 +15138,8 @@ msgid "recurse into nested submodules"
msgstr "rekursi ke dalam submodul bersarang"
#: builtin/submodule--helper.c
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr ""
-"git submodule--helper foreach [--quiet] [--recursive] [--] [<perintah>]"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] [<perintah>]"
#: builtin/submodule--helper.c
#, c-format
@@ -14883,8 +15166,8 @@ msgid "suppress output for initializing a submodule"
msgstr "sembunyikan keluaran menginisialisasi submodul"
#: builtin/submodule--helper.c
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<opsi>] [<jalur>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<opsi>] [<jalur>]"
#: builtin/submodule--helper.c
#, c-format
@@ -14918,10 +15201,6 @@ msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<jalur>...]"
#: builtin/submodule--helper.c
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <jalur>"
-
-#: builtin/submodule--helper.c
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submodul)"
@@ -14963,8 +15242,8 @@ msgid "limit the summary size"
msgstr "batasi ukuran ringkasan"
#: builtin/submodule--helper.c
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<opsi>] [<commit>] -- [<jalur>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<opsi>] [<commit>] -- [<jalur>]"
#: builtin/submodule--helper.c
msgid "could not fetch a revision for HEAD"
@@ -14982,11 +15261,6 @@ msgstr "gagal mendaftarkan url untuk jalur submodul '%s'"
#: builtin/submodule--helper.c
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "gagal mendapatkan remote asali untuk submodul '%s'"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "gagal memperbarui remote untuk submodul '%s'"
@@ -14995,8 +15269,8 @@ msgid "suppress output of synchronizing submodule url"
msgstr "sembunyikan keluaran mensinkronisasi url submodul"
#: builtin/submodule--helper.c
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<jalur>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<jalur>]"
#: builtin/submodule--helper.c
#, c-format
@@ -15069,6 +15343,11 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "tidak dapat mendapat pegangan repositori untuk direktori git '%s'"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "submodul '%s' tidak dapat menambahkan pengganti: %s"
@@ -15104,6 +15383,10 @@ msgid "could not get submodule directory for '%s'"
msgstr "tidak dapat mendapatkan direktori submodul untuk '%s'"
#: builtin/submodule--helper.c
+msgid "alternative anchor for relative paths"
+msgstr "jangkar alternatif untuk jalur relatif"
+
+#: builtin/submodule--helper.c
msgid "where the new submodule will be cloned to"
msgstr "di mana submodul baru akan dikloning"
@@ -15139,11 +15422,6 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Mode pembaruan '%s' tidak valid untuk jalur submodul '%s'"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr "Mode pembaruan '%s' tidak valid untuk jalur submodul '%s'"
@@ -15234,6 +15512,11 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "tidak dapat menginisialisasi submodul pada jalur '%s'"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -15243,11 +15526,6 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "tidak dapat mendapat pegangan repositori untuk submodul '%s'"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "Tidak dapat menemukan revisi saat ini pada jalur submodul '%s'"
@@ -15291,12 +15569,16 @@ msgid "path into the working tree"
msgstr "jalur ke dalam pohon kerja"
#: builtin/submodule--helper.c
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "jalur ke dalam pohon kerja, melintasi perbatasan submodul bersarang"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "gunakan strategi pembaruan 'checkout' (asali)"
#: builtin/submodule--helper.c
-msgid "rebase, merge, checkout or none"
-msgstr "dasarkan ulang, gabungkan, checkout atau tidak sama sekali"
+msgid "use the 'merge' update strategy"
+msgstr "gunakan strategi penmbaruan 'merge'"
+
+#: builtin/submodule--helper.c
+msgid "use the 'rebase' update strategy"
+msgstr "gunakan strategi pembaruan 'rebase'"
#: builtin/submodule--helper.c
msgid "create a shallow clone truncated to the specified number of revisions"
@@ -15315,6 +15597,11 @@ msgid "don't print cloning progress"
msgstr "jangan cetak perkembangan pengkloningan"
#: builtin/submodule--helper.c
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr ""
+"tak perbolehkan kloning ke dalam direktori berisi, mengimplikasikan --init"
+
+#: builtin/submodule--helper.c
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -15327,16 +15614,12 @@ msgstr ""
"[--] [<jalur>...]"
#: builtin/submodule--helper.c
-msgid "bad value for update parameter"
-msgstr "nilai jelek untuk parameter pembaruan"
-
-#: builtin/submodule--helper.c
msgid "recurse into submodules"
msgstr "rekursi ke dalam submodul"
#: builtin/submodule--helper.c
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<opsi>] [<jalur>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<opsi>] [<jalur>...]"
#: builtin/submodule--helper.c
msgid "check if it is safe to write to the .gitmodules file"
@@ -15363,8 +15646,8 @@ msgid "suppress output for setting url of a submodule"
msgstr "sembunyikan keluaran penyetelan url submodule"
#: builtin/submodule--helper.c
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <jalur> <url baru>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <jalur> <url baru>"
#: builtin/submodule--helper.c
msgid "set the default tracking branch to master"
@@ -15375,14 +15658,12 @@ msgid "set the default tracking branch"
msgstr "setel cabang pelacak asali"
#: builtin/submodule--helper.c
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <jalur>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <jalur>"
#: builtin/submodule--helper.c
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <cabang> <jalur>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <cabang> <jalur>"
#: builtin/submodule--helper.c
msgid "--branch or --default required"
@@ -15478,7 +15759,7 @@ msgstr "'%s' sudah ada di dalam indeks dan bukan submodul"
#: builtin/submodule--helper.c read-cache.c
#, c-format
msgid "'%s' does not have a commit checked out"
-msgstr ""
+msgstr "'%s' tidak punya sebuah komit tercheckout"
#: builtin/submodule--helper.c
msgid "branch of repository to add as submodule"
@@ -15500,8 +15781,8 @@ msgstr ""
"setel nama submodul ke untai yang diberikan daripada diasalkan ke jalurnya"
#: builtin/submodule--helper.c
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<opsi>] [--] <repositori> [<jalur>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<opsi>] [--] <repositori> [<jalur>]"
#: builtin/submodule--helper.c
msgid "Relative path can only be used from the toplevel of the working tree"
@@ -15758,6 +16039,19 @@ msgid "pack exceeds maximum allowed size"
msgstr "paket melebihi ukuran maksimum yang diperbolehkan"
#: builtin/unpack-objects.c
+msgid "failed to write object in stream"
+msgstr "gagal menulis objek di dalam arus"
+
+#: builtin/unpack-objects.c
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "inflate mengembalikan (%d)"
+
+#: builtin/unpack-objects.c
+msgid "invalid blob object from stream"
+msgstr "objek blob tidak valid dari arus"
+
+#: builtin/unpack-objects.c
msgid "Unpacking objects"
msgstr "Membongkar objek"
@@ -16414,6 +16708,33 @@ msgstr "tulis objek pohon untuk subdirektori <prefiks>"
msgid "only useful for debugging"
msgstr "hanya berguna untuk penirkutuan"
+#: bulk-checkin.c
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch tidak didukung pada platform ini"
+
+#: bundle-uri.c
+msgid "failed to create temporary file"
+msgstr "tidak dapat membuat berkas sementara"
+
+#: bundle-uri.c
+msgid "insufficient capabilities"
+msgstr "tidak cukup kemampuan"
+
+#: bundle-uri.c
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "gagal mengunduh bundel dari URI '%s'"
+
+#: bundle-uri.c
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "berkas pada URI '%s' bukan sebuah bundle"
+
+#: bundle-uri.c
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "gagal membongkar bundel dari URI '%s'"
+
#: bundle.c
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
@@ -16502,941 +16823,1013 @@ msgstr "index-pack mati"
#: chunk-format.c
msgid "terminating chunk id appears earlier than expected"
-msgstr ""
+msgstr "id bingkah pengakhiran muncul lebih awal dari yang diharapkan"
#: chunk-format.c
#, c-format
msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>"
-msgstr ""
+msgstr "offset bingkah %<PRIx64> dan %<PRIx64> tidak tepat"
#: chunk-format.c
#, c-format
msgid "duplicate chunk ID %<PRIx32> found"
-msgstr ""
+msgstr "ID bingkah duplikat %<PRIx32> ditemukan"
#: chunk-format.c
#, c-format
msgid "final chunk has non-zero id %<PRIx32>"
-msgstr ""
+msgstr "bingkah terakhir punya id bukan nol %<PRIx32>"
#: chunk-format.c
msgid "invalid hash version"
-msgstr ""
+msgstr "versi hash tidak valid"
#: color.c
#, c-format
msgid "invalid color value: %.*s"
-msgstr ""
+msgstr "nilai warna tidak valid: %.*s"
#: command-list.h
msgid "Add file contents to the index"
-msgstr ""
+msgstr "Tambahkan isi berkas ke indeks"
#: command-list.h
msgid "Apply a series of patches from a mailbox"
-msgstr ""
+msgstr "Terapkan rangkaian tambalan dari kotak surat"
#: command-list.h
msgid "Annotate file lines with commit information"
-msgstr ""
+msgstr "Anotasi baris berkas dengan informasi komit"
#: command-list.h
msgid "Apply a patch to files and/or to the index"
-msgstr ""
+msgstr "Terapkan tambalan pada berkas dan/atau pada indeks"
#: command-list.h
msgid "Import a GNU Arch repository into Git"
-msgstr ""
+msgstr "Impor repositori GNU Arch ke dalam Git"
#: command-list.h
msgid "Create an archive of files from a named tree"
-msgstr ""
+msgstr "Buat arsip berkas dari pohon bernama"
#: command-list.h
msgid "Use binary search to find the commit that introduced a bug"
-msgstr ""
+msgstr "Gunakan pencarian biner untuk mencari komit yang memasukkan bug"
#: command-list.h
msgid "Show what revision and author last modified each line of a file"
msgstr ""
+"Perlihatkan revisi dan pengarang apa yang terakhir kali mengubah setiap "
+"baris berkas"
#: command-list.h
msgid "List, create, or delete branches"
-msgstr ""
+msgstr "Daftar, buat, atau hapus cabang"
#: command-list.h
msgid "Collect information for user to file a bug report"
-msgstr ""
+msgstr "Kumpulkan informasi agar pengguna melaporkan laporan bug"
#: command-list.h
msgid "Move objects and refs by archive"
-msgstr ""
+msgstr "Pindahkan objek dan referensi oleh arsip"
#: command-list.h
msgid "Provide content or type and size information for repository objects"
msgstr ""
+"Sediakan isi atau informasi tipe dan ukuran berkas untuk objek repositori"
#: command-list.h
msgid "Display gitattributes information"
-msgstr ""
+msgstr "Perlihatkan informasi gitattributes"
#: command-list.h
msgid "Debug gitignore / exclude files"
-msgstr ""
+msgstr "Nirkutukan berkas gitignore / exclude"
#: command-list.h
msgid "Show canonical names and email addresses of contacts"
-msgstr ""
+msgstr "Perlihatkan nama dan alamat email kanonikal"
#: command-list.h
msgid "Ensures that a reference name is well formed"
-msgstr ""
+msgstr "Pastikan bahwa nama referensi baik dan benar"
#: command-list.h
msgid "Switch branches or restore working tree files"
-msgstr ""
+msgstr "Ganti cabang atau kembalikan berkas pohon kerja"
#: command-list.h
msgid "Copy files from the index to the working tree"
-msgstr ""
+msgstr "Salin berkas dari indeks ke pohon kerja"
#: command-list.h
msgid "Find commits yet to be applied to upstream"
-msgstr ""
+msgstr "Cari komit yang belum diterapkan pada hulu"
#: command-list.h
msgid "Apply the changes introduced by some existing commits"
-msgstr ""
+msgstr "Terapkan perubahan yang dimasukkan oleh beberapa komit yang ada"
#: command-list.h
msgid "Graphical alternative to git-commit"
-msgstr ""
+msgstr "Alternatif grafik untuk git-commit"
#: command-list.h
msgid "Remove untracked files from the working tree"
-msgstr ""
+msgstr "Hapus berkas tak terlacak dari pohon kerja"
#: command-list.h
msgid "Clone a repository into a new directory"
-msgstr ""
+msgstr "Salin repositori ke dalam direktori baru"
#: command-list.h
msgid "Display data in columns"
-msgstr ""
+msgstr "Tampilkan data dalam kolom"
#: command-list.h
msgid "Record changes to the repository"
-msgstr ""
+msgstr "Rekam perubahan ke dalam repositori"
#: command-list.h
msgid "Write and verify Git commit-graph files"
-msgstr ""
+msgstr "Tulis dan verifikasi berkas Git commit-graph"
#: command-list.h
msgid "Create a new commit object"
-msgstr ""
+msgstr "Buat objek komit baru"
#: command-list.h
msgid "Get and set repository or global options"
-msgstr ""
+msgstr "Dapatkan dan setel opsi repositori atau global"
#: command-list.h
msgid "Count unpacked number of objects and their disk consumption"
-msgstr ""
+msgstr "Hitung jumlah berkas tak terlacak dan penggunaan disknya"
#: command-list.h
msgid "Retrieve and store user credentials"
-msgstr ""
+msgstr "Dapatkan dan simpan kredensial pengguna"
#: command-list.h
msgid "Helper to temporarily store passwords in memory"
-msgstr ""
+msgstr "Pembantu untuk sementara simpan kata sandi di memori"
#: command-list.h
msgid "Helper to store credentials on disk"
-msgstr ""
+msgstr "Pembantu untuk menyimpan kredensial pada disk"
#: command-list.h
msgid "Export a single commit to a CVS checkout"
-msgstr ""
+msgstr "Ekspor satu komit tunggal ke checkout CVS"
#: command-list.h
msgid "Salvage your data out of another SCM people love to hate"
-msgstr ""
+msgstr "Selamatkan data karena pengguna SCM lainnya yang suka membenci"
#: command-list.h
msgid "A CVS server emulator for Git"
-msgstr ""
+msgstr "Emulator peladen CVS untuk Git"
#: command-list.h
msgid "A really simple server for Git repositories"
-msgstr ""
+msgstr "Peladen sederhana beneran untuk repositori Git"
#: command-list.h
msgid "Give an object a human readable name based on an available ref"
msgstr ""
+"Berikan nama yang dapat dibaca manusia pada objek berdasarkan referensi yang "
+"ada"
+
+#: command-list.h
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Buat arsip zip informasi diagnostik"
#: command-list.h
msgid "Show changes between commits, commit and working tree, etc"
msgstr ""
+"Perlihatkan perubahan di antara komit-komit, komit dan pohon kerja, dll"
#: command-list.h
msgid "Compares files in the working tree and the index"
-msgstr ""
+msgstr "Bandingkan berkas di dalam pohon kerja dan indeks"
#: command-list.h
msgid "Compare a tree to the working tree or index"
-msgstr ""
+msgstr "Bandingkan pohon kepada pohon kerja atau indeks"
#: command-list.h
msgid "Compares the content and mode of blobs found via two tree objects"
-msgstr ""
+msgstr "Bandingkan isi dan mode blob yang ditemukan lewat dua objek pohon"
#: command-list.h
msgid "Show changes using common diff tools"
-msgstr ""
+msgstr "Perlihatkan perubahan menggunakan alat diff umum"
#: command-list.h
msgid "Git data exporter"
-msgstr ""
+msgstr "Eksportir data Git"
#: command-list.h
msgid "Backend for fast Git data importers"
-msgstr ""
+msgstr "Tulang punggung untuk importir data Git"
#: command-list.h
msgid "Download objects and refs from another repository"
-msgstr ""
+msgstr "Unduh objek dan referensi dari repositori yang lain"
#: command-list.h
msgid "Receive missing objects from another repository"
-msgstr ""
+msgstr "Terima objek yang hilang dari repositori yang lain"
#: command-list.h
msgid "Rewrite branches"
-msgstr ""
+msgstr "Tulis ulang cabang"
#: command-list.h
msgid "Produce a merge commit message"
-msgstr ""
+msgstr "Buat pesan komit penggabungan"
#: command-list.h
msgid "Output information on each ref"
-msgstr ""
+msgstr "Keluarkan informasi pada setiap referensi"
#: command-list.h
msgid "Run a Git command on a list of repositories"
-msgstr ""
+msgstr "Jalankan perintah Git pada daftar repositori"
#: command-list.h
msgid "Prepare patches for e-mail submission"
-msgstr ""
+msgstr "Siapkan tambalan untuk pengiriman surel"
#: command-list.h
msgid "Verifies the connectivity and validity of the objects in the database"
-msgstr ""
+msgstr "Verifikasi hubungan dan validitas objek di dalam basis data"
#: command-list.h
msgid "Cleanup unnecessary files and optimize the local repository"
-msgstr ""
+msgstr "Bersihkan berkas yang tak perlu dan optimalkan repositori lokal"
#: command-list.h
msgid "Extract commit ID from an archive created using git-archive"
-msgstr ""
+msgstr "Ekstrak ID komit dari arsip yang dibuat dengan git-archive"
#: command-list.h
msgid "Print lines matching a pattern"
-msgstr ""
+msgstr "Cetak baris yang cocok dengan sebuah pola"
#: command-list.h
msgid "A portable graphical interface to Git"
-msgstr ""
+msgstr "Sebuah antarmuka grafis Git portabel"
#: command-list.h
msgid "Compute object ID and optionally creates a blob from a file"
-msgstr ""
+msgstr "Hitung ID objek dan buat blob dari berkas (opsional)"
#: command-list.h
msgid "Display help information about Git"
-msgstr ""
+msgstr "Perlihatkan bantuan mengenai Git"
#: command-list.h
msgid "Run git hooks"
-msgstr ""
+msgstr "Jalankan kait git"
#: command-list.h
msgid "Server side implementation of Git over HTTP"
-msgstr ""
+msgstr "Impementasi sisi peladen dari Git lewat HTTP"
#: command-list.h
msgid "Download from a remote Git repository via HTTP"
-msgstr ""
+msgstr "Unduh dari repositori Git remote lewat HTTP"
#: command-list.h
msgid "Push objects over HTTP/DAV to another repository"
-msgstr ""
+msgstr "Dorong objek lewat HTTP/DAV ke repositori lainnya"
#: command-list.h
msgid "Send a collection of patches from stdin to an IMAP folder"
-msgstr ""
+msgstr "Kirim koleksi tambalan dari masukan standar ke sebuah direktori IMAP"
#: command-list.h
msgid "Build pack index file for an existing packed archive"
-msgstr ""
+msgstr "Bangun berkas indeks pak dari arsip terpak yang sudah ada"
#: command-list.h
msgid "Create an empty Git repository or reinitialize an existing one"
-msgstr ""
+msgstr "Buat repositori Git kosong atau inisialisasi ulang yang sudah ada"
#: command-list.h
msgid "Instantly browse your working repository in gitweb"
-msgstr ""
+msgstr "Jelajahi repositori kerja Anda secara instan di gitweb"
#: command-list.h
msgid "Add or parse structured information in commit messages"
-msgstr ""
+msgstr "Tambah atau urai informasi terstruktur di dalam pesan komit"
#: command-list.h
msgid "Show commit logs"
-msgstr ""
+msgstr "Perlihatkan log komit"
#: command-list.h
msgid "Show information about files in the index and the working tree"
msgstr ""
+"Perlihatkan informasi mengenai berkas-berkas di dalam indeks dan pohon kerja"
#: command-list.h
msgid "List references in a remote repository"
-msgstr ""
+msgstr "Daftar referensi di repositori remote"
#: command-list.h
msgid "List the contents of a tree object"
-msgstr ""
+msgstr "Daftar isi objek pohon"
#: command-list.h
msgid "Extracts patch and authorship from a single e-mail message"
-msgstr ""
+msgstr "Ekstrak berkas dan kepengarangan dari pesan surel tunggal"
#: command-list.h
msgid "Simple UNIX mbox splitter program"
-msgstr ""
+msgstr "Program pemisah mbox UNIX sederhana"
#: command-list.h
msgid "Run tasks to optimize Git repository data"
-msgstr ""
+msgstr "Jalankan tugas untuk mengoptimalkan data repositori Git"
#: command-list.h
msgid "Join two or more development histories together"
-msgstr ""
+msgstr "Gabungkan dua riwayat pengembangan atau lebih bersama-sama"
#: command-list.h
msgid "Find as good common ancestors as possible for a merge"
-msgstr ""
+msgstr "Cari leluhur umum sebaik-baiknya untuk penggabungan"
#: command-list.h
msgid "Run a three-way file merge"
-msgstr ""
+msgstr "Lakukan penggabungan berkas tiga arah"
#: command-list.h
msgid "Run a merge for files needing merging"
-msgstr ""
+msgstr "Lakukan penggabungan untuk berkas yang perlu digabungkan"
#: command-list.h
msgid "The standard helper program to use with git-merge-index"
-msgstr ""
+msgstr "Program pembantu standar untuk digunakan dengan git-merge-index"
#: command-list.h
-msgid "Show three-way merge without touching index"
-msgstr ""
+msgid "Perform merge without touching index or working tree"
+msgstr "Lakukan penggabungan tanpa menyentuh indeks atau pohon kerja"
#: command-list.h
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr ""
+"Jalankan alat penyelesaian konflik penggabungan untuk menyelesaikan konflik "
+"penggabungan"
#: command-list.h
msgid "Creates a tag object with extra validation"
-msgstr ""
+msgstr "Buat objek tag dengan validasi ekstra"
#: command-list.h
msgid "Build a tree-object from ls-tree formatted text"
-msgstr ""
+msgstr "Bangun objek pohon dari teks berformat ls-tree"
#: command-list.h
msgid "Write and verify multi-pack-indexes"
-msgstr ""
+msgstr "Tulis dan verifikasi indeks multipak"
#: command-list.h
msgid "Move or rename a file, a directory, or a symlink"
-msgstr ""
+msgstr "Pindahkan atau namai ulang berkas, direktori, atau tautan simbolik"
#: command-list.h
msgid "Find symbolic names for given revs"
-msgstr ""
+msgstr "Cari nama simbolik untuk revisi yang diberikan"
#: command-list.h
msgid "Add or inspect object notes"
-msgstr ""
+msgstr "Tambahkan atau inspeksi catatan objek"
#: command-list.h
msgid "Import from and submit to Perforce repositories"
-msgstr ""
+msgstr "Impor dari dan kirimkan ke repositori Perfore"
#: command-list.h
msgid "Create a packed archive of objects"
-msgstr ""
+msgstr "Buat arsip terpak dari objek"
#: command-list.h
msgid "Find redundant pack files"
-msgstr ""
+msgstr "Cari berkas pak berlebihan"
#: command-list.h
msgid "Pack heads and tags for efficient repository access"
-msgstr ""
+msgstr "Pak kepala dan tag untuk akses repositori yang efisien"
#: command-list.h
msgid "Compute unique ID for a patch"
-msgstr ""
+msgstr "Hitung ID unik untuk sebuah tambalan"
#: command-list.h
msgid "Prune all unreachable objects from the object database"
-msgstr ""
+msgstr "Pangkas semua objek tak tercapai dari basis data objek"
#: command-list.h
msgid "Remove extra objects that are already in pack files"
-msgstr ""
+msgstr "Hapus semua objek ekstra yang sudah ada di dalam berkas pak"
#: command-list.h
msgid "Fetch from and integrate with another repository or a local branch"
-msgstr ""
+msgstr "Ambil dan integrasikan dengan repositori lain atau sebuah cabang lokal"
#: command-list.h
msgid "Update remote refs along with associated objects"
-msgstr ""
+msgstr "Perbarui referensi remote bersama dengan objek yang terkait"
#: command-list.h
msgid "Applies a quilt patchset onto the current branch"
-msgstr ""
+msgstr "Terapkan set tambalan quilt pada cabang saat ini"
#: command-list.h
msgid "Compare two commit ranges (e.g. two versions of a branch)"
-msgstr ""
+msgstr "Bandingkan dua rentang komit (misalnya dua versi cabang)"
#: command-list.h
msgid "Reads tree information into the index"
-msgstr ""
+msgstr "Baca informasi pohon ke dalam indeks"
#: command-list.h
msgid "Reapply commits on top of another base tip"
-msgstr ""
+msgstr "Terapkan ulang komit-komit di atas dasar ujung yang lainnya"
#: command-list.h
msgid "Receive what is pushed into the repository"
-msgstr ""
+msgstr "Terima apa yang didorong pada repositori"
#: command-list.h
msgid "Manage reflog information"
-msgstr ""
+msgstr "Kelola informasi log referensi"
#: command-list.h
msgid "Manage set of tracked repositories"
-msgstr ""
+msgstr "Kelola set repositori terlacak"
#: command-list.h
msgid "Pack unpacked objects in a repository"
-msgstr ""
+msgstr "Pak objek tak terpak di dalam repositori"
#: command-list.h
msgid "Create, list, delete refs to replace objects"
-msgstr ""
+msgstr "Buat, daftar, hapus referensi untuk mengganti objek"
#: command-list.h
msgid "Generates a summary of pending changes"
-msgstr ""
+msgstr "Buat ringkasan perubahan tertunda"
#: command-list.h
msgid "Reuse recorded resolution of conflicted merges"
-msgstr ""
+msgstr "Gunakan ulang resolusi konflik penggabungan terekam"
#: command-list.h
msgid "Reset current HEAD to the specified state"
-msgstr ""
+msgstr "Setel ulang HEAD saat ini ke keadaan yang disebutkan"
#: command-list.h
msgid "Restore working tree files"
-msgstr ""
+msgstr "Pulihkan berkas pohon kerja"
#: command-list.h
msgid "Lists commit objects in reverse chronological order"
-msgstr ""
+msgstr "Daftar objek komit dalam urutan kronologis terbalik"
#: command-list.h
msgid "Pick out and massage parameters"
-msgstr ""
+msgstr "Ambil dan pijat parameter"
#: command-list.h
msgid "Revert some existing commits"
-msgstr ""
+msgstr "Balikkan beberapa komit yang sudah ada"
#: command-list.h
msgid "Remove files from the working tree and from the index"
-msgstr ""
+msgstr "Hapus berkas dari pohon kerja dan indeks"
#: command-list.h
msgid "Send a collection of patches as emails"
-msgstr ""
+msgstr "Kirim koleksi tambalan sebagai surel"
#: command-list.h
msgid "Push objects over Git protocol to another repository"
-msgstr ""
+msgstr "Dorong objek lewat protokol Git ke repositori lainnya"
#: command-list.h
msgid "Git's i18n setup code for shell scripts"
-msgstr ""
+msgstr "kode penyusunan i18n Git untuk skrip cangkang"
#: command-list.h
msgid "Common Git shell script setup code"
-msgstr ""
+msgstr "kode penyusunan skrip cangkang umum Git"
#: command-list.h
msgid "Restricted login shell for Git-only SSH access"
-msgstr ""
+msgstr "Cangkang masuk terbatas untuk akses SSH hanya Git"
#: command-list.h
msgid "Summarize 'git log' output"
-msgstr ""
+msgstr "Rangkum keluaran 'git log'"
#: command-list.h
msgid "Show various types of objects"
-msgstr ""
+msgstr "Perlihatkan berbagai tipe objek"
#: command-list.h
msgid "Show branches and their commits"
-msgstr ""
+msgstr "Perlihatkan cabang dan komitnya"
#: command-list.h
msgid "Show packed archive index"
-msgstr ""
+msgstr "Perlihatkan indeks arsip terpak"
#: command-list.h
msgid "List references in a local repository"
-msgstr ""
+msgstr "Daftar referensi di repositori lokal"
#: command-list.h
msgid "Reduce your working tree to a subset of tracked files"
-msgstr ""
+msgstr "Kurangi pohon kerja Anda sampai subset berkas terlacak"
#: command-list.h
msgid "Add file contents to the staging area"
-msgstr ""
+msgstr "Tambahkan isi berkas ke area penggelaran"
#: command-list.h
msgid "Stash the changes in a dirty working directory away"
-msgstr ""
+msgstr "Stase perubahan di dalam direktori kerja"
#: command-list.h
msgid "Show the working tree status"
-msgstr ""
+msgstr "Perlihatkan status pohon kerja"
#: command-list.h
msgid "Remove unnecessary whitespace"
-msgstr ""
+msgstr "Hapus spasi yang tidak diperlukan"
#: command-list.h
msgid "Initialize, update or inspect submodules"
-msgstr ""
+msgstr "Inisialisasi, perbarui atau inspeksi submodul"
#: command-list.h
msgid "Bidirectional operation between a Subversion repository and Git"
-msgstr ""
+msgstr "Operasi dua arah antara repositori Subversion dan Git"
#: command-list.h
msgid "Switch branches"
-msgstr ""
+msgstr "Ganti cabang"
#: command-list.h
msgid "Read, modify and delete symbolic refs"
-msgstr ""
+msgstr "Baca, ubah dan hapus referensi simbolik"
#: command-list.h
msgid "Create, list, delete or verify a tag object signed with GPG"
msgstr ""
+"Buat, daftar, hapus atau verifikasi objek tag yang ditandatangani dengan GPG"
#: command-list.h
msgid "Creates a temporary file with a blob's contents"
-msgstr ""
+msgstr "Buat berkas sementara dengan isi blob"
#: command-list.h
msgid "Unpack objects from a packed archive"
-msgstr ""
+msgstr "Bongkar objek dari arsip terpak"
#: command-list.h
msgid "Register file contents in the working tree to the index"
-msgstr ""
+msgstr "Daftarkan isi berkas dalam pohon kerja ke indeks"
#: command-list.h
msgid "Update the object name stored in a ref safely"
-msgstr ""
+msgstr "Perbarui nama objek yang disimpan di dalam referensi secara aman"
#: command-list.h
msgid "Update auxiliary info file to help dumb servers"
-msgstr ""
+msgstr "Perbarui berkas info tambahan untuk membantu peladen bodoh"
#: command-list.h
msgid "Send archive back to git-archive"
-msgstr ""
+msgstr "Kirim arsip kembali ke git-archive"
#: command-list.h
msgid "Send objects packed back to git-fetch-pack"
-msgstr ""
+msgstr "Kirim objek terpak kembali ke git-fetch-pack"
#: command-list.h
msgid "Show a Git logical variable"
-msgstr ""
+msgstr "Perlihatkan variabel logikal Git"
#: command-list.h
msgid "Check the GPG signature of commits"
-msgstr ""
+msgstr "Periksa tandatangan GPG komit"
#: command-list.h
msgid "Validate packed Git archive files"
-msgstr ""
+msgstr "Validasi berkas arsip Git terpak"
#: command-list.h
msgid "Check the GPG signature of tags"
-msgstr ""
+msgstr "Periksa tandatangan GPG tag"
+
+#: command-list.h
+msgid "Display version information about Git"
+msgstr "Perlihatkan info versi Git"
#: command-list.h
msgid "Show logs with difference each commit introduces"
-msgstr ""
+msgstr "Perlihatkan log dengan perbedaan yang dimasukkan setiap komit"
#: command-list.h
msgid "Manage multiple working trees"
-msgstr ""
+msgstr "Kelola banyak pohon kerja"
#: command-list.h
msgid "Create a tree object from the current index"
-msgstr ""
+msgstr "Buat objek pohon dari indeks saat ini"
#: command-list.h
msgid "Defining attributes per path"
-msgstr ""
+msgstr "Tentukan atribut tiap jalur"
#: command-list.h
msgid "Git command-line interface and conventions"
-msgstr ""
+msgstr "Antarmuka baris perintah dan konvensi Git"
#: command-list.h
msgid "A Git core tutorial for developers"
-msgstr ""
+msgstr "Tutorial Git dasar untuk pengembang"
#: command-list.h
msgid "Providing usernames and passwords to Git"
-msgstr ""
+msgstr "Sediakan nama pengguna dan kata sandi ke Git"
#: command-list.h
msgid "Git for CVS users"
-msgstr ""
+msgstr "Git untuk pengguna CVS"
#: command-list.h
msgid "Tweaking diff output"
-msgstr ""
+msgstr "Ubah keluaran diff"
#: command-list.h
msgid "A useful minimum set of commands for Everyday Git"
-msgstr ""
+msgstr "Set perintah berguna minimal untuk Git setiap hari"
#: command-list.h
msgid "Frequently asked questions about using Git"
-msgstr ""
+msgstr "Pertanyaan yang sering diajukan tentang penggunaan Git"
+
+#: command-list.h
+msgid "The bundle file format"
+msgstr "Format berkas bundel"
+
+#: command-list.h
+msgid "Chunk-based file formats"
+msgstr "Berkas format berbasis bingkah"
+
+#: command-list.h
+msgid "Git commit graph format"
+msgstr "Format grafik komit Git"
+
+#: command-list.h
+msgid "Git index format"
+msgstr "Format indeks Git"
+
+#: command-list.h
+msgid "Git pack format"
+msgstr "Format pak Git"
+
+#: command-list.h
+msgid "Git cryptographic signature formats"
+msgstr "Format tandatangan kriptografik Git"
#: command-list.h
msgid "A Git Glossary"
-msgstr ""
+msgstr "Glosarium Git"
#: command-list.h
msgid "Hooks used by Git"
-msgstr ""
+msgstr "Kait yang digunakan oleh Git"
#: command-list.h
msgid "Specifies intentionally untracked files to ignore"
-msgstr ""
+msgstr "Sengaja menyebutkan berkas tak terlacak untuk diabaikan"
#: command-list.h
msgid "The Git repository browser"
-msgstr ""
+msgstr "Penjelajah repositori Git"
#: command-list.h
msgid "Map author/committer names and/or E-Mail addresses"
-msgstr ""
+msgstr "Petakan nama pengarang/pengkomit dan/atau alamat surel"
#: command-list.h
msgid "Defining submodule properties"
-msgstr ""
+msgstr "Menentukan properti submodul"
#: command-list.h
msgid "Git namespaces"
-msgstr ""
+msgstr "Nama lingkup Git"
+
+#: command-list.h
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Kemampuan protokol v0 dan v1"
+
+#: command-list.h
+msgid "Things common to various protocols"
+msgstr "Hal-hal yang umum pada berbagai protokol"
+
+#: command-list.h
+msgid "Git HTTP-based protocols"
+msgstr "Protokol Git berbasis HTTP"
+
+#: command-list.h
+msgid "How packs are transferred over-the-wire"
+msgstr "Bagaimana pak ditransfer lewat kabel"
+
+#: command-list.h
+msgid "Git Wire Protocol, Version 2"
+msgstr "Protokol kabel Git, versi 2"
#: command-list.h
msgid "Helper programs to interact with remote repositories"
-msgstr ""
+msgstr "Program pembantu untuk berinteraksi dengan repositori remote"
#: command-list.h
msgid "Git Repository Layout"
-msgstr ""
+msgstr "Tata letak repositori Git"
#: command-list.h
msgid "Specifying revisions and ranges for Git"
-msgstr ""
+msgstr "Menyebutkan revisi dan rentang untuk Git"
#: command-list.h
msgid "Mounting one repository inside another"
-msgstr ""
+msgstr "Menaiki satu repositori di dalam lainnya"
#: command-list.h
msgid "A tutorial introduction to Git"
-msgstr ""
+msgstr "Tutorial perkenalan Git"
#: command-list.h
msgid "A tutorial introduction to Git: part two"
-msgstr ""
+msgstr "Tutorial perkenalan Git: bagian dua"
#: command-list.h
msgid "Git web interface (web frontend to Git repositories)"
-msgstr ""
+msgstr "Antarmuka web Git (tampilan depan web untuk repositori Git)"
#: command-list.h
msgid "An overview of recommended workflows with Git"
-msgstr ""
+msgstr "Selayang pandang alur kerja yang direkomendasikan dengan Git"
+
+#: command-list.h
+msgid "A tool for managing large Git repositories"
+msgstr "Alat untuk mengelola repositori Git besar"
#: commit-graph.c
msgid "commit-graph file is too small"
-msgstr ""
+msgstr "berkas grafik komit terlalu kecil"
#: commit-graph.c
#, c-format
msgid "commit-graph signature %X does not match signature %X"
-msgstr ""
+msgstr "tanda tangan grafik komit %X tidak cocok dengan tanda tangan %X"
#: commit-graph.c
#, c-format
msgid "commit-graph version %X does not match version %X"
-msgstr ""
+msgstr "versi grafik komit %X tidak cocok dengan versi %X"
#: commit-graph.c
#, c-format
msgid "commit-graph hash version %X does not match version %X"
-msgstr ""
+msgstr "versi hash grafik komit %X tidak cocok dengan versi %X"
#: commit-graph.c
#, c-format
msgid "commit-graph file is too small to hold %u chunks"
-msgstr ""
+msgstr "berkas grafik komit terlalu kecil untuk menyimpan %u bingkah"
#: commit-graph.c
msgid "commit-graph has no base graphs chunk"
-msgstr ""
+msgstr "grafik komit tidak punya bingkah grafik dasar"
#: commit-graph.c
msgid "commit-graph chain does not match"
-msgstr ""
+msgstr "rantai grafik komit tidak cocok"
#: commit-graph.c
#, c-format
msgid "invalid commit-graph chain: line '%s' not a hash"
-msgstr ""
+msgstr "rantai grafik komit tidak cocok: baris '%s' bukan sebuah hash"
#: commit-graph.c
msgid "unable to find all commit-graph files"
-msgstr ""
+msgstr "tidak dapat menemukan semua berkas grafik komit"
#: commit-graph.c
msgid "invalid commit position. commit-graph is likely corrupt"
-msgstr ""
+msgstr "posisi komit tidak valid. grafik komit mungkin rusak"
#: commit-graph.c
#, c-format
msgid "could not find commit %s"
-msgstr ""
+msgstr "tidak dapat menemukan komit %s"
#: commit-graph.c
msgid "commit-graph requires overflow generation data but has none"
-msgstr ""
+msgstr "grafik komit memerlukan pembuatan data meluap tapi tidak punya"
#: commit-graph.c
msgid "Loading known commits in commit graph"
-msgstr ""
+msgstr "Memuat komit yang dikenal di grafik komit"
#: commit-graph.c
msgid "Expanding reachable commits in commit graph"
-msgstr ""
+msgstr "Memperluas komit yang dapat dijangkau di grafik komit"
#: commit-graph.c
msgid "Clearing commit marks in commit graph"
-msgstr ""
+msgstr "Membersihkan penanda komit di grafik komit"
#: commit-graph.c
msgid "Computing commit graph topological levels"
-msgstr ""
+msgstr "Menghitung tingat topologis grafik komit"
#: commit-graph.c
msgid "Computing commit graph generation numbers"
-msgstr ""
+msgstr "Menghitung jumlah pembuatan grafik komit"
#: commit-graph.c
msgid "Computing commit changed paths Bloom filters"
-msgstr ""
+msgstr "Menghitung komit yang berubah jalurnya oleh penyaring Bloom"
#: commit-graph.c
msgid "Collecting referenced commits"
-msgstr ""
+msgstr "Mengumpulkan komit tereferensi"
#: commit-graph.c
#, c-format
msgid "Finding commits for commit graph in %<PRIuMAX> pack"
msgid_plural "Finding commits for commit graph in %<PRIuMAX> packs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Mencari komit untuk grafik komit di dalam pak %<PRIuMAX>"
+msgstr[1] "Mencari komit untuk grafik komit di dalam pak %<PRIuMAX>"
#: commit-graph.c
#, c-format
msgid "error adding pack %s"
-msgstr ""
+msgstr "kesalahan menambahkan pak %s"
#: commit-graph.c
#, c-format
msgid "error opening index for %s"
-msgstr ""
+msgstr "kesalahan membuka indeks untuk %s"
#: commit-graph.c
msgid "Finding commits for commit graph among packed objects"
-msgstr ""
+msgstr "Mencari komit untuk grafik komit di antara objek terpak"
#: commit-graph.c
msgid "Finding extra edges in commit graph"
-msgstr ""
+msgstr "Mencari tepi ekstra di dalam grafik komit"
#: commit-graph.c
msgid "failed to write correct number of base graph ids"
-msgstr ""
+msgstr "gagal menulis jumlah id grafik dasar yang benar"
#: commit-graph.c
msgid "unable to create temporary graph layer"
-msgstr ""
+msgstr "tidak dapat membuat lapisan grafik dasar"
#: commit-graph.c
#, c-format
msgid "unable to adjust shared permissions for '%s'"
-msgstr ""
+msgstr "tidak dapat menyesuaikan perizinan berbagi untuk '%s'"
#: commit-graph.c
#, c-format
msgid "Writing out commit graph in %d pass"
msgid_plural "Writing out commit graph in %d passes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Menulis grafik komit dalam %d fase"
+msgstr[1] "Menulis grafik komit dalam %d fase"
#: commit-graph.c
msgid "unable to open commit-graph chain file"
-msgstr ""
+msgstr "tidak dapat membuka berkas rantai grafik komit"
#: commit-graph.c
msgid "failed to rename base commit-graph file"
-msgstr ""
+msgstr "gagal menamai ulang berkas grafik komit dasar"
#: commit-graph.c
msgid "failed to rename temporary commit-graph file"
-msgstr ""
+msgstr "gagal menamai ulang berkas grafik komit sementara"
#: commit-graph.c
msgid "Scanning merged commits"
-msgstr ""
+msgstr "Memindai komit tergabung"
#: commit-graph.c
msgid "Merging commit-graph"
-msgstr ""
+msgstr "Menggabungkan grafik komit"
#: commit-graph.c
msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
-msgstr ""
+msgstr "mencoba menulis grafik komit, tapi 'core.commitGraph' dimatikan"
#: commit-graph.c
msgid "too many commits to write graph"
-msgstr ""
+msgstr "terlalu banyak komit untuk menulis grafik"
#: commit-graph.c
msgid "the commit-graph file has incorrect checksum and is likely corrupt"
-msgstr ""
+msgstr "berkas grafik komit punya checksum salah dan mungkin rusak"
#: commit-graph.c
#, c-format
msgid "commit-graph has incorrect OID order: %s then %s"
-msgstr ""
+msgstr "grafik komit punya urutan OID salah: %s lalu %s"
#: commit-graph.c
#, c-format
msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u"
-msgstr ""
+msgstr "grafik komit punya nilai kipas keluar salah: fanout[%d] = %u != %u"
#: commit-graph.c
#, c-format
msgid "failed to parse commit %s from commit-graph"
-msgstr ""
+msgstr "gagal menguraikan komit %s dari grafik komit"
#: commit-graph.c
msgid "Verifying commits in commit graph"
-msgstr ""
+msgstr "Memverifikasi komit di dalam grafik komit"
#: commit-graph.c
#, c-format
msgid "failed to parse commit %s from object database for commit-graph"
-msgstr ""
+msgstr "gagal menguraikan komit %s dari basis data objek untuk grafik komit"
#: commit-graph.c
#, c-format
msgid "root tree OID for commit %s in commit-graph is %s != %s"
-msgstr ""
+msgstr "OID pohon akar untuk komit %s di dalam grafik komit yaitu %s != %s"
#: commit-graph.c
#, c-format
msgid "commit-graph parent list for commit %s is too long"
-msgstr ""
+msgstr "daftar induk grafik komit untuk %s terlalu panjang"
#: commit-graph.c
#, c-format
msgid "commit-graph parent for %s is %s != %s"
-msgstr ""
+msgstr "induk grafik komit untuk %s adalah %s != %s"
#: commit-graph.c
#, c-format
msgid "commit-graph parent list for commit %s terminates early"
-msgstr ""
+msgstr "daftar induk grafik komit untuk komit %s berakhir lebih awal"
#: commit-graph.c
#, c-format
msgid ""
"commit-graph has generation number zero for commit %s, but non-zero elsewhere"
msgstr ""
+"grafik komit punya angka pembuatan nol untuk komit %s, tapi bukan nol di "
+"tempat lain"
#: commit-graph.c
#, c-format
msgid ""
"commit-graph has non-zero generation number for commit %s, but zero elsewhere"
msgstr ""
+"grafik komit punya angka pembuatan bukan nol untuk komit %s, tapi nol di "
+"tempat lain"
#: commit-graph.c
#, c-format
msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>"
-msgstr ""
+msgstr "pembuatan grafik komit untuk komit %s yaitu %<PRIuMAX> < %<PRIuMAX>"
#: commit-graph.c
#, c-format
msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>"
msgstr ""
+"tanggal komit untuk komit %s di dalam grafik komit yaitu %<PRIuMAX> != "
+"%<PRIuMAX>"
#: commit.c
#, c-format
msgid "%s %s is not a commit!"
-msgstr ""
+msgstr "%s %s bukan sebuah komit!"
#: commit.c
msgid ""
@@ -17449,26 +17842,34 @@ msgid ""
"Turn this message off by running\n"
"\"git config advice.graftFileDeprecated false\""
msgstr ""
+"Dukungan untuk <GIT_DIR>/info/grafts usang dan akan dihapus\n"
+"pada versi Git di masa yang akan datang.\n"
+"\n"
+"Mohon gunakan \"git replace --convert-graft-file\"\n"
+"untuk mengkonversi cangkuk ke referensi penggantian.\n"
+"\n"
+"Matikan pesan ini dengan menjalankan\n"
+"\"git config advice.graftFileDeprecated false\""
#: commit.c
#, c-format
msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
-msgstr ""
+msgstr "Komit %s punya tandatangan GPG tak dipercaya, dituduh sebagai %s."
#: commit.c
#, c-format
msgid "Commit %s has a bad GPG signature allegedly by %s."
-msgstr ""
+msgstr "Komit %s punya tandatangan GPG tak jelek, dituduh sebagai %s."
#: commit.c
#, c-format
msgid "Commit %s does not have a GPG signature."
-msgstr ""
+msgstr "Komit %s tidak punya tandatangan GPG."
#: commit.c
#, c-format
msgid "Commit %s has a good GPG signature by %s\n"
-msgstr ""
+msgstr "Komit %s punya tandatangan GPG bagus oleh %s\n"
#: commit.c
msgid ""
@@ -17476,214 +17877,239 @@ msgid ""
"You may want to amend it after fixing the message, or set the config\n"
"variable i18n.commitEncoding to the encoding your project uses.\n"
msgstr ""
+"Peringatan: pesan komit tidak sesuai dengan UTF-8.\n"
+"Anda dapat mengubahnya setelah memperbaiki pesan, atau menyetel variabel\n"
+"konfigurasi i18n.commitEncoding ke pengkodean yang proyek Anda gunakan.\n"
#: compat/compiler.h
msgid "no compiler information available\n"
-msgstr ""
+msgstr "informasi pengompilasi tidak tersedia\n"
#: compat/compiler.h
msgid "no libc information available\n"
-msgstr ""
+msgstr "informasi libc tidak tersedia\n"
+
+#: compat/disk.h
+#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "tidak dapat menentukan ukuran disk kosong untuk '%s'"
+
+#: compat/disk.h
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "tidak dapat mendapatkan informasi untuk '%s'"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
-msgstr ""
+msgstr "[GLE %ld] utas kesehatan tidak dapat membuka '%ls'"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "[GLE %ld] health thread getting BHFI for '%ls'"
-msgstr ""
+msgstr "[GLE %ld] utas kesehatan mendapatkan BHFI untuk '%ls'"
#: compat/fsmonitor/fsm-health-win32.c compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "could not convert to wide characters: '%s'"
-msgstr ""
+msgstr "tidak dapat mengkonversi ke karakter lebar: '%s'"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "BHFI changed '%ls'"
-msgstr ""
+msgstr "BHFI mengubah '%ls'"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "unhandled case in 'has_worktree_moved': %d"
-msgstr ""
+msgstr "kasus tak tertangani di 'has_worktree_moved': %d"
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "health thread wait failed [GLE %ld]"
-msgstr ""
+msgstr "antri utas kesehatan gagal [GLE %ld]"
#: compat/fsmonitor/fsm-listen-darwin.c
msgid "Unable to create FSEventStream."
-msgstr ""
+msgstr "tidak dapat membuat FSEventStream."
#: compat/fsmonitor/fsm-listen-darwin.c
msgid "Failed to start the FSEventStream"
-msgstr ""
+msgstr "Gagal memulai FSEventStream"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "[GLE %ld] could not convert path to UTF-8: '%.*ls'"
-msgstr ""
+msgstr "[GLE %ld] tidak dapat mengkonversi jalur ke UTF-8: '%.*ls'"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "[GLE %ld] could not watch '%s'"
-msgstr ""
+msgstr "[GLE %ld] tidak dapat menonton '%s'"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "[GLE %ld] could not get longname of '%s'"
-msgstr ""
+msgstr "[GLE %ld] tidak dapat mendapatkan nama panjang dari '%s'"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "ReadDirectoryChangedW failed on '%s' [GLE %ld]"
-msgstr ""
+msgstr "ReadDirectoryChangedW gagal pada '%s' [GLE %ld]"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "GetOverlappedResult failed on '%s' [GLE %ld]"
-msgstr ""
+msgstr "GetOverlappedResult gagal pada '%s' [GLE %ld]"
#: compat/fsmonitor/fsm-listen-win32.c
#, c-format
msgid "could not read directory changes [GLE %ld]"
-msgstr ""
+msgstr "tidak dapat membaca perubahan direktori [GLE %ld]"
+
+#: compat/fsmonitor/fsm-settings-win32.c
+#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] tidak dapat membuka untuk dibaca '%ls'"
+
+#: compat/fsmonitor/fsm-settings-win32.c
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] tidak dapat mendapatkan informasi protokol untuk '%ls'"
#: compat/mingw.c
#, c-format
msgid "failed to copy SID (%ld)"
-msgstr ""
+msgstr "gagal menyalin SID (%ld)"
#: compat/mingw.c
#, c-format
msgid "failed to get owner for '%s' (%ld)"
-msgstr ""
+msgstr "gagal mendapatkan pemilik untuk '%s' (%ld)"
#: compat/obstack.c
msgid "memory exhausted"
-msgstr ""
+msgstr "memory habis"
#: compat/regex/regcomp.c
msgid "Success"
-msgstr ""
+msgstr "Success"
#: compat/regex/regcomp.c
msgid "No match"
-msgstr ""
+msgstr "Tidak ada yang cocok"
#: compat/regex/regcomp.c
msgid "Invalid regular expression"
-msgstr ""
+msgstr "Ekspresi reguler tidak valid"
#: compat/regex/regcomp.c
msgid "Invalid collation character"
-msgstr ""
+msgstr "Karakter kolase tidak valid"
#: compat/regex/regcomp.c
msgid "Invalid character class name"
-msgstr ""
+msgstr "Nama kelas karakter tidak valid"
#: compat/regex/regcomp.c
msgid "Trailing backslash"
-msgstr ""
+msgstr "Garis miring terbalik tertinggal"
#: compat/regex/regcomp.c
msgid "Invalid back reference"
-msgstr ""
+msgstr "Referensi balik tidak valid"
#: compat/regex/regcomp.c
msgid "Unmatched [ or [^"
-msgstr ""
+msgstr "[ atau [^ tak tercocok"
#: compat/regex/regcomp.c
msgid "Unmatched ( or \\("
-msgstr ""
+msgstr "( atau \\( tak tercocok"
#: compat/regex/regcomp.c
msgid "Unmatched \\{"
-msgstr ""
+msgstr "\\{ tak tercocok"
#: compat/regex/regcomp.c
msgid "Invalid content of \\{\\}"
-msgstr ""
+msgstr "Isi \\{\\} tidak valid"
#: compat/regex/regcomp.c
msgid "Invalid range end"
-msgstr ""
+msgstr "Ujung rentang tidak valid"
#: compat/regex/regcomp.c
msgid "Memory exhausted"
-msgstr ""
+msgstr "Memori habis"
#: compat/regex/regcomp.c
msgid "Invalid preceding regular expression"
-msgstr ""
+msgstr "Ekspresi reguler sebelumnya tidak valid"
#: compat/regex/regcomp.c
msgid "Premature end of regular expression"
-msgstr ""
+msgstr "Akhir ekspresi reguler prematur"
#: compat/regex/regcomp.c
msgid "Regular expression too big"
-msgstr ""
+msgstr "Ekspresi reguler terlalu besar"
#: compat/regex/regcomp.c
msgid "Unmatched ) or \\)"
-msgstr ""
+msgstr ") atau \\) tak tercocok"
#: compat/regex/regcomp.c
msgid "No previous regular expression"
-msgstr ""
+msgstr "Tidak ada ekspresi reguler sebelumnya"
#: compat/simple-ipc/ipc-unix-socket.c compat/simple-ipc/ipc-win32.c
msgid "could not send IPC command"
-msgstr ""
+msgstr "tidak dapat mengirimkan perintah IPC"
#: compat/simple-ipc/ipc-unix-socket.c compat/simple-ipc/ipc-win32.c
msgid "could not read IPC response"
-msgstr ""
+msgstr "tidak dapat membaca jawaban IPC"
#: compat/simple-ipc/ipc-unix-socket.c
#, c-format
msgid "could not start accept_thread '%s'"
-msgstr ""
+msgstr "tidak dapat memulai accept_thread '%s'"
#: compat/simple-ipc/ipc-unix-socket.c
#, c-format
msgid "could not start worker[0] for '%s'"
-msgstr ""
+msgstr "tidak dapat memulai worker[0] untuk '%s'"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "ConnectNamedPipe failed for '%s' (%lu)"
-msgstr ""
+msgstr "ConnectNamedPipe gagal untuk '%s' (%lu)"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "could not create fd from pipe for '%s'"
-msgstr ""
+msgstr "tidak dapat membuat penjelas berkas dari pipa untuk '%s'"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "could not start thread[0] for '%s'"
-msgstr ""
+msgstr "tidak dapat memulai thread[0] untuk '%s'"
#: compat/simple-ipc/ipc-win32.c
#, c-format
msgid "wait for hEvent failed for '%s'"
-msgstr ""
+msgstr "antri untuk hEvent gagal untuk '%s'"
#: compat/terminal.c
msgid "cannot resume in the background, please use 'fg' to resume"
msgstr ""
+"tidak dapat melanjutkan di belakang layar, mohon gunakan 'fg' untuk "
+"melanjutkan"
#: compat/terminal.c
msgid "cannot restore terminal settings"
-msgstr ""
+msgstr "tidak dapat mengembalikan setelan terminal"
#: config.c
#, c-format
@@ -18231,233 +18657,15 @@ msgstr "gagal menulis ke rev-list"
msgid "failed to close rev-list's stdin"
msgstr "gagal menutup masukan standar rev-list"
-#: contrib/scalar/scalar.c worktree.c
-#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' tidak ada"
-
-#: contrib/scalar/scalar.c
-msgid "need a working directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "could not find enlistment root"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not switch to '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure %s=%s"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "could not configure log.excludeDecoration"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "Scalar enlistments require a worktree"
-msgstr ""
-
-#: contrib/scalar/scalar.c dir.c
-#, c-format
-msgid "could not open directory '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not get info for '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "failed to get default branch name"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "failed to unregister repository"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "failed to delete enlistment directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "branch to checkout after clone"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "when cloning, create full working directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "only download metadata for the branch that will be checked out"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "directory '%s' exists already"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "partial clone failed; attempting full clone"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "could not configure for full clone"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar diagnose [<enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "could not duplicate stdout"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "failed to write archive"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "`scalar list` does not take arguments"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar register [<enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "reconfigure all registered enlistments"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "--all or <enlistment>, but not both"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "no such task: '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar unregister [<enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar delete <enlistment>"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "refusing to delete current working directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "include Git version"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "include Git's build options"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "-C requires a <directory>"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not change to '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid "-c requires a <key>=<value> argument"
-msgstr ""
-
-#: contrib/scalar/scalar.c
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-
#: convert.c
#, c-format
msgid "illegal crlf_action %d"
-msgstr ""
+msgstr "crlf_action %d ilegal"
#: convert.c
#, c-format
msgid "CRLF would be replaced by LF in %s"
-msgstr ""
+msgstr "CRLF akan digantikan oleh LF di %s"
#: convert.c
#, c-format
@@ -18465,11 +18673,13 @@ msgid ""
"in the working copy of '%s', CRLF will be replaced by LF the next time Git "
"touches it"
msgstr ""
+"di dalam salinan kerja '%s', CRLF akan digantikan oleh LF pada saat Git "
+"menyentuhnya lain kali"
#: convert.c
#, c-format
msgid "LF would be replaced by CRLF in %s"
-msgstr ""
+msgstr "LF akan digantikan oleh CRLF di %s"
#: convert.c
#, c-format
@@ -18477,11 +18687,13 @@ msgid ""
"in the working copy of '%s', LF will be replaced by CRLF the next time Git "
"touches it"
msgstr ""
+"di dalam salinan kerja '%s', LF akan digantikan oleh LF pada saat Git "
+"menyentuhnya lain kali"
#: convert.c
#, c-format
msgid "BOM is prohibited in '%s' if encoded as %s"
-msgstr ""
+msgstr "BOM tidak diperbolehkan di '%s' jika dikodekan sebagai %s"
#: convert.c
#, c-format
@@ -18489,11 +18701,13 @@ msgid ""
"The file '%s' contains a byte order mark (BOM). Please use UTF-%.*s as "
"working-tree-encoding."
msgstr ""
+"Berkas '%s' berisi tanda urutan bita (BOM). Mohon gunakan UTF-%.*s sebagai "
+"pengkodean pohon kerja."
#: convert.c
#, c-format
msgid "BOM is required in '%s' if encoded as %s"
-msgstr ""
+msgstr "BOM diperlukan di '%s' jika dikodekan sebagai %s"
#: convert.c
#, c-format
@@ -18501,49 +18715,51 @@ msgid ""
"The file '%s' is missing a byte order mark (BOM). Please use UTF-%sBE or UTF-"
"%sLE (depending on the byte order) as working-tree-encoding."
msgstr ""
+"Berkas '%s' kehilangan tanda urutan bita (BOM). Mohon gunakan UTF-%sBE atau "
+"UTF-%sLE (tergantung pada urutan bita) sebagai pengkodean pohon kerja."
#: convert.c
#, c-format
msgid "failed to encode '%s' from %s to %s"
-msgstr ""
+msgstr "gagal mengkodekan '%s' dari %s ke %s"
#: convert.c
#, c-format
msgid "encoding '%s' from %s to %s and back is not the same"
-msgstr ""
+msgstr "pengkodean '%s' dari %s ke %s dan sebaliknya berbeda"
#: convert.c
#, c-format
msgid "cannot fork to run external filter '%s'"
-msgstr ""
+msgstr "tidak dapat menggarpu untuk menjalankan penyaring eksternal '%s'"
#: convert.c
#, c-format
msgid "cannot feed the input to external filter '%s'"
-msgstr ""
+msgstr "tidak dapat mengumpan masukan ke penyaring eksternal '%s'"
#: convert.c
#, c-format
msgid "external filter '%s' failed %d"
-msgstr ""
+msgstr "penyaring eksternal '%s' gagal %d"
#: convert.c
#, c-format
msgid "read from external filter '%s' failed"
-msgstr ""
+msgstr "gagal membaca dari penyaring eksternal '%s'"
#: convert.c
#, c-format
msgid "external filter '%s' failed"
-msgstr ""
+msgstr "penyaring eksternal '%s' gagal"
#: convert.c
msgid "unexpected filter type"
-msgstr ""
+msgstr "tipe penyaring tidak diharapkan"
#: convert.c
msgid "path name too long for external filter"
-msgstr ""
+msgstr "nama jalur terlalu panjang untuk penyaring eksternal"
#: convert.c
#, c-format
@@ -18551,48 +18767,50 @@ msgid ""
"external filter '%s' is not available anymore although not all paths have "
"been filtered"
msgstr ""
+"penyaring eksternal '%s' tidak tersedia lagi walaupun tidak semua jalur "
+"sudah disaring"
#: convert.c
msgid "true/false are no valid working-tree-encodings"
-msgstr ""
+msgstr "true/false bukanlah pengkodean pohon kerja valid"
#: convert.c
#, c-format
msgid "%s: clean filter '%s' failed"
-msgstr ""
+msgstr "%s: penyaring bersih '%s' gagal"
#: convert.c
#, c-format
msgid "%s: smudge filter %s failed"
-msgstr ""
+msgstr "%s: penyaring noda %s gagal"
#: credential.c
#, c-format
msgid "skipping credential lookup for key: credential.%s"
-msgstr ""
+msgstr "melewati pencarian kredensial untuk kunci: credential.%s"
#: credential.c
msgid "refusing to work with credential missing host field"
-msgstr ""
+msgstr "menolak bekerja dengan kredensial yang kehilangan bidang host"
#: credential.c
msgid "refusing to work with credential missing protocol field"
-msgstr ""
+msgstr "menolak bekerja dengan kredensial yang kehilangan bidang protokol"
#: credential.c
#, c-format
msgid "url contains a newline in its %s component: %s"
-msgstr ""
+msgstr "url berisi baris baru pada komponen %s: %s"
#: credential.c
#, c-format
msgid "url has no scheme: %s"
-msgstr ""
+msgstr "url tidak punya skema: %s"
#: credential.c
#, c-format
msgid "credential url cannot be parsed: %s"
-msgstr ""
+msgstr "url kredensial tidak dapat diuraikan: %s"
#: date.c
msgid "in the future"
@@ -18664,57 +18882,93 @@ msgstr[1] "%<PRIuMAX> tahun yang lalu"
#: delta-islands.c
msgid "Propagating island marks"
-msgstr ""
+msgstr "Menyebarkan penanda pulau"
#: delta-islands.c
#, c-format
msgid "bad tree object %s"
-msgstr ""
+msgstr "objek pohon jelek %s"
#: delta-islands.c
#, c-format
msgid "failed to load island regex for '%s': %s"
-msgstr ""
+msgstr "gagal memuat regex pulau untuk '%s': %s"
#: delta-islands.c
#, c-format
msgid "island regex from config has too many capture groups (max=%d)"
msgstr ""
+"regeks pulau dari konfigurasi punya terlalu banyak grup tangkap (max=%d)"
#: delta-islands.c
#, c-format
msgid "Marked %d islands, done.\n"
-msgstr ""
+msgstr "%d pulau ditandai, selesai.\n"
+
+#: diagnose.c
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "nilai --%s tidak valid '%s'"
+
+#: diagnose.c
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "tidak dapat mengarsipkan direktori hilang '%s'"
+
+#: diagnose.c dir.c
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "tidak dapat membuka direktori '%s'"
+
+#: diagnose.c
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "melewatkan '%s', yang bukan berkas atau direktori"
+
+#: diagnose.c
+msgid "could not duplicate stdout"
+msgstr "tidak dapat menggandakan keluaran standar"
+
+#: diagnose.c
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "tidak dapat menambahkan direktori '%s' ke pengarsip"
+
+#: diagnose.c
+msgid "failed to write archive"
+msgstr "gagal menulis arsip"
#: diff-lib.c
msgid "--merge-base does not work with ranges"
-msgstr ""
+msgstr "--merge-base tidak bekerja dengan rentang"
#: diff-lib.c
msgid "--merge-base only works with commits"
-msgstr ""
+msgstr "--merge-base hanya bekerja dengan komit"
#: diff-lib.c
msgid "unable to get HEAD"
-msgstr ""
+msgstr "tidak dapat mendapatkan HEAD"
#: diff-lib.c
msgid "no merge base found"
-msgstr ""
+msgstr "dasar penggabungan tidak ditemukan"
#: diff-lib.c
msgid "multiple merge bases found"
-msgstr ""
+msgstr "banyak dasar penggabungan ditemukan"
#: diff-no-index.c
msgid "git diff --no-index [<options>] <path> <path>"
-msgstr ""
+msgstr "git diff --no-index [<opsi>] <jalur> <jalur>"
#: diff-no-index.c
msgid ""
"Not a git repository. Use --no-index to compare two paths outside a working "
"tree"
msgstr ""
+"Bukan sebuah repositori git. Gunakan --no-index untuk membandingkan dua "
+"jalur di luar pohon kerja"
#: diff.c
#, c-format
@@ -18802,7 +19056,7 @@ msgstr "nilai --stat tidak valid: %s"
#: diff.c parse-options.c
#, c-format
msgid "%s expects a numerical value"
-msgstr "%s harap nilai numerik"
+msgstr "%s berharap nilai numerik"
#: diff.c
#, c-format
@@ -19343,53 +19597,53 @@ msgstr ""
#: diffcore-order.c
#, c-format
msgid "failed to read orderfile '%s'"
-msgstr ""
+msgstr "gagal membaca berkas urutan '%s'"
#: diffcore-rename.c
msgid "Performing inexact rename detection"
-msgstr ""
+msgstr "Melakukan deteksi penamaan ulang tidak eksak"
#: diffcore-rotate.c
#, c-format
msgid "No such path '%s' in the diff"
-msgstr ""
+msgstr "Tidak ada jalur seperti '%s' di dalam diff"
#: dir.c
#, c-format
msgid "pathspec '%s' did not match any file(s) known to git"
-msgstr ""
+msgstr "spek jalur '%s' tidak cocok dengan berkas apapun yang git kenal"
#: dir.c
#, c-format
msgid "unrecognized pattern: '%s'"
-msgstr ""
+msgstr "pola tidak dikenal: '%s'"
#: dir.c
#, c-format
msgid "unrecognized negative pattern: '%s'"
-msgstr ""
+msgstr "pola negatif tidak dikenal: '%s'"
#: dir.c
#, c-format
msgid "your sparse-checkout file may have issues: pattern '%s' is repeated"
-msgstr ""
+msgstr "berkas sparse-checkout Anda mungkin ada masalah: pola '%s' diulangi"
#: dir.c
msgid "disabling cone pattern matching"
-msgstr ""
+msgstr "mematikan pencocokan pola kerucut"
#: dir.c
#, c-format
msgid "cannot use %s as an exclude file"
-msgstr ""
+msgstr "tidak dapat menggunakan %s sebagai berkas pengecualian"
#: dir.c
msgid "failed to get kernel name and information"
-msgstr ""
+msgstr "gagal mendapatkan nama dan informasi kernel"
#: dir.c
msgid "untracked cache is disabled on this system or location"
-msgstr ""
+msgstr "tembolok tak terlacat dimatikan pada sistem atau lokasi ini"
#: dir.c
msgid ""
@@ -19402,41 +19656,41 @@ msgstr ""
#: dir.c
#, c-format
msgid "index file corrupt in repo %s"
-msgstr ""
+msgstr "berkas indeks rusak pada repo %s"
#: dir.c
#, c-format
msgid "could not create directories for %s"
-msgstr ""
+msgstr "tidak dapat membuat direktori untuk %s"
#: dir.c
#, c-format
msgid "could not migrate git directory from '%s' to '%s'"
-msgstr ""
+msgstr "tidak dapat memigrasikan direktori git dari '%s' ke '%s'"
#: editor.c
#, c-format
msgid "hint: Waiting for your editor to close the file...%c"
-msgstr ""
+msgstr "petunjuk: Menunggu penyunting Anda untuk menutup berkas...%c"
#: entry.c
msgid "Filtering content"
-msgstr ""
+msgstr "Menyaring isi"
#: entry.c
#, c-format
msgid "could not stat file '%s'"
-msgstr ""
+msgstr "tidak dapat men-stat berkas '%s'"
#: environment.c
#, c-format
msgid "bad git namespace path \"%s\""
-msgstr ""
+msgstr "jalur ruang nama git jelek \"%s\""
#: exec-cmd.c
#, c-format
msgid "too many args to run %s"
-msgstr ""
+msgstr "terlalu banyak argumen untuk menjalankan %s"
#: fetch-pack.c
msgid "git fetch-pack: expected shallow list"
@@ -19460,6 +19714,10 @@ msgid "unable to write to remote"
msgstr "tidak dapat menulis ke remote"
#: fetch-pack.c
+msgid "Server supports filter"
+msgstr "Peladen mendukung saringan"
+
+#: fetch-pack.c
#, c-format
msgid "invalid shallow line: %s"
msgstr "baris dangkal tidak valid: %s"
@@ -19601,10 +19859,6 @@ msgid "Server does not support shallow requests"
msgstr "Peladen tidak mendukung permintaan dangkal"
#: fetch-pack.c
-msgid "Server supports filter"
-msgstr "Peladen mendukung saringan"
-
-#: fetch-pack.c
msgid "unable to write request to remote"
msgstr "tidak dapat menulis permintaan kepada remote"
@@ -19690,47 +19944,49 @@ msgstr "Peladen tidak memperbolehkan permintaan untuk objek tak diiklankan %s"
#: fsmonitor-ipc.c
#, c-format
msgid "fsmonitor_ipc__send_query: invalid path '%s'"
-msgstr ""
+msgstr "fsmonitor_ipc__send_query: jalur tidak valid '%s'"
#: fsmonitor-ipc.c
#, c-format
msgid "fsmonitor_ipc__send_query: unspecified error on '%s'"
-msgstr ""
+msgstr "fsmonitor_ipc__send_query: kesalahan tidak dijelaskan pada '%s'"
#: fsmonitor-ipc.c
msgid "fsmonitor--daemon is not running"
-msgstr ""
+msgstr "fsmonitor--daemon tidak berjalan"
#: fsmonitor-ipc.c
#, c-format
msgid "could not send '%s' command to fsmonitor--daemon"
-msgstr ""
+msgstr "tidak dapat mengirimkan perintah '%s' ke fsmonitor--daemon"
#: fsmonitor-settings.c
#, c-format
msgid "bare repository '%s' is incompatible with fsmonitor"
-msgstr ""
+msgstr "repositori bare '%s' tidak kompatibel dengan fsmonitor"
#: fsmonitor-settings.c
#, c-format
msgid "repository '%s' is incompatible with fsmonitor due to errors"
-msgstr ""
+msgstr "repositori '%s' tidak kompatibel dengan fsmonitor karena kesalahan"
#: fsmonitor-settings.c
#, c-format
msgid "remote repository '%s' is incompatible with fsmonitor"
-msgstr ""
+msgstr "repositori remote '%s' tidak kompatibel dengan fsmonitor"
#: fsmonitor-settings.c
#, c-format
msgid "virtual repository '%s' is incompatible with fsmonitor"
-msgstr ""
+msgstr "repositori virtual '%s' tidka kompatibel dengan fsmonitor"
#: fsmonitor-settings.c
#, c-format
msgid ""
"repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"
msgstr ""
+"repositori '%s' tidak kompatibel dengan fsmonitor karena kekurangan soket "
+"Unix"
#: git.c
msgid ""
@@ -20027,6 +20283,14 @@ msgid "Low-level Commands / Internal Helpers"
msgstr "Perintah Tingak Rendah / Pembantu Internal"
#: help.c
+msgid "User-facing repository, command and file interfaces"
+msgstr "Antarmuka repositori, perintah, dan berkas menghadap-pengguna"
+
+#: help.c
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Antarmuka menghadap-pengembang format berkas, protokol, dan lainnya"
+
+#: help.c
#, c-format
msgid "available git commands in '%s'"
msgstr "perintah git yang tersedia di '%s'"
@@ -20044,6 +20308,14 @@ msgid "The Git concept guides are:"
msgstr "Panduan konsep Git adalah:"
#: help.c
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Antarmuka repositori, perintah, dan berkas menghadap-pengguna:"
+
+#: help.c
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Antarmuka format berkas, protokol, dan antarmuka lainnya:"
+
+#: help.c
msgid "External commands"
msgstr "Perintah eksternal"
@@ -20140,51 +20412,48 @@ msgstr ""
"Anda dapat menonaktifkan peringatan ini dengan `git config advice."
"ignoredHook false`."
-#: hook.c
-#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "Tidak dapat memulai kait '%s'\n"
-
#: http-fetch.c
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
-msgstr ""
+msgstr "argumen ke --packfile harus sebuah hash valid (dapat '%s')"
#: http-fetch.c
msgid "not a git repository"
-msgstr ""
+msgstr "bukan sebuah repositori git"
#: http.c
#, c-format
msgid "negative value for http.postBuffer; defaulting to %d"
-msgstr ""
+msgstr "nilai negatif untuk http.postBuffer; asalkan ke %d"
#: http.c
msgid "Delegation control is not supported with cURL < 7.22.0"
-msgstr ""
+msgstr "Kontrol delegasi tidak didukung oleh cURL < 7.22.0"
#: http.c
msgid "Public key pinning not supported with cURL < 7.39.0"
-msgstr ""
+msgstr "Penyematan kunci publik tidak didukung oleh cURL < 7.39.0"
#: http.c
msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
-msgstr ""
+msgstr "CURLSSLOPT_NO_REVOKE tidak didukung dengan cURL < 7.44.0"
#: http.c
#, c-format
msgid "Unsupported SSL backend '%s'. Supported SSL backends:"
-msgstr ""
+msgstr "Tulang punggung SSL '%s' tidak didukung, yang didukung:"
#: http.c
#, c-format
msgid "Could not set SSL backend to '%s': cURL was built without SSL backends"
msgstr ""
+"Tidak dapat menyetel tulang punggung SSL ke '%s': cURL dibangun tanpa tulang "
+"punggung SSL"
#: http.c
#, c-format
msgid "Could not set SSL backend to '%s': already set"
-msgstr ""
+msgstr "Tidak dapat menyetel tulang punggung SSL ke '%s': sudah disetel"
#: http.c
#, c-format
@@ -20193,6 +20462,9 @@ msgid ""
" asked for: %s\n"
" redirect: %s"
msgstr ""
+"tidak dapat memperbarui dasar url dari pengalihan:\n"
+" diminta: %s\n"
+" pengalihan: %s"
#: ident.c
msgid "Author identity unknown\n"
@@ -20258,71 +20530,72 @@ msgstr "nama hanya terdiri dari karakter yang tidak diperbolehkan: %s"
#: list-objects-filter-options.c
msgid "expected 'tree:<depth>'"
-msgstr ""
+msgstr "'tree:<kedalaman> diharapkan'"
#: list-objects-filter-options.c
msgid "sparse:path filters support has been dropped"
-msgstr ""
+msgstr "dukungan penyaring sparse:path sudah ditiadakan"
#: list-objects-filter-options.c
#, c-format
msgid "'%s' for 'object:type=<type>' is not a valid object type"
-msgstr ""
+msgstr "'%s' untuk 'object:type=<tipe>' bukan tipe objek valid"
#: list-objects-filter-options.c
#, c-format
msgid "invalid filter-spec '%s'"
-msgstr ""
+msgstr "spek penyaring tidak valid '%s'"
#: list-objects-filter-options.c
#, c-format
msgid "must escape char in sub-filter-spec: '%c'"
-msgstr ""
+msgstr "harus melarikan karakter pada spek subpenyaring: '%c'"
#: list-objects-filter-options.c
msgid "expected something after combine:"
-msgstr ""
+msgstr "sesuatu setelah pencampuran diharapkan:"
#: list-objects-filter-options.c
msgid "multiple filter-specs cannot be combined"
-msgstr ""
+msgstr "spek penyaring lebih dari satu tidak dapat dicampurkan"
#: list-objects-filter-options.c
msgid "unable to upgrade repository format to support partial clone"
msgstr ""
+"tidak dapat meningkatkan format repositori untuk mendukung klon parsial"
#: list-objects-filter-options.h
msgid "args"
-msgstr ""
+msgstr "argumen"
#: list-objects-filter-options.h
msgid "object filtering"
-msgstr ""
+msgstr "penyaringan objek"
#: list-objects-filter.c
#, c-format
msgid "unable to access sparse blob in '%s'"
-msgstr ""
+msgstr "tidak dapat mengakses blob tipis di '%s'"
#: list-objects-filter.c
#, c-format
msgid "unable to parse sparse filter data in %s"
-msgstr ""
+msgstr "tidak dapat menyaring data penyaring tipis di %s"
#: list-objects.c
#, c-format
msgid "entry '%s' in tree %s has tree mode, but is not a tree"
-msgstr ""
+msgstr "entri '%s' di dalam pohon %s punya mode pohon, tetapi bukan pohon"
#: list-objects.c
#, c-format
msgid "entry '%s' in tree %s has blob mode, but is not a blob"
-msgstr ""
+msgstr "entri '%s' di dalam pohon %s punya mode blob, tetapi bukan blob"
#: list-objects.c
#, c-format
msgid "unable to load root tree for commit %s"
-msgstr ""
+msgstr "tidak dapat memuat pohon akar untuk komit %s"
#: lockfile.c
#, c-format
@@ -20335,40 +20608,41 @@ msgid ""
"may have crashed in this repository earlier:\n"
"remove the file manually to continue."
msgstr ""
+"Tidak dapat membuat '%s.lock': %s.\n"
+"\n"
+"Sepertinya proses git lainnya berjalan pada repositori ini, seperti\n"
+"penyunting yang dibuka oleh 'git commit'. Mohon pastikan semua proses\n"
+"berhenti dan coba lagi. Jika masih gagal, mungkin sebuah proses git hancur\n"
+"pada repositori ini sebelumnya: hapus berkas secara manual untuk melanjutkan."
#: lockfile.c
#, c-format
msgid "Unable to create '%s.lock': %s"
-msgstr ""
+msgstr "Tidak dapat membuat '%s.lock': %s"
#: ls-refs.c
#, c-format
msgid "unexpected line: '%s'"
-msgstr ""
+msgstr "baris tak diharapkan: '%s'"
#: ls-refs.c
msgid "expected flush after ls-refs arguments"
-msgstr ""
+msgstr "bilasan diharapkan setelah argumen ls-refs"
#: mailinfo.c
msgid "quoted CRLF detected"
-msgstr ""
-
-#: merge-ort-wrappers.c merge-recursive.c
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh "
-"penggabungan:\n"
-" %s"
+msgstr "CRLF terkutip terdeteksi"
#: merge-ort.c merge-recursive.c
#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Gagal menggabungkan submodul %s (tidak di-checkout)"
+#: merge-ort.c
+#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "Gagal menggabungkan submodul %s (tidak ada dasar penggabungan)"
+
#: merge-ort.c merge-recursive.c
#, c-format
msgid "Failed to merge submodule %s (commits not present)"
@@ -20393,28 +20667,10 @@ msgstr "Gagal menggabungkan submodul %s"
#: merge-ort.c
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
msgstr ""
-"Gagal menggabungkan submodul %s, tetapi sebuah penyelesaian penggabungan "
-"yang mungkin ada:\n"
-"%s\n"
-
-#: merge-ort.c merge-recursive.c
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Jika benar, cukup misalkan tambahkan ke indeks dengan menggunakan:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"yang akan menerima saran ini.\n"
+"Gagal menggabungkan submodul %s, tetapi ada kemungkinan penyelesaian "
+"penggabungan: %s"
#: merge-ort.c
#, c-format
@@ -20603,14 +20859,47 @@ msgstr ""
"KONFLIK (pengubahan/penghapusan): %s dihapus di %s dan diubah di %s. Versi "
"%s dari %s ditinggalkan di dalam pohon."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
#: merge-ort.c
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
msgstr ""
-"Catatan: %s tidak terbaru dan dalam men-checkout versi berkonflik; salinan "
-"lama dinamai ulang ke %s"
+" - pergi ke submodul (%s), dan baik gabungkan komit %s\n"
+" atau perbarui ke komit yang sudah ada yang sudah menggabungkan "
+"perubahan tersebut\n"
+
+#: merge-ort.c
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"Saat ini penggabungan rekursif dengan submodul hanya mendukung kasus-kasus "
+"sepele.\n"
+"Mohon tangani penggabungan setiap submodul berkonflik secara manual.\n"
+"Hal ini dapat dicapai dengan langkah berikut:\n"
+"%s - kembali ke proyek induk dan jalankan:\n"
+"\n"
+" git add %s\n"
+"\n"
+" untuk merekam penggabungan di atas atau perbarui\n"
+" - selesaikan semua konflik lainnya di dalam proyek induk\n"
+" - komit hasil indeks di dalam proyek induk\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -20702,6 +20991,22 @@ msgstr "Sebuah resolusi penggabungan yang mungkin ditemukan untuk submodul:\n"
#: merge-recursive.c
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Jika benar, cukup misalkan tambahkan ke indeks dengan menggunakan:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"yang akan menerima saran ini.\n"
+
+#: merge-recursive.c
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "Gagal menggabungkan submodul %s (banyak penggabungan ditemukan)"
@@ -21120,17 +21425,17 @@ msgstr "tidak dapat menyelesaikan pack-objects"
#: name-hash.c
#, c-format
msgid "unable to create lazy_dir thread: %s"
-msgstr ""
+msgstr "tidak dapat membuat utas lazy_dir: %s"
#: name-hash.c
#, c-format
msgid "unable to create lazy_name thread: %s"
-msgstr ""
+msgstr "tidak dapat membuat utas lazy_name: %s"
#: name-hash.c
#, c-format
msgid "unable to join lazy_name thread: %s"
-msgstr ""
+msgstr "tidak dapat menggabungkan utas lazy_name: %s"
#: notes-merge.c
#, c-format
@@ -21139,25 +21444,29 @@ msgid ""
"Please, use 'git notes merge --commit' or 'git notes merge --abort' to "
"commit/abort the previous merge before you start a new notes merge."
msgstr ""
+"Anda belum menyelesaikan penggabungan catatan Anda sebelumnya (%s ada).\n"
+"Mohon gunakan 'git notes merge --commit' atau 'git notes merge --abort' "
+"untuk mengkomit/membatalkan penggabungan sebelumnya sebelum Anda memulai "
+"penggabungan catatan baru."
#: notes-merge.c
#, c-format
msgid "You have not concluded your notes merge (%s exists)."
-msgstr ""
+msgstr "Anda belum menyelesaikan penggabungan catatan Anda (%s ada)."
#: notes-utils.c
msgid "Cannot commit uninitialized/unreferenced notes tree"
-msgstr ""
+msgstr "Tidak dapat mengkomit pohon catatan tak dinisialisasi/tak dirujuk"
#: notes-utils.c
#, c-format
msgid "Bad notes.rewriteMode value: '%s'"
-msgstr ""
+msgstr "Nilai notes.rewriteMode jelek: '%s'"
#: notes-utils.c
#, c-format
msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
-msgstr ""
+msgstr "Menolak menulis ulang catatan di %s (di luar refs/notes/)"
#. TRANSLATORS: The first %s is the name of
#. the environment variable, the second %s is
@@ -21166,7 +21475,7 @@ msgstr ""
#: notes-utils.c
#, c-format
msgid "Bad %s value: '%s'"
-msgstr ""
+msgstr "Nilai %s jelek: '%s'"
#: object-file.c
#, c-format
@@ -21350,6 +21659,26 @@ msgstr "kebingungan oleh data sumber objek tidak stabil untuk %s"
#: object-file.c
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "tulis objek arus %ld != %<PRIuMAX>"
+
+#: object-file.c
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "tidak dapat mengempis arus objek baru (%d)"
+
+#: object-file.c
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "deflateEnd pada objek arus gagal (%d)"
+
+#: object-file.c
+#, c-format
+msgid "unable to create directory %s"
+msgstr "gagal membuat direktori %s"
+
+#: object-file.c
+#, c-format
msgid "cannot read object for %s"
msgstr "tidak dapat membaca objek untuk %s"
@@ -21616,6 +21945,72 @@ msgstr "tidak dapat menguraikan objek: %s"
msgid "hash mismatch %s"
msgstr "hash tidak cocok %s"
+#: pack-bitmap-write.c
+msgid "trying to write commit not in index"
+msgstr "mencoba menulis komit yang bukan di indeks"
+
+#: pack-bitmap.c
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "gagal menulis indeks bitmap (rusak?)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index (too small)"
+msgstr "indeks bitmap rusak (terlalu kecil)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "berkas indeks bitmap rusak (kepala salah)"
+
+#: pack-bitmap.c
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "versi '%d' tidak didukung untuk berkas indeks bitmap"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr "berkas indeks bitmap rusak (terlalu pendek untuk masuk tembolok hash)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr ""
+"berkas indeks bitmap rusak (terlalu pendek untuk masuk tabel pencarian)"
+
+#: pack-bitmap.c
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "entri duplikat di indeks bitmap: '%s'"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "bitmap ewah rusak: kepala terpotong untuk entri %d"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "bitmap ewah rusak: indeks komit %u di luar jangkauan"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap pack index"
+msgstr "indeks pak bitmap rusak"
+
+#: pack-bitmap.c
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "offset XOR tidak valid di indeks pak bitmap"
+
+#: pack-bitmap.c
+msgid "cannot fstat bitmap file"
+msgstr "tidak dapat fstat berkas bitmap"
+
+#: pack-bitmap.c
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "mengabaikan berkas bitmap tambahan: '%s'"
+
+#: pack-bitmap.c
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "checksum tidak cocok di MIDX dan bitmap"
+
#: pack-bitmap.c
msgid "multi-pack bitmap is missing required reverse index"
msgstr "bitmap multipak kehilangan indeks balik yang diperlukan"
@@ -21631,9 +22026,69 @@ msgid "preferred pack (%s) is invalid"
msgstr "pak yang disukai '%s' kadaluarsa"
#: pack-bitmap.c
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "tabel pencarian bitmap rusak: posisi kembar tiga di luar indeks"
+
+#: pack-bitmap.c
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr "tabel pencarian bitmap rusak: rantai xor melebihi hitungan entri"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr "tabel pencarian bitmap rusak: indeks komit %u di luar jangkauan"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr "bitmap ewah rusak: kepala terpotong untuk bitmap komit \"%s\""
+
+#: 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>"
+msgid "object '%s' not found in type bitmaps"
+msgstr "objek '%s' tidak ditemukan di bitmap tipe"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "objek '%s' tidak punya tipe unik"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "objek '%s': bertipe sebenarnya '%s', diharapkan '%s'"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "object bukan di bitmap: '%s'"
+
+#: pack-bitmap.c
+msgid "failed to load bitmap indexes"
+msgstr "gagal memuat indeks bitmap"
+
+#: pack-bitmap.c
+msgid "you must specify exactly one commit to test"
+msgstr "Anda harus sebutkan tepat satu komit untuk diuji"
+
+#: pack-bitmap.c
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "komit '%s' tidak punya bitmap terindeks"
+
+#: pack-bitmap.c
+msgid "mismatch in bitmap results"
+msgstr "ketidaksesuaian di dalam hasil bitmap"
+
+#: 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>"
+
+#: pack-bitmap.c
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "tidak dapat mendapatkan penggunaan disk dari '%s'"
#: pack-mtimes.c
#, c-format
@@ -21726,91 +22181,97 @@ msgstr "offset di luar ujung indeks pak untuk %s (indeks terpotong?)"
#: parse-options-cb.c
#, c-format
msgid "malformed expiration date '%s'"
-msgstr ""
+msgstr "tanggal kadaluarsa rusak '%s'"
#: parse-options-cb.c
#, c-format
msgid "option `%s' expects \"always\", \"auto\", or \"never\""
-msgstr ""
+msgstr "opsi `%s' mengharapkan \"always\", \"auto\", atau \"never\""
#: parse-options-cb.c
#, c-format
msgid "malformed object name '%s'"
-msgstr ""
+msgstr "nama objek rusak '%s'"
#: parse-options-cb.c
#, c-format
msgid "option `%s' expects \"%s\" or \"%s\""
-msgstr ""
+msgstr "opsi `%s' mengharapkan \"%s\" atau \"%s\""
#: parse-options.c
#, c-format
msgid "%s requires a value"
-msgstr ""
+msgstr "%s butuh sebuah nilai"
#: parse-options.c
#, c-format
msgid "%s is incompatible with %s"
-msgstr ""
+msgstr "%s tidak kompatibel dengan %s"
#: parse-options.c
#, c-format
msgid "%s : incompatible with something else"
-msgstr ""
+msgstr "%s : tidak kompatibel dengan sesuatu yang lain"
#: parse-options.c
#, c-format
msgid "%s takes no value"
-msgstr ""
+msgstr "%s tidak mengambil nilai apapun"
#: parse-options.c
#, c-format
msgid "%s isn't available"
-msgstr ""
+msgstr "%s tidak ada"
#: parse-options.c
#, c-format
msgid "%s expects a non-negative integer value with an optional k/m/g suffix"
msgstr ""
+"%s mengharapkan nilai bilangan bulat non negatif dengan akhiran opsional k/m/"
+"g"
#: parse-options.c
#, c-format
msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
-msgstr ""
+msgstr "opsi ambigu: %s (bisa jadi --%s%s atau --%s%s)"
#: parse-options.c
#, c-format
msgid "did you mean `--%s` (with two dashes)?"
-msgstr ""
+msgstr "mungkin maksud Anda `--%s` (dengan dua tanda strip)?"
#: parse-options.c
#, c-format
msgid "alias of --%s"
-msgstr ""
+msgstr "alias untuk --%s"
+
+#: parse-options.c
+msgid "need a subcommand"
+msgstr "butuh sebuah subperintah"
#: parse-options.c
#, c-format
msgid "unknown option `%s'"
-msgstr ""
+msgstr "opsi tidak dikenal `%s'"
#: parse-options.c
#, c-format
msgid "unknown switch `%c'"
-msgstr ""
+msgstr "sakelar tidak dikenal `%c'"
#: parse-options.c
#, c-format
msgid "unknown non-ascii option in string: `%s'"
-msgstr ""
+msgstr "opsi non-ascii di dalam untai tidak dikenal: `%s'"
#: parse-options.c
msgid "..."
-msgstr ""
+msgstr "..."
#: parse-options.c
#, c-format
msgid "usage: %s"
-msgstr ""
+msgstr "penggunaan: %s"
#. TRANSLATORS: the colon here should align with the
#. one in "usage: %s" translation.
@@ -21818,7 +22279,7 @@ msgstr ""
#: parse-options.c
#, c-format
msgid " or: %s"
-msgstr ""
+msgstr " atau: %s"
#. TRANSLATORS: You should only need to translate this format
#. string if your language is a RTL language (e.g. Arabic,
@@ -21842,237 +22303,243 @@ msgstr ""
#: parse-options.c
#, c-format
msgid "%*s%s"
-msgstr ""
+msgstr "%*s%s"
#: parse-options.c
#, c-format
msgid " %s"
-msgstr ""
+msgstr " %s"
#: parse-options.c
msgid "-NUM"
-msgstr ""
+msgstr "-NUM"
#: parse-options.h
msgid "expiry-date"
-msgstr ""
+msgstr "tanggal kadaluarsa"
#: parse-options.h
msgid "no-op (backward compatibility)"
-msgstr ""
+msgstr "tanpa operasi (kompatibilitas ke belakang)"
#: parse-options.h
msgid "be more verbose"
-msgstr ""
+msgstr "jadi lebih berkata-kata"
#: parse-options.h
msgid "be more quiet"
-msgstr ""
+msgstr "jadi lebih dian"
#: parse-options.h
msgid "use <n> digits to display object names"
-msgstr ""
+msgstr "gunakan <n> digit untuk menampilkan nama objek"
#: parse-options.h
msgid "how to strip spaces and #comments from message"
-msgstr ""
+msgstr "bagaimana cara mengupas spasi dan #komentar dari pesan"
#: parse-options.h
msgid "read pathspec from file"
-msgstr ""
+msgstr "baca spek jalur dari berkas"
#: parse-options.h
msgid ""
"with --pathspec-from-file, pathspec elements are separated with NUL character"
msgstr ""
+"dengan --pathspec-from-file, elemen spek jalur dipisahkan dengan karakter NUL"
#: path.c
#, c-format
msgid "Could not make %s writable by group"
-msgstr ""
+msgstr "Tidak dapat membuat %s bisa ditulis oleh grup"
#: pathspec.c
msgid "Escape character '\\' not allowed as last character in attr value"
msgstr ""
+"Karakter pelarian '\\' tidak diperbolehkan sebagai karakter terakhir dalam "
+"nilai atribut"
#: pathspec.c
msgid "Only one 'attr:' specification is allowed."
-msgstr ""
+msgstr "Hanya satu spesifikasi 'attr:' yang diperbolehkan."
#: pathspec.c
msgid "attr spec must not be empty"
-msgstr ""
+msgstr "spek atribut tidak boleh kosong"
#: pathspec.c
#, c-format
msgid "invalid attribute name %s"
-msgstr ""
+msgstr "nama atribut tidak valid %s"
#: pathspec.c
msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
-msgstr ""
+msgstr "setelan spek jalur global 'glob' dan 'noglob' tidak kompatibel"
#: pathspec.c
msgid ""
"global 'literal' pathspec setting is incompatible with all other global "
"pathspec settings"
msgstr ""
+"setelan spek jalur global 'literal' tidak kompatibel dengan semua setelan "
+"spek jalur lainnya"
#: pathspec.c
msgid "invalid parameter for pathspec magic 'prefix'"
-msgstr ""
+msgstr "parameter tidak valid untuk spek jalur ajaib 'prefix'"
#: pathspec.c
#, c-format
msgid "Invalid pathspec magic '%.*s' in '%s'"
-msgstr ""
+msgstr "Spek jalur ajaib '%.*s' tidak valid di '%s'"
#: pathspec.c
#, c-format
msgid "Missing ')' at the end of pathspec magic in '%s'"
-msgstr ""
+msgstr "Kehilangan ')' pada akhir spek jalur ajaib di '%s'"
#: pathspec.c
#, c-format
msgid "Unimplemented pathspec magic '%c' in '%s'"
-msgstr ""
+msgstr "Spek jalur ajaib '%c' tidak diterapkan di '%s'"
#: pathspec.c
#, c-format
msgid "%s: 'literal' and 'glob' are incompatible"
-msgstr ""
+msgstr "%s: 'literal' dan 'glob' tidak kompatibel"
#: pathspec.c
#, c-format
msgid "%s: '%s' is outside repository at '%s'"
-msgstr ""
+msgstr "%s: '%s' di luar repositori pada '%s'"
#: pathspec.c
#, c-format
msgid "'%s' (mnemonic: '%c')"
-msgstr ""
+msgstr "'%s' (mnemonik: '%c')"
#: pathspec.c
#, c-format
msgid "%s: pathspec magic not supported by this command: %s"
-msgstr ""
+msgstr "%s: spek jalur ajaib tidak didukung oleh perintah ini: %s"
#: pathspec.c
#, c-format
msgid "pathspec '%s' is beyond a symbolic link"
-msgstr ""
+msgstr "spek jalur '%s' di luar tautan simbolik"
#: pathspec.c
#, c-format
msgid "line is badly quoted: %s"
-msgstr ""
+msgstr "baris dikutip jelek: %s"
#: pkt-line.c
msgid "unable to write flush packet"
-msgstr ""
+msgstr "tidak dapat menulis paket bilas"
#: pkt-line.c
msgid "unable to write delim packet"
-msgstr ""
+msgstr "tidak dapat menulis paket pembatas"
#: pkt-line.c
msgid "unable to write response end packet"
-msgstr ""
+msgstr "tidak dapat menulis paket ujung jawaban"
#: pkt-line.c
msgid "flush packet write failed"
-msgstr ""
+msgstr "gagal membilas penulisan paket"
#: pkt-line.c
msgid "protocol error: impossibly long line"
-msgstr ""
+msgstr "kesalahan protokol: baris panjang tidak mungkin"
#: pkt-line.c
msgid "packet write with format failed"
-msgstr ""
+msgstr "gagal menulis paket dengan format"
#: pkt-line.c
msgid "packet write failed - data exceeds max packet size"
-msgstr ""
+msgstr "gagal menulis paket - data melebihi ukuran paket maksimum"
#: pkt-line.c
#, c-format
msgid "packet write failed: %s"
-msgstr ""
+msgstr "gagal menulis paket: %s"
#: pkt-line.c
msgid "read error"
-msgstr ""
+msgstr "kesalahan membaca"
#: pkt-line.c
msgid "the remote end hung up unexpectedly"
-msgstr ""
+msgstr "ujung remote menggantung secara tidak terduga"
#: pkt-line.c
#, c-format
msgid "protocol error: bad line length character: %.4s"
-msgstr ""
+msgstr "kesalahan protokol: karakter panjang baris jelek: %.4s"
#: pkt-line.c
#, c-format
msgid "protocol error: bad line length %d"
-msgstr ""
+msgstr "kesalahan protokol: panjang baris %d jelek"
#: pkt-line.c sideband.c
#, c-format
msgid "remote error: %s"
-msgstr ""
+msgstr "kesalahan remote: %s"
#: preload-index.c
msgid "Refreshing index"
-msgstr ""
+msgstr "Menyegarkan indeks"
#: preload-index.c
#, c-format
msgid "unable to create threaded lstat: %s"
-msgstr ""
+msgstr "tidak dapat membuat lstat terutas: %s"
#: pretty.c
msgid "unable to parse --pretty format"
-msgstr ""
+msgstr "tidak dapat menguraikan format --pretty"
#: promisor-remote.c
msgid "promisor-remote: unable to fork off fetch subprocess"
-msgstr ""
+msgstr "promisor-remote: tidak dapat menggarpu subproses pengambilan"
#: promisor-remote.c
msgid "promisor-remote: could not write to fetch subprocess"
-msgstr ""
+msgstr "promisor-remote: tidak dapat menulis ke subproses pengambilan"
#: promisor-remote.c
msgid "promisor-remote: could not close stdin to fetch subprocess"
msgstr ""
+"promisor-remote: tidak dapat menutup masukan standar ke subproses pengambilan"
#: promisor-remote.c
#, c-format
msgid "promisor remote name cannot begin with '/': %s"
-msgstr ""
+msgstr "nama remote penjanji tidak dapat diawali dengan '/': %s"
#: protocol-caps.c
msgid "object-info: expected flush after arguments"
-msgstr ""
+msgstr "object-info: bilasan diharapkan setelah argumen"
#: prune-packed.c
msgid "Removing duplicate objects"
-msgstr ""
+msgstr "Menghapus objek duplikat"
#: range-diff.c
msgid "could not start `log`"
-msgstr ""
+msgstr "tidak dapat memulai `log`"
#: range-diff.c
msgid "could not read `log` output"
-msgstr ""
+msgstr "tidak dapat membaca keluaran `log`"
#: range-diff.c sequencer.c
#, c-format
msgid "could not parse commit '%s'"
-msgstr ""
+msgstr "tidak dapat menguraikan komit '%s'"
#: range-diff.c
#, c-format
@@ -22080,58 +22547,63 @@ msgid ""
"could not parse first line of `log` output: did not start with 'commit ': "
"'%s'"
msgstr ""
+"tidak dapat menguraikan baris pertama dari keluaran `log`: tidak dimulai "
+"dengan 'commit ': '%s'"
#: range-diff.c
#, c-format
msgid "could not parse git header '%.*s'"
-msgstr ""
+msgstr "tidak dapat menguraikan kepala git '%.*s'"
#: range-diff.c
msgid "failed to generate diff"
-msgstr ""
+msgstr "gagal membuat diff"
#: range-diff.c
#, c-format
msgid "could not parse log for '%s'"
-msgstr ""
+msgstr "tidak dapat menguraikan log untuk '%s'"
#: read-cache.c
#, c-format
msgid "will not add file alias '%s' ('%s' already exists in index)"
msgstr ""
+"tidak akan menambahkan alias berkas '%s' ('%s' sudah ada di dalam indeks)"
#: read-cache.c
msgid "cannot create an empty blob in the object database"
-msgstr ""
+msgstr "tidak dapat membuat sebuah blob kosong di dalam basis data objek"
#: read-cache.c
#, c-format
msgid "%s: can only add regular files, symbolic links or git-directories"
msgstr ""
+"%s: hanya dapat menambahkan berkas reguler, tautan simbolik, atau direktori "
+"git"
#: read-cache.c
#, c-format
msgid "unable to index file '%s'"
-msgstr ""
+msgstr "tidak dapat menulis berkas indeks '%s'"
#: read-cache.c
#, c-format
msgid "unable to add '%s' to index"
-msgstr ""
+msgstr "tidak dapat menambahkan '%s' ke indeks"
#: read-cache.c
#, c-format
msgid "unable to stat '%s'"
-msgstr ""
+msgstr "tidak dapat men-stat '%s'"
#: read-cache.c
#, c-format
msgid "'%s' appears as both a file and as a directory"
-msgstr ""
+msgstr "'%s' muncul baik sebagai sebuah berkas dan sebagai sebuah direktori"
#: read-cache.c
msgid "Refresh index"
-msgstr ""
+msgstr "Segarkan indeks indeks"
#: read-cache.c
#, c-format
@@ -22139,6 +22611,8 @@ msgid ""
"index.version set, but the value is invalid.\n"
"Using version %i"
msgstr ""
+"index.version disetel, tetapi nilainya tidak valid.\n"
+"Menggunakan versi %i"
#: read-cache.c
#, c-format
@@ -22146,137 +22620,139 @@ msgid ""
"GIT_INDEX_VERSION set, but the value is invalid.\n"
"Using version %i"
msgstr ""
+"GIT_INDEX_VERSION disetel, tetapi nilainya tidak valid.\n"
+"Menggunakan versi %i"
#: read-cache.c
#, c-format
msgid "bad signature 0x%08x"
-msgstr ""
+msgstr "tandatangan 0x%08x jelek"
#: read-cache.c
#, c-format
msgid "bad index version %d"
-msgstr ""
+msgstr "versi indeks %d jelek"
#: read-cache.c
msgid "bad index file sha1 signature"
-msgstr ""
+msgstr "tandatangan sha1 berkas indeks jelek"
#: read-cache.c
#, c-format
msgid "index uses %.4s extension, which we do not understand"
-msgstr ""
+msgstr "indeks menggunakan ekstensi %s, yang kami tidak mengerti"
#: read-cache.c
#, c-format
msgid "ignoring %.4s extension"
-msgstr ""
+msgstr "mengabaikan ekstensi %.4s"
#: read-cache.c
#, c-format
msgid "unknown index entry format 0x%08x"
-msgstr ""
+msgstr "format entri indeks 0x%08x tidak dikenal"
#: read-cache.c
#, c-format
msgid "malformed name field in the index, near path '%s'"
-msgstr ""
+msgstr "bidang nama di dalam indeks rusak, di dekat jalur '%s'"
#: read-cache.c
msgid "unordered stage entries in index"
-msgstr ""
+msgstr "entri gelaran tidak terurut di dalam indeks"
#: read-cache.c
#, c-format
msgid "multiple stage entries for merged file '%s'"
-msgstr ""
+msgstr "banyak entri gelaran untuk berkas tergabung '%s'"
#: read-cache.c
#, c-format
msgid "unordered stage entries for '%s'"
-msgstr ""
+msgstr "entri gelaran tidak terurut untuk '%s'"
#: read-cache.c
#, c-format
msgid "unable to create load_cache_entries thread: %s"
-msgstr ""
+msgstr "tidak dapat membuat utas load_cache_entries: %s"
#: read-cache.c
#, c-format
msgid "unable to join load_cache_entries thread: %s"
-msgstr ""
+msgstr "tidak dapat menggabungkan utas load_cache_entries: %s"
#: read-cache.c
#, c-format
msgid "%s: index file open failed"
-msgstr ""
+msgstr "%s: gagal membuka berkas indeks"
#: read-cache.c
#, c-format
msgid "%s: cannot stat the open index"
-msgstr ""
+msgstr "%s: tidak dapat men-stat indeks terbuka"
#: read-cache.c
#, c-format
msgid "%s: index file smaller than expected"
-msgstr ""
+msgstr "%s: berkas indeks lebih kecil dari yang diharapkan"
#: read-cache.c
#, c-format
msgid "%s: unable to map index file%s"
-msgstr ""
+msgstr "%s: tidak dapat memetakan berkas indeks%s"
#: read-cache.c
#, c-format
msgid "unable to create load_index_extensions thread: %s"
-msgstr ""
+msgstr "tidak dapat membuat utas load_index_extensions: %s"
#: read-cache.c
#, c-format
msgid "unable to join load_index_extensions thread: %s"
-msgstr ""
+msgstr "tidak dapat menggabungkan utas load_index_extensions: %s"
#: read-cache.c
#, c-format
msgid "could not freshen shared index '%s'"
-msgstr ""
+msgstr "tidak dapat menyegarkan indeks berbagi '%s'"
#: read-cache.c
#, c-format
msgid "broken index, expect %s in %s, got %s"
-msgstr ""
+msgstr "indeks rusak, mengharapkan %s di %s, dapat %s"
#: read-cache.c
msgid "cannot write split index for a sparse index"
-msgstr ""
+msgstr "tidak dapat membuat indeks terpisah untuk indeks jarang"
#: read-cache.c
msgid "failed to convert to a sparse-index"
-msgstr ""
+msgstr "gagal mengubah ke indeks jarang"
#: read-cache.c
#, c-format
msgid "could not stat '%s'"
-msgstr ""
+msgstr "tidak dapat men-stat '%s'"
#: read-cache.c
#, c-format
msgid "unable to open git dir: %s"
-msgstr ""
+msgstr "tidak dapat membuka direktori git: %s"
#: read-cache.c
#, c-format
msgid "unable to unlink: %s"
-msgstr ""
+msgstr "tidak dapat membatal tautan: %s"
#: read-cache.c
#, c-format
msgid "cannot fix permission bits on '%s'"
-msgstr ""
+msgstr "tidak dapat memperbaiki bit perizinan pada '%s'"
#: read-cache.c
#, c-format
msgid "%s: cannot drop to stage #0"
-msgstr ""
+msgstr "%s: tidak dapat menurunkan ke tahap #0"
#: rebase-interactive.c
msgid ""
@@ -22313,9 +22789,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -22326,20 +22805,23 @@ msgstr ""
"e, edit <komit> = gunakan komit, tapi berhenti untuk amandemen\n"
"s, squash <komit> = gunakan komit, tapi lebur ke komit sebelumnya\n"
"f, fixup [-C | -c] <komit> = seperti \"squash\" tapi hanya pertahankan\n"
-" pesan komit sebelumnya, kecuali -C digunakan, dimana\n"
-" hanya pertahankan pesan komit ini; -c sama dengan -C "
-"tapi\n"
-" buka penyuntingx, exec <perintah> = jalankan perintah "
-"(sisa baris) menggunakan cangkang\n"
+" pesan komit sebelumnya; kecuali -C digunakan, dimana\n"
+" hanya pertahankan pesan komit ini; -c sama dengan -C\n"
+" tapi buka penyunting\n"
+"x, exec <perintah> = jalankan perintah (sisa baris) menggunakan cangkang\n"
"b, break = berhenti disini (lanjutkan pendasaran ulang nanti dengan 'git "
"rebase --continue')\n"
"d, drop <komit> = hapus komit\n"
"l, label <label> = tandai HEAD saat ini dengan nama\n"
"t, reset <label> = setel ulang HEAD ke sebuah label\n"
"m, merge [-C <komit> | -c <komit>] <label> [# <satu baris>]\n"
-". buat komit penggabungan dengan pesan komit penggabungan asli\n"
-". (atau satu baris, jika tidak ada komit penggabungan asli yang\n"
-". disebutkan); gunakan -c <komit> untuk menulis ulang pesan komit\n"
+" buat komit penggabungan dengan pesan komit penggabungan asli\n"
+" (atau satu baris, jika tidak ada komit penggabungan asli yang\n"
+" disebutkan); gunakan -c <komit> untuk menulis ulang pesan komit\n"
+"u, update-ref <referensi> = lacak tempat penampung untuk <referensi> yang\n"
+" akan diperbarui ke posisi ini di dalam komit\n"
+" baru. <referensi> diperbarui pada "
+"akhir pendasaran ulang.\n"
"\n"
"Baris diatas dapat disusun ulang; hal itu dieksekusi dari atas ke bawah.\n"
@@ -22431,245 +22913,246 @@ msgstr "%s: 'preserve' digantikan oleh 'merges'"
#: ref-filter.c wt-status.c
msgid "gone"
-msgstr ""
+msgstr "pergi"
#: ref-filter.c
#, c-format
msgid "ahead %d"
-msgstr ""
+msgstr "di depan %d"
#: ref-filter.c
#, c-format
msgid "behind %d"
-msgstr ""
+msgstr "di belakang %d"
#: ref-filter.c
#, c-format
msgid "ahead %d, behind %d"
-msgstr ""
+msgstr "di depan %d, di belakang %d"
#: ref-filter.c
#, c-format
msgid "expected format: %%(color:<color>)"
-msgstr ""
+msgstr "format yang diharapkan: %%(color:<warna>)"
#: ref-filter.c
#, c-format
msgid "unrecognized color: %%(color:%s)"
-msgstr ""
+msgstr "warna tidak dikenal: %%(color:%s)"
#: ref-filter.c
#, c-format
msgid "Integer value expected refname:lstrip=%s"
-msgstr ""
+msgstr "Nilai bilangan bulat diharapkan refname:lstrip=%s"
#: ref-filter.c
#, c-format
msgid "Integer value expected refname:rstrip=%s"
-msgstr ""
+msgstr "Nilai bilangan bulat diharapkan refname:rstrip=%s"
#: ref-filter.c
#, c-format
msgid "unrecognized %%(%s) argument: %s"
-msgstr ""
+msgstr "argumen %%(%s) tidak dikenal: %s"
#: ref-filter.c
#, c-format
msgid "%%(objecttype) does not take arguments"
-msgstr ""
+msgstr "%%(objecttype) tidak mengambil argumen"
#: ref-filter.c
#, c-format
msgid "%%(deltabase) does not take arguments"
-msgstr ""
+msgstr "%%(deltabase) tidak mengambil argumen"
#: ref-filter.c
#, c-format
msgid "%%(body) does not take arguments"
-msgstr ""
+msgstr "%%(body) tidak mengambil argumen"
#: ref-filter.c
#, c-format
msgid "expected %%(trailers:key=<value>)"
-msgstr ""
+msgstr "diharapkan %%(trailers:key=<nilai>)"
#: ref-filter.c
#, c-format
msgid "unknown %%(trailers) argument: %s"
-msgstr ""
+msgstr "argumen %%(trailers) tidak dikenal: %s"
#: ref-filter.c
#, c-format
msgid "positive value expected contents:lines=%s"
-msgstr ""
+msgstr "nilai positif diharapkan contents:lines=%s"
#: ref-filter.c
#, c-format
msgid "positive value expected '%s' in %%(%s)"
-msgstr ""
+msgstr "nilai positif '%s' diharapkan di %%(%s)"
#: ref-filter.c
#, c-format
msgid "unrecognized email option: %s"
-msgstr ""
+msgstr "opsi surel tidak dikenal: %s"
#: ref-filter.c
#, c-format
msgid "expected format: %%(align:<width>,<position>)"
-msgstr ""
+msgstr "format diharapkan: %%(align:<lebar>,<posisi>)"
#: ref-filter.c
#, c-format
msgid "unrecognized position:%s"
-msgstr ""
+msgstr "posisi tidak dikenal: %s"
#: ref-filter.c
#, c-format
msgid "unrecognized width:%s"
-msgstr ""
+msgstr "lebar tidak dikenal: %s"
#: ref-filter.c
#, c-format
msgid "positive width expected with the %%(align) atom"
-msgstr ""
+msgstr "lebar positif diharapkan dengan atom %%(align)"
#: ref-filter.c
#, c-format
msgid "%%(rest) does not take arguments"
-msgstr ""
+msgstr "%%(rest) tidak mengambil argumen"
#: ref-filter.c
#, c-format
msgid "malformed field name: %.*s"
-msgstr ""
+msgstr "nama bidang rusak: %.*s"
#: ref-filter.c
#, c-format
msgid "unknown field name: %.*s"
-msgstr ""
+msgstr "nama bidang tidak dikenal: %.*s"
#: ref-filter.c
#, c-format
msgid ""
"not a git repository, but the field '%.*s' requires access to object data"
msgstr ""
+"bukan sebuah repositori git, tapi bidang '%.*s' butuh akses ke data objek"
#: ref-filter.c
#, c-format
msgid "format: %%(%s) atom used without a %%(%s) atom"
-msgstr ""
+msgstr "format: atom %%(%s) digunakan tanpa sebuah atom %%(%s)"
#: ref-filter.c
#, c-format
msgid "format: %%(then) atom used more than once"
-msgstr ""
+msgstr "format: atom%%(then) digunakan lebih dari sekali"
#: ref-filter.c
#, c-format
msgid "format: %%(then) atom used after %%(else)"
-msgstr ""
+msgstr "format: atom %%(then) digunakan setelah %%(else)"
#: ref-filter.c
#, c-format
msgid "format: %%(else) atom used more than once"
-msgstr ""
+msgstr "format: atom %%(else) digunakan lebih dari sekali"
#: ref-filter.c
#, c-format
msgid "format: %%(end) atom used without corresponding atom"
-msgstr ""
+msgstr "format: atom %%(end) digunakan tanpa atom yang bersesuaian"
#: ref-filter.c
#, c-format
msgid "malformed format string %s"
-msgstr ""
+msgstr "untai format %s rusak"
#: ref-filter.c
#, c-format
msgid "this command reject atom %%(%.*s)"
-msgstr ""
+msgstr "perintah ini menolak atom %%(%.*s)"
#: ref-filter.c
#, c-format
msgid "--format=%.*s cannot be used with --python, --shell, --tcl"
-msgstr ""
+msgstr "--format=%.*s tidak dapat digunakan dengan --python, --shell, --tcl"
#: ref-filter.c
#, c-format
msgid "(no branch, rebasing %s)"
-msgstr ""
+msgstr "(tanpa cabang, mendasarkan ulang %s)"
#: ref-filter.c
#, c-format
msgid "(no branch, rebasing detached HEAD %s)"
-msgstr ""
+msgstr "(tanpa cabang, mendasarkan ulang HEAD tercopot %s)"
#: ref-filter.c
#, c-format
msgid "(no branch, bisect started on %s)"
-msgstr ""
+msgstr "(tanpa cabang, pembagian dua dimulai pada %s)"
#: ref-filter.c
#, c-format
msgid "(HEAD detached at %s)"
-msgstr ""
+msgstr "(HEAD tercopot pada %s)"
#: ref-filter.c
#, c-format
msgid "(HEAD detached from %s)"
-msgstr ""
+msgstr "(HEAD tercopot dari %s)"
#: ref-filter.c
msgid "(no branch)"
-msgstr ""
+msgstr "(tanpa cabang)"
#: ref-filter.c
#, c-format
msgid "missing object %s for %s"
-msgstr ""
+msgstr "objek %s hilang untuk %s"
#: ref-filter.c
#, c-format
msgid "parse_object_buffer failed on %s for %s"
-msgstr ""
+msgstr "parse_object_buffer gagal pada %s untuk %s"
#: ref-filter.c
#, c-format
msgid "malformed object at '%s'"
-msgstr ""
+msgstr "objek rusak pada '%s'"
#: ref-filter.c
#, c-format
msgid "ignoring ref with broken name %s"
-msgstr ""
+msgstr "mengabaikan referensi dengan nama rusak %s"
#: ref-filter.c refs.c
#, c-format
msgid "ignoring broken ref %s"
-msgstr ""
+msgstr "mengabaikan referensi rusak %s"
#: ref-filter.c
#, c-format
msgid "format: %%(end) atom missing"
-msgstr ""
+msgstr "format: atom %%(end) hilang"
#: ref-filter.c
#, c-format
msgid "malformed object name %s"
-msgstr ""
+msgstr "nama objek rusak %s"
#: ref-filter.c
#, c-format
msgid "option `%s' must point to a commit"
-msgstr ""
+msgstr "opsi `%s' harus menunjuk pada sebuah komit"
#: ref-filter.h
msgid "key"
-msgstr ""
+msgstr "kunci"
#: ref-filter.h
msgid "field name to sort on"
-msgstr ""
+msgstr "nama bidang untuk diurutkan"
#: reflog.c
#, c-format
@@ -22799,139 +23282,150 @@ msgstr "spek referensi tidak valid '%s'"
#: remote-curl.c
#, c-format
msgid "invalid quoting in push-option value: '%s'"
-msgstr ""
+msgstr "kuotasi tidak valid dalam nilai push-option: '%s'"
#: remote-curl.c
#, c-format
msgid "%sinfo/refs not valid: is this a git repository?"
-msgstr ""
+msgstr "%sinfo/refs tidak valid: apakah ini sebuah repositori git?"
#: remote-curl.c
msgid "invalid server response; expected service, got flush packet"
msgstr ""
+"tanggapan peladen tidak valid; mengharapkan layanan, dapat bilasan paket"
#: remote-curl.c
#, c-format
msgid "invalid server response; got '%s'"
-msgstr ""
+msgstr "tanggapan peladen tidak valid; dapat '%s'"
#: remote-curl.c
#, c-format
msgid "repository '%s' not found"
-msgstr ""
+msgstr "repositori '%s' tidak ditemukan"
#: remote-curl.c
#, c-format
msgid "Authentication failed for '%s'"
-msgstr ""
+msgstr "Autentikasi gagal untuk '%s'"
#: remote-curl.c
#, c-format
msgid "unable to access '%s' with http.pinnedPubkey configuration: %s"
-msgstr ""
+msgstr "tidak dapat mengakses '%s' dengan konfigurasi http.pinnedPubkey: %s"
#: remote-curl.c
#, c-format
msgid "unable to access '%s': %s"
-msgstr ""
+msgstr "tidak dapat mengakses '%s': %s"
#: remote-curl.c
#, c-format
msgid "redirecting to %s"
-msgstr ""
+msgstr "mengalihkan ke %s"
#: remote-curl.c
msgid "shouldn't have EOF when not gentle on EOF"
-msgstr ""
+msgstr "seharusnya tidak punya EOF ketika tidak lembut pada EOF"
#: remote-curl.c
msgid "remote server sent unexpected response end packet"
-msgstr ""
+msgstr "peladen remote mengirim paket ujung tanggapan yang tak diharapkan"
#: remote-curl.c
msgid "unable to rewind rpc post data - try increasing http.postBuffer"
msgstr ""
+"tidak dapat memutar ulang data post rpc - coba menaikkan http.postBuffer"
#: remote-curl.c
#, c-format
msgid "remote-curl: bad line length character: %.4s"
-msgstr ""
+msgstr "remote-curl: karakter panjang baris jelek : %.4s"
#: remote-curl.c
msgid "remote-curl: unexpected response end packet"
-msgstr ""
+msgstr "remote-curl: paket ujung tanggapan tidak diharapkan"
#: remote-curl.c
#, c-format
msgid "RPC failed; %s"
-msgstr ""
+msgstr "RPC gagal; %s"
#: remote-curl.c
msgid "cannot handle pushes this big"
-msgstr ""
+msgstr "tidak dapat menangani dorongan sebesar ini"
#: remote-curl.c
#, c-format
msgid "cannot deflate request; zlib deflate error %d"
-msgstr ""
+msgstr "tidak dapat mengempiskan permintaan; kesalahan mengempiskan zlib %d"
#: remote-curl.c
#, c-format
msgid "cannot deflate request; zlib end error %d"
-msgstr ""
+msgstr "tidak dapat mengempiskan permintaan; kesalahan ujung zlib %d"
#: remote-curl.c
#, c-format
msgid "%d bytes of length header were received"
-msgstr ""
+msgstr "%d bita dari kepala panjang diterima"
#: remote-curl.c
#, c-format
msgid "%d bytes of body are still expected"
-msgstr ""
+msgstr "%d bita badan masih diharapkan"
#: remote-curl.c
msgid "dumb http transport does not support shallow capabilities"
-msgstr ""
+msgstr "transportasi http bodoh tidak mendukung kemampuan dangkal"
#: remote-curl.c
msgid "fetch failed."
-msgstr ""
+msgstr "pengambilan gagal."
#: remote-curl.c
msgid "cannot fetch by sha1 over smart http"
-msgstr ""
+msgstr "tidak dapat mengambil oleh sha1 melalui http pintar"
#: remote-curl.c
#, c-format
msgid "protocol error: expected sha/ref, got '%s'"
-msgstr ""
+msgstr "kesalahan protokol: sha/referensi diharapkan, dapat '%s'"
#: remote-curl.c
#, c-format
msgid "http transport does not support %s"
-msgstr ""
+msgstr "transportasi http tidak mendukung %s"
+
+#: remote-curl.c
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "kesalahan protokol: '<url> <jalur>' diharapkan, spasi hilang"
+
+#: remote-curl.c
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "gagal mengunduh berkas pada URL '%s'"
#: remote-curl.c
msgid "git-http-push failed"
-msgstr ""
+msgstr "git-http-push gagal"
#: remote-curl.c
msgid "remote-curl: usage: git remote-curl <remote> [<url>]"
-msgstr ""
+msgstr "remote-curl: penggunaan: git remote-curl <remote> [<url>]"
#: remote-curl.c
msgid "remote-curl: error reading command stream from git"
-msgstr ""
+msgstr "remote-curl: kesalahan membaca arus perintah dari git"
#: remote-curl.c
msgid "remote-curl: fetch attempted without a local repo"
-msgstr ""
+msgstr "remote-curl: pengambilan dicoba tanpa repositori lokal"
#: remote-curl.c
#, c-format
msgid "remote-curl: unknown command '%s' from git"
-msgstr ""
+msgstr "remote-curl: perintah tidak dikenal '%s' dari git"
#: remote.c
#, c-format
@@ -23176,7 +23670,9 @@ msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural ""
"Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
msgstr[0] ""
+"Cabang Anda di belakang '%s' oleh %d komit, dan bisa di maju-cepatkan.\n"
msgstr[1] ""
+"Cabang Anda di belakan '%s' oleh %d komit, dan bisa di maju-cepatkan.\n"
#: remote.c
msgid " (use \"git pull\" to update your local branch)\n"
@@ -23214,17 +23710,17 @@ msgstr "tidak dapat mencopot satu komponen dari url '%s'"
#: replace-object.c
#, c-format
msgid "bad replace ref name: %s"
-msgstr ""
+msgstr "nama referensi pengganti jelek: %s"
#: replace-object.c
#, c-format
msgid "duplicate replace ref: %s"
-msgstr ""
+msgstr "referensi pengganti duplikat: %s"
#: replace-object.c
#, c-format
msgid "replace depth too high for object %s"
-msgstr ""
+msgstr "kedalaman penggantian terlalu tinggi untuk objek %s"
#: rerere.c
msgid "corrupt MERGE_RR"
@@ -23311,6 +23807,8 @@ msgstr "tidak dapat membuka direktori rr-cache"
#: rerere.h
msgid "update the index with reused conflict resolution if possible"
msgstr ""
+"perbarui indeks dengan resolusi konflik yang digunakan kembali bila "
+"memungkinkan"
#: reset.c
msgid "could not determine HEAD revision"
@@ -23322,6 +23820,16 @@ msgid "failed to find tree of %s"
msgstr "gagal menemukan pohon %s"
#: revision.c
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo merekam `%s` yang dimana hilang"
+
+#: revision.c
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "tidak dapat mendapatkan komit untuk argumen jalur leluhur '%s'"
+
+#: revision.c
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<berkas pak> tidak didukung lagi"
@@ -23345,7 +23853,222 @@ msgstr "-L belum mendukung format diff selain -p dan -s"
#: run-command.c
#, c-format
msgid "cannot create async thread: %s"
+msgstr "tidak dapat membuat utas async: %s"
+
+#: scalar.c worktree.c
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' tidak ada"
+
+#: scalar.c
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "tidak dapat berganti ke '%s'"
+
+#: scalar.c
+msgid "need a working directory"
+msgstr "butuh sebuah direktori kerja"
+
+#: scalar.c
+msgid "Scalar enlistments require a worktree"
+msgstr "Pendaftaran scalar membutuhkan pohon kerja"
+
+#: scalar.c
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "tidak dapat menyetel %s=%s"
+
+#: scalar.c
+msgid "could not configure log.excludeDecoration"
+msgstr "tidak dapat menyetel log.excludeDecoration"
+
+#: scalar.c
+msgid "could not add enlistment"
+msgstr "tidak dapat menambah pendaftaran"
+
+#: scalar.c
+msgid "could not set recommended config"
+msgstr "tidak dapat menyetel konfigurasi yang direkomendasikan"
+
+#: scalar.c
+msgid "could not turn on maintenance"
+msgstr "tidak dapat mengaktifkan pemeliharaan"
+
+#: scalar.c
+msgid "could not start the FSMonitor daemon"
+msgstr "tidak dapat menjalankan daemon FSMonitor"
+
+#: scalar.c
+msgid "could not turn off maintenance"
+msgstr "tidak dapat menonaktifkan pemeliharaan"
+
+#: scalar.c
+msgid "could not remove enlistment"
+msgstr "tidak dapat menghapus pendaftaran"
+
+#: scalar.c
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "HEAD remote bukan sebuah cabang: '%.*s'"
+
+#: scalar.c
+msgid "failed to get default branch name from remote; using local default"
msgstr ""
+"gagal mendapatkan nama cabang asali dari remote; menggunakan asali lokal"
+
+#: scalar.c
+msgid "failed to get default branch name"
+msgstr "gagal mendapatkan nama cabang asali"
+
+#: scalar.c
+msgid "failed to unregister repository"
+msgstr "gagal menghapus pendaftaran repositori"
+
+#: scalar.c
+msgid "failed to stop the FSMonitor daemon"
+msgstr "gagal menghentikan daemon FSMonitor"
+
+#: scalar.c
+msgid "failed to delete enlistment directory"
+msgstr "gagal menghapus direktori pendaftaran"
+
+#: scalar.c
+msgid "branch to checkout after clone"
+msgstr "cabang untuk dicheckout setelah kloning"
+
+#: scalar.c
+msgid "when cloning, create full working directory"
+msgstr "ketika kloning, buat direktori kerja penuh"
+
+#: scalar.c
+msgid "only download metadata for the branch that will be checked out"
+msgstr "hanya unduh metadata untuk cabang yang akan dicheckout"
+
+#: scalar.c
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<options>] [--] <repositori> [<direktori>]"
+
+#: scalar.c
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "tidak dapat menyimpulkan nama pohon kerja dari '%s'"
+
+#: scalar.c
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "direktori '%s' sudah ada"
+
+#: scalar.c
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "gagal mendapatkan cabang asali untuk '%s'"
+
+#: scalar.c
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "tidak dapat menyetel remote di '%s'"
+
+#: scalar.c
+#, c-format
+msgid "could not configure '%s'"
+msgstr "tidak dapat menyetel '%s'"
+
+#: scalar.c
+msgid "partial clone failed; attempting full clone"
+msgstr "kloning parsial gagal; mencoba kloning penuh"
+
+#: scalar.c
+msgid "could not configure for full clone"
+msgstr "tidak dapat menyetel untuk kloning penuh"
+
+#: scalar.c
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<pendaftaran>]"
+
+#: scalar.c
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` tidak mengambil argumen"
+
+#: scalar.c
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<pendaftaran>]"
+
+#: scalar.c
+msgid "reconfigure all registered enlistments"
+msgstr "konfigurasi ulang semua pendaftaran yang terdaftar"
+
+#: scalar.c
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <pendaftaran>]"
+
+#: scalar.c
+msgid "--all or <enlistment>, but not both"
+msgstr "--all atau <pendaftaran>, tetapi bukan kedua-duanya"
+
+#: scalar.c
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "repositori git pergi di '%s'"
+
+#: scalar.c
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <tugas> [<pendaftaran>]\n"
+"Tugas:\n"
+
+#: scalar.c
+#, c-format
+msgid "no such task: '%s'"
+msgstr "tidak ada tugas: '%s'"
+
+#: scalar.c
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<pendaftaran>]"
+
+#: scalar.c
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <pendaftaran>"
+
+#: scalar.c
+msgid "refusing to delete current working directory"
+msgstr "menolak menghapus direktori kerja saat ini"
+
+#: scalar.c
+msgid "include Git version"
+msgstr "masukkan versi Git"
+
+#: scalar.c
+msgid "include Git's build options"
+msgstr "masukkan opsi bangun Git"
+
+#: scalar.c
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+#: scalar.c
+msgid "-C requires a <directory>"
+msgstr "-C butuh sebuah <direktori>"
+
+#: scalar.c
+#, c-format
+msgid "could not change to '%s'"
+msgstr "tidak dapat berganti ke '%s'"
+
+#: scalar.c
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c butuh argumen <kunci>=<nilai>"
+
+#: scalar.c
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <direktori>] [-c <kunci>=<nilai>] perintah [<opsi>]\n"
+"\n"
+"Perintah:\n"
#: send-pack.c
msgid "unexpected flush packet while reading remote unpack status"
@@ -23493,11 +24216,6 @@ msgstr "perubahan lokal Anda akan ditimpa oleh %s."
msgid "commit your changes or stash them to proceed."
msgstr "komit perubahan Anda atau stase untuk melanjutkan."
-#: sequencer.c
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: maju-cepat"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -24090,6 +24808,30 @@ msgid "merge: Unable to write new index file"
msgstr "merge: Tidak dapat menulis berkas indeks baru"
#: sequencer.c
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "sepertinya proses 'rebase' lainnya berjalan; '%s.lock' sudah ada"
+
+#: sequencer.c
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Referensi berikut diperbarui dengan %s:\n"
+"%s"
+
+#: sequencer.c
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Gagal memperbarui referensi berikut dengan %s:\n"
+"%s"
+
+#: sequencer.c
msgid "Cannot autostash"
msgstr "Tidak dapat menstase otomatis"
@@ -24293,6 +25035,11 @@ msgstr "tidak dapat melewatkan perintah pick yang tidak perlu"
msgid "the script was already rearranged."
msgstr "skrip sudah ditata ulang."
+#: sequencer.c
+#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "berkas update-refs pada '%s' tidak valid"
+
#: setup.c
#, c-format
msgid "'%s' is outside repository at '%s'"
@@ -24438,18 +25185,24 @@ msgstr ""
#: setup.c
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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 ""
-"repositori tidak aman ('%s' dimiliki oleh orang lain)\n"
-"Untuk menambahkan pengecualian untuk direktori ini, panggil:\n"
+"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')"
+
+#: setup.c
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -24890,16 +25643,16 @@ msgstr "tidak dapat menamai ulang berkas sementara ke %s"
#: transport-helper.c
msgid "full write to remote helper failed"
-msgstr ""
+msgstr "gagal menulis penuh ke pembantu remote"
#: transport-helper.c
#, c-format
msgid "unable to find remote helper for '%s'"
-msgstr ""
+msgstr "tidak dapat menemukan pembantu remote untuk '%s'"
#: transport-helper.c
msgid "can't dup helper output fd"
-msgstr ""
+msgstr "tidak dapat menipu penjelas berkas keluaran pembantu"
#: transport-helper.c
#, c-format
@@ -24907,120 +25660,122 @@ msgid ""
"unknown mandatory capability %s; this remote helper probably needs newer "
"version of Git"
msgstr ""
+"kemampuan wajib %s tidak dikenal; pembantu remote ini sepertinya butuh versi "
+"Git baru"
#: transport-helper.c
msgid "this remote helper should implement refspec capability"
-msgstr ""
+msgstr "pembantu remote ini seharusnya menerapkan kemampuan spek referensi"
#: transport-helper.c
#, c-format
msgid "%s unexpectedly said: '%s'"
-msgstr ""
+msgstr "%s tiba-tiba berkata: '%s'"
#: transport-helper.c
#, c-format
msgid "%s also locked %s"
-msgstr ""
+msgstr "%s juga mengunci %s"
#: transport-helper.c
msgid "couldn't run fast-import"
-msgstr ""
+msgstr "tidak dapat menjalankan fast-import"
#: transport-helper.c
msgid "error while running fast-import"
-msgstr ""
+msgstr "kesalahan ketika menjalankan fast-import"
#: transport-helper.c
#, c-format
msgid "could not read ref %s"
-msgstr ""
+msgstr "tidak dapat membaca referensi %s"
#: transport-helper.c
#, c-format
msgid "unknown response to connect: %s"
-msgstr ""
+msgstr "tanggapan terhadap hubungan tidak dikenal: %s"
#: transport-helper.c
msgid "setting remote service path not supported by protocol"
-msgstr ""
+msgstr "menyetel jalur layanan remote tidak didukung oleh protokol"
#: transport-helper.c
msgid "invalid remote service path"
-msgstr ""
+msgstr "jalur layanan remote tidak valid"
#: transport-helper.c transport.c
msgid "operation not supported by protocol"
-msgstr ""
+msgstr "operasi tidak didukung oleh protokol"
#: transport-helper.c
#, c-format
msgid "can't connect to subservice %s"
-msgstr ""
+msgstr "tidak dapat menghubungkan ke sublayanan %s"
#: transport-helper.c transport.c
msgid "--negotiate-only requires protocol v2"
-msgstr ""
+msgstr "--negotiate-only butuh protokol v2"
#: transport-helper.c
msgid "'option' without a matching 'ok/error' directive"
-msgstr ""
+msgstr "'option' tanpa pengarah 'ok/error' yang bersesuaian"
#: transport-helper.c
#, c-format
msgid "expected ok/error, helper said '%s'"
-msgstr ""
+msgstr "ok/error diharapkan, pembantu berkata '%s'"
#: transport-helper.c
#, c-format
msgid "helper reported unexpected status of %s"
-msgstr ""
+msgstr "pembantu melaporkan status %s yang tak diharapkan"
#: transport-helper.c
#, c-format
msgid "helper %s does not support dry-run"
-msgstr ""
+msgstr "pembantu %s tidak mendukung latihan"
#: transport-helper.c
#, c-format
msgid "helper %s does not support --signed"
-msgstr ""
+msgstr "pembantu %s tidak mendukung --signed"
#: transport-helper.c
#, c-format
msgid "helper %s does not support --signed=if-asked"
-msgstr ""
+msgstr "pembantu %s tidak mendukung --signed=if-asked"
#: transport-helper.c
#, c-format
msgid "helper %s does not support --atomic"
-msgstr ""
+msgstr "pembantu %s tidak mendukung --atomic"
#: transport-helper.c
#, c-format
msgid "helper %s does not support --%s"
-msgstr ""
+msgstr "pembantu %s tidak mendukung --%s"
#: transport-helper.c
#, c-format
msgid "helper %s does not support 'push-option'"
-msgstr ""
+msgstr "pembantu %s tidak mendukung 'push-option'"
#: transport-helper.c
msgid "remote-helper doesn't support push; refspec needed"
-msgstr ""
+msgstr "pembantu tidak mendukung pendorongan; spek referensi diperlukan"
#: transport-helper.c
#, c-format
msgid "helper %s does not support 'force'"
-msgstr ""
+msgstr "pembantu %s tidak mendukung 'force'"
#: transport-helper.c
msgid "couldn't run fast-export"
-msgstr ""
+msgstr "tidak dapat menjalankan fast-export"
#: transport-helper.c
msgid "error while running fast-export"
-msgstr ""
+msgstr "kesalahan ketika menjalankan fast-export"
#: transport-helper.c
#, c-format
@@ -25028,104 +25783,106 @@ msgid ""
"No refs in common and none specified; doing nothing.\n"
"Perhaps you should specify a branch.\n"
msgstr ""
+"Tidak ada kesamaan referensi dan tidak ada yang disebutkan; tidak melakuan\n"
+"apa-apa. Mungkin Anda perlu menyebutkan sebuah cabang.\n"
#: transport-helper.c
#, c-format
msgid "unsupported object format '%s'"
-msgstr ""
+msgstr "format objek tidak didukung '%s'"
#: transport-helper.c
#, c-format
msgid "malformed response in ref list: %s"
-msgstr ""
+msgstr "jawaban rusak di daftar referensi: %s"
#: transport-helper.c
#, c-format
msgid "read(%s) failed"
-msgstr ""
+msgstr "read(%s) gagal"
#: transport-helper.c
#, c-format
msgid "write(%s) failed"
-msgstr ""
+msgstr "write(%s) gagal"
#: transport-helper.c
#, c-format
msgid "%s thread failed"
-msgstr ""
+msgstr "utas %s gagal"
#: transport-helper.c
#, c-format
msgid "%s thread failed to join: %s"
-msgstr ""
+msgstr "utas %s gagal bergabung: %s"
#: transport-helper.c
#, c-format
msgid "can't start thread for copying data: %s"
-msgstr ""
+msgstr "tidak dapat memulai utas untuk menyalin data: %s"
#: transport-helper.c
#, c-format
msgid "%s process failed to wait"
-msgstr ""
+msgstr "proses %s gagal menunggu"
#: transport-helper.c
#, c-format
msgid "%s process failed"
-msgstr ""
+msgstr "proses %s gagal"
#: transport-helper.c
msgid "can't start thread for copying data"
-msgstr ""
+msgstr "tidak dapat memulai utas untuk menyalin data"
#: transport.c
#, c-format
msgid "Would set upstream of '%s' to '%s' of '%s'\n"
-msgstr ""
+msgstr "Akan menyetel hulu '%s' ke '%s' dari '%s'\n"
#: transport.c
#, c-format
msgid "could not read bundle '%s'"
-msgstr ""
+msgstr "tidak dapat membaca bundel '%s'"
#: transport.c
#, c-format
msgid "transport: invalid depth option '%s'"
-msgstr ""
+msgstr "transport: opsi kedalaman '%s' tidak valid"
#: transport.c
msgid "see protocol.version in 'git help config' for more details"
-msgstr ""
+msgstr "lihat protocol.version di 'git help config' untuk lebih lengkapnya"
#: transport.c
msgid "server options require protocol version 2 or later"
-msgstr ""
+msgstr "opsi peladen butuh protokol versi 2 atau lebih baru"
#: transport.c
msgid "server does not support wait-for-done"
-msgstr ""
+msgstr "peladen tidak mendukung wait-for-done"
#: transport.c
msgid "could not parse transport.color.* config"
-msgstr ""
+msgstr "tidak dapat menguraikan konfigurasi transport.color.*"
#: transport.c
msgid "support for protocol v2 not implemented yet"
-msgstr ""
+msgstr "dukungan untuk protokol v2 belum diterapkan"
#: transport.c
#, c-format
msgid "unknown value for config '%s': %s"
-msgstr ""
+msgstr "nilai tidak dikenal untuk konfigurasi '%s': %s"
#: transport.c
#, c-format
msgid "transport '%s' not allowed"
-msgstr ""
+msgstr "transportasi '%s' tidak diperbolehkan"
#: transport.c
msgid "git-over-rsync is no longer supported"
-msgstr ""
+msgstr "git-over-rsync tidak lagi didukung"
#: transport.c
#, c-format
@@ -25133,6 +25890,8 @@ msgid ""
"The following submodule paths contain changes that can\n"
"not be found on any remote:\n"
msgstr ""
+"Jalur submodul berikut berisi perubahan yang tidak dapat ditemukan\n"
+"pada remote apapun:\n"
#: transport.c
#, c-format
@@ -25149,30 +25908,40 @@ msgid ""
"to push them to a remote.\n"
"\n"
msgstr ""
+"\n"
+"Mohon coba\n"
+"\n"
+"\tgit push --recurse-submodules=on-demand\n"
+"\n"
+"atau berganti direktori ke jalur dan gunakan\n"
+"\n"
+"\tgit push\n"
+"untuk mendorong ke remote.\n"
+"\n"
#: transport.c
msgid "Aborting."
-msgstr ""
+msgstr "Membatalkan."
#: transport.c
msgid "failed to push all needed submodules"
-msgstr ""
+msgstr "gagal mendorong semua submodul yang dibutuhkan"
#: tree-walk.c
msgid "too-short tree object"
-msgstr ""
+msgstr "objek pohon terlalu pendek"
#: tree-walk.c
msgid "malformed mode in tree entry"
-msgstr ""
+msgstr "mode salah di entri pohon"
#: tree-walk.c
msgid "empty filename in tree entry"
-msgstr ""
+msgstr "nama berkas kosong di entri pohon"
#: tree-walk.c
msgid "too-short tree file"
-msgstr ""
+msgstr "berkas pohon terlalu pendek"
#: unpack-trees.c
#, c-format
@@ -25180,6 +25949,8 @@ msgid ""
"Your local changes to the following files would be overwritten by checkout:\n"
"%%sPlease commit your changes or stash them before you switch branches."
msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh checkout:\n"
+"%%sMohon komit atau stase sebelum Anda mengganti cabang."
#: unpack-trees.c
#, c-format
@@ -25187,6 +25958,8 @@ msgid ""
"Your local changes to the following files would be overwritten by checkout:\n"
"%%s"
msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh checkout:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25194,6 +25967,9 @@ msgid ""
"Your local changes to the following files would be overwritten by merge:\n"
"%%sPlease commit your changes or stash them before you merge."
msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh "
+"penggabungan:\n"
+"%%sMohon komit atau stase sebelum Anda gabungkan."
#: unpack-trees.c
#, c-format
@@ -25201,6 +25977,9 @@ msgid ""
"Your local changes to the following files would be overwritten by merge:\n"
"%%s"
msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh "
+"penggabungan:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25208,6 +25987,8 @@ msgid ""
"Your local changes to the following files would be overwritten by %s:\n"
"%%sPlease commit your changes or stash them before you %s."
msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh %s:\n"
+"%%sMohon komit atau stase sebelum Anda %s."
#: unpack-trees.c
#, c-format
@@ -25215,6 +25996,8 @@ msgid ""
"Your local changes to the following files would be overwritten by %s:\n"
"%%s"
msgstr ""
+"Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh %s:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25222,6 +26005,9 @@ msgid ""
"Updating the following directories would lose untracked files in them:\n"
"%s"
msgstr ""
+"Memperbarui direktori berikut akan menghilangkan berkas tak terlacak di "
+"dalam:\n"
+"%s"
#: unpack-trees.c
#, c-format
@@ -25229,6 +26015,8 @@ msgid ""
"Refusing to remove the current working directory:\n"
"%s"
msgstr ""
+"Menolak menghapus direktori kerja saat ini:\n"
+"%s"
#: unpack-trees.c
#, c-format
@@ -25236,6 +26024,8 @@ msgid ""
"The following untracked working tree files would be removed by checkout:\n"
"%%sPlease move or remove them before you switch branches."
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan dihapus oleh checkout:\n"
+"%%sMohon pindahkan atau hapus sebelum Anda berganti cabang."
#: unpack-trees.c
#, c-format
@@ -25243,6 +26033,8 @@ msgid ""
"The following untracked working tree files would be removed by checkout:\n"
"%%s"
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan dihapus oleh checkout:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25250,6 +26042,8 @@ msgid ""
"The following untracked working tree files would be removed by merge:\n"
"%%sPlease move or remove them before you merge."
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan dihapus oleh penggabungan:\n"
+"%%sMohon pindahkan atau hapus sebelum Anda gabungkan."
#: unpack-trees.c
#, c-format
@@ -25257,6 +26051,8 @@ msgid ""
"The following untracked working tree files would be removed by merge:\n"
"%%s"
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan dihapus oleh penggabungan:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25264,6 +26060,8 @@ msgid ""
"The following untracked working tree files would be removed by %s:\n"
"%%sPlease move or remove them before you %s."
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan dihapus oleh %s:\n"
+"%%sMohon pindahkan atau hapus sebelum Anda %s."
#: unpack-trees.c
#, c-format
@@ -25271,6 +26069,8 @@ msgid ""
"The following untracked working tree files would be removed by %s:\n"
"%%s"
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan dihapus oleh %s:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25279,6 +26079,8 @@ msgid ""
"checkout:\n"
"%%sPlease move or remove them before you switch branches."
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan ditimpa oleh checkout:\n"
+"%%sMohon pindahkan atau hapus sebelum Anda berganti cabang."
#: unpack-trees.c
#, c-format
@@ -25287,6 +26089,8 @@ msgid ""
"checkout:\n"
"%%s"
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan ditimpa oleh checkout:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25294,6 +26098,8 @@ msgid ""
"The following untracked working tree files would be overwritten by merge:\n"
"%%sPlease move or remove them before you merge."
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan ditimpa oleh penggabungan:\n"
+"%%sMohon pindahkan atau hapus sebelum Anda gabungkan."
#: unpack-trees.c
#, c-format
@@ -25301,6 +26107,8 @@ msgid ""
"The following untracked working tree files would be overwritten by merge:\n"
"%%s"
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan ditimpa oleh penggabungan:\n"
+"%%s"
#: unpack-trees.c
#, c-format
@@ -25308,6 +26116,8 @@ msgid ""
"The following untracked working tree files would be overwritten by %s:\n"
"%%sPlease move or remove them before you %s."
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan ditimpa oleh %s:\n"
+"%%sMohon pindahkan atau hapus sebelum Anda %s."
#: unpack-trees.c
#, c-format
@@ -25315,11 +26125,13 @@ msgid ""
"The following untracked working tree files would be overwritten by %s:\n"
"%%s"
msgstr ""
+"Berkas pohon kerja tak terlacak berikut akan ditimpa oleh %s:\n"
+"%%s"
#: unpack-trees.c
#, c-format
msgid "Entry '%s' overlaps with '%s'. Cannot bind."
-msgstr ""
+msgstr "Entri '%s' tumpang tindih dengan '%s'. Tidak dapat mengikat."
#: unpack-trees.c
#, c-format
@@ -25327,6 +26139,8 @@ msgid ""
"Cannot update submodule:\n"
"%s"
msgstr ""
+"Tidak dapat memperbarui submodul:\n"
+"%s"
#: unpack-trees.c
#, c-format
@@ -25335,6 +26149,8 @@ msgid ""
"patterns:\n"
"%s"
msgstr ""
+"Jalur berikut tidak diperbarui dan dibiarkan walaupun merupakan pola tipis:\n"
+"%s"
#: unpack-trees.c
#, c-format
@@ -25342,6 +26158,9 @@ msgid ""
"The following paths are unmerged and were left despite sparse patterns:\n"
"%s"
msgstr ""
+"Jalur berikut tidak digabungkan dan dibiarkan walaupun merupakan pola "
+"tipis:\n"
+"%s"
#: unpack-trees.c
#, c-format
@@ -25350,11 +26169,13 @@ msgid ""
"patterns:\n"
"%s"
msgstr ""
+"Jalur berikut sudah ada dan tidak diperbarui walaupun merupakan pola tipis:\n"
+"%s"
#: unpack-trees.c
#, c-format
msgid "Aborting\n"
-msgstr ""
+msgstr "Membatalkan\n"
#: unpack-trees.c
#, c-format
@@ -25362,10 +26183,12 @@ msgid ""
"After fixing the above paths, you may want to run `git sparse-checkout "
"reapply`.\n"
msgstr ""
+"Setelah memperbarui jalur tersebut, Anda mungkin ingin menjalankan `git "
+"sparse-checkout reapply`.\n"
#: unpack-trees.c
msgid "Updating files"
-msgstr ""
+msgstr "Memperbarui berkas"
#: unpack-trees.c
msgid ""
@@ -25373,15 +26196,18 @@ msgid ""
"on a case-insensitive filesystem) and only one from the same\n"
"colliding group is in the working tree:\n"
msgstr ""
+"jalur berikut bertabrakan (misalnya jalur peka huruf besar-kecil pada\n"
+"sistem berkas tidak peka huruf besar-kecil) dan hanya satu dari grup\n"
+"bertabrakan yang sama yang berada di dalam pohon kerja:\n"
#: unpack-trees.c
msgid "Updating index flags"
-msgstr ""
+msgstr "Memperbarui bendera indeks"
#: unpack-trees.c
#, c-format
msgid "worktree and untracked commit have duplicate entries: %s"
-msgstr ""
+msgstr "pohon kerja dan komit tak terlacak punya entri duplikat: %s"
#: upload-pack.c
msgid "expected flush after fetch arguments"
@@ -25389,36 +26215,52 @@ msgstr "bilasan diharapkan setelah argumen pengambilan"
#: urlmatch.c
msgid "invalid URL scheme name or missing '://' suffix"
-msgstr ""
+msgstr "skema URL tidak valid atau kehilangan akhiran '://'"
#: urlmatch.c
#, c-format
msgid "invalid %XX escape sequence"
-msgstr ""
+msgstr "urutan pelarian %XX tidak valid"
#: urlmatch.c
msgid "missing host and scheme is not 'file:'"
-msgstr ""
+msgstr "kehilangan host dan skema bukan 'file:'"
#: urlmatch.c
msgid "a 'file:' URL may not have a port number"
-msgstr ""
+msgstr "sebuah URL 'file:' tidak boleh punya nomor port"
#: urlmatch.c
msgid "invalid characters in host name"
-msgstr ""
+msgstr "karakter tidak valid pada nama host"
#: urlmatch.c
msgid "invalid port number"
-msgstr ""
+msgstr "nomor port tidak valid"
#: urlmatch.c
msgid "invalid '..' path segment"
-msgstr ""
+msgstr "segmen jalur '..' tidak valid"
+
+#: usage.c
+msgid "usage: "
+msgstr "penggunaan: "
+
+#: usage.c
+msgid "fatal: "
+msgstr "fatal: "
+
+#: usage.c
+msgid "error: "
+msgstr "kesalahan: "
+
+#: usage.c
+msgid "warning: "
+msgstr "peringatan: "
#: walker.c
msgid "Fetching objects"
-msgstr ""
+msgstr "Mengambil objek"
#: worktree.c
#, c-format
@@ -25524,7 +26366,7 @@ msgstr "gagal menyetel setelan extensions.worktreeConfig"
#: wrapper.c
#, c-format
msgid "could not setenv '%s'"
-msgstr ""
+msgstr "tidak dapat menyetel lingkungan (setenv) '%s'"
#: wrapper.c
#, c-format
@@ -25534,16 +26376,16 @@ msgstr "tidak dapat membuat '%s'"
#: wrapper.c
#, c-format
msgid "could not open '%s' for reading and writing"
-msgstr ""
+msgstr "tidak dapat membuka '%s' untuk membaca dan menulis"
#: wrapper.c
#, c-format
msgid "unable to access '%s'"
-msgstr ""
+msgstr "tidak dapat mengakses '%s'"
#: wrapper.c
msgid "unable to get current working directory"
-msgstr ""
+msgstr "tidak dapat mendapatkan direktori kerja saat ini"
#: wt-status.c
msgid "Unmerged paths:"
@@ -25960,11 +26802,11 @@ msgstr "sedang mendasarkan ulang; ke "
#: wt-status.c
msgid "HEAD detached at "
-msgstr ""
+msgstr "HEAD terlepas pada "
#: wt-status.c
msgid "HEAD detached from "
-msgstr ""
+msgstr "HEAD terlepas dari "
#: wt-status.c
msgid "Not currently on any branch."
@@ -26093,84 +26935,86 @@ msgstr "juga indeks Anda berisi perubahan yang belum dikomit."
msgid "cannot %s: Your index contains uncommitted changes."
msgstr "tidak dapat %s: indeks Anda berisi perubahan yang belum dikomit."
-#: git-merge-octopus.sh
+#: git-merge-octopus.sh git-merge-resolve.sh
msgid ""
"Error: Your local changes to the following files would be overwritten by "
"merge"
msgstr ""
+"Kesalahan: Perubahan lokal Anda terhadap berkas berikut akan ditimpa oleh "
+"penggabungan"
#: git-merge-octopus.sh
msgid "Automated merge did not work."
-msgstr ""
+msgstr "Penggabungan otomatis tidak bekerja."
#: git-merge-octopus.sh
msgid "Should not be doing an octopus."
-msgstr ""
+msgstr "Seharusnya tidak melakukan gurita."
#: git-merge-octopus.sh
#, sh-format
msgid "Unable to find common commit with $pretty_name"
-msgstr ""
+msgstr "Tidak dapat menemukan komit umum dengan $pretty_name"
#: git-merge-octopus.sh
#, sh-format
msgid "Already up to date with $pretty_name"
-msgstr ""
+msgstr "Sudah terbaru dengan $pretty_name"
#: git-merge-octopus.sh
#, sh-format
msgid "Fast-forwarding to: $pretty_name"
-msgstr ""
+msgstr "Memaju-cepat ke: $pretty_name"
#: git-merge-octopus.sh
#, sh-format
msgid "Trying simple merge with $pretty_name"
-msgstr ""
+msgstr "Mencoba penggabungan sederhana dengan $pretty_name"
#: git-merge-octopus.sh
msgid "Simple merge did not work, trying automatic merge."
-msgstr ""
+msgstr "Penggabungan sederhana tidak berkerja, mencoba penggabungan otomatis."
#: git-sh-setup.sh
#, sh-format
msgid "usage: $dashless $USAGE"
-msgstr ""
+msgstr "penggunaan: $dashless $USAGE"
#: git-sh-setup.sh
#, sh-format
msgid "Cannot chdir to $cdup, the toplevel of the working tree"
-msgstr ""
+msgstr "tidak dapat berganti direktori ke $cdup, level atas dari pohon kerja"
#: git-sh-setup.sh
#, sh-format
msgid "fatal: $program_name cannot be used without a working tree."
-msgstr ""
+msgstr "fatal: $program_name tidak dapat digunakan tanpa pohon kerja."
#: git-sh-setup.sh
msgid "Cannot rewrite branches: You have unstaged changes."
-msgstr ""
+msgstr "Tidak dapat menulis ulang cabang: Anda punya perubahan tak tergelar."
#: git-sh-setup.sh
#, sh-format
msgid "Cannot $action: You have unstaged changes."
-msgstr ""
+msgstr "Tidak dapat $action: Anda punya perubahan tak tergelar."
#: git-sh-setup.sh
#, sh-format
msgid "Cannot $action: Your index contains uncommitted changes."
-msgstr ""
+msgstr "Tidak dapat $action: Indeks Anda berisi perubahan tak terkomit."
#: git-sh-setup.sh
msgid "Additionally, your index contains uncommitted changes."
-msgstr ""
+msgstr "Selain itu, indeks Anda berisi perubahan tak terkomit."
#: git-sh-setup.sh
msgid "You need to run this command from the toplevel of the working tree."
-msgstr ""
+msgstr "Anda perlu menjalankan perintah ini dari level atas dari pohon kerja."
#: git-sh-setup.sh
msgid "Unable to determine absolute path of git directory"
-msgstr ""
+msgstr "Tidak dapat menentukan jalur absolut direktori git"
#. TRANSLATORS: you can adjust this to align "git add -i" status menu
#: git-add--interactive.perl
@@ -26329,26 +27173,6 @@ msgid "ignoring unmerged: %s\n"
msgstr ""
#: git-add--interactive.perl
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl
msgid "No other hunks to goto\n"
msgstr ""
diff --git a/po/sv.po b/po/sv.po
index 56db2f1bb19..825142fde7d 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,15 +5,15 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: git 2.37.0\n"
+"Project-Id-Version: git 2.38.0\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-24 21:19+0100\n"
-"PO-Revision-Date: 2022-06-24 21:23+0100\n"
+"POT-Creation-Date: 2022-09-26 06:34+0100\n"
+"PO-Revision-Date: 2022-09-26 06:35+0100\n"
"Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 3.38.0\n"
@@ -409,6 +409,22 @@ msgstr ""
"a - applicera stycket och alla följande i filen\n"
"d - applicera inte stycket eller något av de följande i filen\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "Applicera ändrat läge på arbetskatalogen [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Applicera borttagning på arbetskatalogen [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Applicera tillägg på arbetskatalogen [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Applicera stycket på arbetskatalogen [y,n,q,a,d%s,?]? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -426,10 +442,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "kunde inte tolka styckehuvudet \"%.*s\""
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "kunde inte tolka färgat styckehuvud \"%.*s\""
-
msgid "could not parse diff"
msgstr "kunde inte tolka diff"
@@ -672,7 +684,7 @@ msgid ""
"outside of your sparse-checkout definition, so will not be\n"
"updated in the index:\n"
msgstr ""
-"Följande sökvägar och/eller ökvägsangivelser motsvarar sökvägar\n"
+"Följande sökvägar och/eller sökvägsangivelser motsvarar sökvägar\n"
"utanför din \"sparse-checkout\"-definition, så de kommer inte\n"
"uppdateras i indexet:\n"
@@ -727,6 +739,25 @@ msgstr ""
"advice.detachedHead till false\n"
"\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Följande sökvägar har flyttats ut från din\n"
+"\"sparse-checkout\"-definition, men är inte glesa på grund av\n"
+"lokala ändringar.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"För att korrigera glesheten för dessa sökvägar, gör följande:\n"
+"* Använd \"git add --sparse <sökväg>\" för att uppdatera indexet\n"
+"* Använd \"git sparse-checkout reapply\" för att tillämpa gleshetsreglerna"
+
msgid "cmdline ends with \\"
msgstr "kommandorad avslutas med \\"
@@ -1229,6 +1260,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "filens läge stöds ej: 0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "fel i deflate (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "kunde inte starta filtret \"%s\""
@@ -1248,10 +1283,6 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "sökvägen för lång (%d tecken, SHA1: %s): %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "fel i deflate (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "tidsstämpeln för stor för detta system: %<PRIuMAX>"
@@ -3014,8 +3045,12 @@ msgstr "libc-info:"
msgid "not run from a git repository - no hooks to show\n"
msgstr "körs inte från ett git-arkiv - inga krokar att visa\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <fil>] [-s|--suffix <format>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <fil>] [-s|--suffix <format>] [--"
+"diagnose[=<läge>]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3052,16 +3087,29 @@ msgstr ""
"Se över resten av felrapporten nedan.\n"
"Du kan ta bort rader du inte vill dela.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "ange mål för buggrapporteringsfilen"
+msgid "mode"
+msgstr "läge"
-msgid "specify a strftime format suffix for the filename"
-msgstr "ange ett filändelse i strftime-format"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr ""
+"skapa ett ytterligare zip-arkiv med detaljerad diagnostik (förval är \"stats"
+"\")"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "ange mål för buggrapporteringsfilen/-rna"
+
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "ange filändelse i strftime-format"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "kunde inte skapa inledande kataloger för \"%s\""
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "kunde inte skapa diagnostikarkiven %s"
+
msgid "System Info"
msgstr "Systeminfo"
@@ -3120,10 +3168,6 @@ msgid "Unbundling objects"
msgstr "Packar upp objektbunt"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Okänt underkommando: %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "kan inte läsa objektet %s: \"%s\""
@@ -3201,6 +3245,9 @@ msgstr "visa objektstorlek"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "låter -s och -t att fungera med trasiga/sönderskrivna objekt"
+msgid "use mail map file"
+msgstr "använd e-postmappningsfil"
+
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr "Buntobjekt ombeds på standard in (eller --batch-all-objects)"
@@ -3210,6 +3257,9 @@ msgstr "visa komplett innehåll för <objekt> eller <rev>"
msgid "like --batch, but don't emit <contents>"
msgstr "som --batch, men mata inte ut <innehåll>"
+msgid "stdin is NUL-terminated"
+msgstr "standard in är NUL-terminerad"
+
msgid "read commands from stdin"
msgstr "läs kommandon från standard in"
@@ -4078,6 +4128,12 @@ msgstr "klonade undermoduler kommer använda sin fjärrspårningsgren"
msgid "initialize sparse-checkout file to include only files at root"
msgstr "initiera sparse-checkout-filen till att bara ta med filer i roten"
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "en URI för att hämta buntar innan de hämtas från ursprungsfjärr"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: Kan inte skapa suppleant för \"%s\": %s\n"
@@ -4137,9 +4193,8 @@ msgstr "kan inte uppdatera %s"
msgid "failed to initialize sparse-checkout"
msgstr "misslyckades initiera sparse-checkout"
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr ""
-"HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
+msgstr "HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut"
msgid "unable to checkout working tree"
msgstr "kunde inte checka ut arbetskatalogen"
@@ -4163,6 +4218,13 @@ msgstr "Du måste ange ett arkiv att klona."
msgid "options '%s' and '%s %s' cannot be used together"
msgstr "flaggorna \"%s\" och \"%s %s\" kan inte användas samtidigt"
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri är inkompatibelt med --depth, --shallow-since och --shallow-"
+"exclude"
+
#, c-format
msgid "repository '%s' does not exist"
msgstr "arkivet \"%s\" finns inte"
@@ -4234,6 +4296,13 @@ msgstr "--local ignoreras"
msgid "cannot clone from filtered bundle"
msgstr "kan inte klona från filtrerad bunt"
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "misslyckades initiera arkivet, hoppar över bunt-URI"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "misslyckades hämta objekt från bunt-URI \"%s\""
+
msgid "remote transport reported error"
msgstr "fjärrtransport rapporterade fel"
@@ -4348,10 +4417,6 @@ msgstr "använd som mest en av --reachable, --stdin-commits och --stdin-packs"
msgid "Collecting commits from input"
msgstr "Hämtar incheckningar från indata"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "okänt underkommando: %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -4705,9 +4770,6 @@ msgstr "visa status i långt format (standard)"
msgid "terminate entries with NUL"
msgstr "terminera poster med NUL"
-msgid "mode"
-msgstr "läge"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr "visa ospårade filer, valfria lägen: all, normal, no. (Standard: all)"
@@ -5296,6 +5358,22 @@ msgstr "Inga namn hittades, kan inte beskriva något."
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "flaggorna \"%s\" och incheckning-igter kan inte användas samtidigt"
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <sökväg>] [-s|--suffix <format>] [--"
+"mode=<läge>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "ange mål för diagnostikarkivet"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr "ange ett filändelse i strftime-format"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "ange vilket innehåll diagnostikarkivet ska ha"
+
msgid "--merge-base only works with two commits"
msgstr "--merge-base fungerar endast med två incheckningar"
@@ -5668,11 +5746,8 @@ msgstr "[àjour]"
msgid "[rejected]"
msgstr "[refuserad]"
-msgid "can't fetch in current branch"
-msgstr "kan inte hämta i aktuell gren"
-
-msgid "checked out in another worktree"
-msgstr "utcheckat i en annan arbetskatalog"
+msgid "can't fetch into checked-out branch"
+msgstr "kan inte hämta i utcheckad gren"
msgid "[tag update]"
msgstr "[uppdaterad tagg]"
@@ -6110,6 +6185,10 @@ msgstr "%s: ogiltig sha1-pekare i cacheträd"
msgid "non-tree in cache-tree"
msgstr "icke-träd i cacheträd"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s: ogiltig sha1-pekare i resolve-undo"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<flaggor>] [<objekt>...]"
@@ -6441,13 +6520,16 @@ msgstr "misslyckades starta schtasks"
msgid "failed to run 'crontab -l'; your system might not support 'cron'"
msgstr ""
-"kunde inte köra \"crontab -l\"; ditt system kanske inte stöder \"cron\""
+"misslyckades köra \"crontab -l\"; ditt system kanske inte stöder \"cron\""
-msgid "failed to run 'crontab'; your system might not support 'cron'"
-msgstr "kunde inte köra \"crontab\"; ditt system kanske inte stöder \"cron\""
+msgid "failed to create crontab temporary file"
+msgstr "misslyckades skapa temporär crontab-fil"
+
+msgid "failed to open temporary file"
+msgstr "misslyckades öppna temporär fil"
-msgid "failed to open stdin of 'crontab'"
-msgstr "misslyckades öppna standard in för \"crontab\""
+msgid "failed to run 'crontab'; your system might not support 'cron'"
+msgstr "misslyckades köra \"crontab\"; ditt system kanske inte stöder \"cron\""
msgid "'crontab' died"
msgstr "\"crontab\" dog"
@@ -6495,10 +6577,6 @@ msgstr "misslyckades lägga till arkiv till global konfiguration"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <underkommando> [<flaggor>]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "felaktigt underkommando: %s"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<flaggor>] [-e] <mönster> [<rev>...] [[--] <sökväg>...]"
@@ -6669,6 +6747,9 @@ msgstr "visa träffade filer i filbläddraren"
msgid "allow calling of grep(1) (ignored by this build)"
msgstr "tillåt anropa grep(1) (ignoreras av detta bygge)"
+msgid "maximum number of results per file"
+msgstr "maximalt antal resultat per fil"
+
msgid "no pattern given"
msgstr "inget mönster angavs"
@@ -6755,11 +6836,17 @@ msgstr "visa kommandobeskrivning"
msgid "print list of useful guides"
msgstr "lista användbara vägledningar"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr "lista arkiv-, kommando- och filgränssnitt tänkta för användare"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr "lista filformat, protokoll och andra utvecklargränssnitt"
+
msgid "print all configuration variable names"
msgstr "visa namn på alla konfigurationsvariabler"
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<kommando>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<kommando>|<doc>]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -7230,8 +7317,8 @@ msgstr "undertryck diff-utdata"
msgid "show source"
msgstr "visa källkod"
-msgid "use mail map file"
-msgstr "använd e-postmappningsfil"
+msgid "clear all previously-defined decoration filters"
+msgstr "rensa alla tidigare definierade dekorationsfilter"
msgid "only decorate refs that match <pattern>"
msgstr "dekorera endast referenser som motsvarar <mönster>"
@@ -7482,6 +7569,9 @@ msgstr "visa ändringar mot <refspec> i omslagsbrev eller ensam patch"
msgid "percentage by which creation is weighted"
msgstr "procent som skapelse vägs med"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "visa From: i kroppen även om samma som i e-posthuvudet"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "ogiltig ident-rad: %s"
@@ -7540,6 +7630,18 @@ msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr "Kunde inte hitta en spårad fjärrgren, ange <uppström> manuellt.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "felaktigt ls-files-format: elementet \"%s\" börjar inte med \"(\""
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "felaktigt ls-files-format: elementet \"%s\" slutar inte med \")\""
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "felaktigt ls-files-format: %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<flaggor>] [<fil>...]"
@@ -7625,6 +7727,13 @@ msgid "show sparse directories in the presence of a sparse index"
msgstr "visa glesa kataloger när et glest index existerar"
msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format kan inte användas med -s, -o, -k, -t, --resolve-undo, --"
+"deduplicate, --eol"
+
+msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url]\n"
" [--symref] [<repository> [<refs>...]]"
@@ -7842,6 +7951,39 @@ msgstr "kunde inte bestämma referensen \"%s\""
msgid "Merging %s with %s\n"
msgstr "Slår ihop %s med %s\n"
+msgid "not something we can merge"
+msgstr "inte något vi kan slå ihop"
+
+msgid "refusing to merge unrelated histories"
+msgstr "vägrar slå samman orelaterad historik"
+
+msgid "failure to merge"
+msgstr "misslyckades slå ihop"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<flaggor>] <gren1> <gren2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <baseträd> <gren1> <gren2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "gör en riktig sammanslagning istället för en enkel sammanslagning"
+
+msgid "do a trivial merge only"
+msgstr "gör endast en enkel sammanslagning"
+
+msgid "also show informational/conflict messages"
+msgstr "visa även informations-/konfliktmeddelanden"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "lista filnamn utan lägen/oid/köer"
+
+msgid "allow merging unrelated histories"
+msgstr "tillåt sammanslagning av orelaterade historier"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge är inkompatibelt med andra flaggor"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<flaggor>] [<incheckning>...]"
@@ -7922,9 +8064,6 @@ msgstr "--abort men lämna index och arbetskatalog ensamma"
msgid "continue the current in-progress merge"
msgstr "fortsätt den pågående sammanslagningen"
-msgid "allow merging unrelated histories"
-msgstr "tillåt sammanslagning av orelaterade historier"
-
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "förbigå pre-merge-commit- och commit-msg-krokar"
@@ -8045,9 +8184,6 @@ msgstr "kunde inte stänga \"%s\""
msgid "not something we can merge in %s: %s"
msgstr "inte något vi kan slå ihop med %s: %s"
-msgid "not something we can merge"
-msgstr "inte något vi kan slå ihop"
-
msgid "--abort expects no arguments"
msgstr "--abort tar inga argument"
@@ -8096,14 +8232,20 @@ msgstr "%s - inte något vi kan slå ihop"
msgid "Can merge only exactly one commit into empty head"
msgstr "Kan endast slå ihop en enda incheckning i ett tomt huvud"
-msgid "refusing to merge unrelated histories"
-msgstr "vägrar slå samman orelaterad historik"
-
#, c-format
msgid "Updating %s..%s\n"
msgstr "Uppdaterar %s..%s\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Dina lokala ändringar av följande filer skulle skrivas över av "
+"sammanslagning:\n"
+" %s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Försöker riktigt enkel sammanslagning i indexet...\n"
@@ -8137,6 +8279,10 @@ msgstr ""
"Automatisk sammanslagning lyckades; stoppar före incheckning som önskat\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "När färdig, applicerade sparade ändringar med \"git stash pop\"\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
msgstr "varning: taggindata godkänns inte av fsck: %s"
@@ -8253,6 +8399,9 @@ msgstr "Kontrollerar namnbyte av \"%s\" till \"%s\"\n"
msgid "bad source"
msgstr "felaktig källa"
+msgid "destination exists"
+msgstr "destinationen finns"
+
msgid "can not move directory into itself"
msgstr "kan inte flytta katalog till sig själv"
@@ -8268,9 +8417,6 @@ msgstr "inte versionshanterad"
msgid "conflicted"
msgstr "i konflikt"
-msgid "destination exists"
-msgstr "destinationen finns"
-
#, c-format
msgid "overwriting '%s'"
msgstr "skriver över \"%s\""
@@ -8284,6 +8430,9 @@ msgstr "flera källor för samma mål"
msgid "destination directory does not exist"
msgstr "destinationskatalogen finns inte"
+msgid "destination exists in the index"
+msgstr "destinationen finns i indexet"
+
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s, källa=%s, mål=%s"
@@ -8320,7 +8469,6 @@ msgstr "ignorera referenser som motsvarar <mönster>"
msgid "list all commits reachable from all refs"
msgstr "lista alla incheckningar som kan nås alla referenser"
-#| msgid "deprecated: use annotate-stdin instead"
msgid "deprecated: use --annotate-stdin instead"
msgstr "avråds: använd --annotate-stdin istället"
@@ -8643,8 +8791,8 @@ msgid "use notes from <notes-ref>"
msgstr "använd anteckningar från <anteckningsref>"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "okänt underkommando: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "okänt underkommando: \"%s\""
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -9528,11 +9676,16 @@ msgid "only emit output related to the second range"
msgstr "visa endast utdata för det andra intervallet"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "inte en revision: \"%s\""
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "inte ett incheckningsintervall: \"%s\""
-msgid "single arg format must be symmetric range"
-msgstr "ensamt argument måste vara symmetriskt intervall"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "inte ett symmetriskt intervall: \"%s\""
msgid "need two commit ranges"
msgstr "behöver två incheckningsintervall"
@@ -9805,6 +9958,9 @@ msgstr "behåller incheckningar som är tomma från början"
msgid "move commits that begin with squash!/fixup! under -i"
msgstr "flytta incheckningar som börjar med squash!/fixup! under -i"
+msgid "update branches that point to commits that are being rebased"
+msgstr "uppdatera grenar som pekar på incheckningar som ombaseras"
+
msgid "add exec lines after each commit of the editable list"
msgstr "lägg till exec-rader efter varje incheckning i den redigerbara listan"
@@ -10325,6 +10481,9 @@ msgstr " ny (nästa hämtning sparar i remotes/%s)"
msgid " tracked"
msgstr " spårad"
+msgid " skipped"
+msgstr " överhoppad"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " förlegad (använd \"git remote prune\" för att ta bort)"
@@ -10990,6 +11149,11 @@ msgstr "Kunde inte skriva ny indexfil."
msgid "unable to get disk usage of %s"
msgstr "kan inte hämta diskanvändning för %s"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr ""
+"felaktigt värde för \"%s\": \"%s\", det enda tillåtna formatet är \"%s\""
+
msgid "rev-list does not support display of notes"
msgstr "rev-list stöder inte visning av anteckningar"
@@ -11015,6 +11179,9 @@ msgstr "för tidigt slut på indata"
msgid "no usage string given before the `--' separator"
msgstr "ingen användningssträng angavs före \"--\"-avdelaren"
+msgid "missing opt-spec before option flags"
+msgstr "saknar flagg-spec före alternativflaggor"
+
msgid "Needed a single revision"
msgstr "Behövde ensam revision"
@@ -11775,6 +11942,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "Förväntade fullt referensnamn, fick %s"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "kunde inte få tag i arkivhandtag för undermodulen \"%s\""
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -11782,12 +11953,6 @@ msgstr ""
"kunde inte slå upp konfigurationen \"%s\". Antar att arkivet är sin eget "
"officiella uppström."
-msgid "alternative anchor for relative paths"
-msgstr "alternativa ankare för relativa sökvägar"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<sökväg>] [<sökväg>...]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "Hittade ingen url för undermodulsökvägen \"%s\" i .gitmodules"
@@ -11820,8 +11985,8 @@ msgstr "dölj utdata från för varje undermodulskommando som startas"
msgid "recurse into nested submodules"
msgstr "rekursera in i nästlade undermoduler"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [--] [<kommando>]"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <kommando>"
#, c-format
msgid "Failed to register url for submodule path '%s'"
@@ -11842,8 +12007,8 @@ msgstr "Misslyckades registrera uppdateringsläge för undermodulsökväg \"%s\"
msgid "suppress output for initializing a submodule"
msgstr "dölj utdata från initiering av undermodul"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<flaggor>] [<sökväg>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<flaggor>] [<sökväg>]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -11870,9 +12035,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quitet] [--cached] [--recursive] [<sökväg>...]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <sökväg>"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submodule)"
@@ -11906,9 +12068,8 @@ msgstr ""
msgid "limit the summary size"
msgstr "begränsa översiktsstorleken"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr ""
-"git submodule--helper summary [<flaggor>] [<incheckning>] [--] [<sökväg>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<flaggor>] [<incheckning>] [--] [<sökväg>]"
msgid "could not fetch a revision for HEAD"
msgstr "kunde inte hämta en version för HEAD"
@@ -11922,18 +12083,14 @@ msgid "failed to register url for submodule path '%s'"
msgstr "misslyckades registrera url för undermodulsökväg \"%s\""
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "misslyckades hämta standardfjärr för undermodulsökväg \"%s\""
-
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "misslyckades uppdatera fjärr för undermodulsökväg \"%s\""
msgid "suppress output of synchronizing submodule url"
msgstr "dölj utdata från synkronisering av undermodul-url"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<sökväg>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<sökväg>]"
#, c-format
msgid ""
@@ -11988,12 +12145,16 @@ msgid ""
"submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
"'--reference-if-able' instead of '--reference'."
msgstr ""
-"En suppleant beräknad från överprojektets suppleant är ogiltig.\n"
+"En suppleant beräknad från huvudprojektets suppleant är ogiltig.\n"
"För att i så fall låta Git klona utan ett suppleant, sätt\n"
"submodule.alternateErrorStrategy till \"info\" eller, likvärdigt, klona\n"
"med \"--reference-if-able\" istället för \"--reference\"."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "kunde inte få tag i arkivhandtag för gitkatalogen \"%s\""
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "undermodulen \"%s\" kan inte lägga till suppleant: %s"
@@ -12021,6 +12182,9 @@ msgstr "katalogen inte tom: \"%s\""
msgid "could not get submodule directory for '%s'"
msgstr "kunde inte få tag i undermodulkatalog för \"%s\""
+msgid "alternative anchor for relative paths"
+msgstr "alternativa ankare för relativa sökvägar"
+
msgid "where the new submodule will be cloned to"
msgstr "var den nya undermodulen ska klonas till"
@@ -12049,10 +12213,6 @@ msgstr ""
"<filterangivelse>] --url <url> --path <sökväg>"
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Ogiltigt uppdateringsläge \"%s\" för undermodulsökväg \"%s\""
-
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr ""
"Ogiltigt uppdateringsläge \"%s\" konfigurerat för undermodulsökväg \"%s\""
@@ -12125,6 +12285,10 @@ msgstr ""
"hämtning av incheckningen misslyckades."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "kunde inte initiera undermodul i sökvägen \"%s\""
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -12133,10 +12297,6 @@ msgstr ""
"huvudprojektet är inte på någon gren"
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "kunde inte få tag i arkivhandtag för undermodulen \"%s\""
-
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "Kan inte hitta aktuell revision i undermodulsökvägen \"%s\""
@@ -12170,11 +12330,14 @@ msgstr "hämta inte nya objekt från fjärrplatsen"
msgid "path into the working tree"
msgstr "sökväg inuti arbetskatalogen"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "sökväg inuti arbetskatalogen, genom nästlade undermodulgränser"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "använd uppdateringsstrategin \"checkout\" (utcheckning; förval)"
+
+msgid "use the 'merge' update strategy"
+msgstr "använd uppdateringsstrategin \"merge\" (sammanslagning)"
-msgid "rebase, merge, checkout or none"
-msgstr "rebase, merge, checkout eller none"
+msgid "use the 'rebase' update strategy"
+msgstr "använd uppdateringsstrategin \"rebase\" (ombasering)"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr "skapa en grund klon trunkerad till angivet antal revisioner"
@@ -12188,6 +12351,9 @@ msgstr "om den första klonen ska följa rekommendation för grund kloning"
msgid "don't print cloning progress"
msgstr "skriv inte klonförlopp"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "förhindra kloning till icke-tom katalog, implicerar --init"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12199,14 +12365,11 @@ msgstr ""
"[no-]recommend-shallow] [--reference <arkiv>] [--recursive] [--[no-]single-"
"branch] [--] [<sökväg>...]"
-msgid "bad value for update parameter"
-msgstr "felaktigt värde för parametern update"
-
msgid "recurse into submodules"
msgstr "rekursera ner i undermoduler"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<flaggor>] [<sökväg>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<flaggor>] [<sökväg>...]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr "se om det är säkert att skriva till .gitmodules-filen"
@@ -12226,8 +12389,8 @@ msgstr "se till att .gitmodules finns i arbetskatalogen"
msgid "suppress output for setting url of a submodule"
msgstr "dölj utdata från inställning av url för undermodul"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <sökväg> <nyurl>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <sökväg> <nyurl>"
msgid "set the default tracking branch to master"
msgstr "välj master som förvald spårad gren"
@@ -12235,13 +12398,11 @@ msgstr "välj master som förvald spårad gren"
msgid "set the default tracking branch"
msgstr "välj förvald spårad gren"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <sökväg>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <sökväg>"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <gren> <sökväg>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <gren> <sökväg>"
msgid "--branch or --default required"
msgstr "--branch eller --default krävs"
@@ -12339,8 +12500,8 @@ msgstr ""
"sätter undermodulens namn till den angivna strängen istället för att använda "
"sökvägen"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<flaggor>] [--] <arkiv> [<sökväg>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<flaggor>] [--] <arkiv> [<sökväg>]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr "Relativ sökväg kan endast användas från arbetskatalogens toppnivå"
@@ -12546,6 +12707,16 @@ msgstr "Uppdaterad tagg \"%s\" (var %s)\n"
msgid "pack exceeds maximum allowed size"
msgstr "paket är större än tillåten maximal storlek"
+msgid "failed to write object in stream"
+msgstr "misslyckades skriva objekt i ström"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "inflate returnerade (%d)"
+
+msgid "invalid blob object from stream"
+msgstr "ogiltigt blob-objekt från ström"
+
msgid "Unpacking objects"
msgstr "Packar upp objekt"
@@ -13061,6 +13232,27 @@ msgstr "visa trädobjekt för underkatalogen <prefix>"
msgid "only useful for debugging"
msgstr "endast användbart vid felsökning"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch stöds inte på denna plattform"
+
+msgid "failed to create temporary file"
+msgstr "misslyckades skapa temporär fil"
+
+msgid "insufficient capabilities"
+msgstr "otillräckliga kapabiliteter"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "kunde inte hämta bunt från URI:en \"%s\""
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "filen på URI \"%s\" är inte en bunt"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "misslyckades packa upp bunten från URI:en \"%s\""
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
msgstr "okänd hashningsalgoritm för bunt: \"%s\""
@@ -13263,6 +13455,9 @@ msgstr "En riktigt enkel server för Git-arkiv"
msgid "Give an object a human readable name based on an available ref"
msgstr "Ge ett objekt användarläsbara namn baserade på en tillgänglig referens"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Skapa ett zip-arkiv med diagnostisk information"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr "Visa ändringar mellan incheckningar, med arbetskatalogen, osv"
@@ -13390,8 +13585,8 @@ msgstr "Kör en sammanslagning för filer som behöver det"
msgid "The standard helper program to use with git-merge-index"
msgstr "Förvalt hjälpprogram att använda tillsammans med git-merge-index"
-msgid "Show three-way merge without touching index"
-msgstr "Visa trevägssammanslagning utan att röra indexet"
+msgid "Perform merge without touching index or working tree"
+msgstr "Utför sammanslagning utan att röra index eller arbetskatalog"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr "Kör verktyg för lösning av sammanslagningskonflikter"
@@ -13585,6 +13780,9 @@ msgstr "Bekräfta packade Git-arkivfiler"
msgid "Check the GPG signature of tags"
msgstr "Kontrollera GPG-signaturer i taggar"
+msgid "Display version information about Git"
+msgstr "Visa versionsinformation om Git"
+
msgid "Show logs with difference each commit introduces"
msgstr "Visa loggar med differenser varje incheckning introducerar"
@@ -13618,6 +13816,24 @@ msgstr "Ett användbart minsta uppsättning kommandon för vardags-Git"
msgid "Frequently asked questions about using Git"
msgstr "Ofta ställda frågor om att använda Git"
+msgid "The bundle file format"
+msgstr "Filformat för bunt"
+
+msgid "Chunk-based file formats"
+msgstr "Styckebaserade filformat"
+
+msgid "Git commit graph format"
+msgstr "Format för Git-incheckningsgraf"
+
+msgid "Git index format"
+msgstr "Format för Git-index"
+
+msgid "Git pack format"
+msgstr "Format för Git-paket"
+
+msgid "Git cryptographic signature formats"
+msgstr "Format för kryptografiska signaturer i Git"
+
msgid "A Git Glossary"
msgstr "En Git-ordlista"
@@ -13639,6 +13855,21 @@ msgstr "Ange egenskaper för undermoduler"
msgid "Git namespaces"
msgstr "Git-namnrymder"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Kapabiliteter i protokoll v0 och v1"
+
+msgid "Things common to various protocols"
+msgstr "Vad är gemensamt i de olika protokollen"
+
+msgid "Git HTTP-based protocols"
+msgstr "HTTP-baserade Git-protokoll"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Hur paket överförs på linjen"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Gits linjeprotokoll, version 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Hjälpprogram för att interagera med fjärrarkiv"
@@ -13663,6 +13894,9 @@ msgstr "Git-webbgränssnitt (webbframända för Git-arkiv)"
msgid "An overview of recommended workflows with Git"
msgstr "Översikt över rekommenderade arbetsflöden med Git"
+msgid "A tool for managing large Git repositories"
+msgstr "Verktyg för att hantera stora Git-arkiv"
+
msgid "commit-graph file is too small"
msgstr "incheckningsgraffilen %s är för liten"
@@ -13910,6 +14144,14 @@ msgid "no libc information available\n"
msgstr "ingen libc-information tillgänglig\n"
#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "kunde inte ta reda på ledigt diskutrymme för \"%s\""
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "kunde inte hämta info för \"%s\""
+
+#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
msgstr "[GLE %ld] hälsotråden kunde inte öppna \"%ls\""
@@ -13964,6 +14206,14 @@ msgid "could not read directory changes [GLE %ld]"
msgstr "kunde inte läsa katalogändringar [GLE %ld]"
#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] kunde inte öppna \"%ls\" för läsning"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] kunde inte hämta protokollinformation för \"%ls\""
+
+#, c-format
msgid "failed to copy SID (%ld)"
msgstr "misslyckades kopiera SID (%ld)"
@@ -14507,181 +14757,6 @@ msgid "failed to close rev-list's stdin"
msgstr "kunde inte stänga rev-list:s standard in"
#, c-format
-msgid "'%s' does not exist"
-msgstr "\"%s\" finns inte"
-
-msgid "need a working directory"
-msgstr "behöver en arbetskatalog"
-
-msgid "could not find enlistment root"
-msgstr "kunde inte hitta enrolleringsroten"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "kunde inte växla till \"%s\""
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "kunde inte ställa in %s=%s"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "kunde inte ställa in log.excludeDecoration"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "Scalar-enrolleringar kräver en arbetskatalog"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "kunde inte öppna katalogen \"%s\""
-
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "hoppar över \"%s\", som varken är en fil eller en katalog"
-
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "kunde inte ta reda på ledigt diskutrymme för \"%s\""
-
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "kunde inte hämta info för \"%s\""
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "HEAD hos fjärren är inte en gren: \"%.*s\""
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-"misslyckades hämta namn på standardgren för fjärr; använder lokalt förval"
-
-msgid "failed to get default branch name"
-msgstr "misslyckades hämta namn på standardgren"
-
-msgid "failed to unregister repository"
-msgstr "misslyckades avregistrera arkivet"
-
-msgid "failed to delete enlistment directory"
-msgstr "misslyckades ta bort enrolleringskatalogen"
-
-msgid "branch to checkout after clone"
-msgstr "gren att checka ut efter kloning"
-
-msgid "when cloning, create full working directory"
-msgstr "skapa komplett arbetskatalog vid kloning"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "hämta endast metadata för grenen som skall checkas ut"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<flaggor>] [--] <arkiv> [<kat>]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "Kan inte härleda arbetsträdsnamn från \"%s\""
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "katalogen \"%s\" finns redan"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "misslyckades hämta standardgren för \"%s\""
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "kunde inte ställa in fjärr i \"%s\""
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "kunde inte ställa in \"%s\""
-
-msgid "partial clone failed; attempting full clone"
-msgstr "delvis klon misslyckades; försöker med fullständig klon"
-
-msgid "could not configure for full clone"
-msgstr "kunde inte ställa in för komplett klon"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<enrollering>]"
-
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "kunde inte skapa katalog för \"%s\""
-
-msgid "could not duplicate stdout"
-msgstr "kunde inte duplicera standard ut"
-
-msgid "failed to write archive"
-msgstr "misslyckades skriva arkiv"
-
-msgid "`scalar list` does not take arguments"
-msgstr "\"scalar list\" tar inte argument"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<enrollering>]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "konfigurera alla registrerade enrolleringar på nytt"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <enrollering>]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "--all eller <enrollering>, men inte bägge"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "git-arkiv försvunnet i \"%s\""
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <uppgift> [<enrollering>]\n"
-"Uppgifter:\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "okänd uppgift: \"%s\""
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<enrollering>]"
-
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <enrollering>"
-
-msgid "refusing to delete current working directory"
-msgstr "vägrar ta bort aktuell arbetskatalog"
-
-msgid "include Git version"
-msgstr "ta med Git-version"
-
-msgid "include Git's build options"
-msgstr "ta med Gits byggflaggor"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "-C kräver en <katalog>"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "kunde inte byta till \"%s\""
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c kräver ett argument på formen <nyckel>=<värde>"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <katalog>] [-c <nyckel>=<värde>] <kommando> [<flaggor>]\n"
-"\n"
-"Kommandon:\n"
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "felaktig crlf_action %d"
@@ -14884,6 +14959,32 @@ msgstr "ö-regex från konfiguration har för många fångstgrupper (max=%d)"
msgid "Marked %d islands, done.\n"
msgstr "Markerade %d öar, klar.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "ogiltigt värde för --%s: \"%s\""
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "kunde inte arkivera saknad katalog \"%s\""
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "kunde inte öppna katalogen \"%s\""
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "hoppar över \"%s\", som varken är en fil eller en katalog"
+
+msgid "could not duplicate stdout"
+msgstr "kunde inte duplicera standard ut"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "kunde inte lägga till katalogen \"%s\" till arkiveraren"
+
+msgid "failed to write archive"
+msgstr "misslyckades skriva arkiv"
+
msgid "--merge-base does not work with ranges"
msgstr "--merge-base fungerar inte med intervall"
@@ -15490,6 +15591,9 @@ msgstr "git fetch-pack: förväntade ACK/NAK, fick \"%s\""
msgid "unable to write to remote"
msgstr "kunde inte skriva till fjärren"
+msgid "Server supports filter"
+msgstr "Servern stöder filter"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "ogiltig \"shallow\"-rad: %s"
@@ -15600,9 +15704,6 @@ msgstr "servern stöder inte algoritmen \"%s\""
msgid "Server does not support shallow requests"
msgstr "Servern stöder inte grunda förfrågningar"
-msgid "Server supports filter"
-msgstr "Servern stöder filter"
-
msgid "unable to write request to remote"
msgstr "kunde inte skriva anrop till fjärren"
@@ -15948,6 +16049,12 @@ msgstr "Lågnivåkommandon / synka arkiv"
msgid "Low-level Commands / Internal Helpers"
msgstr "Lågnivåkommandon / interna hjälpare"
+msgid "User-facing repository, command and file interfaces"
+msgstr "Arkiv-, kommando- och filgränssnitt tänkta för användare"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Filformat, protokoll och andra gränssnitt tänkta för utvecklare"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "git-kommandon tillgängliga i \"%s\""
@@ -15961,6 +16068,12 @@ msgstr "Dessa vanliga Git-kommandon används i olika situationer:"
msgid "The Git concept guides are:"
msgstr "Vägledningar för Git-koncept:"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Arkiv-, kommando- och filgränssnitt tänkta för användare:"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Filformat, protokoll och andra utvecklargränssnitt:"
+
msgid "External commands"
msgstr "Externa kommandon"
@@ -16044,10 +16157,6 @@ msgstr ""
"Du kan inaktivera varningen med \"git config advice.ignoredHook false\"."
#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "Kunde inte starta kroken \"%s\"\n"
-
-#, 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')"
@@ -16230,19 +16339,14 @@ msgid "quoted CRLF detected"
msgstr "citerad CRLF upptäcktes"
#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Dina lokala ändringar av följande filer skulle skrivas över av "
-"sammanslagning:\n"
-" %s"
-
-#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "Misslyckades slå ihop undermodulen %s (ej utcheckad)"
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "Misslyckades slå ihop undermodulen %s (ingen sammanslagningsbas)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
msgstr "Misslyckades slå ihop undermodulen %s (incheckningar saknas)"
@@ -16262,27 +16366,8 @@ msgstr "Misslyckades slå ihop undermodulen %s"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-"Misslyckades slå ihop undermodulen %s, men en möjlig lösning finns:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Om detta är riktigt lägger du bara till det i indexet, till\n"
-"exempel så här:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"vilket godtar lösningen.\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
+msgstr "Misslyckades slå ihop undermodulen %s, men en möjlig lösning finns: %s"
#, c-format
msgid ""
@@ -16360,7 +16445,7 @@ msgid ""
"in %s, suggesting it should perhaps be moved to %s."
msgstr ""
"KONFLIKT (filplacering): %s lade till %s inuti en katalog som bytte namn i "
-"%s, föreslår att den bör flyttas till%s."
+"%s, föreslår att den bör flyttas till %s."
#, c-format
msgid ""
@@ -16443,13 +16528,45 @@ msgstr ""
"KONFLIKT (ändra/radera): %s raderad i %s och ändrad i %s. Versionen %s av %s "
"lämnad i trädet."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
+#, c-format
+msgid ""
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
+msgstr ""
+" - gå till undermodulen (%s), och slå antingen ihop incheckningen %s\n"
+" eller uppdatera till en befintlig incheckning som slagit ihop "
+"ändringarna\n"
+
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
msgstr ""
-"Observera: %s är inte à jour och i vägen för att checka ut version i "
-"konflikt; gammal upplaga har nytt namn %s"
+"Rekursiv sammanslaning med undermoduler stöder för närvarande endast enkla "
+"fall.\n"
+"Du måste hantera sammanslagning av undermoduler i konflikt manuellt.\n"
+"Detta kan göras genom att utföra följande steg:\n"
+"%s - kom tillbaka till huvudprojektet och kör:\n"
+"\n"
+" git add %s\n"
+"\n"
+" för att registrera sammanslagningen över eller uppdatera\n"
+" - lös eventuella andra konflikter i huvudprojektet\n"
+" - checka in det slutförda indexet i huvudprojektet\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -16525,6 +16642,22 @@ msgid "Found a possible merge resolution for the submodule:\n"
msgstr "Hittade en möjlig lösning av sammanslagning för undermodulen:\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Om detta är riktigt lägger du bara till det i indexet, till\n"
+"exempel så här:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"vilket godtar lösningen.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr ""
"Misslyckades slå ihop undermodulen %s (flera sammanslagningar hittades)"
@@ -17038,6 +17171,22 @@ msgid "confused by unstable object source data for %s"
msgstr "förvirrad av instabil objektkälldata för %s"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "skriv strömobjektet %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "kan inte utföra \"deflate\" på nytt strömobjekt (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "\"deflateend\" på strömobjektet misslyckades (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "kunde inte skapa katalogen %s"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "kan inte läsa objekt för %s"
@@ -17263,6 +17412,56 @@ msgstr "kunde inte tolka objektet: %s"
msgid "hash mismatch %s"
msgstr "hashvärde stämmer inte överens %s"
+msgid "trying to write commit not in index"
+msgstr "försöker skriva incheckning som inte finns i indexet"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "misslyckade läsa in bitkarteindex (trasigt?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "trasigt bitkarteindex (för litet)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "trasigt bitkarteindex (felaktigt huvud)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "versionen \"%d\" i bitkarteindexfilen stöds inte"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+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)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "duplicerad post i bitkarteindex: \"%s\""
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "trasig ewah-bitkarta: avhugget huvud för post %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "trasig ewah-bitkarta: incheckningsindex %u utanför intervall"
+
+msgid "corrupted bitmap pack index"
+msgstr "trasigt bitkarte-packindex"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "ogiltigt XOR-offset i bitkarte-packindex"
+
+msgid "cannot fstat bitmap file"
+msgstr "kan inte utföra \"fstat\" på bitkartefil"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "ignorerar extra bitkartefil: %s"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "checksumman stämmer inte i MIDX och bitkarta"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "flerpaketsbitkarta saknar nödvändigt omvänt index"
@@ -17274,9 +17473,58 @@ msgstr "kunde inte öppna paketfilen %s"
msgid "preferred pack (%s) is invalid"
msgstr "föredragen paketfil (%s) är ogiltig"
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "trasig bitkarteuppslagstabell: trippelposition utanför indexet"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr "trasig bitkarteuppslagstabell: xor-kedja överskrider postantalet"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr ""
+"trasig bitkarteuppslagstabell: incheckningsindexet %u utanför intervallet"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr ""
+"trasig ewah-bitkarta: avhugget huvud för bitkarta för incheckning \"%s\""
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "objektet \"%s\" hittades inte i typbitkartor"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "objektet \"%s\" har inte en unik typ"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "objektet \"%s\": riktig typ \"%s\", förväntade \"%s\""
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "objekt saknas i bitkarta: %s"
+
+msgid "failed to load bitmap indexes"
+msgstr "misslyckade läsa in bitkarteindex"
+
+msgid "you must specify exactly one commit to test"
+msgstr "du måste ange exakt en incheckning att testa"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "incheckningen \"%s\" har inte en indexerad bitkarta"
+
+msgid "mismatch in bitmap results"
+msgstr "bitkarteresultat stämmer inte överens"
+
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "kunde inte hitta %s i paketet %s på offset %<PRIuMAX>"
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "kunde inte hitta \"%s\" i paketet \"%s\" på offset %<PRIuMAX>"
+
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "kan inte hämta diskanvändning för \"%s\""
#, c-format
msgid "mtimes file %s is too small"
@@ -17401,6 +17649,9 @@ msgstr "menade du \"--%s\" (med två bindestreck)?"
msgid "alias of --%s"
msgstr "alias för --%s"
+msgid "need a subcommand"
+msgstr "behöver ett underkommando"
+
#, c-format
msgid "unknown option `%s'"
msgstr "okänd flagga \"%s\""
@@ -17834,9 +18085,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -17864,9 +18118,12 @@ msgstr ""
"l, label <etikett> = ge aktuellt HEAD ett namn\n"
"t, reset <etikett> = återställ HEAD till en etikett\n"
"m, merge [-C <incheckning> | -c <incheckning>] <etikett> [# <enrads>]\n"
-". skapa en sammanslagning med ursprungligt meddelande (eller\n"
-". enrads, om inget incheckningsmeddelande angavs); använd\n"
-". -c <incheckning> för att skriva om meddelandet.\n"
+" skapa en sammanslagning med ursprungligt meddelande (eller\n"
+" enrads, om inget incheckningsmeddelande angavs); använd\n"
+" -c <incheckning> för att skriva om meddelandet.\n"
+"u, update-ref <ref> = spåra en platshållare för <ref> att uppdatera\n"
+" till denna position bland nya inchecknngar.\n"
+" <ref> uppdateras i slutet av ombaseringen.\n"
"\n"
"Du kan byta ordning på raderna; de utförs uppifrån och ned.\n"
@@ -18335,6 +18592,13 @@ msgstr "protokollfel: förväntade sha/ref, fick \"%s\""
msgid "http transport does not support %s"
msgstr "http-transporten stöder inte %s"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "protokollfel: förväntade \"<url> <sökväg>\", saknar blanksteg"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "misslyckades hämta filen på URL \"%s\""
+
msgid "git-http-push failed"
msgstr "git-http-push misslyckades"
@@ -18672,6 +18936,14 @@ msgstr "kunde inte bestämma HEAD-revision"
msgid "failed to find tree of %s"
msgstr "kunde inte hitta trädet för %s."
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo registrerar \"%s\" som saknas"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "kunde inte hämta incheckning för \"ancestry-path\"-argumentet %s"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<paketfil> stöds inte längre"
@@ -18692,6 +18964,173 @@ msgstr "-L stöder ännu inte andra diff-format än -p och -s"
msgid "cannot create async thread: %s"
msgstr "kan inte skapa asynkron tråd: %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "\"%s\" finns inte"
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "kunde inte växla till \"%s\""
+
+msgid "need a working directory"
+msgstr "behöver en arbetskatalog"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "Scalar-enrolleringar kräver en arbetskatalog"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "kunde inte ställa in %s=%s"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "kunde inte ställa in log.excludeDecoration"
+
+msgid "could not add enlistment"
+msgstr "kunde inte lägga till enrollering"
+
+msgid "could not set recommended config"
+msgstr "kan inte ange rekommenderad konfiguration"
+
+msgid "could not turn on maintenance"
+msgstr "kunde inte aktivera underhåll"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "kunde inte starta FSMonitor-server"
+
+msgid "could not turn off maintenance"
+msgstr "kunde inte slå av underhåll"
+
+msgid "could not remove enlistment"
+msgstr "kunde inte ta bort enrollering"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "HEAD hos fjärren är inte en gren: \"%.*s\""
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"misslyckades hämta namn på standardgren för fjärr; använder lokalt förval"
+
+msgid "failed to get default branch name"
+msgstr "misslyckades hämta namn på standardgren"
+
+msgid "failed to unregister repository"
+msgstr "misslyckades avregistrera arkivet"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "misslyckades stoppa FSMonitor-server"
+
+msgid "failed to delete enlistment directory"
+msgstr "misslyckades ta bort enrolleringskatalogen"
+
+msgid "branch to checkout after clone"
+msgstr "gren att checka ut efter kloning"
+
+msgid "when cloning, create full working directory"
+msgstr "skapa komplett arbetskatalog vid kloning"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "hämta endast metadata för grenen som skall checkas ut"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<flaggor>] [--] <arkiv> [<kat>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "Kan inte härleda arbetsträdsnamn från \"%s\""
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "katalogen \"%s\" finns redan"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "misslyckades hämta standardgren för \"%s\""
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "kunde inte ställa in fjärr i \"%s\""
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "kunde inte ställa in \"%s\""
+
+msgid "partial clone failed; attempting full clone"
+msgstr "delvis klon misslyckades; försöker med fullständig klon"
+
+msgid "could not configure for full clone"
+msgstr "kunde inte ställa in för komplett klon"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<enrollering>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "\"scalar list\" tar inte argument"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<enrollering>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "konfigurera alla registrerade enrolleringar på nytt"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <enrollering>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all eller <enrollering>, men inte bägge"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "git-arkiv försvunnet i \"%s\""
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <uppgift> [<enrollering>]\n"
+"Uppgifter:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "okänd uppgift: \"%s\""
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<enrollering>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <enrollering>"
+
+msgid "refusing to delete current working directory"
+msgstr "vägrar ta bort aktuell arbetskatalog"
+
+msgid "include Git version"
+msgstr "ta med Git-version"
+
+msgid "include Git's build options"
+msgstr "ta med Gits byggflaggor"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C kräver en <katalog>"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "kunde inte byta till \"%s\""
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c kräver ett argument på formen <nyckel>=<värde>"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <katalog>] [-c <nyckel>=<värde>] <kommando> [<flaggor>]\n"
+"\n"
+"Kommandon:\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr "oväntat flush-paket vid läsning av fjärruppackningsstatus"
@@ -18812,10 +19251,6 @@ msgstr "dina lokala ändringar skulle skrivas över av %s."
msgid "commit your changes or stash them to proceed."
msgstr "checka in dina ändringar eller använd \"stash\" för att fortsätta."
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: snabbspola"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -19302,6 +19737,27 @@ msgstr "kunde inte ens försöka slå ihop \"%.*s\""
msgid "merge: Unable to write new index file"
msgstr "sammanslagning: Kunde inte skriva ny indexfil"
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "en annan \"rebase\"-process verkar vara aktiv; \"%s.lock\" finns redan"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Uppdaterade följande referenser med %s:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Misslyckades uppdatera följande referenser med %s:\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "Kan inte utföra \"autostash\""
@@ -19468,6 +19924,10 @@ msgid "the script was already rearranged."
msgstr "skriptet har redan omordnats."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "update-refs-filen vid \"%s\" är ogiltig"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "\"%s\" är utanför arkivet på \"%s\""
@@ -19587,17 +20047,21 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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 ""
-"osäkert arkiv (\"%s\" ägs av någon annan)\n"
-"För att lägga till ett undantag för denna katalog, kör:\n"
+"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\")"
+
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -20467,6 +20931,18 @@ msgstr "felaktigt portnummer"
msgid "invalid '..' path segment"
msgstr "felaktigt \"..\"-sökvägssegment"
+msgid "usage: "
+msgstr "användning: "
+
+msgid "fatal: "
+msgstr "ödesdigert: "
+
+msgid "error: "
+msgstr "fel: "
+
+msgid "warning: "
+msgstr "varning: "
+
msgid "Fetching objects"
msgstr "Hämtar objekt"
@@ -21257,22 +21733,6 @@ msgstr "Markerade stycken kan inte appliceras på indexet!\n"
msgid "ignoring unmerged: %s\n"
msgstr "ignorerar ej sammanslagen: %s\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "Applicera ändrat läge på arbetskatalogen [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Applicera borttagning på arbetskatalogen [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Applicera tillägg på arbetskatalogen [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "Applicera stycket på arbetskatalogen [y,n,q,a,d%s,?]? "
-
msgid "No other hunks to goto\n"
msgstr "Inga andra stycken att gå till\n"
diff --git a/po/tr.po b/po/tr.po
index 1e1d0318fd9..484e0acf2d2 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -74,6 +74,7 @@
# string | dizi #
# subdirectory | altdizin #
# submodule | altmodül #
+# superproject | üst proje #
# symlink | sembolik baÄŸ #
# symref | sembolik baÅŸvuru #
# tag | etiket #
@@ -91,8 +92,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: 2022-06-22 12:46+0300\n"
-"PO-Revision-Date: 2022-06-22 16:00+0300\n"
+"POT-Creation-Date: 2022-09-28 10:54+0300\n"
+"PO-Revision-Date: 2022-09-28 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"
@@ -494,6 +495,22 @@ msgstr ""
"a - bu parçayı ve sonraki tüm parçaları uygula\n"
"d - bu parçayı veya sonraki parçalardan herhangi birini uygulama\n"
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "Kip değişimi çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Silme çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Ekleme çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
+
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Bu parça çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
+
msgid ""
"y - apply this hunk to worktree\n"
"n - do not apply this hunk to worktree\n"
@@ -511,10 +528,6 @@ msgstr ""
msgid "could not parse hunk header '%.*s'"
msgstr "parça üstbilgisi '%.*s' ayrıştırılamadı"
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "renklendirilmiş parça üstbilgisi '%.*s' ayrıştırılamadı"
-
msgid "could not parse diff"
msgstr "diff ayrıştırılamadı"
@@ -730,7 +743,7 @@ msgid "Exiting because of an unresolved conflict."
msgstr "Çözüme kavuşturulmamış bir çakışmadan dolayı çıkılıyor."
msgid "You have not concluded your merge (MERGE_HEAD exists)."
-msgstr "Birleştirmenizi sonuçlandırmadınız (MERGE_HEAD mevcut)."
+msgstr "Birleştirmenizi sonuçlandırmadınız (MERGE_HEAD var)."
msgid "Please, commit your changes before merging."
msgstr "Birleştirme öncesinde değişikliklerinizi işleyin."
@@ -801,6 +814,26 @@ msgstr ""
"kapatabilirsiniz.\n"
"\n"
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Aşağıdaki yollar, aralıklı çıkış tanımının dışına\n"
+"taşındı; ancak yerel değişikliklerden dolayı\n"
+"aralıklı değiller.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Bu yollardaki aralıklılığı düzeltmek için aşağıdakini yapın:\n"
+"* İndeksi güncellemek için \"git add --sparse <yollar>\" kullanın\n"
+"* Aralıklılık kurallarını uygulamak için \"git sparse-checkout reapply\" "
+"yapın"
+
msgid "cmdline ends with \\"
msgstr "komut satırı \\ ile bitiyor"
@@ -1298,6 +1331,10 @@ msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "desteklenmeyen dosya kipi: 0%o (SHA1: %s)"
#, c-format
+msgid "deflate error (%d)"
+msgstr "söndürme hatası (%d)"
+
+#, c-format
msgid "unable to start '%s' filter"
msgstr "'%s' süzgeci başlatılamıyor"
@@ -1317,10 +1354,6 @@ msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "yol çok uzun (%d karakter, SHA1: %s): %s"
#, c-format
-msgid "deflate error (%d)"
-msgstr "söndürme hatası (%d)"
-
-#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
msgstr "zaman damgası bu sistem için çok büyük: %<PRIuMAX>"
@@ -1696,7 +1729,7 @@ msgstr "izleme bilgisi ayarlanamıyor; başlangıç noktası '%s' bir dal değil
#, c-format
msgid "the requested upstream branch '%s' does not exist"
-msgstr "istenen üstkaynak dalı '%s' mevcut değil"
+msgstr "istenen üstkaynak dalı '%s' yok"
msgid ""
"\n"
@@ -1739,7 +1772,7 @@ msgid ""
"update --init'"
msgstr ""
"Altmodülleri güncellemeyi 'git checkout %s && git submodule update --init' "
-"kullanarak deneyebilirsiniz."
+"kullanarak deneyebilirsiniz"
#, c-format
msgid "submodule '%s': cannot create branch '%s'"
@@ -1893,7 +1926,7 @@ msgid ""
msgstr ""
"Gerçekten eklemek istiyorsanız -f kullanın.\n"
"Bu iletiyi 'git config advice.addIgnoredFile false'\n"
-"kullanarak kapatabilirsiniz."
+"yaparak kapatabilirsiniz"
msgid "adding files failed"
msgstr "dosya ekleme başarısız"
@@ -1917,10 +1950,10 @@ msgid ""
msgstr ""
"'git add .' mı demek istediniz?\n"
"Bu iletiyi 'git config advice.addEmptyPathspec false'\n"
-"yaparak kapatabilirsiniz."
+"yaparak kapatabilirsiniz"
msgid "index file corrupt"
-msgstr "indeks dosyası hasar görmüş"
+msgstr "indeks dosyası hasarlı"
#, c-format
msgid "bad action '%s' for '%s'"
@@ -2145,7 +2178,7 @@ msgid ""
"Not rewinding to ORIG_HEAD"
msgstr ""
"Son 'am' başarısızlığından bu yana HEAD'i hareket ettirmiş görünüyorsunuz.\n"
-"ORIG_HEAD'e geri sarılmıyor."
+"ORIG_HEAD'e geri sarılmıyor"
#, c-format
msgid "failed to read '%s'"
@@ -2250,7 +2283,7 @@ msgid "GPG-sign commits"
msgstr "GPG imzalı işlemeler"
msgid "how to handle empty patches"
-msgstr "boş yamaların nasıl değerlendirileceği"
+msgstr "boş yamaların nasıl ele alınacağı"
msgid "(internal use for git-rebase)"
msgstr "(git-rebase için iç kullanım)"
@@ -2268,7 +2301,7 @@ msgstr "indeks okunamadı"
#, c-format
msgid "previous rebase directory %s still exists but mbox given."
msgstr ""
-"Bir önceki yeniden temellendirme dizini %s hâlâ mevcut; ancak mbox verildi."
+"Bir önceki yeniden temellendirme dizini %s hâlâ var; ancak mbox verildi."
#, c-format
msgid ""
@@ -2806,11 +2839,11 @@ msgid "cannot use -a with -d"
msgstr "-a, -d ile kullanılamıyor"
msgid "Couldn't look up commit object for HEAD"
-msgstr "HEAD için işleme nesnesi aranamadı."
+msgstr "HEAD için işleme nesnesi aranamadı"
#, c-format
msgid "Cannot delete branch '%s' checked out at '%s'"
-msgstr "'%s' dalı silinemiyor, şurada çıkış yapılmış: '%s'."
+msgstr "'%s' dalı silinemiyor, şurada çıkış yapılmış: '%s'"
#, c-format
msgid "remote-tracking branch '%s' not found."
@@ -3044,7 +3077,7 @@ msgstr "'%s' diye bir dal yok"
#, c-format
msgid "branch '%s' does not exist"
-msgstr "'%s' diye bir dal mevcut deÄŸil"
+msgstr "'%s' diye bir dal yok"
msgid "too many arguments to unset upstream"
msgstr "üst kaynağı kaldırmak için çok fazla argüman"
@@ -3087,8 +3120,12 @@ msgstr "libc bilgisi: "
msgid "not run from a git repository - no hooks to show\n"
msgstr "bir git deposundan çalıştırılmadı - gösterilecek kanca yok\n"
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <dosya>] [-s|--suffix <biçim>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <dosya>] [-s|--suffix <biçim>] [--"
+"diagnose[=<kip>]"
msgid ""
"Thank you for filling out a Git bug report!\n"
@@ -3124,16 +3161,27 @@ msgstr ""
"Aşağıda hata raporunun geri kalanına bir göz atın.\n"
"Paylaşmak istemediğiniz satırları silebilirsiniz.\n"
-msgid "specify a destination for the bugreport file"
-msgstr "hata raporu dosyası için bir konum belirtin"
+msgid "mode"
+msgstr "kip"
-msgid "specify a strftime format suffix for the filename"
-msgstr "dosya adı için bir strftime biçimli ek belirtin"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr "ayrıntılı tanıların ek bir zip arşivini oluştur (öntanımlı: 'stats')"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "hata raporu dosyaları için bir hedef konum belirtin"
+
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "dosya adları için bir strftime biçim soneki belirtin"
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "'%s' için öncü dizinler oluşturulamadı"
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "tanı arşivi %s oluşturulamadı"
+
msgid "System Info"
msgstr "Sistem Bilgisi"
@@ -3192,10 +3240,6 @@ msgid "Unbundling objects"
msgstr "Nesneler demetten çıkarılıyor"
#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Bilinmeyen altkomut: %s"
-
-#, c-format
msgid "cannot read object %s '%s'"
msgstr "%s '%s' nesnesi okunamıyor"
@@ -3270,7 +3314,10 @@ msgid "show object size"
msgstr "nesne boyutunu göster"
msgid "allow -s and -t to work with broken/corrupt objects"
-msgstr "-s ve -t'nin bozuk/hasar görmüş nesnelerle çalışmasına izin ver"
+msgstr "-s ve -t'nin bozuk/hasarlı nesnelerle çalışmasına izin ver"
+
+msgid "use mail map file"
+msgstr "posta eşlem dosyasını kullan"
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr "Toplu iÅŸ nesneleri stdin'de istendi (veya --batch-all-objects)"
@@ -3281,6 +3328,9 @@ msgstr "tam <nesne> veya <revizyon> içeriğini göster"
msgid "like --batch, but don't emit <contents>"
msgstr "--batch gibi; ancak <içerik> yayma"
+msgid "stdin is NUL-terminated"
+msgstr "stdin, NUL ile sonlandırılmış"
+
msgid "read commands from stdin"
msgstr "komutları stdin'den oku"
@@ -3433,10 +3483,10 @@ msgid "do not skip files with skip-worktree set"
msgstr "skip-worktree kümesiyle dosyaları atlama"
msgid "force overwrite of existing files"
-msgstr "mevcut dosyaların üzerine yazılmasını zorla"
+msgstr "var olan dosyaların üzerine yazılmasını zorla"
msgid "no warning for existing files and files not in index"
-msgstr "mevcut dosyalar ve indekste olmayan dosyalar için uyarma"
+msgstr "var olan dosyalar ve indekste olmayan dosyalar için uyarma"
msgid "don't checkout new files"
msgstr "yeni dosyaları çıkış yapma"
@@ -3639,7 +3689,7 @@ msgid ""
"Please use -- (and optionally --no-guess) to disambiguate"
msgstr ""
"'%s' hem bir yerel dosya hem de bir izleme dalı olabilir.\n"
-"Lütfen -- (ve isteğe bağlı olarak --no-guess) kullanıp belirsizliği giderin."
+"-- (ve isteğe bağlı olarak --no-guess) kullanıp belirsizliği giderin"
msgid ""
"If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
@@ -4150,6 +4200,12 @@ msgstr ""
"sparse-checkout dosyasını yalnızca kökteki dosyaları içerecek biçimde "
"ilklendir"
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "uzak konum kökeninden getirmeden önce demetleri indirmek için bir URI"
+
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: '%s' için alternatif eklenemedi: %s\n"
@@ -4209,9 +4265,8 @@ msgstr "%s güncellenemiyor"
msgid "failed to initialize sparse-checkout"
msgstr "sparse-checkout ilklendirilemedi"
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr ""
-"uzak konum HEAD'i var olmayan başvuruya bağlanıyor, çıkış yapılamıyor.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
+msgstr "uzak konum HEAD'i, var olmayan başvuruya başvuruyor; çıkış yapılamıyor"
msgid "unable to checkout working tree"
msgstr "çalışma ağacı çıkış yapılamıyor"
@@ -4235,9 +4290,15 @@ msgstr "Klonlamak için bir depo belirtmelisiniz."
msgid "options '%s' and '%s %s' cannot be used together"
msgstr "'%s' ve '%s %s' seçenekleri birlikte kullanılamaz"
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr ""
+"--bundle-uri; --depth, --shallow-since ve --shallow-exclude ile uyumsuz"
+
#, c-format
msgid "repository '%s' does not exist"
-msgstr "'%s' deposu mevcut deÄŸil"
+msgstr "'%s' deposu yok"
#, c-format
msgid "depth %s is not a positive number"
@@ -4245,15 +4306,15 @@ msgstr "%s derinliği pozitif bir sayı değil"
#, c-format
msgid "destination path '%s' already exists and is not an empty directory."
-msgstr "Hedef yolu '%s' halihazırda mevcut ve boş bir dizin değil."
+msgstr "Hedef yolu '%s' halihazırda var ve boş bir dizin değil."
#, c-format
msgid "repository path '%s' already exists and is not an empty directory."
-msgstr "Depo yolu '%s' halihazırda mevcut ve boş bir dizin değil."
+msgstr "Depo yolu '%s' halihazırda var ve boş bir dizin değil."
#, c-format
msgid "working tree '%s' already exists."
-msgstr "Çalışma ağacı '%s' halihazırda mevcut."
+msgstr "Çalışma ağacı '%s' halihazırda var."
#, c-format
msgid "could not create leading directories of '%s'"
@@ -4306,6 +4367,13 @@ msgstr "--local yok sayıldı"
msgid "cannot clone from filtered bundle"
msgstr "süzülmüş demetten klonlanamıyor"
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "depo ilklendirilemedi, demet URI'si atlanıyor"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "'%s' demet URI'sinden nesneler getirilemedi"
+
msgid "remote transport reported error"
msgstr "uzak konum taşıması hata bildirdi"
@@ -4423,10 +4491,6 @@ msgstr ""
msgid "Collecting commits from input"
msgstr "Girdiden işlemeler toplanıyor"
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "tanımlanamayan altkomut: %s"
-
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
"<file>)...] <tree>"
@@ -4584,7 +4648,7 @@ msgid ""
"unable to select a comment character that is not used\n"
"in the current commit message"
msgstr ""
-"mevcut işleme iletisinde kullanılmayan bir yorum\n"
+"geçerli işleme iletisinde kullanılmayan bir yorum\n"
"karakteri seçilemiyor"
#, c-format
@@ -4707,7 +4771,7 @@ msgstr "Lütfen iletiyi -m veya -F seçeneğini kullanarak destekleyin.\n"
#, c-format
msgid "--author '%s' is not 'Name <email>' and matches no existing author"
msgstr ""
-"--author '%s', 'Ad <e-posta>' biçiminde değil ve mevcut bir yazarla "
+"--author '%s', 'Ad <e-posta>' biçiminde değil ve var olan bir yazarla "
"eÅŸleÅŸmiyor"
#, c-format
@@ -4782,9 +4846,6 @@ msgstr "durumu uzun biçimde göster (öntanımlı)"
msgid "terminate entries with NUL"
msgstr "girdileri NUL ile sonlandır"
-msgid "mode"
-msgstr "kip"
-
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr ""
"izlenmeyen dosyaları göster, ist. bağlı kipler: all, normal, no (Öntanım.: "
@@ -4795,7 +4856,7 @@ msgid ""
"traditional)"
msgstr ""
"yok sayılan dosyaları göster, isteğe bağlı kipler: traditional (geleneksel) "
-"matching (eşleşen), no (hayır) (Öntanımlı: traditional)."
+"matching (eşleşen), no (hayır) (Öntanımlı: traditional)"
msgid "when"
msgstr "ne zaman"
@@ -4805,7 +4866,7 @@ msgid ""
"(Default: all)"
msgstr ""
"altmodüllere olan değişiklikleri yok say, isteğe bağlı ne zaman: all "
-"(hepsi), dirty (kirli), untracked (izlenmeyen) (Öntanımlı: all)."
+"(hepsi), dirty (kirli), untracked (izlenmeyen) (Öntanımlı: all)"
msgid "list untracked files in columns"
msgstr "izlenmeyen dosyaları sütunlarla göster"
@@ -5173,7 +5234,7 @@ msgid ""
msgstr ""
"--worktree, worktreeConfig yapılandırma genişletmesi etkinleştirilmediği\n"
"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."
+"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"
@@ -5272,7 +5333,7 @@ msgstr "ek açıklamalı"
#, c-format
msgid "annotated tag %s not available"
-msgstr "%s ek açıklamalı etiketi mevcut değil"
+msgstr "ek açıklamalı etiket %s kullanılamıyor"
#, c-format
msgid "tag '%s' is externally known as '%s'"
@@ -5380,6 +5441,22 @@ msgstr "Hiçbir ad bulunamadı, hiçbir şey betimlenemiyor."
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "'%s' seçeneği ve işlememsiler birlikte kullanılamaz"
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <yol>] [-s|--suffix <biçim>] [--"
+"mode=<kip>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "tanı arşivi için bir hedef konum belirtin"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr "dosya adı için bir strftime biçimli ek belirtin"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "tanı arşivinin içeriğini belirtin"
+
msgid "--merge-base only works with two commits"
msgstr "--merge-base yalnızca iki işleme ile kullanılabilir"
@@ -5400,7 +5477,7 @@ msgstr "Bir git deposu deÄŸil"
#, c-format
msgid "invalid object '%s' given."
-msgstr "geçersiz nesne '%s' verildi"
+msgstr "geçersiz nesne '%s' verildi."
#, c-format
msgid "more than two blobs given: '%s'"
@@ -5408,7 +5485,7 @@ msgstr "ikiden çok ikili nesne verildi: '%s'"
#, c-format
msgid "unhandled object '%s' given."
-msgstr "ele alınmayan nesne '%s' verildi"
+msgstr "ele alınmayan nesne '%s' verildi."
#, c-format
msgid "%s...%s: multiple merge bases, using %s"
@@ -5758,11 +5835,8 @@ msgstr "[güncel]"
msgid "[rejected]"
msgstr "[reddedildi]"
-msgid "can't fetch in current branch"
-msgstr "geçerli dalda getirme yapılamıyor"
-
-msgid "checked out in another worktree"
-msgstr "başka bir çalışma ağacında çıkış yapıldı"
+msgid "can't fetch into checked-out branch"
+msgstr "çıkış yapılmış dala getirilemiyor"
msgid "[tag update]"
msgstr "[etiket güncellemesi]"
@@ -5797,9 +5871,9 @@ msgid ""
"but that check has been disabled; to re-enable, use '--show-forced-updates'\n"
"flag or run 'git config fetch.showForcedUpdates true'"
msgstr ""
-"Getirme normalde hangi dallarda zorla güncelleme yapıldığını belirtir;\n"
-"ancak bu denetleme kapatılmış. Yeniden açmak için '--show-forced-updates'\n"
-"bayrağını kullanın veya 'git config fetch.showForcedUpdates true' çalıştırın."
+"Getirme, normalde hangi dallarda zorla güncelleme yapıldığını belirtir;\n"
+"ancak bu denetleme kapatılmış; yeniden açmak için '--show-forced-updates'\n"
+"bayrağını kullanın veya 'git config fetch.showForcedUpdates true' çalıştırın"
#, c-format
msgid ""
@@ -5891,8 +5965,8 @@ msgid ""
"no source branch found;\n"
"you need to specify exactly one branch with the --set-upstream option"
msgstr ""
-"Kaynak dal bulunamadı.\n"
-"--set-upstream seçeneği ile tam olarak bir dal belirtmeniz gerekiyor."
+"Kaynak dal bulunamadı;\n"
+"--set-upstream seçeneği ile tam olarak bir dal belirtmeniz gerekiyor"
#, c-format
msgid "Fetching %s\n"
@@ -5910,8 +5984,8 @@ msgid ""
"no remote repository specified; please specify either a URL or a\n"
"remote name from which new revisions should be fetched"
msgstr ""
-"Bir uzak dal belirtilmedi. Lütfen yeni revizyonların\n"
-"getirileceği bir URL veya uzak konum adı belirtin."
+"Bir uzak dal belirtilmedi; lütfen yeni revizyonların\n"
+"getirileceği bir URL veya uzak konum adı belirtin"
msgid "you need to specify a tag name"
msgstr "bir etiket adı belirtmeniz gerekiyor"
@@ -5949,8 +6023,8 @@ msgid ""
"--filter can only be used with the remote configured in extensions."
"partialclone"
msgstr ""
-"--filter yalnızca extensions.partialclone içinde yapılandırılmış uzak konum "
-"ile kullanılabilir."
+"--filter, yalnızca extensions.partialclone içinde yapılandırılmış uzak konum "
+"ile kullanılabilir"
msgid "--atomic can only be used when fetching from one remote"
msgstr "--atomic yalnızca bir uzak konumdan getirirken kullanılabilir"
@@ -6118,7 +6192,7 @@ msgstr "%s %s (%s) ÅŸurada etiketlendi: %s"
#, c-format
msgid "%s: object corrupt or missing"
-msgstr "%s: nesne hasar görmüş veya kayıp"
+msgstr "%s: nesne hasarlı veya kayıp"
#, c-format
msgid "%s: invalid reflog entry %s"
@@ -6145,7 +6219,7 @@ msgstr "%s: sağlama yolu uyuşmazlığı, şurada bulundu: %s"
#, c-format
msgid "%s: object corrupt or missing: %s"
-msgstr "%s: nesne hasar görmüş veya kayıp: %s"
+msgstr "%s: nesne hasarlı veya kayıp: %s"
#, c-format
msgid "%s: object is of unknown type '%s': %s"
@@ -6195,6 +6269,10 @@ msgstr "%s: cache-tree içinde geçersiz sha1 işaretçisi"
msgid "non-tree in cache-tree"
msgstr "cache-tree içinde ağaç olmayan öge"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s: resolve-undo içinde geçersiz sha1 işaretçisi"
+
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<seçenekler>] [<nesne>...]"
@@ -6337,7 +6415,7 @@ msgstr "geçersiz 'ipc-threads' değeri (%d)"
#, c-format
msgid "Unhandled subcommand '%s'"
-msgstr "Ä°ÅŸlenmemiÅŸ altkomut '%s'"
+msgstr "Ele alınmamış altkomut '%s'"
msgid "fsmonitor--daemon not supported on this platform"
msgstr "fsmonitor--daemon bu platformda desteklenmiyor"
@@ -6461,7 +6539,7 @@ msgstr ""
#, c-format
msgid "lock file '%s' exists, skipping maintenance"
-msgstr "kilit dosyası '%s' mevcut, bakım atlanıyor"
+msgstr "kilit dosyası '%s' var, bakım atlanıyor"
#, c-format
msgid "task '%s' failed"
@@ -6523,12 +6601,15 @@ msgstr "schtasks başlatılamadı"
msgid "failed to run 'crontab -l'; your system might not support 'cron'"
msgstr "'crontab -l' çalıştırılamadı; sisteminiz 'cron' desteklemiyor olabilir"
+msgid "failed to create crontab temporary file"
+msgstr "crontab geçici dosyası oluşturulamadı"
+
+msgid "failed to open temporary file"
+msgstr "geçici dosya açılamadı"
+
msgid "failed to run 'crontab'; your system might not support 'cron'"
msgstr "'crontab' çalıştırılamadı; sisteminiz 'cron' desteklemiyor olabilir"
-msgid "failed to open stdin of 'crontab'"
-msgstr "'crontab' stdin'i açılamadı"
-
msgid "'crontab' died"
msgstr "'crontab' beklenmedik bir biçimde sonlandı"
@@ -6551,11 +6632,11 @@ msgid "unrecognized --scheduler argument '%s'"
msgstr "tanımlanamayan --scheduler argümanı, '%s'"
msgid "neither systemd timers nor crontab are available"
-msgstr "ne systemd zamanlayıcıları ne de crontab mevcut değil"
+msgstr "ne systemd zamanlayıcıları ne de crontab kullanılabiliyor"
#, c-format
msgid "%s scheduler is not available"
-msgstr "%s planlayıcısı mevcut değil"
+msgstr "%s planlayıcısı kullanılamıyor"
msgid "another process is scheduling background maintenance"
msgstr "başka bir işlem arka plan bakımı zamanını planlıyor"
@@ -6575,10 +6656,6 @@ msgstr "depo, global yapılandırmaya eklenemedi"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <altkomut> [<seçenekler>]"
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "geçersiz altkomut: %s"
-
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<seçenekler>] [-e] <dizgi> [<rev>...] [[--] <yol>...]"
@@ -6750,6 +6827,9 @@ msgstr "sayfalayıcıda eşleşen dosyaları göster"
msgid "allow calling of grep(1) (ignored by this build)"
msgstr "grep(1)'in çağrılmasına izin ver (bu yapım tarafından yok sayıldı)"
+msgid "maximum number of results per file"
+msgstr "dosya başına en çok sonuç sayısı"
+
msgid "no pattern given"
msgstr "bir dizgi verilmedi"
@@ -6837,11 +6917,21 @@ msgstr "komut açıklamasını yazdır"
msgid "print list of useful guides"
msgstr "kullanışlı kılavuzların listesini çıkar"
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr ""
+"kullanıcıya görünür depolar, komutlar ve dosya arayüzlerinin bir listesini "
+"yazdır"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr ""
+"dosya biçimleri, protokoller ve diğer geliştirici arayüzlerinin bir "
+"listesini yazdır"
+
msgid "print all configuration variable names"
msgstr "tüm yapılandırma değişkenleri adlarını yazdır"
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<komutlar>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<komut>|<belge>]"
#, c-format
msgid "unrecognized help format '%s'"
@@ -6998,11 +7088,11 @@ msgstr "%s okunamıyor"
#, c-format
msgid "cannot read existing object info %s"
-msgstr "mevcut %s nesne bilgisi okunamıyor"
+msgstr "var olan nesne bilgisi %s okunamıyor"
#, c-format
msgid "cannot read existing object %s"
-msgstr "mevcut %s nesnesi okunamıyor"
+msgstr "var olan nesne %s okunamıyor"
#, c-format
msgid "invalid blob object %s"
@@ -7025,7 +7115,7 @@ msgid "Indexing objects"
msgstr "Nesneler indeksleniyor"
msgid "pack is corrupted (SHA1 mismatch)"
-msgstr "paket hasar görmüş (SHA1 uyumsuzluğu)"
+msgstr "paket hasarlı (SHA1 uyumsuzluğu)"
msgid "cannot fstat packfile"
msgstr "paket dosyası fstat yapılamıyor"
@@ -7099,7 +7189,7 @@ msgstr "Mevcut paket dosyası '%s' açılamıyor"
#, c-format
msgid "Cannot open existing pack idx file for '%s'"
-msgstr "'%s' için mevcut paket idx dosyası açılamıyor"
+msgstr "'%s' için var olan paket idx dosyası açılamıyor"
#, c-format
msgid "non delta: %d object"
@@ -7190,11 +7280,11 @@ msgstr "re-init: --initial-branch=%s yok sayıldı"
#, c-format
msgid "Reinitialized existing shared Git repository in %s%s\n"
-msgstr "%s%s içindeki mevcut paylaşılan Git deposu yeniden ilklendirildi\n"
+msgstr "%s%s içindeki var olan paylaşılan Git deposu yeniden ilklendirildi\n"
#, c-format
msgid "Reinitialized existing Git repository in %s%s\n"
-msgstr "%s%s içindeki mevcut Git deposu yeniden ilklendirildi\n"
+msgstr "%s%s içindeki var olan Git deposu yeniden ilklendirildi\n"
#, c-format
msgid "Initialized empty shared Git repository in %s%s\n"
@@ -7311,8 +7401,8 @@ msgstr "diff çıktısını gizle"
msgid "show source"
msgstr "kaynağı göster"
-msgid "use mail map file"
-msgstr "posta eşlem dosyasını kullan"
+msgid "clear all previously-defined decoration filters"
+msgstr "tüm önceden tanımlanmış süsleme süzgeçlerini temizle"
msgid "only decorate refs that match <pattern>"
msgstr "yalnızca <dizgi> ile eşleşen başvuruları süsle"
@@ -7408,7 +7498,7 @@ msgstr ""
"Üstkaynak alınamadı; taban işlemesinin kaydını kendiliğinden yazmak\n"
"istiyorsanız lütfen git branch --set-upstream-to kullanarak bir uzak dalı\n"
"izleyin. Bunun dışında taban işlemesini kendiniz --base=<taban-işlemesi-no>\n"
-"kullanarak el ile belirtebilirsiniz."
+"kullanarak el ile belirtebilirsiniz"
msgid "failed to find exact merge base"
msgstr "kesin birleştirme temeli bulunamadı"
@@ -7566,6 +7656,9 @@ msgstr ""
msgid "percentage by which creation is weighted"
msgstr "oluşumun tartıldığı yüzde"
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "e-posta üstbilgisinin aynısı dahi olsa gövde için From:'u göster"
+
#, c-format
msgid "invalid ident line: %s"
msgstr "geçersiz tanımlayıcı satırı: %s"
@@ -7624,6 +7717,18 @@ msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr "İzlenen bir uzak dal bulunamadı, lütfen el ile <üstkaynak> belirtin.\n"
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "hatalı ls-files biçimi: '%s' ögesi, '(' ile başlamıyor"
+
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "hatalı ls-files biçimi: '%s' ögesi, ')' ile sonlanmıyor"
+
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "hatalı ls-files biçimi: %%%.*s"
+
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<seçenekler>] [<dosya>...]"
@@ -7709,6 +7814,13 @@ msgid "show sparse directories in the presence of a sparse index"
msgstr "bir aralıklı indeks bulunurluğunda aralıklı dizinleri göster"
msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format; -s, -o, -k, -t, --resolve-undo, --deduplicate, --eol ile birlikte "
+"kullanılamaz"
+
+msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
" [-q | --quiet] [--exit-code] [--get-url]\n"
" [--symref] [<repository> [<refs>...]]"
@@ -7926,6 +8038,39 @@ msgstr "'%s' başvurusu çözülemedi"
msgid "Merging %s with %s\n"
msgstr "%s, %s ile birleÅŸtiriliyor\n"
+msgid "not something we can merge"
+msgstr "birleÅŸtirebileceÄŸimiz bir ÅŸey deÄŸil"
+
+msgid "refusing to merge unrelated histories"
+msgstr "birbiriyle ilişkisi olmayan geçmişleri birleştirme reddediliyor"
+
+msgid "failure to merge"
+msgstr "birleÅŸtirilemedi"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<seçenekler>] <dal1> <dal2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <taban-ağaç> <dal1> <dal2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "bir önemsiz birleştirme yerine gerçek bir birleştirme yap"
+
+msgid "do a trivial merge only"
+msgstr "yalnızca bir önemsiz birleştirme yap"
+
+msgid "also show informational/conflict messages"
+msgstr "ayrıcı bilgi/çakışma iletilerini göster"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "kipi/oid'si/hazırlığı olmayan dosya adlarını listele"
+
+msgid "allow merging unrelated histories"
+msgstr "birbiriyle ilişkisi olmayan geçmişlerin birleştirilmesine izin ver"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge, tüm diğer seçeneklerle uyumsuz"
+
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<seçenekler>] [<işleme>...]"
@@ -8007,9 +8152,6 @@ msgstr "--abort; ancak indeksi ve çalışma ağacını değiştirmeden bırakı
msgid "continue the current in-progress merge"
msgstr "ilerlemekte olan geçerli birleştirmeyi sürdürün"
-msgid "allow merging unrelated histories"
-msgstr "birbiriyle ilişkisi olmayan geçmişlerin birleştirilmesine izin ver"
-
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "pre-merge-commit ve commit-msg kancalarını atla"
@@ -8027,7 +8169,7 @@ msgid "read-tree failed"
msgstr "read-tree başarısız oldu"
msgid "Already up to date. (nothing to squash)"
-msgstr "Tümü güncel (tıkıştırılacak bir şey yok)."
+msgstr "Tümü güncel (tıkıştırılacak bir şey yok)"
msgid "Already up to date."
msgstr "Tümü güncel."
@@ -8126,9 +8268,6 @@ msgstr "'%s' kapatılamadı"
msgid "not something we can merge in %s: %s"
msgstr "%s içinde birleştirebileceğimiz bir şey değil: %s"
-msgid "not something we can merge"
-msgstr "birleÅŸtirebileceÄŸimiz bir ÅŸey deÄŸil"
-
msgid "--abort expects no arguments"
msgstr "--abort bir argüman beklemez"
@@ -8148,18 +8287,18 @@ msgid ""
"You have not concluded your merge (MERGE_HEAD exists).\n"
"Please, commit your changes before you merge."
msgstr ""
-"Birleştirmenizi sonuçlandırmadınız (MERGE_HEAD mevcut).\n"
+"Birleştirmenizi sonuçlandırmadınız (MERGE_HEAD var).\n"
"Lütfen birleştirmeden önce değişikliklerinizi işleyin."
msgid ""
"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
"Please, commit your changes before you merge."
msgstr ""
-"Seç-al'ınızı sonuçlandırmadınız (CHERRY_PICK_HEAD mevcut).\n"
+"Seç-al'ınızı sonuçlandırmadınız (CHERRY_PICK_HEAD var).\n"
"Lütfen birleştirmeden önce değişikliklerinizi işleyin."
msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
-msgstr "Seç-al'ınızı sonuçlandırmadınız (CHERRY_PICK_HEAD mevcut)."
+msgstr "Seç-al'ınızı sonuçlandırmadınız (CHERRY_PICK_HEAD var)."
msgid "No commit specified and merge.defaultToUpstream not set."
msgstr "Belirtilen bir işleme yok ve merge.defaultToUpstream ayarlanmamış."
@@ -8178,14 +8317,19 @@ msgstr "%s - birleÅŸtirebileceÄŸimiz bir ÅŸey deÄŸil"
msgid "Can merge only exactly one commit into empty head"
msgstr "Boş dal ucuna tam olarak yalnızca bir işleme birleştirilebilir"
-msgid "refusing to merge unrelated histories"
-msgstr "birbiriyle ilişkisi olmayan geçmişleri birleştirme reddediliyor"
-
#, c-format
msgid "Updating %s..%s\n"
msgstr "Güncelleniyor: %s..%s\n"
#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"Birleştirme ile aşağıdaki yerel değişikliklerin üzerine yazılacak:\n"
+"\t%s"
+
+#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Gerçekten önemsiz indeks içi birleştirme deneniyor...\n"
@@ -8203,7 +8347,7 @@ msgstr "%s birleÅŸtirme stratejisi deneniyor...\n"
#, c-format
msgid "No merge strategy handled the merge.\n"
-msgstr "Birleştirmeyi hiçbir birleştirme stratejisi işlemedi\n"
+msgstr "Birleştirmeyi hiçbir birleştirme stratejisi ele almadı\n"
#, c-format
msgid "Merge with strategy %s failed.\n"
@@ -8219,6 +8363,10 @@ msgstr ""
"Otomatik birleştirme iyi geçti; istendiği üzere gönderme öncesinde durdu.\n"
#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "BittiÄŸinde, 'git stash pop' ile zulalalan deÄŸiÅŸiklikleri uygula\n"
+
+#, c-format
msgid "warning: tag input does not pass fsck: %s"
msgstr "uyarı: etiket girdisi fsck'den geçemiyor: %s"
@@ -8336,6 +8484,9 @@ msgstr "'%s'->'%s' yeniden adlandırması denetleniyor\n"
msgid "bad source"
msgstr "hatalı kaynak"
+msgid "destination exists"
+msgstr "hedef konum var"
+
msgid "can not move directory into itself"
msgstr "dizin kendi içine taşınamıyor"
@@ -8351,9 +8502,6 @@ msgstr "sürüm denetimi altında değil"
msgid "conflicted"
msgstr "çakışmalı"
-msgid "destination exists"
-msgstr "hedef mevcut"
-
#, c-format
msgid "overwriting '%s'"
msgstr "üzerine yazılıyor: '%s'"
@@ -8365,7 +8513,10 @@ msgid "multiple sources for the same target"
msgstr "aynı hedef için birden çok kaynak"
msgid "destination directory does not exist"
-msgstr "hedef dizin mevcut deÄŸil"
+msgstr "hedef dizin yok"
+
+msgid "destination exists in the index"
+msgstr "hedef konum indekste var"
#, c-format
msgid "%s, source=%s, destination=%s"
@@ -8517,11 +8668,11 @@ msgstr "not içeriği %s içinde bırakıldı"
#, c-format
msgid "could not open or read '%s'"
-msgstr "'%s' açılamadı veya okunamadı"
+msgstr "'%s', açılamadı veya okunamadı"
#, c-format
msgid "failed to resolve '%s' as a valid ref."
-msgstr "'%s' geçerli bir başvuru olarak çözülemedi"
+msgstr "'%s', geçerli bir başvuru olarak çözülemedi."
#, c-format
msgid "failed to read object '%s'."
@@ -8533,7 +8684,7 @@ msgstr "İkili nesne olmayan '%s' nesnesinden not verisi okunamıyor."
#, c-format
msgid "malformed input line: '%s'."
-msgstr "hatalı oluşturulmuş girdi satırı: '%s'"
+msgstr "hatalı oluşturulmuş girdi satırı: '%s'."
#, c-format
msgid "failed to copy notes from '%s' to '%s'"
@@ -8574,7 +8725,7 @@ msgid ""
"existing notes"
msgstr ""
"Not eklenemiyor. %s nesnesi için halihazırda var olan notlar bulundu. Bu "
-"notların üzerine yazmak için '-f' kullanın."
+"notların üzerine yazmak için '-f' kullanın"
#, c-format
msgid "Overwriting existing notes for object %s\n"
@@ -8599,7 +8750,7 @@ msgid ""
"existing notes"
msgstr ""
"Notlar kopyalanamıyor. %s nesnesi için halihazırda var olan notlar bulundu. "
-"Bu notların üzerine yazmak için '-f' kullanın."
+"Bu notların üzerine yazmak için '-f' kullanın"
#, c-format
msgid "missing notes on source object %s. Cannot copy."
@@ -8629,7 +8780,7 @@ msgid "could not find commit from NOTES_MERGE_PARTIAL."
msgstr "işleme, NOTES_MERGE_PARTIAL ögesinden bulunamadı."
msgid "could not parse commit from NOTES_MERGE_PARTIAL."
-msgstr "işleme, NOTES_MERGE_PARTIAL ögesinden ayrıştırılamadı"
+msgstr "işleme, NOTES_MERGE_PARTIAL ögesinden ayrıştırılamadı."
msgid "failed to resolve NOTES_MERGE_REF"
msgstr "NOTES_MERGE_REF çözülemedi"
@@ -8696,7 +8847,7 @@ msgstr ""
#, c-format
msgid "Failed to resolve '%s' as a valid ref."
-msgstr "'%s' geçerli bir başvuru olarak çözülemiyor"
+msgstr "'%s', geçerli bir başvuru olarak çözülemiyor."
#, c-format
msgid "Object %s has no note\n"
@@ -8721,8 +8872,8 @@ msgid "use notes from <notes-ref>"
msgstr "notları <not-bşvr>'ndan kullan"
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "bilinmeyen altkomut: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "bilinmeyen altkomut: '%s'"
msgid ""
"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
@@ -8749,7 +8900,7 @@ msgstr "%s için hatalı paketlenmiş nesne CRC'si"
#, c-format
msgid "corrupt packed object for %s"
-msgstr "%s için hasar görmüş paketlenmiş nesne"
+msgstr "%s için hasarlı paketlenmiş nesne"
#, c-format
msgid "recursive delta detected for object %s"
@@ -9204,7 +9355,7 @@ msgid "Please specify which branch you want to merge with."
msgstr "Lütfen hangi dal ile birleştirmek istediğinizi belirtin."
msgid "See git-pull(1) for details."
-msgstr "Ayrıntılar için: git-pull(1)"
+msgstr "Ayrıntılar için git-pull(1)'a bakın."
msgid "<remote>"
msgstr "<uzak-konum>"
@@ -9250,7 +9401,7 @@ msgid ""
"or --ff-only on the command line to override the configured default per\n"
"invocation.\n"
msgstr ""
-"Iraksak dallarınız mevcut ve onların nasıl uzlaştırılacağını\n"
+"Iraksak dallarınız var ve onların nasıl uzlaştırılacağını\n"
"belirtmeniz gerekiyor. Bunu bir sonraki çekimden önce\n"
"aşağıdaki komutlardan birini çalıştırarak yapabilirsiniz:\n"
"\n"
@@ -9431,7 +9582,7 @@ msgid ""
msgstr ""
"Güncellemeler reddedildi; çünkü geçerli dalınızın ucu kendisinin\n"
"uzak konum karşıtından geride. Yeniden itmeden önce uzak konumdaki\n"
-"değişiklikleri entegre edin (örn. 'git pull ...').\n"
+"değişiklikleri tümleştirin (örn. 'git pull ...').\n"
"Ayrıntılar için 'git push --help' içinde 'Notes about fast-forwards'a\n"
"bakın."
@@ -9443,7 +9594,7 @@ msgid ""
msgstr ""
"Güncellemeler reddedildi; çünkü itilmiş bir dal ucu kendisinin\n"
"uzak konum karşıtından geride. Yeniden itmeden önce bu dalı çıkış\n"
-"yapın ve uzak konumdaki değişiklikleri entegre edin (örn. 'git pull\n"
+"yapın ve uzak konumdaki değişiklikleri tümleştirin (örn. 'git pull\n"
"...'). Ayrıntılar için 'git push --help' içinde 'Notes about\n"
"fast-forwards'a bakın."
@@ -9456,8 +9607,8 @@ msgid ""
msgstr ""
"Güncellemeler reddedildi; çünkü uzak konumda henüz yerelde sizde olmayan\n"
"değişiklikler var. Bu genelde başka bir deponun aynı başvuruya itmesinden\n"
-"dolayı olur. Yeniden itmeden önce uzak konumdaki değişiklikleri entegre\n"
-"etmek isteyebilirsiniz (örn. 'git pull ...').\n"
+"dolayı olur. Yeniden itmeden önce uzak konumdaki değişiklikleri tümleş-\n"
+"tirmek isteyebilirsiniz (örn. 'git pull ...').\n"
"Ayrıntılar için 'git push --help' içinde 'Notes about fast-forwards'a\n"
"bakın."
@@ -9481,7 +9632,7 @@ msgid ""
msgstr ""
"Güncellemeler reddedildi; çünkü uzak izleme dalının ucu son\n"
"çıkıştan bu yana güncellenmiş. Bir güncellemeyi zorlamadan\n"
-"önce bu değişiklikleri yerel olarak entegre etmek isteye-\n"
+"önce bu değişiklikleri yerel olarak tümleştirmek isteye-\n"
"bilirsiniz (örn. 'git pull ...'\n"
#, c-format
@@ -9521,7 +9672,7 @@ msgid "require old value of ref to be at this value"
msgstr "başvurunun eski değerinin bu değerde olmasını gerektir"
msgid "require remote updates to be integrated locally"
-msgstr "uzak güncellemelerin yerele entegre edilmesini gerektir"
+msgstr "uzak güncellemelerin yerele tümleştirilmesini gerektir"
msgid "control recursive pushing of submodules"
msgstr "altmodüllerin özyineli itilmesini denetle"
@@ -9613,11 +9764,16 @@ msgid "only emit output related to the second range"
msgstr "yalnızca ikinci erimle ilişkili çıktıyı yay"
#, c-format
+msgid "not a revision: '%s'"
+msgstr "bir revizyon deÄŸil: '%s'"
+
+#, c-format
msgid "not a commit range: '%s'"
msgstr "bir iÅŸleme erimi deÄŸil: '%s'"
-msgid "single arg format must be symmetric range"
-msgstr "tekli argüman biçimi simetrik erim olmalı"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "bir simetrik erim deÄŸil: '%s'"
msgid "need two commit ranges"
msgstr "iki iÅŸleme erimi gerekli"
@@ -9895,6 +10051,9 @@ msgstr "boÅŸ baÅŸlayan iÅŸlemeleri tut"
msgid "move commits that begin with squash!/fixup! under -i"
msgstr "-i altındaki squash!/fixup! ile başlayan işlemeleri taşı"
+msgid "update branches that point to commits that are being rebased"
+msgstr "yeniden temellendirilen işlemelere işaret eden dalları güncelle"
+
msgid "add exec lines after each commit of the editable list"
msgstr "düzenlenebilir listenin her işlemesinden sonra exec satırları ekle"
@@ -9963,7 +10122,7 @@ msgid ""
"mark them as resolved using git add"
msgstr ""
"Önce tüm birleştirme çakışmalarını düzenlemeli ve onları\n"
-"git add kullanarak tamamlandı olarak imlemelisiniz."
+"git add kullanarak tamamlandı olarak imlemelisiniz"
msgid "could not discard worktree changes"
msgstr "çalışma ağacı değişiklikleri atılamadı"
@@ -10292,7 +10451,7 @@ msgid ""
"\t use --mirror=fetch or --mirror=push instead"
msgstr ""
"--mirror tehlikeli ve artık kullanılmamalı; lütfen\n"
-"\t yerine --mirror=fetch veya --mirror=push kullanın."
+"\t yerine --mirror=fetch veya --mirror=push kullanın"
#, c-format
msgid "unknown mirror argument: %s"
@@ -10339,7 +10498,7 @@ msgstr "birden çok %s"
#, c-format
msgid "unhandled branch.%s.rebase=%s; assuming 'true'"
-msgstr "ilgilenilmemiş branch.%s.rebase=%s, 'true' olduğu var sayılıyor"
+msgstr "ele alınmamış branch.%s.rebase=%s, 'true' olduğu var sayılıyor"
#, c-format
msgid "Could not get fetch map for refspec %s"
@@ -10367,7 +10526,7 @@ msgid ""
msgstr ""
"Şuradaki %s yapılandırması remote.pushDefault:\n"
"\t%s:%d\n"
-"artık var olmayan '%s' uzak konumunu adlandırıyor."
+"artık var olmayan '%s' uzak konumunu adlandırıyor"
#, c-format
msgid "No such remote: '%s'"
@@ -10422,6 +10581,9 @@ msgstr " yeni (bir sonraki getirme uzak konumlarda depolayacak/%s"
msgid " tracked"
msgstr " izlendi"
+msgid " skipped"
+msgstr " atlandı"
+
msgid " stale (use 'git remote prune' to remove)"
msgstr " eskimiş (kaldırmak için 'git remote prune' kullanın)"
@@ -10814,7 +10976,7 @@ msgstr "'%s' geçerli bir başvuru adı değil"
#, c-format
msgid "replace ref '%s' already exists"
-msgstr "değiştirme başvurusu '%s' halihazırda mevcut"
+msgstr "değiştirme başvurusu '%s' halihazırda var"
#, c-format
msgid ""
@@ -10927,10 +11089,10 @@ msgid "change a commit's parents"
msgstr "bir işlemenin üst ögelerini değiştir"
msgid "convert existing graft file"
-msgstr "mevcut aşı dosyasını dönüştür"
+msgstr "var olan aşı dosyasını dönüştür"
msgid "replace the ref if it exists"
-msgstr "baÅŸvuru mevcutsa onu deÄŸiÅŸtir"
+msgstr "baÅŸvuru varsa onu deÄŸiÅŸtir"
msgid "do not pretty-print contents for --edit"
msgstr "--edit içeriğini hoş biçimde gösterme"
@@ -11093,6 +11255,10 @@ msgstr "Yeni indeks dosyası yazılamadı."
msgid "unable to get disk usage of %s"
msgstr "%s ögesinin disk kullanımı alınamıyor"
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "'%s' için geçersiz değer: '%s', tek izin verilen biçim '%s'"
+
msgid "rev-list does not support display of notes"
msgstr "rev-list not görüntülemesini desteklemiyor"
@@ -11118,6 +11284,9 @@ msgstr "zamansız girdi sonu"
msgid "no usage string given before the `--' separator"
msgstr "'--' ayırıcısı öncesinde bir kullanım dizisi verilmedi"
+msgid "missing opt-spec before option flags"
+msgstr "seçenek bayraklarından önce eksik opt-spec"
+
msgid "Needed a single revision"
msgstr "Tek bir revizyon gerekiyordu"
@@ -11129,8 +11298,8 @@ msgid ""
"Run \"git rev-parse --parseopt -h\" for more information on the first usage."
msgstr ""
"git rev-parse --parseopt [<seçenekler>] -- [<argümanlar>...]\n"
-"\tor: git rev-parse --sq-quote [<argümanlar>...]\n"
-"\tor: git rev-parse [<seçenekler>] [<argümanlar>...]\n"
+" veya: git rev-parse --sq-quote [<argümanlar>...]\n"
+" veya: git rev-parse [<seçenekler>] [<argümanlar>...]\n"
"\n"
"İlki hakkında ek bilgi için \"git rev-parse --parseopt -h\" çalıştırın."
@@ -11253,10 +11422,10 @@ msgid_plural ""
"file and the HEAD:"
msgstr[0] ""
"Aşağıdaki dosyanın hem HEAD'den hem de dosyadan farklı hazırlanmış\n"
-"içeriği mevcut:"
+"içeriği var:"
msgstr[1] ""
"Aşağıdaki dosyaların hem HEAD'den hem de dosyadan farklı hazırlanmış\n"
-"içeriği mevcut:"
+"içeriği var:"
msgid ""
"\n"
@@ -11267,8 +11436,8 @@ msgstr ""
msgid "the following file has changes staged in the index:"
msgid_plural "the following files have changes staged in the index:"
-msgstr[0] "Aşağıdaki dosyanın indekste hazırlanmış değişiklikleri mevcut:"
-msgstr[1] "Aşağıdaki dosyaların indekste hazırlanmış değişiklikleri mevcut:"
+msgstr[0] "Aşağıdaki dosyanın indekste hazırlanmış değişiklikleri var:"
+msgstr[1] "Aşağıdaki dosyaların indekste hazırlanmış değişiklikleri var:"
msgid ""
"\n"
@@ -11575,10 +11744,10 @@ msgid "unable to unquote C-style string '%s'"
msgstr "C biçemli '%s' dizisinin tırnakları kaldırılamıyor"
msgid "unable to load existing sparse-checkout patterns"
-msgstr "mevcut aralıklı çıkış dizgileri yüklenemiyor"
+msgstr "var olan aralıklı çıkış dizgileri yüklenemiyor"
msgid "existing sparse-checkout patterns do not use cone mode"
-msgstr "mevcut aralıklı çıkış dizgileri koni kipini kullanmıyor"
+msgstr "var olan aralıklı çıkış dizgileri koni kipini kullanmıyor"
msgid "please run from the toplevel directory in non-cone mode"
msgstr "koni dışı kipte en üst düzey dizinden çalıştırın"
@@ -11879,6 +12048,10 @@ msgid "Expecting a full ref name, got %s"
msgstr "Tam bir başvuru adı bekleniyordu, %s alındı"
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "'%s' altmodülü için depo tutacağı alınamadı"
+
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
@@ -11886,12 +12059,6 @@ msgstr ""
"'%s' yapılandırması aranamadı. Bu deponun kendi yetkili üstkaynağı olduğu "
"varsayılıyor."
-msgid "alternative anchor for relative paths"
-msgstr "göreceli yollar için alternatif tutturucu"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<yol>] [<yol>...]"
-
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr ".gitmodules içinde '%s' altmodül yolu için url bulunamadı"
@@ -11923,8 +12090,8 @@ msgstr "her bir altmodül komutu girişinin çıktısını gizle"
msgid "recurse into nested submodules"
msgstr "iç içe geçmiş altmodüle özyinele"
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <komut>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <komut>"
#, c-format
msgid "Failed to register url for submodule path '%s'"
@@ -11945,8 +12112,8 @@ msgstr "'%s' altmodülü yolu için güncelleme kipi kaydı yapılamadı"
msgid "suppress output for initializing a submodule"
msgstr "bir altmodül ilklendirmesi çıktısını gizle"
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<seçenekler>] [<yol>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<seçenekler>] [<yol>]"
#, c-format
msgid "no submodule mapping found in .gitmodules for path '%s'"
@@ -11973,9 +12140,6 @@ msgstr ""
msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<yol>...]"
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <yol>"
-
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(ikili nesne)->%s(altmodül)"
@@ -12008,8 +12172,8 @@ msgstr "'ignore_config' değeri 'all' olan altmodülleri atla"
msgid "limit the summary size"
msgstr "özet boyutunu sınırla"
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<seçenekler>] [<işleme>] [--] [<yol>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<seçenekler>] [<işleme>] [--] [<yol>]"
msgid "could not fetch a revision for HEAD"
msgstr "HEAD için bir revizyon getirilemedi"
@@ -12023,18 +12187,14 @@ msgid "failed to register url for submodule path '%s'"
msgstr "'%s' altmodülü yolu için url kaydı yapılamadı"
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "'%s' altmodülü için öntanımlı uzak konum alınamadı"
-
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "'%s' altmodülü için uzak konum güncellenemedi"
msgid "suppress output of synchronizing submodule url"
msgstr "altmodül url'si eşitleme çıktısını gizle"
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<yol>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<yol>]"
#, c-format
msgid ""
@@ -12090,12 +12250,16 @@ msgid ""
"submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
"'--reference-if-able' instead of '--reference'."
msgstr ""
-"Bir süperprojenin alternatifinden hesaplanan bir alternatif geçersiz.\n"
+"Bir üst projenin alternatifinden hesaplanan bir alternatif geçersiz.\n"
"Böyle bir durumda Git'in alternatifsiz klonlamasına izin vermek için\n"
"submodule.alternateErrorStrategy ayarını 'info'ya ayarlayın veya\n"
"--reference yerine --reference-if-able kullanarak klonlayın."
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "'%s' git dizini için bir depo tutacı alınamadı"
+
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "'%s' altmodülü alternatif ekleyemiyor: %s"
@@ -12124,6 +12288,9 @@ msgstr "dizin boÅŸ deÄŸil: '%s'"
msgid "could not get submodule directory for '%s'"
msgstr "'%s' için altmodül dizini alınamadı"
+msgid "alternative anchor for relative paths"
+msgstr "göreceli yollar için alternatif tutturucu"
+
msgid "where the new submodule will be cloned to"
msgstr "yeni altmodülün nereye klonlanacağı"
@@ -12152,10 +12319,6 @@ msgstr ""
"belirteci>] --url <url> --path <yol>"
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Geçersiz güncelleme kipi '%s', '%s' altmodül yolu için"
-
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr "Geçersiz güncelleme kipi '%s', '%s' altmodül yolu için yapılandırılmış"
@@ -12176,7 +12339,7 @@ msgstr "'%s' altmodülü atlanıyor"
#, c-format
msgid "Failed to clone '%s'. Retry scheduled"
-msgstr "'%s' klonlanamadı. Yeniden deneme zamanlandı."
+msgstr "'%s' klonlanamadı. Yeniden deneme zamanlandı"
#, c-format
msgid "Failed to clone '%s' a second time, aborting"
@@ -12229,16 +12392,16 @@ msgstr ""
"doğrudan getirilmesi başarısız oldu."
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "'%s' konumundaki altmodül ilklendirilemedi"
+
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
msgstr ""
-"Altmodül (%s) dalı süperproje dalından devralmak üzere yapılandırıldı; ancak "
-"süperproje herhangi bir dalda değil"
-
-#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "'%s' altmodülü için depo tutacağı alınamadı"
+"Altmodül (%s) dalı, üst projenin dalından devralmak üzere yapılandırıldı; "
+"ancak üst proje, herhangi bir dalda değil"
#, c-format
msgid "Unable to find current revision in submodule path '%s'"
@@ -12274,11 +12437,14 @@ msgstr "yeni nesneleri uzak konumdan getirme"
msgid "path into the working tree"
msgstr "çalışma ağacına giden yol"
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "iç içe geçmiş altmodül sınırları üzerinden çalışma ağacına giden yol"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "'checkout' güncelleme stratejisini kullan (öntanımlı)"
+
+msgid "use the 'merge' update strategy"
+msgstr "'merge' güncelleme stratejisini kullan"
-msgid "rebase, merge, checkout or none"
-msgstr "rebase, merge, checkout veya none"
+msgid "use the 'rebase' update strategy"
+msgstr "'rebase' güncelleme stratejisini kullan"
msgid "create a shallow clone truncated to the specified number of revisions"
msgstr "belirli bir revizyon sayısına kısaltılmış sığ klon oluştur"
@@ -12292,6 +12458,9 @@ msgstr "ilk klonun sığlık üzerine olan tavsiyeyi izleyip izlemeyeceği"
msgid "don't print cloning progress"
msgstr "klonlama işlemini yazdırma"
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "boÅŸ olmayan dizine klonlamaya izin verme, --init ima eder"
+
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12303,14 +12472,11 @@ msgstr ""
"shallow] [--reference <depo>] [--recursive] [--[no-]single-branch] [--] "
"[<yol>...]"
-msgid "bad value for update parameter"
-msgstr "güncelleme parametresi için hatalı değer"
-
msgid "recurse into submodules"
msgstr "altmodüllere özyinele"
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<seçenekler>] [<yol>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<seçenekler>] [<yol>...]"
msgid "check if it is safe to write to the .gitmodules file"
msgstr ".gitmodules dosyasına yazım güvenli mi değil mi denetle"
@@ -12330,8 +12496,8 @@ msgstr ".gitmodules dosyasının çalışma ağacında olduğundan lütfen emin
msgid "suppress output for setting url of a submodule"
msgstr "bir altmodül url ayarlanması çıktısını gizle"
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <yol> <yeniurl>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <yol> <yeniurl>"
msgid "set the default tracking branch to master"
msgstr "öntanımlı izleme dalını master olarak ayarla"
@@ -12339,13 +12505,11 @@ msgstr "öntanımlı izleme dalını master olarak ayarla"
msgid "set the default tracking branch"
msgstr "öntanımlı izleme dalını ayarla"
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <yol>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <yol>"
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <dal> <yol>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <dal> <yol>"
msgid "--branch or --default required"
msgstr "--branch veya --default gerekli"
@@ -12372,11 +12536,11 @@ msgstr "'%s' dalı oluşturuluyor"
#, c-format
msgid "Adding existing repo at '%s' to the index\n"
-msgstr "'%s' konumundaki mevcut repo indekse ekleniyor\n"
+msgstr "'%s' konumundaki var olan depo indekse ekleniyor\n"
#, c-format
msgid "'%s' already exists and is not a valid git repo"
-msgstr "'%s' halihazırda mevcut ve geçerli bir git deposu değil"
+msgstr "'%s' halihazırda var ve geçerli bir git deposu değil"
#, c-format
msgid "A git directory for '%s' is found locally with remote(s):\n"
@@ -12441,8 +12605,8 @@ msgid ""
msgstr ""
"altmodülün adını kendi yoluna öntanımlamak yerine verilen dizi olarak ayarlar"
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<seçenekler>] [--] <depo> [<yol>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<seçenekler>] [--] <depo> [<yol>]"
msgid "Relative path can only be used from the toplevel of the working tree"
msgstr ""
@@ -12647,6 +12811,16 @@ msgstr "'%s' etiketi güncellendi (%s idi)\n"
msgid "pack exceeds maximum allowed size"
msgstr "paket izin verilen en büyük boyutu aşıyor"
+msgid "failed to write object in stream"
+msgstr "akışta nesne yazılamadı"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "şişirme programı (%d) döndürdü"
+
+msgid "invalid blob object from stream"
+msgstr "akıştan geçersiz ikili nesne"
+
msgid "Unpacking objects"
msgstr "Nesneler açılıyor"
@@ -12739,7 +12913,7 @@ msgid "add to index only; do not add content to object database"
msgstr "yalnızca indekse ekle; içeriğe nesne veritabanına ekleme"
msgid "remove named paths even if present in worktree"
-msgstr "çalışma ağacında mevcut olsa bile ad verilen yolları kaldır"
+msgstr "çalışma ağacında var olsa bile ad verilen yolları kaldır"
msgid "with --stdin: input lines are terminated by null bytes"
msgstr "--stdin ile: girdi satırları boş baytlarla sonlandırılır"
@@ -13157,6 +13331,27 @@ msgstr "bir <önek> altdizini için ağaç nesnesi yaz"
msgid "only useful for debugging"
msgstr "yalnızca hata ayıklama için yararlı"
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch, bu platformda desteklenmiyor"
+
+msgid "failed to create temporary file"
+msgstr "geçici dosya oluşturulamadı"
+
+msgid "insufficient capabilities"
+msgstr "yetersiz yetenekler"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "'%s' URI'sinden demet indirilemedi"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "'%s' URI'sindeki dosya bir demet deÄŸil"
+
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "'%s' URI'sindeki demet çözülemedi"
+
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
msgstr "bilinmeyen demet sağlama algoritması: %s"
@@ -13358,6 +13553,9 @@ msgstr "Git depoları için gerçekten yalın bir sunucu"
msgid "Give an object a human readable name based on an available ref"
msgstr "Uygun bir başvuruyu temel alıp nesneye okunabilir ad ver"
+msgid "Generate a zip archive of diagnostic information"
+msgstr "Tanı bilgisinin bir zip arşivini oluştur"
+
msgid "Show changes between commits, commit and working tree, etc"
msgstr "İşlemeler, işleme ve ağaçlar vb. arası değişiklikler"
@@ -13368,8 +13566,7 @@ msgid "Compare a tree to the working tree or index"
msgstr "Bir ağacı çalışma ağacı veya indeks ile karşılaştır"
msgid "Compares the content and mode of blobs found via two tree objects"
-msgstr ""
-"İki ağaç nesnesi aracılığıyla bulunan ikililerin içerik ve kipini karşılaştır"
+msgstr "İki ağaç nesnesiyle bulunan ikililerin içerik/kipini karşılaştır"
msgid "Show changes using common diff tools"
msgstr "Değişiklikleri yaygın diff araçlarıyla göster"
@@ -13485,8 +13682,8 @@ msgstr "Birleştirilmesi gereken dosyaları birleştir"
msgid "The standard helper program to use with git-merge-index"
msgstr "Bu yardımcı program git-merge-index kullanımı içindir"
-msgid "Show three-way merge without touching index"
-msgstr "İndekse dokunmadan üçlü birleştirmeyi göster"
+msgid "Perform merge without touching index or working tree"
+msgstr "İndekse veya çalışma ağacına dokunmadan birleştir"
msgid "Run merge conflict resolution tools to resolve merge conflicts"
msgstr "Çakışmaları çözmek için çözüm araçlarını çalıştır"
@@ -13531,7 +13728,7 @@ msgid "Remove extra objects that are already in pack files"
msgstr "Halihazırda paket dosyalarında olan ek nesneleri kaldır"
msgid "Fetch from and integrate with another repository or a local branch"
-msgstr "BaÅŸka bir depo veya yerel daldan getir ve entegre et"
+msgstr "Başka bir depo veya yerel daldan getir ve tümleştir"
msgid "Update remote refs along with associated objects"
msgstr "İlişkin nesnelerle birlikte uzak başvuruları da güncelle"
@@ -13618,7 +13815,7 @@ msgid "List references in a local repository"
msgstr "Yerel bir depodaki başvuruları listele"
msgid "Reduce your working tree to a subset of tracked files"
-msgstr "Çalışma ağacını izlenen dosyaların bir alt kümesine küçült"
+msgstr "Çalışma ağacını izlenen dosyaların alt kümesine küçült"
msgid "Add file contents to the staging area"
msgstr "Dosya içeriğini hazırlama alanına ekle"
@@ -13681,6 +13878,9 @@ msgstr "Paketlenmiş Git arşiv dosyalarını doğrula"
msgid "Check the GPG signature of tags"
msgstr "Etiketlerin GPG imzasını doğrula"
+msgid "Display version information about Git"
+msgstr "Git sürüm bilgisini görüntüle"
+
msgid "Show logs with difference each commit introduces"
msgstr "Günlükleri her işlemenin sunduğu değişikliklerle göster"
@@ -13714,6 +13914,24 @@ msgstr "Günlük Git kullanımı için yararlı komutlar"
msgid "Frequently asked questions about using Git"
msgstr "Git kullanımı hakkında sıkça sorulan sorular"
+msgid "The bundle file format"
+msgstr "Demet dosya biçimi"
+
+msgid "Chunk-based file formats"
+msgstr "geçersiz gitfile biçimi: %s"
+
+msgid "Git commit graph format"
+msgstr "Git işleme grafiği biçimi"
+
+msgid "Git index format"
+msgstr "Git indeks biçimi"
+
+msgid "Git pack format"
+msgstr "Git paket biçimi"
+
+msgid "Git cryptographic signature formats"
+msgstr "Git kriptografik imza biçimleri"
+
msgid "A Git Glossary"
msgstr "Git Kavram Dizini"
@@ -13735,6 +13953,21 @@ msgstr "Altmodül özelliklerini tanımlama"
msgid "Git namespaces"
msgstr "Git ad alanları"
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Protokol v0 ve v1 yetenekleri"
+
+msgid "Things common to various protocols"
+msgstr "Çeşitli protokollerde ortak olan şeyler"
+
+msgid "Git HTTP-based protocols"
+msgstr "Git HTTP tabanlı protokolleri"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Paketlerin nice aktarıldığı"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Git Wire Protokolü, Sürüm 2"
+
msgid "Helper programs to interact with remote repositories"
msgstr "Uzak depolar ile etkileşim için yardımcı programlar"
@@ -13759,6 +13992,9 @@ msgstr "Git web arabirimi (Git depoları için web ön ucu)"
msgid "An overview of recommended workflows with Git"
msgstr "Önerilen Git çalışma akışlarına genel bakış"
+msgid "A tool for managing large Git repositories"
+msgstr "Büyük Git depolarını yönetmek için bir araç"
+
msgid "commit-graph file is too small"
msgstr "commit-graph dosyası pek küçük"
@@ -13792,7 +14028,7 @@ msgid "unable to find all commit-graph files"
msgstr "tüm commit-graph dosyaları bulunamıyor"
msgid "invalid commit position. commit-graph is likely corrupt"
-msgstr "geçersiz işleme konumu, commit-graph büyük olasılıkla hasar görmüş"
+msgstr "geçersiz işleme konumu, commit-graph büyük olasılıkla hasarlı"
#, c-format
msgid "could not find commit %s"
@@ -13883,8 +14119,7 @@ msgstr "grafik yazımı için çok fazla işleme"
msgid "the commit-graph file has incorrect checksum and is likely corrupt"
msgstr ""
-"commit-graph dosyasının sağlama toplamı yanlış ve büyük olasılıkla hasar "
-"görmüş"
+"commit-graph dosyasının sağlama toplamı yanlış ve büyük olasılıkla hasarlı"
#, c-format
msgid "commit-graph has incorrect OID order: %s then %s"
@@ -13967,7 +14202,7 @@ msgstr ""
"lütfen \"git replace --convert-graft-file\" kullanın.\n"
"\n"
"\"git config advice.graftFileDeprecated false\"\n"
-"kullanarak bu iletiyi kapatabilirsiniz."
+"kullanarak bu iletiyi kapatabilirsiniz"
#, c-format
msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
@@ -13997,10 +14232,18 @@ msgstr ""
"kodlama ile deÄŸiÅŸtirmek isteyebilirsiniz.\n"
msgid "no compiler information available\n"
-msgstr "derleyici bilgisi mevcut deÄŸil\n"
+msgstr "derleyici bilgisi yok\n"
msgid "no libc information available\n"
-msgstr "libc bilgisi mevcut deÄŸil\n"
+msgstr "libc bilgisi yok\n"
+
+#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "'%s' için boş disk alanı belirlenemedi"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "'%s' için bilgi alınamadı"
#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
@@ -14057,6 +14300,14 @@ msgid "could not read directory changes [GLE %ld]"
msgstr "dizin değişiklikleri okunamadı [GLE %ld]"
#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] '%ls', okuma için açılamıyor"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] '%ls' için protokol bilgisi alınamıyor"
+
+#, c-format
msgid "failed to copy SID (%ld)"
msgstr "SID kopyalanamadı (%ld)"
@@ -14600,181 +14851,6 @@ msgid "failed to close rev-list's stdin"
msgstr "rev-list'in stdin'i kapatılamadı"
#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' mevcut deÄŸil"
-
-msgid "need a working directory"
-msgstr "bir çalışma dizini gerekiyor"
-
-msgid "could not find enlistment root"
-msgstr "gönüllü yazılma kaydı bulunamıyor"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "şuraya geçilemedi: '%s'"
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "%s=%s yapılandırılamadı"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "log.excludeDecoration yapılandırılamadı"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "Scalar gönüllü kayıtları bir çalışma ağacı gerektiriyor"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "'%s' dizini açılamadı"
-
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "ne bir dosya ne de dizin olan '%s' atlanıyor"
-
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "'%s' için boş disk alanı belirlenemedi"
-
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "'%s' için bilgi alınamadı"
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "uzak konum HEAD'i bir dal deÄŸil: '%.*s'"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-"uzak konumdan öntanımlı dal adı alınamadı; yerel öntanımlı kullanılıyor"
-
-msgid "failed to get default branch name"
-msgstr "öntanımlı dal adı alınamadı"
-
-msgid "failed to unregister repository"
-msgstr "depo kaydı silinemedi"
-
-msgid "failed to delete enlistment directory"
-msgstr "gönüllü kayıt dizini silinemedi"
-
-msgid "branch to checkout after clone"
-msgstr "klonlama sonrası çıkış yapılacak dal"
-
-msgid "when cloning, create full working directory"
-msgstr "klonlama sırasında tam çalışma dizini oluştur"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "yalnızca çıkış yapılacak dalın üstverisini indir"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<seçenekler>] [--] <depo> [<dizin>]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "'%s' ögesinden çalışma ağacı adı ortaya çıkarılamıyor"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "'%s' dizini halihazırda var"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "'%s' için öntanımlı dal alınamadı"
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "'%s' içindeki uzak konum yapılandırılamadı"
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "'%s' yapılandırılamadı"
-
-msgid "partial clone failed; attempting full clone"
-msgstr "kısımsal klonlama başarısız; tam klonlama deneniyor"
-
-msgid "could not configure for full clone"
-msgstr "tam klonlama için yapılandırılamadı"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<gönüllükayıt>]"
-
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "'%s' için dizin oluşturulamadı"
-
-msgid "could not duplicate stdout"
-msgstr "stdout çoğaltılamadı"
-
-msgid "failed to write archive"
-msgstr "arşiv yazılamadı"
-
-msgid "`scalar list` does not take arguments"
-msgstr "'scalar list' argüman almıyor"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<gönüllükayıt>]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "tüm kaydı yapılmış gönüllü kayıtları yeniden yapılandır"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <gönüllükayıt>]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "--all veya <gönüllükayıt>; ancak ikisi değil"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "git deposu '%s' içinde gitti"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <görev> [<gönüllükayıt>]\n"
-"Görevler:\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "böyle bir görev yok: '%s'"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<enlistment>]"
-
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <gönüllükayıt>"
-
-msgid "refusing to delete current working directory"
-msgstr "geçerli çalışma dizinini silme reddediliyor"
-
-msgid "include Git version"
-msgstr "Git sürümünü içer"
-
-msgid "include Git's build options"
-msgstr "Git'in yapı seçeneklerini içer"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "-C, bir <dizin> gerektiriyor"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "'%s' olarak deÄŸiÅŸtirilemedi"
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c, bir <anahtar>=<değer> argümanı gerektiriyor"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <dizin>] [-c <anahtar>=<değer>] <komut> [<seçenekler>]\n"
-"\n"
-"Komutlar:\n"
-
-#, c-format
msgid "illegal crlf_action %d"
msgstr "izin verilmeyen crlf_action %d"
@@ -14980,6 +15056,32 @@ msgstr ""
msgid "Marked %d islands, done.\n"
msgstr "%d delta adası imlendi, bitti.\n"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "geçersiz --%s değeri '%s'"
+
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "eksik dizin '%s', arÅŸivlenemedi"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "'%s' dizini açılamadı"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "ne bir dosya ne de dizin olan '%s' atlanıyor"
+
+msgid "could not duplicate stdout"
+msgstr "stdout çoğaltılamadı"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "'%s' dizini, arÅŸivleyiciye eklenemedi"
+
+msgid "failed to write archive"
+msgstr "arşiv yazılamadı"
+
msgid "--merge-base does not work with ranges"
msgstr "--merge-base erimlerle çalışmaz"
@@ -15003,7 +15105,7 @@ msgid ""
"tree"
msgstr ""
"Bir git deposu değil. Bir çalışma ağacının dışındaki iki yolu karşılaştırmak "
-"için --no-index kullanın."
+"için --no-index kullanın"
#, c-format
msgid " Failed to parse dirstat cut-off percentage '%s'\n"
@@ -15539,7 +15641,7 @@ msgid ""
"Please specify a directory on the command line"
msgstr ""
"Bir dizin adı tahmin edilemedi.\n"
-"Lütfen komut satırında bir dizin belirtin."
+"Lütfen komut satırında bir dizin belirtin"
#, c-format
msgid "index file corrupt in repo %s"
@@ -15588,6 +15690,9 @@ msgstr "git fetch-pack: ACK/NAK bekleniyordu, '%s' alındı"
msgid "unable to write to remote"
msgstr "uzak konuma yazılamıyor"
+msgid "Server supports filter"
+msgstr "Sunucu süzgeç destekliyor"
+
#, c-format
msgid "invalid shallow line: %s"
msgstr "geçersiz sığ satır: %s"
@@ -15698,9 +15803,6 @@ msgstr "sunucu '%s' algoritmasını desteklemiyor"
msgid "Server does not support shallow requests"
msgstr "Sunucu sığ istekleri desteklemiyor"
-msgid "Server supports filter"
-msgstr "Sunucu süzgeç destekliyor"
-
msgid "unable to write request to remote"
msgstr "uzak konuma istek yazılamıyor"
@@ -15870,7 +15972,7 @@ msgid ""
"You can use '!git' in the alias to do this"
msgstr ""
"'%s' arması çevre değişkenlerini değiştirir.\n"
-"Bunu yapmak için armada '!git' kullanabilirsiniz."
+"Bunu yapmak için armada '!git' kullanabilirsiniz"
#, c-format
msgid "empty alias for %s"
@@ -15933,7 +16035,7 @@ msgid ""
"verification (available in openssh version 8.2p1+)"
msgstr ""
"ssh-keygen -Y find-principals/verify, ssh imza doğrulaması için gerekli "
-"(openssh 8.21p1+ sürümünde mevcut)"
+"(openssh 8.21p1+ sürümünde var)"
#, c-format
msgid "ssh signing revocation file configured but not found: %s"
@@ -15982,7 +16084,7 @@ msgid ""
"8.2p1+)"
msgstr ""
"ssh-keygen -Y imzası, ssh imzalaması için gerekli (openssh 8.21p1+ sürümünde "
-"mevcut)"
+"var)"
#, c-format
msgid "failed reading ssh signing data buffer from '%s'"
@@ -16047,6 +16149,12 @@ msgstr "Düşük Düzeyli Komutlar / Depo Eşitleme"
msgid "Low-level Commands / Internal Helpers"
msgstr "Düşük Düzeyli Komutlar / İç Yardımcılar"
+msgid "User-facing repository, command and file interfaces"
+msgstr "Kullanıcı için depo, komut ve dosya arayüzleri"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Geliştirici için dosya biçimleri, protokoller ve arayüzler"
+
#, c-format
msgid "available git commands in '%s'"
msgstr "'%s' içindeki kullanılabilir git komutları"
@@ -16060,6 +16168,12 @@ msgstr "En çok kullanılan temel Git komutlarının bir listesi aşağıdadır:
msgid "The Git concept guides are:"
msgstr "Git konsept kılavuzları şunlardır:"
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Kullanıcıya görünür depo, komut ve dosya arayüzleri:"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Dosya biçimleri, protokoller ve diğer geliştirici arayüzleri:"
+
msgid "External commands"
msgstr "Dış komutlar"
@@ -16143,16 +16257,13 @@ msgstr ""
"Bu uyarıyı 'git config advice.ignoredHook false' ile kapatabilirsiniz."
#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "'%s' kancası başlatılamadı\n"
-
-#, 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"
@@ -16330,21 +16441,16 @@ msgid "quoted CRLF detected"
msgstr "alıntılanmış CRLF algılandı"
#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"Birleştirme ile aşağıdaki dosyalardaki yerel değişikliklerin üzerine "
-"yazılacak:\n"
-"\t%s"
-
-#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "%s altmodülü birleştirilemedi (çıkış yapılmadı)"
#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "%s altmodülü birleştirilemedi (birleştirme temeli yok)"
+
+#, c-format
msgid "Failed to merge submodule %s (commits not present)"
-msgstr "%s altmodülü birleştirilemedi (işlemeler mevcut değil)"
+msgstr "%s altmodülü birleştirilemedi (işlemeler yok)"
#, c-format
msgid "Failed to merge submodule %s (commits don't follow merge-base)"
@@ -16360,34 +16466,16 @@ msgstr "'%s' altmodülü birleştirilemedi"
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-"%s altmodülü birleştirilemedi; ancak olası bir birleştirme çözümü mevcut:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
msgstr ""
-"Eğer bu doğruysa yalnızca indekse ekleyin, örneğin:\n"
-"\n"
-"\tgit update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"komutu bu öneriyi kabul edecektir.\n"
+"%s altmodülü birleştirilemedi; ancak olası bir birleştirme çözümü var: %s"
#, c-format
msgid ""
"Failed to merge submodule %s, but multiple possible merges exist:\n"
"%s"
msgstr ""
-"%s altmodülü birleştirilemedi; ancak birden çok olası birleştirmeler "
-"mevcut:\n"
+"%s altmodülü birleştirilemedi; ancak birden çok olası birleştirmeler var:\n"
"%s"
msgid "Failed to execute internal merge"
@@ -16406,7 +16494,7 @@ msgid ""
"CONFLICT (implicit dir rename): Existing file/dir at %s in the way of "
"implicit directory rename(s) putting the following path(s) there: %s."
msgstr ""
-"ÇAKIŞMA (örtülü dizin yeniden adlandırma): %s konumundaki mevcut dosya/dizin "
+"ÇAKIŞMA (örtülü dizin yeniden adlandırma): %s konumunda var olan dosya/dizin "
"örtülü yeniden adlandırmanın aşağıdaki yolları oraya koymasına engel oluyor: "
"%s."
@@ -16417,7 +16505,7 @@ msgid ""
msgstr ""
"ÇAKIŞMA (örtülü dizin yeniden adlandırma): %s için birden çok yol "
"eşlemlenemiyor; örtülü dizin yeniden adlandırmaları aşağıdaki yolları oraya "
-"koymayı denedi: %s."
+"koymayı denedi: %s"
#, c-format
msgid ""
@@ -16546,13 +16634,44 @@ msgstr ""
"ÇAKIŞMA (değiştir/sil): %s silindi (%s içinde) ve %s içinde değiştirildi. %s "
"sürümü (şunun: %s) ağaçta bırakıldı."
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
msgstr ""
-"Not: %s güncel değil ve çakışmalı sürümlerin çıkışının önünde; eski kopya %s "
-"olarak yeniden adlandırıldı."
+" - altmodüle gidin (%s) ve %s işlemesini birleştirin\n"
+" veya bu değişiklikleri birleştirmiş var olan bir işlemeye güncelleyin\n"
+
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"Altmodülle özyineli birleştirme şu anda yalnızca önemsiz durumları "
+"destekler.\n"
+"Her bir çakışan altmodülün birleştirmesini lütfen elle yapın.\n"
+"Bu, aşağıdaki adımlarla gerçekleştirilebilir:\n"
+"%s - yukarıdaki birleştirmeyi kaydetmek veya güncellemek için\n"
+" üst projeye geri gelin ve şunu çalıştırın:\n"
+"\n"
+" git add %s\n"
+"\n"
+" - üst projedeki kalan diğer çakışmaları çözün\n"
+" - üst projedeki sonuç olarak alınan indeksi işleyin\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -16625,6 +16744,21 @@ msgid "Found a possible merge resolution for the submodule:\n"
msgstr "Şu altmodül için olası bir birleştirme çözümü bulundu:\n"
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Eğer bu doğruysa yalnızca indekse ekleyin, örneğin:\n"
+"\n"
+"\tgit update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"komutu bu öneriyi kabul edecektir.\n"
+
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "%s altmodülü birleştirilemedi (birden çok birleştirme bulundu)"
@@ -16685,7 +16819,7 @@ msgstr ""
msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s"
msgstr ""
"ÇAKIŞMA (yeniden adlandır/ekle): %s->%s olarak adlandırıldı (%s içinde). %s "
-"eklendi (%s içinde)."
+"eklendi (%s içinde)"
#, c-format
msgid "%s is a directory in %s adding as %s instead"
@@ -16730,7 +16864,7 @@ msgid ""
">%s in %s"
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)."
+"içinde). Dizini %s->%s olarak adlandır (%s içinde)"
msgid "modify"
msgstr "deÄŸiÅŸtir"
@@ -16740,7 +16874,7 @@ msgstr "deÄŸiÅŸtirilmiÅŸ"
#, c-format
msgid "Skipped %s (merged same as existing)"
-msgstr "%s atlandı (mevcut ile aynı biçimde birleştirildi)"
+msgstr "%s atlandı (var olan ile aynı biçimde birleştirildi)"
#, c-format
msgid "Adding as %s instead"
@@ -16759,7 +16893,7 @@ msgstr "dizin/dosya"
#, c-format
msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
msgstr ""
-"ÇAKIŞMA (%s): %s adıyla bir dizin var (%s içinde). %s, %s olarak ekleniyor."
+"ÇAKIŞMA (%s): %s adıyla bir dizin var (%s içinde). %s, %s olarak ekleniyor"
#, c-format
msgid "Adding %s"
@@ -16858,7 +16992,7 @@ msgid "malformed line: %s"
msgstr "hatalı oluşturulmuş satır: %s"
msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "mevcut multi-pack-index yok sayılıyor; sağlama toplamı uyumsuzluğu"
+msgstr "var olan multi-pack-index yok sayılıyor; sağlama toplamı uyumsuzluğu"
msgid "could not load pack"
msgstr "paket yüklenemedi"
@@ -16903,7 +17037,7 @@ msgid "failed to clear multi-pack-index at %s"
msgstr "multi-pack-index %s konumunda temizlenemedi"
msgid "multi-pack-index file exists, but failed to parse"
-msgstr "multi-pack-index dosyası mevcut, ancak ayrıştırılamadı"
+msgstr "multi-pack-index dosyası var; ancak ayrıştırılamadı"
msgid "incorrect checksum"
msgstr "yanlış sağlama toplamı"
@@ -17070,7 +17204,7 @@ msgstr "nesne dosyası %s boş"
#, c-format
msgid "corrupt loose object '%s'"
-msgstr "hasar görmüş gevşek nesne '%s'"
+msgstr "hasarlı gevşek nesne '%s'"
#, c-format
msgid "garbage at end of loose object '%s'"
@@ -17101,11 +17235,11 @@ msgstr "%s yedeği %s için bulunamadı"
#, c-format
msgid "loose object %s (stored in %s) is corrupt"
-msgstr "%s gevşek nesnesi (%s içinde depolanıyor) hasar görmüş"
+msgstr "%s gevşek nesnesi (%s içinde depolanıyor) hasarlı"
#, c-format
msgid "packed object %s (stored in %s) is corrupt"
-msgstr "paketlenmiş nesne %s (%s içinde depolanıyor) hasar görmüş"
+msgstr "paketlenmiş nesne %s (%s içinde depolanıyor) hasarlı"
#, c-format
msgid "unable to write file %s"
@@ -17144,14 +17278,30 @@ msgid "confused by unstable object source data for %s"
msgstr "%s için olan nesne kaynak verisinden dolayı kafa karışıklığı"
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "akış nesnesini yaz %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "yeni nesne akışı söndürülemiyor (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "akış nesnesi üzerinde deflateEnd başarısız (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "%s dizini oluşturulamıyor"
+
+#, c-format
msgid "cannot read object for %s"
msgstr "%s için nesne okunamıyor"
msgid "corrupt commit"
-msgstr "hasar görmüş işleme"
+msgstr "hasarlı işleme"
msgid "corrupt tag"
-msgstr "hasar görmüş etiket"
+msgstr "hasarlı etiket"
#, c-format
msgid "read error while indexing %s"
@@ -17284,12 +17434,12 @@ msgstr ""
"oluşturmaz; çünkü 40 onaltılı bir başvuru, onu belirlediğiniz zaman yok\n"
"sayılacaktır. Bu başvurular yanlışlıkla oluşturulmuş olabilir. Örneğin:\n"
"\n"
-"\tgit switch -c $br $(git rev-parse ...)\n"
+" git switch -c $br $(git rev-parse ...)\n"
"\n"
"komutunda \"$br\" bir şekilde boş kalmış ve 40 onaltılı bir başvuru\n"
"oluşturulmuş. Lütfen bu başvuruları inceleyin ve gerekirse silin. Bu "
"iletiyi\n"
-"kapatmak için \"git config advice.objectNameWarning\" yapın."
+"kapatmak için \"git config advice.objectNameWarning\" yapın"
#, c-format
msgid "log for '%.*s' only goes back to %s"
@@ -17301,7 +17451,7 @@ msgstr "'%.*s' günlüğünde yalnızca %d girdi var"
#, c-format
msgid "path '%s' exists on disk, but not in '%.*s'"
-msgstr "'%s' yolu disk üzerinde mevcut; ancak '%.*s' içinde değil"
+msgstr "'%s' yolu disk üzerinde var; ancak '%.*s' içinde değil"
#, c-format
msgid ""
@@ -17370,6 +17520,58 @@ msgstr "nesne ayrıştırılamıyor: %s"
msgid "hash mismatch %s"
msgstr "sağlama uyuşmazlığı %s"
+msgid "trying to write commit not in index"
+msgstr "indekste olmayan işleme yazılmaya çalışılıyor"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "biteşlem indeksi yüklenemedi (hasarlı mı?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "hasarlı biteşlem indeksi (pek küçük)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "hasarlı biteşlem indeks dosyası (yanlış üstbilgi)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "biteşlem indeks dosyası için desteklenmeyen sürüm '%d'"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr ""
+"hasarlı biteşlem indeks dosyası (sağlama önbelleğine sığmak için pek küçük)"
+
+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)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "biteÅŸlem indeksinde yinelenen girdi: '%s'"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "hasarlı ewah biteşlemi: %d girdisi için kısaltılmış üstbilgi"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "hasarlı ewah biteşlemi: işleme erimi %u, erim dışında"
+
+msgid "corrupted bitmap pack index"
+msgstr "hasarlı biteşlem paket indeksi"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "biteşlem paket indeksinde geçersi XOR ofseti"
+
+msgid "cannot fstat bitmap file"
+msgstr "biteşlem dosyası fstat yapılamıyor"
+
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "ek biteşlem dosyası yok sayılıyor: '%s'"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "sağlama toplamı, MIDX ve biteşlem içinde uymuyor"
+
msgid "multi-pack bitmap is missing required reverse index"
msgstr "çoklu paket biteşlemi gereken ters indeksi içermiyor"
@@ -17381,9 +17583,57 @@ msgstr "%s paketi açılamadı"
msgid "preferred pack (%s) is invalid"
msgstr "tercih edilen (%s) paket geçersiz"
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "hasarlı biteşlem arama tablosu: üçlü konum indeks dışında"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr "hasarlı biteşlem arama tablosu: xor zinciri, girdi sayısını aşıyor"
+
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr "hasarlı biteşlem arama tablosu: işleme indeksi %u, erim dışında"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr ""
+"hasarlı ewah biteşlemi: \"%s\" işlemesinin biteşleminde kısaltılmış üstbilgi"
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "'%s' nesnesi, tür biteşlemlerinde bulunamadı"
+
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "%s, %s paketi %<PRIuMAX> ofsetinde bulunamadı"
+msgid "object '%s' does not have a unique type"
+msgstr "'%s' nesnesinin benzersiz bir türü yok"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "'%s' nesnesi: gerçek tür '%s', beklenen: '%s'"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "nesne, biteÅŸlemde deÄŸil: '%s'"
+
+msgid "failed to load bitmap indexes"
+msgstr "biteşlem indeksi yüklenemedi"
+
+msgid "you must specify exactly one commit to test"
+msgstr "sınamak için tam olarak bir işleme belirtmelisiniz"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "'%s' iÅŸlemesinin indekslenmiÅŸ bir biteÅŸlemi yok"
+
+msgid "mismatch in bitmap results"
+msgstr "biteşlem sonuçlarında uyuşmazlık"
+
+#, c-format
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "öge bulunamadı: '%s'; '%s' paketinde, %<PRIuMAX> ofsetinde"
+
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "'%s' ögesinin disk kullanımı alınamadı"
#, c-format
msgid "mtimes file %s is too small"
@@ -17507,6 +17757,9 @@ msgstr "ÅŸunu mu demek istediniz: '--%s' (iki tire ile)?"
msgid "alias of --%s"
msgstr "şunun arması: --%s"
+msgid "need a subcommand"
+msgstr "bir altkomut gerekli"
+
#, c-format
msgid "unknown option `%s'"
msgstr "bilinmeyen seçenek '%s'"
@@ -17939,9 +18192,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -17952,8 +18208,8 @@ msgstr ""
"e, edit <işleme> = işlemeyi kullan; ancak değiştirmek için dur\n"
"s, squash <işleme> = işlemeyi kullan; ancak önceki işleme içine karıştır\n"
"f, fixup [-C | -c] <işleme> = \"squash\" gibi; ancak yalnızca bir önceki\n"
-" işlemenin günlük iletisini tutar (-C kullanılmadıysa,\n"
-" o zaman yalnızca bu işlemenin iletisini tutar; -c, -C\n"
+" işlemenin günlük iletisini tutar (-C kullanılmadıysa\n"
+" o zaman yalnızca bu işlemenin iletisini tut; -c, -C\n"
" ile aynıdır; ancak ek olarak düzenleyiciyi açar)\n"
"x, exec <komut> = komutu (satırın geri kalanı) kabuk kullanarak çalıştır\n"
"b, break = burada dur (daha sonra sürdürmek için 'git rebase --continue')\n"
@@ -17964,7 +18220,10 @@ msgstr ""
". orijinal birleÅŸtirme iÅŸlemesi iletisini kullanarak bir\n"
". birleştirme işlemesi oluştur (veya teksatır, eğer bir orijinal\n"
". birleÅŸtirme iÅŸlemesi belirtilmemiÅŸse). Ä°ÅŸleme iletisini yeniden\n"
-". yazmak için -c <işleme> kullanın.\n"
+". yazmak için -c <işleme> kullan.\n"
+"u, update-ref <baş> = yeni iletilerde <baş>'ın bu konuma güncellenmesi için\n"
+" bir yer tutucu izle. <baÅŸ>, yeniden temellendirmenin\n"
+" sonunda güncellenir\n"
"\n"
"Bu satırlar yeniden sıralanabilirler, yukarıdan aşağıya çalıştırılırlar.\n"
@@ -18035,9 +18294,9 @@ msgid ""
msgstr ""
"Bu iletiden kaçınmak için, bir işlemeyi kaldırırken açıkça \"drop\" "
"kullanın.\n"
-"Uyarıların düzeyini değiştirmek için 'git config rebase.missingCommitsCheck' "
-"kullanın.\n"
-"Kullanılabilir davranışlar: ignore, warn, error.\n"
+"Uyarıların düzeyini değiştirmek için 'git config rebase."
+"missingCommitsCheck'\n"
+"kullanın. Kullanılabilir davranışlar: ignore, warn, error.\n"
"\n"
#, c-format
@@ -18434,6 +18693,13 @@ msgstr "protokol hatası: sha/ref bekleniyordu, '%s' alındı"
msgid "http transport does not support %s"
msgstr "http taşıyıcısı %s desteklemiyor"
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "protokol hatası: '<url> <yol>' bekleniyordu, eksik boşluk"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "'%s' URL'sindeki dosya indirilemedi"
+
msgid "git-http-push failed"
msgstr "git-http-push başarısız"
@@ -18460,6 +18726,7 @@ msgstr "birden fazla receivepack verildi, birincisi kullanılıyor"
msgid "more than one uploadpack given, using the first"
msgstr "birden fazla uploadpack verildi, birincisi kullanılıyor"
+#, c-format
msgid "unrecognized value transfer.credentialsInUrl: '%s'"
msgstr "tanımlanamayan değer transfer.credentialsInUrl: '%s'"
@@ -18770,6 +19037,14 @@ msgstr "HEAD revizyonu saptanamadı"
msgid "failed to find tree of %s"
msgstr "%s ögesinin ağacı bulunamadı"
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo, kayıp olan '%s' ögesini kaydetmiş"
+
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "soy yolu argümanı %s için işleme alınamadı"
+
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<paketdosyası> artık desteklenmiyor"
@@ -18790,6 +19065,173 @@ msgstr "-L, -p ve -s dışında başka diff biçimlerini henüz desteklemiyor"
msgid "cannot create async thread: %s"
msgstr "async iş parçacığı oluşturulamadı: %s"
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' yok"
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "şuraya geçilemedi: '%s'"
+
+msgid "need a working directory"
+msgstr "bir çalışma dizini gerekiyor"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "Scalar gönüllü kayıtları bir çalışma ağacı gerektiriyor"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "%s=%s yapılandırılamadı"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "log.excludeDecoration yapılandırılamadı"
+
+msgid "could not add enlistment"
+msgstr "gönüllü yazılma eklenemedi"
+
+msgid "could not set recommended config"
+msgstr "önerilen yapılandırma ayarlanamadı"
+
+msgid "could not turn on maintenance"
+msgstr "bakım ayarı açılamadı"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "FSMonitor ardalan süreci başlatılamadı"
+
+msgid "could not turn off maintenance"
+msgstr "bakım ayarı kapatılamadı"
+
+msgid "could not remove enlistment"
+msgstr "gönüllü yazılma kaldırılamadı"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "uzak konum HEAD'i bir dal deÄŸil: '%.*s'"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr ""
+"uzak konumdan öntanımlı dal adı alınamadı; yerel öntanımlı kullanılıyor"
+
+msgid "failed to get default branch name"
+msgstr "öntanımlı dal adı alınamadı"
+
+msgid "failed to unregister repository"
+msgstr "depo kaydı silinemedi"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "FSMonitor ardalan süreci durdurulamadı"
+
+msgid "failed to delete enlistment directory"
+msgstr "gönüllü kayıt dizini silinemedi"
+
+msgid "branch to checkout after clone"
+msgstr "klonlama sonrası çıkış yapılacak dal"
+
+msgid "when cloning, create full working directory"
+msgstr "klonlama sırasında tam çalışma dizini oluştur"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "yalnızca çıkış yapılacak dalın üstverisini indir"
+
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<seçenekler>] [--] <depo> [<dizin>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "'%s' ögesinden çalışma ağacı adı ortaya çıkarılamıyor"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "'%s' dizini halihazırda var"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "'%s' için öntanımlı dal alınamadı"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "'%s' içindeki uzak konum yapılandırılamadı"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "'%s' yapılandırılamadı"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "kısımsal klonlama başarısız; tam klonlama deneniyor"
+
+msgid "could not configure for full clone"
+msgstr "tam klonlama için yapılandırılamadı"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<gönüllükayıt>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "'scalar list' argüman almıyor"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<gönüllükayıt>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "tüm kaydı yapılmış gönüllü kayıtları yeniden yapılandır"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <gönüllükayıt>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all veya <gönüllükayıt>; ancak ikisi değil"
+
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "git deposu '%s' içinde gitti"
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <görev> [<gönüllükayıt>]\n"
+"Görevler:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "böyle bir görev yok: '%s'"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<enlistment>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <gönüllükayıt>"
+
+msgid "refusing to delete current working directory"
+msgstr "geçerli çalışma dizinini silme reddediliyor"
+
+msgid "include Git version"
+msgstr "Git sürümünü içer"
+
+msgid "include Git's build options"
+msgstr "Git'in yapı seçeneklerini içer"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C, bir <dizin> gerektiriyor"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "'%s' olarak deÄŸiÅŸtirilemedi"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c, bir <anahtar>=<değer> argümanı gerektiriyor"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <dizin>] [-c <anahtar>=<değer>] <komut> [<seçenekler>]\n"
+"\n"
+"Komutlar:\n"
+
msgid "unexpected flush packet while reading remote unpack status"
msgstr "uzak konum açım durumu okunurken beklenmedik floş paketi"
@@ -18910,10 +19352,6 @@ msgstr "%s ile yerel değişikliklerinizin üzerine yazılacaktır."
msgid "commit your changes or stash them to proceed."
msgstr "İlerlemek için değişikliklerinizi işleyin veya zulalayın."
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: ileri sar"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -18976,15 +19414,15 @@ msgstr ""
"Eğer bu değişikliklerin bir önceki işlemeye eklenmesi\n"
"gerekiyorsa şu komutu çalıştırın:\n"
"\n"
-"\tgit commit --amend %s\n"
+" git commit --amend %s\n"
"\n"
"Yeni bir işleme yapmak istiyorsanız şu komutu çalıştırın:\n"
"\n"
-"\tgit commit %s\n"
+" git commit %s\n"
"\n"
"Her iki durumda da işiniz bittikten sonra şu komut ile sürdürün:\n"
"\n"
-"\tgit rebase --continue\n"
+" git rebase --continue\n"
msgid "'prepare-commit-msg' hook failed"
msgstr "'prepare-commit-msg' başarısız oldu"
@@ -19397,6 +19835,27 @@ msgstr "şunu birleştirme girişiminde bulunulamadı bile: '%.*s'"
msgid "merge: Unable to write new index file"
msgstr "merge: Yeni indeks dosyası yazılamıyor"
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "başka bir 'rebase' süreci çalışıyor gibi; '%s.lock' halihazırda var"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Aşağıdaki başvurular, %s ile güncellendi:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Aşağıdaki başvurular, %s ile güncellenemedi:\n"
+"%s"
+
msgid "Cannot autostash"
msgstr "Kendiliğinden zulalanamıyor"
@@ -19563,6 +20022,10 @@ msgid "the script was already rearranged."
msgstr "betik halihazırda yeniden düzenlenmişti."
#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "'%s' konumundaki update-refs dosyası geçersiz"
+
+#, c-format
msgid "'%s' is outside repository at '%s'"
msgstr "'%s', '%s' konumunda depo dışında"
@@ -19681,17 +20144,21 @@ msgstr ""
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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 ""
-"güvensiz depo ('%s' sahibi bir başkası)\n"
-"Bu dizin için bir istisna eklemek için şunu çağırın:\n"
+"'%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')"
+
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -20555,6 +21022,18 @@ msgstr "geçersiz kapı numarası"
msgid "invalid '..' path segment"
msgstr "geçersiz '..' yol kesimi"
+msgid "usage: "
+msgstr "kullanım: "
+
+msgid "fatal: "
+msgstr "onulmaz: "
+
+msgid "error: "
+msgstr "hata: "
+
+msgid "warning: "
+msgstr "uyarı: "
+
msgid "Fetching objects"
msgstr "Nesneler getiriliyor"
@@ -21345,22 +21824,6 @@ msgstr "Seçili parçalar indekse uygulanamıyor!\n"
msgid "ignoring unmerged: %s\n"
msgstr "birleştirilmeyenler yok sayılıyor: %s\n"
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "Kip değişimi çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Silme çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Ekleme çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "Bu parça çalışma ağacına uygulansın mı [y,n,q,a,d%s,?]? "
-
msgid "No other hunks to goto\n"
msgstr "Gidilecek başka parça yok\n"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 7de9c72d564..b0832be6952 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -144,8 +144,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-22 10:25+0100\n"
-"PO-Revision-Date: 2022-06-14 20:52+0100\n"
+"POT-Creation-Date: 2022-09-28 15:50+0100\n"
+"PO-Revision-Date: 2022-09-23 14:53+0100\n"
"Last-Translator: Fangyi Zhou <me@fangyi.io>\n"
"Language-Team: GitHub <https://github.com/fangyi-zhou/git-po/>\n"
"Language: zh_CN\n"
@@ -153,14 +153,14 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 40.0\n"
+"X-Generator: Gtranslator 42.0\n"
#: add-interactive.c
#, c-format
msgid "Huh (%s)?"
msgstr "嗯(%s)?"
-#: add-interactive.c builtin/rebase.c reset.c sequencer.c
+#: add-interactive.c builtin/merge.c builtin/rebase.c reset.c sequencer.c
msgid "could not read index"
msgstr "ä¸èƒ½è¯»å–索引"
@@ -341,8 +341,8 @@ msgid "unstaged"
msgstr "未缓存"
#: add-interactive.c apply.c builtin/am.c builtin/bugreport.c builtin/clone.c
-#: builtin/fetch.c builtin/merge.c builtin/pull.c builtin/submodule--helper.c
-#: git-add--interactive.perl
+#: builtin/diagnose.c builtin/fetch.c builtin/merge.c builtin/pull.c
+#: builtin/submodule--helper.c git-add--interactive.perl
msgid "path"
msgstr "路径"
@@ -623,6 +623,26 @@ msgstr ""
"a - 应用该å—和本文件中åŽé¢çš„全部å—\n"
"d - ä¸è¦åº”用该å—和本文件中åŽé¢çš„全部å—\n"
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "将模å¼å˜æ›´åº”用到工作区 [y,n,q,a,d%s,?]? "
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "将删除æ“作应用到工作区 [y,n,q,a,d%s,?]? "
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "将添加æ“作应用到工作区 [y,n,q,a,d%s,?]? "
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "将该å—应用到工作区 [y,n,q,a,d%s,?]? "
+
#: add-patch.c
msgid ""
"y - apply this hunk to worktree\n"
@@ -643,11 +663,6 @@ msgid "could not parse hunk header '%.*s'"
msgstr "无法解æžæ•°æ®å—å¤´ä¿¡æ¯ '%.*s'"
#: add-patch.c
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "无法解æžå½©è‰²æ•°æ®å—å¤´ä¿¡æ¯ '%.*s'"
-
-#: add-patch.c
msgid "could not parse diff"
msgstr "ä¸èƒ½è§£æžå·®å¼‚ä¿¡æ¯"
@@ -973,6 +988,26 @@ msgstr ""
"通过将é…ç½®å˜é‡ advice.detachedHead 设置为 false æ¥å…³é—­æ­¤å»ºè®®\n"
"\n"
+#: advice.c
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"下列的路径已ç»è¢«ç§»åŠ¨è‡³ç¨€ç–检出的定义之外,\n"
+"但是由于本地的修改而并éžç¨€ç–。\n"
+
+#: advice.c
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"为了修正这些的路径的稀ç–性,请è¿è¡Œä¸‹åˆ—命令:\n"
+"* 使用 \"git add --sparse <路径>\" æ¥æ›´æ–°ç´¢å¼•\n"
+"* 使用 \"git sparse-checkout reapply\" æ¥åº”用稀ç–规则"
+
#: alias.c
msgid "cmdline ends with \\"
msgstr "命令行以 \\ 结尾"
@@ -1204,7 +1239,7 @@ msgstr "到 '%s' 的二进制补ä¸äº§ç”Ÿäº†ä¸æ­£ç¡®çš„结果(应为 %s,å´
msgid "patch failed: %s:%ld"
msgstr "打补ä¸å¤±è´¥ï¼š%s:%ld"
-#: apply.c
+#: apply.c builtin/mv.c
#, c-format
msgid "cannot checkout %s"
msgstr "ä¸èƒ½æ£€å‡º %s"
@@ -1597,6 +1632,11 @@ msgstr "ä¸èƒ½æ‰“开数æ®å¯¹è±¡ %s"
msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "ä¸æ”¯æŒçš„文件模å¼ï¼š0%o (SHA1: %s)"
+#: archive-tar.c archive-zip.c builtin/pack-objects.c
+#, c-format
+msgid "deflate error (%d)"
+msgstr "压缩错误 (%d)"
+
#: archive-tar.c
#, c-format
msgid "unable to start '%s' filter"
@@ -1621,11 +1661,6 @@ msgstr "路径ä¸æ˜¯æœ‰æ•ˆçš„ UTF-8:%s"
msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "路径太长(%d 字符,SHA1:%s):%s"
-#: archive-zip.c builtin/pack-objects.c
-#, c-format
-msgid "deflate error (%d)"
-msgstr "压缩错误 (%d)"
-
#: archive-zip.c
#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
@@ -1941,10 +1976,10 @@ msgid "--reverse and --first-parent together require specified latest commit"
msgstr "--reverse å’Œ --first-parent 共用,需è¦æŒ‡å®šæœ€æ–°çš„æ交"
#: blame.c builtin/commit.c builtin/log.c builtin/merge.c
-#: builtin/pack-objects.c builtin/shortlog.c bundle.c midx.c ref-filter.c
-#: remote.c sequencer.c submodule.c
+#: builtin/pack-objects.c builtin/shortlog.c bundle.c midx.c pack-bitmap.c
+#: ref-filter.c remote.c sequencer.c submodule.c
msgid "revision walk setup failed"
-msgstr "版本é历设置失败"
+msgstr "版本é历åˆå§‹åŒ–失败"
#: blame.c
msgid ""
@@ -2399,7 +2434,7 @@ msgstr "fseek 失败"
msgid "could not open '%s' for reading"
msgstr "无法打开 '%s' 进行读å–"
-#: builtin/am.c builtin/rebase.c strbuf.c wrapper.c
+#: builtin/am.c builtin/rebase.c sequencer.c strbuf.c wrapper.c
#, c-format
msgid "could not open '%s' for writing"
msgstr "无法打开 '%s' 进行写入"
@@ -2700,8 +2735,8 @@ msgid "n"
msgstr "n"
#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
-#: builtin/for-each-ref.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c
+#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c
msgid "format"
msgstr "æ ¼å¼"
@@ -2804,7 +2839,7 @@ msgstr "交互å¼æ¨¡å¼éœ€è¦å‘½ä»¤è¡Œä¸Šæ供补ä¸"
msgid "git apply [<options>] [<patch>...]"
msgstr "git apply [<选项>] [<è¡¥ä¸>...]"
-#: builtin/archive.c contrib/scalar/scalar.c
+#: builtin/archive.c diagnose.c
msgid "could not redirect output"
msgstr "ä¸èƒ½é‡å®šå‘输出"
@@ -3686,8 +3721,8 @@ msgstr "排åºå’Œè¿‡æ»¤å±žäºŽå¤§å°å†™ä¸æ•æ„Ÿ"
msgid "recurse through submodules"
msgstr "在å­æ¨¡ç»„中递归"
-#: builtin/branch.c builtin/for-each-ref.c builtin/ls-tree.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/branch.c builtin/for-each-ref.c builtin/ls-files.c builtin/ls-tree.c
+#: builtin/tag.c builtin/verify-tag.c
msgid "format to use for the output"
msgstr "输出格å¼"
@@ -3810,8 +3845,12 @@ msgid "not run from a git repository - no hooks to show\n"
msgstr "ä¸æ˜¯åœ¨ git 仓库中执行 - 没有å¯æ˜¾ç¤ºçš„é’©å­\n"
#: builtin/bugreport.c
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <文件>] [-s|--suffix <æ ¼å¼>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <文件>] [-s|--suffix <æ ¼å¼>] [--"
+"diagnose[=<模å¼>]"
#: builtin/bugreport.c
msgid ""
@@ -3847,19 +3886,34 @@ msgstr ""
"请检查下é¢é”™è¯¯æŠ¥å‘Šä¸­ä½™ä¸‹çš„内容。\n"
"您å¯ä»¥åˆ é™¤ä»»ä½•æ‚¨ä¸æƒ³å…±äº«çš„内容。\n"
+#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c
+#: parse-options.h
+msgid "mode"
+msgstr "模å¼"
+
+#: builtin/bugreport.c
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr "é¢å¤–创建详细诊断信æ¯çš„压缩包(默认 'stats')"
+
#: builtin/bugreport.c
-msgid "specify a destination for the bugreport file"
+msgid "specify a destination for the bugreport file(s)"
msgstr "指定错误报告文件的目标ä½ç½®"
#: builtin/bugreport.c
-msgid "specify a strftime format suffix for the filename"
+msgid "specify a strftime format suffix for the filename(s)"
msgstr "指定文件的 strftime æ ¼å¼åŽç¼€"
-#: builtin/bugreport.c
+#: builtin/bugreport.c builtin/diagnose.c
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "ä¸èƒ½ä¸º '%s' 创建先导目录"
+#: builtin/bugreport.c builtin/diagnose.c
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "ä¸èƒ½åˆ›å»ºè¯Šæ–­å½’档包 %s"
+
#: builtin/bugreport.c
msgid "System Info"
msgstr "系统信æ¯"
@@ -3935,11 +3989,6 @@ msgstr "需è¦ä¸€ä¸ªä»“库æ¥è§£å¼€å½’档包。"
msgid "Unbundling objects"
msgstr "解包对象中"
-#: builtin/bundle.c builtin/remote.c
-#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "未知å­å‘½ä»¤ï¼š%s"
-
#: builtin/cat-file.c merge-recursive.c
#, c-format
msgid "cannot read object %s '%s'"
@@ -4037,6 +4086,10 @@ msgstr "显示对象大å°"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "å…许 -s å’Œ -t 对æŸå的对象生效"
+#: builtin/cat-file.c builtin/log.c
+msgid "use mail map file"
+msgstr "使用邮件映射文件"
+
#: builtin/cat-file.c
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr "批é‡å¤„ç†æ ‡å‡†è¾“入中请求的对象(或者 --batch-all-objects)"
@@ -4050,6 +4103,10 @@ msgid "like --batch, but don't emit <contents>"
msgstr "类似于 --batch,但ä¸è¾“出 <内容>"
#: builtin/cat-file.c
+msgid "stdin is NUL-terminated"
+msgstr "标准输入以 NUL 字符分隔"
+
+#: builtin/cat-file.c
msgid "read commands from stdin"
msgstr "从标准输入读å–命令"
@@ -4725,7 +4782,7 @@ msgstr ""
#: builtin/checkout.c
msgid "you must specify path(s) to restore"
-msgstr "您必须指定一个è¦æ¢å¤çš„路径"
+msgstr "您必须指定è¦æ¢å¤çš„路径"
#: builtin/checkout.c builtin/clone.c builtin/remote.c
#: builtin/submodule--helper.c builtin/worktree.c
@@ -5131,6 +5188,14 @@ msgid "initialize sparse-checkout file to include only files at root"
msgstr "åˆå§‹åŒ–稀ç–检出文件,åªåŒ…å«æ ¹ç›®å½•æ–‡ä»¶"
#: builtin/clone.c
+msgid "uri"
+msgstr "uri"
+
+#: builtin/clone.c
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "用于在从 origin 远程获å–之å‰ä¸‹è½½å½’档包的 URI"
+
+#: builtin/clone.c
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: ä¸èƒ½ä¸º '%s' 添加一个备用:%s\n"
@@ -5204,8 +5269,8 @@ msgid "failed to initialize sparse-checkout"
msgstr "无法åˆå§‹åŒ–稀ç–检出"
#: builtin/clone.c
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr "远程 HEAD 指å‘一个ä¸å­˜åœ¨çš„引用,无法检出。\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
+msgstr "远程 HEAD 指å‘一个ä¸å­˜åœ¨çš„引用,无法检出"
#: builtin/clone.c
msgid "unable to checkout working tree"
@@ -5227,7 +5292,7 @@ msgstr "无法删除临时的 alternates 文件"
msgid "Too many arguments."
msgstr "太多å‚数。"
-#: builtin/clone.c contrib/scalar/scalar.c
+#: builtin/clone.c scalar.c
msgid "You must specify a repository to clone."
msgstr "您必须指定一个仓库æ¥å…‹éš†ã€‚"
@@ -5237,6 +5302,12 @@ msgid "options '%s' and '%s %s' cannot be used together"
msgstr "选项 '%s' å’Œ '%s %s' ä¸èƒ½åŒæ—¶ä½¿ç”¨"
#: builtin/clone.c
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr "--bundle-uri 与 --depthã€--shallow-since å’Œ --shallow-exclude ä¸å…¼å®¹"
+
+#: builtin/clone.c
#, c-format
msgid "repository '%s' does not exist"
msgstr "仓库 '%s' ä¸å­˜åœ¨"
@@ -5325,6 +5396,15 @@ msgid "cannot clone from filtered bundle"
msgstr "无法从ç»è¿‡è¿‡æ»¤çš„归档包克隆"
#: builtin/clone.c
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "无法åˆå§‹åŒ–仓库,跳过归档包 URI"
+
+#: builtin/clone.c
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "无法从归档包 URI '%s' 获å–对象"
+
+#: builtin/clone.c
msgid "remote transport reported error"
msgstr "远程传输报告错误"
@@ -5471,11 +5551,6 @@ msgstr "ä¸èƒ½åŒæ—¶ä½¿ç”¨ --reachableã€--stdin-commits 或 --stdin-packs"
msgid "Collecting commits from input"
msgstr "正从标准输入收集æ交"
-#: builtin/commit-graph.c builtin/multi-pack-index.c
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "未识别的å­å‘½ä»¤ï¼š%s"
-
#: builtin/commit-tree.c
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
@@ -5903,10 +5978,6 @@ msgstr "以长格å¼æ˜¾ç¤ºçŠ¶æ€ï¼ˆé»˜è®¤ï¼‰"
msgid "terminate entries with NUL"
msgstr "æ¡ç›®ä»¥ NUL 字符结尾"
-#: builtin/commit.c builtin/fast-export.c builtin/rebase.c parse-options.h
-msgid "mode"
-msgstr "模å¼"
-
#: builtin/commit.c
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr "显示未跟踪的文件,“模å¼â€çš„å¯é€‰å‚数:allã€normalã€no。(默认:all)"
@@ -6644,6 +6715,26 @@ msgstr "没有å‘现å称,无法æ述任何东西。"
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "选项 '%s' å’Œæ交å·ä¸èƒ½åŒæ—¶ä½¿ç”¨"
+#: builtin/diagnose.c
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <文件>] [-s|--suffix <æ ¼å¼>] [--mode=<模"
+"å¼>]"
+
+#: builtin/diagnose.c
+msgid "specify a destination for the diagnostics archive"
+msgstr "指定诊断归档包的目标ä½ç½®"
+
+#: builtin/diagnose.c
+msgid "specify a strftime format suffix for the filename"
+msgstr "指定文件的 strftime æ ¼å¼åŽç¼€"
+
+#: builtin/diagnose.c
+msgid "specify the content of the diagnostic archive"
+msgstr "指定诊断信æ¯å½’档包的内容"
+
#: builtin/diff-tree.c
msgid "--merge-base only works with two commits"
msgstr "--merge-base 仅适用于两个æ交"
@@ -7115,12 +7206,8 @@ msgid "[rejected]"
msgstr "[已拒ç»]"
#: builtin/fetch.c
-msgid "can't fetch in current branch"
-msgstr "当å‰åˆ†æ”¯ä¸‹ä¸èƒ½æ‰§è¡ŒèŽ·å–æ“作"
-
-#: builtin/fetch.c
-msgid "checked out in another worktree"
-msgstr "已在å¦ä¸€ä¸ªå·¥ä½œæ ‘中检出"
+msgid "can't fetch into checked-out branch"
+msgstr "无法获å–到已检出的分支"
#: builtin/fetch.c
msgid "[tag update]"
@@ -7659,6 +7746,11 @@ msgid "non-tree in cache-tree"
msgstr "cache-tree 中éžæ ‘对象"
#: builtin/fsck.c
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s:resolve-undo 中无效的 sha1 指针"
+
+#: builtin/fsck.c
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<选项>] [<对象>...]"
@@ -8075,12 +8167,16 @@ msgid "failed to run 'crontab -l'; your system might not support 'cron'"
msgstr "无法执行 'crontab -l',您的系统å¯èƒ½ä¸æ”¯æŒ 'cron'"
#: builtin/gc.c
-msgid "failed to run 'crontab'; your system might not support 'cron'"
-msgstr "无法è¿è¡Œ 'crontab',您的系统å¯èƒ½ä¸æ”¯æŒ 'cron'"
+msgid "failed to create crontab temporary file"
+msgstr "无法创建 crontab 临时文件"
#: builtin/gc.c
-msgid "failed to open stdin of 'crontab'"
-msgstr "无法打开 'crontab' 的标准输入"
+msgid "failed to open temporary file"
+msgstr "无法打开临时文件"
+
+#: builtin/gc.c
+msgid "failed to run 'crontab'; your system might not support 'cron'"
+msgstr "无法è¿è¡Œ 'crontab',您的系统å¯èƒ½ä¸æ”¯æŒ 'cron'"
#: builtin/gc.c
msgid "'crontab' died"
@@ -8142,11 +8238,6 @@ msgstr "无法将仓库添加到全局é…ç½®"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <å­å‘½ä»¤> [<选项>]"
-#: builtin/gc.c
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "无效å­å‘½ä»¤ï¼š%s"
-
#: builtin/grep.c
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<选项>] [-e] <模å¼> [<版本>...] [[--] <路径>...]"
@@ -8371,6 +8462,10 @@ msgid "allow calling of grep(1) (ignored by this build)"
msgstr "å…许调用 grep(1)(本次构建忽略)"
#: builtin/grep.c
+msgid "maximum number of results per file"
+msgstr "æ¯ä¸ªæ–‡ä»¶çš„最大结果数é‡"
+
+#: builtin/grep.c
msgid "no pattern given"
msgstr "未æ供匹é…模å¼"
@@ -8482,12 +8577,20 @@ msgid "print list of useful guides"
msgstr "显示有用的指å—列表"
#: builtin/help.c
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr "打å°é¢å‘用户的仓库ã€å‘½ä»¤å’Œæ–‡ä»¶æŽ¥å£åˆ—表"
+
+#: builtin/help.c
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr "打å°æ–‡ä»¶æ ¼å¼ã€å议和其他开å‘者接å£åˆ—表"
+
+#: builtin/help.c
msgid "print all configuration variable names"
msgstr "打å°æ‰€æœ‰é…ç½®å˜é‡å称"
#: builtin/help.c
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<命令>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<命令>|<文档>]"
#: builtin/help.c
#, c-format
@@ -9078,8 +9181,8 @@ msgid "show source"
msgstr "显示æº"
#: builtin/log.c
-msgid "use mail map file"
-msgstr "使用邮件映射文件"
+msgid "clear all previously-defined decoration filters"
+msgstr "清除所有之å‰å®šä¹‰çš„修饰过滤器"
#: builtin/log.c
msgid "only decorate refs that match <pattern>"
@@ -9405,6 +9508,10 @@ msgid "percentage by which creation is weighted"
msgstr "创建æƒé‡çš„百分比"
#: builtin/log.c
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "显示正文内的 From:,å³ä½¿å…¶ä¸Žç”µå­é‚®ä»¶å¤´ä¸­ä¸€è‡´"
+
+#: builtin/log.c
#, c-format
msgid "invalid ident line: %s"
msgstr "包å«æ— æ•ˆçš„身份标识:%s"
@@ -9480,10 +9587,25 @@ msgid ""
msgstr "ä¸èƒ½æ‰¾åˆ°è·Ÿè¸ªçš„远程分支,请手工指定 <上游>。\n"
#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "åçš„ ls-files æ ¼å¼ï¼šå…ƒç´  '%s' 没有以 '(' 开头"
+
+#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "åçš„ ls-files æ ¼å¼ï¼šå…ƒç´  '%s' 没有以 ')' 结尾"
+
+#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "åçš„ ls-files æ ¼å¼: %%%.*s"
+
+#: builtin/ls-files.c
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<选项>] [<文件>...]"
-#: builtin/ls-files.c
+#: builtin/ls-files.c builtin/merge-tree.c
msgid "separate paths with the NUL character"
msgstr "用 NUL 字符分隔路径"
@@ -9591,6 +9713,14 @@ msgstr "抑制é‡å¤æ¡ç›®"
msgid "show sparse directories in the presence of a sparse index"
msgstr "在稀ç–索引存在时显示稀ç–目录"
+#: builtin/ls-files.c
+msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format ä¸èƒ½å’Œ -sã€-oã€-kã€-tã€--resolve-undoã€--deduplicate å’Œ --eol åŒæ—¶ä½¿"
+"用"
+
#: builtin/ls-remote.c
msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -9874,6 +10004,50 @@ msgstr "无法解æžå¼•ç”¨ '%s'"
msgid "Merging %s with %s\n"
msgstr "åˆå¹¶ %s å’Œ %s\n"
+#: builtin/merge-tree.c builtin/merge.c
+msgid "not something we can merge"
+msgstr "ä¸æ˜¯å¯ä»¥åˆå¹¶çš„东西"
+
+#: builtin/merge-tree.c builtin/merge.c
+msgid "refusing to merge unrelated histories"
+msgstr "æ‹’ç»åˆå¹¶æ— å…³çš„历å²"
+
+#: builtin/merge-tree.c
+msgid "failure to merge"
+msgstr "åˆå¹¶å¤±è´¥"
+
+#: builtin/merge-tree.c
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<选项>] <分支1> <分支2>"
+
+#: builtin/merge-tree.c
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <基准树> <分支1> <分支2>"
+
+#: builtin/merge-tree.c
+msgid "do a real merge instead of a trivial merge"
+msgstr "进行真正的åˆå¹¶è€Œä¸æ˜¯ç®€å•çš„åˆå¹¶"
+
+#: builtin/merge-tree.c
+msgid "do a trivial merge only"
+msgstr "åªè¿›è¡Œç®€å•çš„åˆå¹¶"
+
+#: builtin/merge-tree.c
+msgid "also show informational/conflict messages"
+msgstr "åŒæ—¶æ˜¾ç¤ºé¢å¤–ä¿¡æ¯/冲çªæ¶ˆæ¯"
+
+#: builtin/merge-tree.c
+msgid "list filenames without modes/oids/stages"
+msgstr "列出没有模å¼/对象 ID/暂存的文件å"
+
+#: builtin/merge-tree.c builtin/merge.c builtin/pull.c
+msgid "allow merging unrelated histories"
+msgstr "å…许åˆå¹¶ä¸ç›¸å…³çš„历å²"
+
+#: builtin/merge-tree.c
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge 与其他所有选项ä¸å…¼å®¹"
+
#: builtin/merge.c
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<选项>] [<æ交>...]"
@@ -9980,10 +10154,6 @@ msgstr "--abort,但是ä¿ç•™ç´¢å¼•å’Œå·¥ä½œåŒº"
msgid "continue the current in-progress merge"
msgstr "继续当å‰æ­£åœ¨è¿›è¡Œçš„åˆå¹¶"
-#: builtin/merge.c builtin/pull.c
-msgid "allow merging unrelated histories"
-msgstr "å…许åˆå¹¶ä¸ç›¸å…³çš„历å²"
-
#: builtin/merge.c
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "绕过 pre-merge-commit å’Œ commit-msg é’©å­"
@@ -10129,10 +10299,6 @@ msgid "not something we can merge in %s: %s"
msgstr "ä¸èƒ½åœ¨ %s 中åˆå¹¶ï¼š%s"
#: builtin/merge.c
-msgid "not something we can merge"
-msgstr "ä¸èƒ½åˆå¹¶"
-
-#: builtin/merge.c
msgid "--abort expects no arguments"
msgstr "--abort ä¸å¸¦å‚æ•°"
@@ -10194,14 +10360,19 @@ msgid "Can merge only exactly one commit into empty head"
msgstr "åªèƒ½å°†ä¸€ä¸ªæ交åˆå¹¶åˆ°ç©ºåˆ†æ”¯ä¸Š"
#: builtin/merge.c
-msgid "refusing to merge unrelated histories"
-msgstr "æ‹’ç»åˆå¹¶æ— å…³çš„历å²"
-
-#: builtin/merge.c
#, c-format
msgid "Updating %s..%s\n"
msgstr "æ›´æ–° %s..%s\n"
+#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c
+#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"您对下列文件的本地修改将被åˆå¹¶æ“作覆盖:\n"
+" %s"
+
#: builtin/merge.c
#, c-format
msgid "Trying really trivial in-index merge...\n"
@@ -10242,6 +10413,11 @@ msgstr "使用 %s 策略以准备手工解决。\n"
msgid "Automatic merge went well; stopped before committing as requested\n"
msgstr "自动åˆå¹¶è¿›å±•é¡ºåˆ©ï¼ŒæŒ‰è¦æ±‚在æ交å‰åœæ­¢\n"
+#: builtin/merge.c
+#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "在完æˆåŽï¼Œä½¿ç”¨ `git stash pop` 应用贮è—çš„å˜æ›´\n"
+
#: builtin/mktag.c
#, c-format
msgid "warning: tag input does not pass fsck: %s"
@@ -10390,6 +10566,10 @@ msgid "bad source"
msgstr "åçš„æº"
#: builtin/mv.c
+msgid "destination exists"
+msgstr "目标已存在"
+
+#: builtin/mv.c
msgid "can not move directory into itself"
msgstr "ä¸èƒ½å°†ç›®å½•ç§»åŠ¨åˆ°è‡ªèº«"
@@ -10410,10 +10590,6 @@ msgid "conflicted"
msgstr "冲çª"
#: builtin/mv.c
-msgid "destination exists"
-msgstr "目标已存在"
-
-#: builtin/mv.c
#, c-format
msgid "overwriting '%s'"
msgstr "覆盖 '%s'"
@@ -10431,6 +10607,10 @@ msgid "destination directory does not exist"
msgstr "目标目录ä¸å­˜åœ¨"
#: builtin/mv.c
+msgid "destination exists in the index"
+msgstr "目标在索引中已存在"
+
+#: builtin/mv.c
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s,æº=%s,目标=%s"
@@ -10872,10 +11052,10 @@ msgstr "注解引用"
msgid "use notes from <notes-ref>"
msgstr "从 <注解引用> 使用注解"
-#: builtin/notes.c builtin/stash.c
+#: builtin/notes.c builtin/remote.c parse-options.c
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "未知å­å‘½ä»¤ï¼š%s"
+msgid "unknown subcommand: `%s'"
+msgstr "未知å­å‘½ä»¤ï¼š`%s'"
#: builtin/pack-objects.c
msgid ""
@@ -11473,7 +11653,7 @@ msgstr "è¯¦è§ git-pull(1)。"
msgid "<remote>"
msgstr "<远程>"
-#: builtin/pull.c contrib/scalar/scalar.c
+#: builtin/pull.c scalar.c
msgid "<branch>"
msgstr "<分支>"
@@ -11926,12 +12106,18 @@ msgstr "仅显示与第二个范围有关的输出"
#: builtin/range-diff.c
#, c-format
+msgid "not a revision: '%s'"
+msgstr "ä¸æ˜¯ç‰ˆæœ¬ï¼š'%s'"
+
+#: builtin/range-diff.c
+#, c-format
msgid "not a commit range: '%s'"
-msgstr "ä¸æ˜¯ä¸€ä¸ªæ交范围:'%s'"
+msgstr "ä¸æ˜¯æ交范围:'%s'"
#: builtin/range-diff.c
-msgid "single arg format must be symmetric range"
-msgstr "å•ä¸ªå‚æ•°æ ¼å¼å¿…须是对称范围(å³åŒ…å«...)"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "ä¸æ˜¯å¯¹ç§°çš„范围:'%s'"
#: builtin/range-diff.c
msgid "need two commit ranges"
@@ -12266,6 +12452,10 @@ msgid "move commits that begin with squash!/fixup! under -i"
msgstr "在 -i 交互模å¼ä¸‹ï¼Œç§»åŠ¨ä»¥ squash!/fixup! 开头的æ交"
#: builtin/rebase.c
+msgid "update branches that point to commits that are being rebased"
+msgstr "更新指å‘正在被å˜åŸºçš„æ交的分支"
+
+#: builtin/rebase.c
msgid "add exec lines after each commit of the editable list"
msgstr "å¯ç¼–辑列表的æ¯ä¸€ä¸ªæ交下é¢å¢žåŠ ä¸€è¡Œ exec"
@@ -12889,6 +13079,10 @@ msgid " tracked"
msgstr " 已跟踪"
#: builtin/remote.c
+msgid " skipped"
+msgstr " 已跳过"
+
+#: builtin/remote.c
msgid " stale (use 'git remote prune' to remove)"
msgstr " 过时(使用 'git remote prune' æ¥ç§»é™¤ï¼‰"
@@ -13729,12 +13923,17 @@ msgstr "ä¸èƒ½é‡ç½®ç´¢å¼•æ–‡ä»¶è‡³ç‰ˆæœ¬ '%s'。"
msgid "Could not write new index file."
msgstr "ä¸èƒ½å†™å…¥æ–°çš„索引文件。"
-#: builtin/rev-list.c pack-bitmap.c
+#: builtin/rev-list.c
#, c-format
msgid "unable to get disk usage of %s"
msgstr "无法得到 %s çš„ç£ç›˜ä½¿ç”¨é‡"
#: builtin/rev-list.c
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "'%s' 的值无效:'%s',唯一å…许的格å¼æ˜¯ '%s'"
+
+#: builtin/rev-list.c
msgid "rev-list does not support display of notes"
msgstr "rev-list ä¸æ”¯æŒæ˜¾ç¤ºæ³¨è§£"
@@ -13768,6 +13967,10 @@ msgid "no usage string given before the `--' separator"
msgstr "在 `--' 分隔符之å‰æ²¡æœ‰ç»™å‡ºä½¿ç”¨æ–¹æ³•å­—符串"
#: builtin/rev-parse.c
+msgid "missing opt-spec before option flags"
+msgstr "选项å‚数之å‰ç¼ºå°‘选项规格"
+
+#: builtin/rev-parse.c
msgid "Needed a single revision"
msgstr "需è¦ä¸€ä¸ªå•ç‹¬çš„版本"
@@ -14317,7 +14520,7 @@ msgstr "åˆå§‹åŒ–稀ç–检出为锥形模å¼"
msgid "toggle the use of a sparse index"
msgstr "切æ¢ç¨€ç–索引的使用"
-#: builtin/sparse-checkout.c commit-graph.c midx.c
+#: builtin/sparse-checkout.c commit-graph.c midx.c sequencer.c
#, c-format
msgid "unable to create leading directories of %s"
msgstr "ä¸èƒ½ä¸º %s 创建先导目录"
@@ -14713,20 +14916,17 @@ msgstr "期望一个完整的引用å称,å´å¾—到 %s"
#: builtin/submodule--helper.c
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "无法获得å­æ¨¡ç»„ '%s' 的仓库å¥æŸ„"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
msgstr "无法找到é…ç½® '%s'。å‡å®šè¿™ä¸ªä»“库是其自身的官方上游。"
#: builtin/submodule--helper.c
-msgid "alternative anchor for relative paths"
-msgstr "相对路径的替代锚记(anchor)"
-
-#: builtin/submodule--helper.c
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<路径>] [<路径>...]"
-
-#: builtin/submodule--helper.c
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "在 .gitmodules 中未找到å­æ¨¡ç»„路径 '%s' çš„ url"
@@ -14764,8 +14964,8 @@ msgid "recurse into nested submodules"
msgstr "递归进入嵌套å­æ¨¡ç»„中"
#: builtin/submodule--helper.c
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <命令>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <命令>"
#: builtin/submodule--helper.c
#, c-format
@@ -14792,8 +14992,8 @@ msgid "suppress output for initializing a submodule"
msgstr "抑制å­æ¨¡ç»„åˆå§‹åŒ–的输出"
#: builtin/submodule--helper.c
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<选项>] [<路径>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<选项>] [<路径>]"
#: builtin/submodule--helper.c
#, c-format
@@ -14825,10 +15025,6 @@ msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<路径>...]"
#: builtin/submodule--helper.c
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <路径>"
-
-#: builtin/submodule--helper.c
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(数æ®å¯¹è±¡ï¼‰->%s(å­æ¨¡ç»„)"
@@ -14870,8 +15066,8 @@ msgid "limit the summary size"
msgstr "é™åˆ¶æ€»ç»“的大å°"
#: builtin/submodule--helper.c
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<选项>] [<æ交>] [--] [<路径>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<选项>] [<æ交>] [--] [<路径>]"
#: builtin/submodule--helper.c
msgid "could not fetch a revision for HEAD"
@@ -14889,11 +15085,6 @@ msgstr "无法为å­æ¨¡ç»„路径 '%s' 注册 url"
#: builtin/submodule--helper.c
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "无法得到å­æ¨¡ç»„ '%s' 的默认远程关è”"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "无法为å­æ¨¡ç»„ '%s' 更新远程关è”"
@@ -14902,8 +15093,8 @@ msgid "suppress output of synchronizing submodule url"
msgstr "抑制å­æ¨¡ç»„ URL åŒæ­¥çš„输出"
#: builtin/submodule--helper.c
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<路径>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<路径>]"
#: builtin/submodule--helper.c
#, c-format
@@ -14973,6 +15164,11 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "无法获得 git 目录 '%s' 的仓库å¥æŸ„"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "å­æ¨¡ç»„ '%s' ä¸èƒ½æ·»åŠ ä»“库备选:%s"
@@ -15007,6 +15203,10 @@ msgid "could not get submodule directory for '%s'"
msgstr "无法得到 '%s' çš„å­æ¨¡ç»„目录"
#: builtin/submodule--helper.c
+msgid "alternative anchor for relative paths"
+msgstr "相对路径的替代锚记(anchor)"
+
+#: builtin/submodule--helper.c
msgid "where the new submodule will be cloned to"
msgstr "æ–°çš„å­æ¨¡ç»„å°†è¦å…‹éš†çš„路径"
@@ -15042,11 +15242,6 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "å­æ¨¡ç»„路径 '%2$s' çš„æ›´æ–°æ¨¡å¼ '%1$s' 无效"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr "为å­æ¨¡ç»„路径 '%2$s' é…ç½®çš„æ›´æ–°æ¨¡å¼ '%1$s' 无效"
@@ -15133,6 +15328,11 @@ msgstr "获å–了å­æ¨¡ç»„路径 '%s'ï¼Œä½†æ˜¯å®ƒæ²¡æœ‰åŒ…å« %s。直接获å–è
#: builtin/submodule--helper.c
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "无法在路径 '%s' åˆå§‹åŒ–å­æ¨¡ç»„"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -15140,11 +15340,6 @@ msgstr "å­æ¨¡ç»„(%s)的分支é…置为继承上级项目的分支,但是ä
#: builtin/submodule--helper.c
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "无法获得å­æ¨¡ç»„ '%s' 的仓库å¥æŸ„"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "无法在å­æ¨¡ç»„路径 '%s' 中找到当å‰ç‰ˆæœ¬"
@@ -15188,12 +15383,16 @@ msgid "path into the working tree"
msgstr "到工作区的路径"
#: builtin/submodule--helper.c
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "工作区中的路径,递归嵌套å­æ¨¡ç»„"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "使用 'checkout' 更新策略(默认)"
#: builtin/submodule--helper.c
-msgid "rebase, merge, checkout or none"
-msgstr "rebaseã€mergeã€checkout 或 none"
+msgid "use the 'merge' update strategy"
+msgstr "使用 'merge' 更新策略"
+
+#: builtin/submodule--helper.c
+msgid "use the 'rebase' update strategy"
+msgstr "使用 'rebase' 更新策略"
#: builtin/submodule--helper.c
msgid "create a shallow clone truncated to the specified number of revisions"
@@ -15212,6 +15411,10 @@ msgid "don't print cloning progress"
msgstr "ä¸è¦è¾“出克隆进度"
#: builtin/submodule--helper.c
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "ä¸å…许克隆到一个éžç©ºç›®å½•ï¼Œæš—å« --init"
+
+#: builtin/submodule--helper.c
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -15224,16 +15427,12 @@ msgstr ""
"径>...]"
#: builtin/submodule--helper.c
-msgid "bad value for update parameter"
-msgstr "update å‚æ•°å–值错误"
-
-#: builtin/submodule--helper.c
msgid "recurse into submodules"
msgstr "在å­æ¨¡ç»„中递归"
#: builtin/submodule--helper.c
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<选项>] [<路径>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<选项>] [<路径>...]"
#: builtin/submodule--helper.c
msgid "check if it is safe to write to the .gitmodules file"
@@ -15260,8 +15459,8 @@ msgid "suppress output for setting url of a submodule"
msgstr "抑制设置å­æ¨¡ç»„ URL 的输出"
#: builtin/submodule--helper.c
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <路径> <新地å€>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <路径> <新地å€>"
#: builtin/submodule--helper.c
msgid "set the default tracking branch to master"
@@ -15272,14 +15471,12 @@ msgid "set the default tracking branch"
msgstr "设置默认跟踪分支"
#: builtin/submodule--helper.c
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <路径>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <路径>"
#: builtin/submodule--helper.c
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <分支> <路径>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <分支> <路径>"
#: builtin/submodule--helper.c
msgid "--branch or --default required"
@@ -15394,8 +15591,8 @@ msgid ""
msgstr "å°†å­æ¨¡ç»„çš„å称设置为给定的字符串,而éžé»˜è®¤ä¸ºå…¶è·¯å¾„"
#: builtin/submodule--helper.c
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<选项>] [--] <仓库> [<路径>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<选项>] [--] <仓库> [<路径>]"
#: builtin/submodule--helper.c
msgid "Relative path can only be used from the toplevel of the working tree"
@@ -15649,6 +15846,19 @@ msgid "pack exceeds maximum allowed size"
msgstr "包超过了最大å…许大å°"
#: builtin/unpack-objects.c
+msgid "failed to write object in stream"
+msgstr "无法在æµä¸­å†™å…¥å¯¹è±¡"
+
+#: builtin/unpack-objects.c
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "解压缩返回了 (%d)"
+
+#: builtin/unpack-objects.c
+msgid "invalid blob object from stream"
+msgstr "æµä¸­æ— æ•ˆçš„æ•°æ®å¯¹è±¡"
+
+#: builtin/unpack-objects.c
msgid "Unpacking objects"
msgstr "展开对象中"
@@ -16290,6 +16500,33 @@ msgstr "å°† <å‰ç¼€> å­ç›®å½•å†…容写到一个树对象"
msgid "only useful for debugging"
msgstr "åªå¯¹è°ƒè¯•æœ‰ç”¨"
+#: bulk-checkin.c
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch ä¸æ”¯æŒæœ¬å¹³å°"
+
+#: bundle-uri.c
+msgid "failed to create temporary file"
+msgstr "无法创建临时文件"
+
+#: bundle-uri.c
+msgid "insufficient capabilities"
+msgstr "缺ä¹èƒ½åŠ›"
+
+#: bundle-uri.c
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "无法从 URI '%s' 下载归档包"
+
+#: bundle-uri.c
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "ä½äºŽ URI '%s' 的文件ä¸æ˜¯å½’档包"
+
+#: bundle-uri.c
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "无法从 URI '%s' 解开归档包"
+
#: bundle.c
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
@@ -16553,6 +16790,10 @@ msgid "Give an object a human readable name based on an available ref"
msgstr "基于一个现存的引用为一个对象起一个å¯è¯»çš„å称"
#: command-list.h
+msgid "Generate a zip archive of diagnostic information"
+msgstr "生æˆè¯Šæ–­ä¿¡æ¯çš„压缩包"
+
+#: command-list.h
msgid "Show changes between commits, commit and working tree, etc"
msgstr "显示æ交之间ã€æ交和工作区之间等的差异"
@@ -16721,8 +16962,8 @@ msgid "The standard helper program to use with git-merge-index"
msgstr "与 git-merge-index 一起使用的标准å‘导程åº"
#: command-list.h
-msgid "Show three-way merge without touching index"
-msgstr "在ä¸åŠ¨ç´¢å¼•çš„情况下显示三路åˆå¹¶"
+msgid "Perform merge without touching index or working tree"
+msgstr "在ä¸è§¦ç¢°ç´¢å¼•æˆ–工作树情况下应用åˆå¹¶"
#: command-list.h
msgid "Run merge conflict resolution tools to resolve merge conflicts"
@@ -16983,6 +17224,10 @@ msgid "Check the GPG signature of tags"
msgstr "检查标签的 GPG ç­¾å"
#: command-list.h
+msgid "Display version information about Git"
+msgstr "显示关于 Git 的版本信æ¯"
+
+#: command-list.h
msgid "Show logs with difference each commit introduces"
msgstr "显示æ¯ä¸€ä¸ªæ交引入的差异日志"
@@ -17027,6 +17272,30 @@ msgid "Frequently asked questions about using Git"
msgstr "关于使用 Git 的常è§é—®é¢˜"
#: command-list.h
+msgid "The bundle file format"
+msgstr "归档包文件格å¼"
+
+#: command-list.h
+msgid "Chunk-based file formats"
+msgstr "å—å¼æ–‡ä»¶æ ¼å¼"
+
+#: command-list.h
+msgid "Git commit graph format"
+msgstr "Git æ交图格å¼"
+
+#: command-list.h
+msgid "Git index format"
+msgstr "Git 索引格å¼"
+
+#: command-list.h
+msgid "Git pack format"
+msgstr "Git 包格å¼"
+
+#: command-list.h
+msgid "Git cryptographic signature formats"
+msgstr "Git 密ç å­¦ç­¾åæ ¼å¼"
+
+#: command-list.h
msgid "A Git Glossary"
msgstr "Git è¯æ±‡è¡¨"
@@ -17036,7 +17305,7 @@ msgstr "Git 使用的钩å­"
#: command-list.h
msgid "Specifies intentionally untracked files to ignore"
-msgstr "忽略指定的未跟踪文件"
+msgstr "指定故æ„忽略的未跟踪文件"
#: command-list.h
msgid "The Git repository browser"
@@ -17055,6 +17324,26 @@ msgid "Git namespaces"
msgstr "Git å字空间"
#: command-list.h
+msgid "Protocol v0 and v1 capabilities"
+msgstr "åè®® v0 å’Œ v1 能力"
+
+#: command-list.h
+msgid "Things common to various protocols"
+msgstr "ä¸åŒå议的共åŒéƒ¨åˆ†"
+
+#: command-list.h
+msgid "Git HTTP-based protocols"
+msgstr "Git 基于 HTTP çš„åè®®"
+
+#: command-list.h
+msgid "How packs are transferred over-the-wire"
+msgstr "包在线路中传输的方å¼"
+
+#: command-list.h
+msgid "Git Wire Protocol, Version 2"
+msgstr "Git 传输å议,第二版"
+
+#: command-list.h
msgid "Helper programs to interact with remote repositories"
msgstr "与远程仓库交互的助手程åº"
@@ -17086,6 +17375,10 @@ msgstr "Git web ç•Œé¢ï¼ˆGit 仓库的 web å‰ç«¯ï¼‰"
msgid "An overview of recommended workflows with Git"
msgstr "Git 推è的工作æµæ¦‚览"
+#: command-list.h
+msgid "A tool for managing large Git repositories"
+msgstr "一个管ç†å¤§åž‹ Git 仓库的工具"
+
#: commit-graph.c
msgid "commit-graph file is too small"
msgstr "æ交图形文件太å°"
@@ -17374,6 +17667,16 @@ msgstr "编译器信æ¯ä¸å¯ç”¨\n"
msgid "no libc information available\n"
msgstr "libc ä¿¡æ¯ä¸å¯ç”¨\n"
+#: compat/disk.h
+#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "ä¸èƒ½ç¡®å®š '%s' 的空余ç£ç›˜ç©ºé—´"
+
+#: compat/disk.h
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "无法获得 '%s' çš„ä¿¡æ¯"
+
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
@@ -17442,6 +17745,16 @@ msgstr "GetOverlappedResult 失败于 '%s' [GLE %ld]"
msgid "could not read directory changes [GLE %ld]"
msgstr "无法获å–目录å˜æ›´ [GLE %ld]"
+#: compat/fsmonitor/fsm-settings-win32.c
+#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] 无法打开è¦è¯»å–çš„ '%ls'"
+
+#: compat/fsmonitor/fsm-settings-win32.c
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] æ— æ³•èŽ·å– '%ls' çš„åè®®ä¿¡æ¯ "
+
#: compat/mingw.c
#, c-format
msgid "failed to copy SID (%ld)"
@@ -18115,229 +18428,6 @@ msgstr "写入 rev-list 失败"
msgid "failed to close rev-list's stdin"
msgstr "无法关闭 rev-list 的标准输入"
-#: contrib/scalar/scalar.c worktree.c
-#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' ä¸å­˜åœ¨"
-
-#: contrib/scalar/scalar.c
-msgid "need a working directory"
-msgstr "需è¦ä¸€ä¸ªå·¥ä½œç›®å½•"
-
-#: contrib/scalar/scalar.c
-msgid "could not find enlistment root"
-msgstr "无法找到登记根"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "无法切æ¢åˆ° '%s'"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "无法é…ç½® %s=%s"
-
-#: contrib/scalar/scalar.c
-msgid "could not configure log.excludeDecoration"
-msgstr "无法é…ç½® log.excludeDecoration"
-
-#: contrib/scalar/scalar.c
-msgid "Scalar enlistments require a worktree"
-msgstr "Scalar 登记需è¦ä¸€ä¸ªå·¥ä½œæ ‘"
-
-#: contrib/scalar/scalar.c dir.c
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "ä¸èƒ½æ‰“开目录 '%s'"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "跳过 '%s',既ä¸æ˜¯æ–‡ä»¶åˆä¸æ˜¯ç›®å½•"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "ä¸èƒ½ç¡®å®š '%s' 的空余ç£ç›˜ç©ºé—´"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "ä¸èƒ½èŽ·å¾— '%s' çš„ä¿¡æ¯"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "远程 HEAD ä¸æ˜¯ä¸€ä¸ªåˆ†æ”¯ï¼š'%.*s'"
-
-#: contrib/scalar/scalar.c
-msgid "failed to get default branch name from remote; using local default"
-msgstr "无法从远程获å–默认分支å称;使用本地默认值"
-
-#: contrib/scalar/scalar.c
-msgid "failed to get default branch name"
-msgstr "无法获å–默认分支å称"
-
-#: contrib/scalar/scalar.c
-msgid "failed to unregister repository"
-msgstr "无法å–消注册仓库"
-
-#: contrib/scalar/scalar.c
-msgid "failed to delete enlistment directory"
-msgstr "无法删除登记目录"
-
-#: contrib/scalar/scalar.c
-msgid "branch to checkout after clone"
-msgstr "克隆åŽè¦æ£€å‡ºçš„分支"
-
-#: contrib/scalar/scalar.c
-msgid "when cloning, create full working directory"
-msgstr "在克隆时,创建完整的工作目录"
-
-#: contrib/scalar/scalar.c
-msgid "only download metadata for the branch that will be checked out"
-msgstr "åªä¸‹è½½è¦æ£€å‡ºçš„分支的元信æ¯"
-
-#: contrib/scalar/scalar.c
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<选项>] [--] <仓库> [<目录>]"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "无法从 '%s' 猜测工作区å称"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "目录 '%s' 已存在"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "æ— æ³•èŽ·å– '%s' 的默认分支"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "无法在 '%s' 中é…置远程"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure '%s'"
-msgstr "无法é…ç½® '%s'"
-
-#: contrib/scalar/scalar.c
-msgid "partial clone failed; attempting full clone"
-msgstr "部分克隆失败;å°è¯•å®Œæ•´å…‹éš†"
-
-#: contrib/scalar/scalar.c
-msgid "could not configure for full clone"
-msgstr "无法é…置完整克隆"
-
-#: contrib/scalar/scalar.c
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<登记>]"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "ä¸èƒ½ä¸º '%s' 创建目录"
-
-#: contrib/scalar/scalar.c
-msgid "could not duplicate stdout"
-msgstr "ä¸èƒ½å¤åˆ¶æ ‡å‡†è¾“出"
-
-#: contrib/scalar/scalar.c
-msgid "failed to write archive"
-msgstr "无法写入归档"
-
-#: contrib/scalar/scalar.c
-msgid "`scalar list` does not take arguments"
-msgstr "`scalar list` ä¸å¸¦å‚æ•°"
-
-#: contrib/scalar/scalar.c
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<登记>]"
-
-#: contrib/scalar/scalar.c
-msgid "reconfigure all registered enlistments"
-msgstr "é‡æ–°é…置所有注册的登记"
-
-#: contrib/scalar/scalar.c
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <登记>]"
-
-#: contrib/scalar/scalar.c
-msgid "--all or <enlistment>, but not both"
-msgstr "--all 或者 <登记>,而ä¸æ˜¯ä¸¤ä¸ªä¸€èµ·"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "在 '%s' 的 git 仓库已消失"
-
-#: contrib/scalar/scalar.c
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <任务> [<登记>]\n"
-"任务:\n"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "no such task: '%s'"
-msgstr "没有此任务:'%s'"
-
-#: contrib/scalar/scalar.c
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<登记>]"
-
-#: contrib/scalar/scalar.c
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <登记>"
-
-#: contrib/scalar/scalar.c
-msgid "refusing to delete current working directory"
-msgstr "æ‹’ç»åˆ é™¤å½“å‰å·¥ä½œç›®å½•"
-
-#: contrib/scalar/scalar.c
-msgid "include Git version"
-msgstr "包括 Git 的版本"
-
-#: contrib/scalar/scalar.c
-msgid "include Git's build options"
-msgstr "包括 Git 的构建选项"
-
-#: contrib/scalar/scalar.c
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-#: contrib/scalar/scalar.c
-msgid "-C requires a <directory>"
-msgstr "-C éœ€è¦ <目录>"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not change to '%s'"
-msgstr "无法å˜æ›´åˆ° '%s'"
-
-#: contrib/scalar/scalar.c
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c éœ€è¦ <é”®>=<值> å‚æ•°"
-
-#: contrib/scalar/scalar.c
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <目录>] [-c <键>=<值>] <命令> [<选项>]\n"
-"\n"
-"命令:\n"
-
#: convert.c
#, c-format
msgid "illegal crlf_action %d"
@@ -18578,6 +18668,39 @@ msgstr "æ¥è‡ª config çš„æ•°æ®å²›æ­£åˆ™è¡¨è¾¾å¼æœ‰å¤ªå¤šçš„æ•èŽ·ç»„(最多
msgid "Marked %d islands, done.\n"
msgstr "已标记 %d 个数æ®å²›ï¼Œç»“æŸã€‚\n"
+#: diagnose.c
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "无效的 --%s 值 '%s'"
+
+#: diagnose.c
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "无法归档缺失的目录 '%s'"
+
+#: diagnose.c dir.c
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "无法打开目录 '%s'"
+
+#: diagnose.c
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "跳过 '%s',既ä¸æ˜¯æ–‡ä»¶åˆä¸æ˜¯ç›®å½•"
+
+#: diagnose.c
+msgid "could not duplicate stdout"
+msgstr "无法å¤åˆ¶æ ‡å‡†è¾“出"
+
+#: diagnose.c
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "无法添加目录 '%s' 至归档器"
+
+#: diagnose.c
+msgid "failed to write archive"
+msgstr "无法写入归档"
+
#: diff-lib.c
msgid "--merge-base does not work with ranges"
msgstr "--merge-base ä¸é€‚用于范围"
@@ -19328,6 +19451,10 @@ msgid "unable to write to remote"
msgstr "无法写到远程"
#: fetch-pack.c
+msgid "Server supports filter"
+msgstr "æœåŠ¡å™¨æ”¯æŒ filter"
+
+#: fetch-pack.c
#, c-format
msgid "invalid shallow line: %s"
msgstr "无效的 shallow ä¿¡æ¯ï¼š%s"
@@ -19469,10 +19596,6 @@ msgid "Server does not support shallow requests"
msgstr "æœåŠ¡å™¨ä¸æ”¯æŒæµ…克隆请求"
#: fetch-pack.c
-msgid "Server supports filter"
-msgstr "æœåŠ¡å™¨æ”¯æŒ filter"
-
-#: fetch-pack.c
msgid "unable to write request to remote"
msgstr "无法将请求写到远程"
@@ -19887,6 +20010,14 @@ msgid "Low-level Commands / Internal Helpers"
msgstr "低级命令/内部助手"
#: help.c
+msgid "User-facing repository, command and file interfaces"
+msgstr "é¢å‘用户的仓库ã€å‘½ä»¤å’Œæ–‡ä»¶æŽ¥å£"
+
+#: help.c
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "é¢å‘å¼€å‘者的文件格å¼ã€å议和其他接å£"
+
+#: help.c
#, c-format
msgid "available git commands in '%s'"
msgstr "在 '%s' 下å¯ç”¨çš„ git 命令"
@@ -19904,6 +20035,14 @@ msgid "The Git concept guides are:"
msgstr "Git 概念å‘导有:"
#: help.c
+msgid "User-facing repository, command and file interfaces:"
+msgstr "é¢å‘用户的仓库ã€å‘½ä»¤å’Œæ–‡ä»¶æŽ¥å£ï¼š"
+
+#: help.c
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "文件格å¼ã€å议和其他开å‘者接å£åˆ—表:"
+
+#: help.c
msgid "External commands"
msgstr "外部命令"
@@ -19999,11 +20138,6 @@ msgstr ""
"å› ä¸ºæ²¡æœ‰å°†é’©å­ '%s' 设置为å¯æ‰§è¡Œï¼Œé’©å­è¢«å¿½ç•¥ã€‚您å¯ä»¥é€šè¿‡\n"
"é…ç½® `git config advice.ignoredHook false` æ¥å…³é—­è¿™æ¡è­¦å‘Šã€‚"
-#: hook.c
-#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "ä¸èƒ½å¯åŠ¨é’©å­ '%s'\n"
-
#: http-fetch.c
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
@@ -20221,20 +20355,16 @@ msgstr "在 ls-refs å‚æ•°åŽåº”该有一个 flush 包"
msgid "quoted CRLF detected"
msgstr "检测到被引用的 CRLF"
-#: merge-ort-wrappers.c merge-recursive.c
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"您对下列文件的本地修改将被åˆå¹¶æ“作覆盖:\n"
-" %s"
-
#: merge-ort.c merge-recursive.c
#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "无法åˆå¹¶å­æ¨¡ç»„ %s (没有检出)"
+#: merge-ort.c
+#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "无法åˆå¹¶å­æ¨¡ç»„ %s (没有åˆå¹¶åŸºçº¿ï¼‰"
+
#: merge-ort.c merge-recursive.c
#, c-format
msgid "Failed to merge submodule %s (commits not present)"
@@ -20258,27 +20388,8 @@ msgstr "无法åˆå¹¶å­æ¨¡ç»„ %s"
#: merge-ort.c
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-"无法åˆå¹¶å­æ¨¡ç»„ %s,但是存在一个å¯èƒ½çš„åˆå¹¶æ–¹æ¡ˆï¼š\n"
-"%s\n"
-
-#: merge-ort.c merge-recursive.c
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"如果这个正确,将其添加到索引,例如使用命令:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"以接å—此建议。\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
+msgstr "无法åˆå¹¶å­æ¨¡ç»„ %s,但是存在一个å¯èƒ½çš„åˆå¹¶æ–¹æ¡ˆï¼š%s"
#: merge-ort.c
#, c-format
@@ -20455,12 +20566,45 @@ msgstr ""
"冲çªï¼ˆä¿®æ”¹/删除):%1$s 在 %2$s 中被删除,在 %3$s 中被修改。%5$s çš„ %4$s 版本"
"在树中被ä¿ç•™ã€‚"
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
#: merge-ort.c
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
-msgstr "注æ„:%s ä¸æ˜¯æœ€æ–°çš„,并且与è¦æ£€å‡ºçš„版本冲çªã€‚旧副本é‡å‘½å为 %s"
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
+msgstr ""
+" - 进入å­æ¨¡ç»„(%s),è¦ä¹ˆåˆå¹¶æ交 %s\n"
+" è¦ä¹ˆæ›´æ–°è‡³å·²åˆå¹¶è¿™äº›å˜æ›´çš„æ交\n"
+
+#: merge-ort.c
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"å­æ¨¡ç»„内的递归åˆå¹¶çŽ°åœ¨åªæ”¯æŒç®€å•çš„情况。\n"
+"请手动åˆå¹¶æ¯ä¸ªæœ‰å†²çªçš„å­æ¨¡ç»„。\n"
+"è¿™å¯ä»¥é€šè¿‡ä¸‹åˆ—步骤完æˆï¼š\n"
+"%s - 回到上级项目并è¿è¡Œï¼š\n"
+"\n"
+" git add %s\n"
+"\n"
+" æ¥è®°å½•ä¸Šè¿°çš„åˆå¹¶æˆ–æ›´æ–°\n"
+" - 解决上级项目中的其他冲çª\n"
+" - æ交上级项目中的结果索引\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -20549,6 +20693,22 @@ msgstr "找到å­æ¨¡ç»„的一个å¯èƒ½çš„åˆå¹¶æ–¹æ¡ˆï¼š\n"
#: merge-recursive.c
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"如果这个正确,将其添加到索引,例如使用命令:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"以接å—此建议。\n"
+
+#: merge-recursive.c
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "无法åˆå¹¶å­æ¨¡ç»„ %s (å‘现多个åˆå¹¶ï¼‰"
@@ -21184,6 +21344,26 @@ msgstr "被 %s çš„ä¸ç¨³å®šå¯¹è±¡æºæ•°æ®æžç³Šæ¶‚了"
#: object-file.c
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "写入æµå¯¹è±¡ %ld != %<PRIuMAX>"
+
+#: object-file.c
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "ä¸èƒ½æµå¼åŽ‹ç¼©æ–°å¯¹è±¡ï¼ˆ%d)"
+
+#: object-file.c
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "在æµå¯¹è±¡ä¸Šè°ƒç”¨ deflateEnd 失败(%d)"
+
+#: object-file.c
+#, c-format
+msgid "unable to create directory %s"
+msgstr "无法创建目录 %s"
+
+#: object-file.c
+#, c-format
msgid "cannot read object for %s"
msgstr "ä¸èƒ½è¯»å–对象 %s"
@@ -21447,6 +21627,71 @@ msgstr "ä¸èƒ½è§£æžå¯¹è±¡ï¼š%s"
msgid "hash mismatch %s"
msgstr "哈希值与 %s ä¸åŒ¹é…"
+#: pack-bitmap-write.c
+msgid "trying to write commit not in index"
+msgstr "å°è¯•å†™å…¥æœªåœ¨ç´¢å¼•ä¸­çš„æ交"
+
+#: pack-bitmap.c
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "无法载入ä½å›¾ç´¢å¼•ï¼ˆå·²æŸå?)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index (too small)"
+msgstr "æŸåçš„ä½å›¾ç´¢å¼•ï¼ˆå¤ªå°ï¼‰"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "æŸåçš„ä½å›¾ç´¢å¼•ï¼ˆé”™è¯¯çš„文件头)"
+
+#: pack-bitmap.c
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "ä¸æ”¯æŒçš„ä½å›¾ç´¢å¼•æ–‡ä»¶ç‰ˆæœ¬ '%d'"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr "æŸåçš„ä½å›¾ç´¢å¼•ï¼ˆå¤ªå°ï¼Œå®¹ä¸ä¸‹å“ˆå¸Œç¼“存)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr "æŸåçš„ä½å›¾ç´¢å¼•ï¼ˆå¤ªå°ï¼Œå®¹ä¸ä¸‹æŸ¥è¯¢è¡¨ï¼‰"
+
+#: pack-bitmap.c
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "ä½å›¾ç´¢å¼•ä¸­çš„é‡å¤æ¡ç›®ï¼š'%s'"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "æŸåçš„ EWAH ä½å›¾ï¼šæ¡ç›® %d 截断的文件头"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "æŸåçš„ EWAH ä½å›¾ï¼šæ交索引 %u 超出范围"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap pack index"
+msgstr "æŸåçš„ä½å›¾åŒ…索引"
+
+#: pack-bitmap.c
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "ä½å›¾åŒ…索引中 XOR å移值无效"
+
+#: pack-bitmap.c
+msgid "cannot fstat bitmap file"
+msgstr "ä¸èƒ½å¯¹ä½å›¾æ–‡ä»¶è°ƒç”¨ fstat"
+
+#: pack-bitmap.c
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "忽略é¢å¤–çš„ä½å›¾æ–‡ä»¶ï¼š'%s'"
+
+#: pack-bitmap.c
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "MIDX å’Œä½å›¾ä¸­çš„校验ç ä¸åŒ¹é…"
+
#: pack-bitmap.c
msgid "multi-pack bitmap is missing required reverse index"
msgstr "多包ä½å›¾ç¼ºå°‘必需的åå‘索引"
@@ -21462,9 +21707,69 @@ msgid "preferred pack (%s) is invalid"
msgstr "首选包 (%s) 无效"
#: pack-bitmap.c
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "æŸåçš„ä½å›¾æŸ¥è¯¢è¡¨ï¼šä¸‰å…ƒç»„ä½ç½®è¶…出索引"
+
+#: pack-bitmap.c
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr "æŸåçš„ä½å›¾æŸ¥è¯¢è¡¨ï¼šxor 链超出æ¡ç›®æ•°"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr "æŸåçš„ä½å›¾æŸ¥è¯¢è¡¨ï¼šæ交索引 %u 超出范围"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr "æŸåçš„ EWAH ä½å›¾ï¼šæ交 \"%s\" ä½å›¾çš„文件头被截断"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "对象 %s 为在类型ä½å›¾ä¸­æ‰¾åˆ°"
+
+#: pack-bitmap.c
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "在包 %2$s å移 %3$<PRIuMAX> 中无法找到 %1$s"
+msgid "object '%s' does not have a unique type"
+msgstr "对象 '%s' 没有唯一的类型"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "对象 '%s':实际类型 '%s',预期:'%s'"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "对象ä¸åœ¨ä½å›¾ä¸­ï¼š%s"
+
+#: pack-bitmap.c
+msgid "failed to load bitmap indexes"
+msgstr "无法载入ä½å›¾ç´¢å¼•"
+
+#: pack-bitmap.c
+msgid "you must specify exactly one commit to test"
+msgstr "您必须准确指定一个æ交æ¥æµ‹è¯•"
+
+#: pack-bitmap.c
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "æ交 '%s' 没有索引ä½å›¾"
+
+#: pack-bitmap.c
+msgid "mismatch in bitmap results"
+msgstr "ä½å›¾ç»“æžœä¸ä¸€è‡´"
+
+#: pack-bitmap.c
+#, c-format
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "无法在包 '%2$s' å移 %3$<PRIuMAX> 中找到 '%1$s'"
+
+#: pack-bitmap.c
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "无法得到 '%s' çš„ç£ç›˜ä½¿ç”¨é‡"
#: pack-mtimes.c
#, c-format
@@ -21620,6 +21925,10 @@ msgid "alias of --%s"
msgstr "--%s 的别å"
#: parse-options.c
+msgid "need a subcommand"
+msgstr "需è¦ä¸€ä¸ªå­å‘½ä»¤"
+
+#: parse-options.c
#, c-format
msgid "unknown option `%s'"
msgstr "未知选项 `%s'"
@@ -22147,9 +22456,12 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
@@ -22157,7 +22469,7 @@ msgstr ""
"命令:\n"
"p, pick <æ交> = 使用æ交\n"
"r, reword <æ交> = 使用æ交,但编辑æ交说明\n"
-"e, edit <æ交> = 使用æ交,但åœæ­¢ä»¥ä¾¿åœ¨ shell 中修补æ交\n"
+"e, edit <æ交> = 使用æ交,但åœæ­¢ä»¥ä¾¿ä¿®è¡¥æ交\n"
"s, squash <æ交> = 使用æ交,但挤压到å‰ä¸€ä¸ªæ交\n"
"f, fixup [-C | -c] <æ交> = 类似于 \"squash\",但åªä¿ç•™å‰ä¸€ä¸ªæ交\n"
" çš„æ交说明,除éžä½¿ç”¨äº† -C å‚数,此情况下则åª\n"
@@ -22172,6 +22484,9 @@ msgstr ""
". 创建一个åˆå¹¶æ交,并使用原始的åˆå¹¶æ交说明(如果没有指定\n"
". 原始æ交,使用注释部分的 oneline 作为æ交说明)。使用\n"
". -c <æ交> å¯ä»¥ç¼–辑æ交说明。\n"
+"u, update-ref <引用> = 为引用 <ref> 设置一个å ä½ç¬¦ï¼Œä»¥å°†è¯¥å¼•ç”¨æ›´æ–°ä¸ºæ­¤å¤„çš„æ–°"
+"æ交。\n"
+" æ­¤ <引用> 在å˜åŸºç»“æŸåŽæ›´æ–°ã€‚\n"
"\n"
"å¯ä»¥å¯¹è¿™äº›è¡Œé‡æ–°æŽ’åºï¼Œå°†ä»Žä¸Šè‡³ä¸‹æ‰§è¡Œã€‚\n"
@@ -22738,6 +23053,15 @@ msgid "http transport does not support %s"
msgstr "http 传输åè®®ä¸æ”¯æŒ %s"
#: remote-curl.c
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "å议错误:预期 '<url> <path>',缺少空格"
+
+#: remote-curl.c
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "无法下载ä½äºŽ URL '%s' 的文件"
+
+#: remote-curl.c
msgid "git-http-push failed"
msgstr "git-http-push 失败"
@@ -23143,6 +23467,16 @@ msgid "failed to find tree of %s"
msgstr "无法找到 %s 指å‘çš„æ ‘"
#: revision.c
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo 记录 `%s`,现缺失"
+
+#: revision.c
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "无法获得 ancestry-path å‚æ•° %s çš„æ交"
+
+#: revision.c
msgid "--unpacked=<packfile> no longer supported"
msgstr "ä¸å†æ”¯æŒ --unpacked=<packfile>"
@@ -23168,6 +23502,220 @@ msgstr "-L å°šä¸æ”¯æŒ -p å’Œ -s 之外的差异格å¼"
msgid "cannot create async thread: %s"
msgstr "ä¸èƒ½åˆ›å»º async 线程:%s"
+#: scalar.c worktree.c
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' ä¸å­˜åœ¨"
+
+#: scalar.c
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "无法切æ¢åˆ° '%s'"
+
+#: scalar.c
+msgid "need a working directory"
+msgstr "需è¦ä¸€ä¸ªå·¥ä½œç›®å½•"
+
+#: scalar.c
+msgid "Scalar enlistments require a worktree"
+msgstr "Scalar 登记需è¦ä¸€ä¸ªå·¥ä½œæ ‘"
+
+#: scalar.c
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "无法é…ç½® %s=%s"
+
+#: scalar.c
+msgid "could not configure log.excludeDecoration"
+msgstr "无法é…ç½® log.excludeDecoration"
+
+#: scalar.c
+msgid "could not add enlistment"
+msgstr "无法添加登记"
+
+#: scalar.c
+msgid "could not set recommended config"
+msgstr "无法设置推èçš„é…ç½®"
+
+#: scalar.c
+msgid "could not turn on maintenance"
+msgstr "无法打开维护模å¼"
+
+#: scalar.c
+msgid "could not start the FSMonitor daemon"
+msgstr "无法å¯åŠ¨ FSMonitor 守护进程"
+
+#: scalar.c
+msgid "could not turn off maintenance"
+msgstr "无法关闭维护模å¼"
+
+#: scalar.c
+msgid "could not remove enlistment"
+msgstr "无法删除登记"
+
+#: scalar.c
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "远程 HEAD ä¸æ˜¯ä¸€ä¸ªåˆ†æ”¯ï¼š'%.*s'"
+
+#: scalar.c
+msgid "failed to get default branch name from remote; using local default"
+msgstr "无法从远程获å–默认分支å称;使用本地默认值"
+
+#: scalar.c
+msgid "failed to get default branch name"
+msgstr "无法获å–默认分支å称"
+
+#: scalar.c
+msgid "failed to unregister repository"
+msgstr "无法å–消注册仓库"
+
+#: scalar.c
+msgid "failed to stop the FSMonitor daemon"
+msgstr "无法åœæ­¢ FSMonitor 守护进程"
+
+#: scalar.c
+msgid "failed to delete enlistment directory"
+msgstr "无法删除登记目录"
+
+#: scalar.c
+msgid "branch to checkout after clone"
+msgstr "克隆åŽè¦æ£€å‡ºçš„分支"
+
+#: scalar.c
+msgid "when cloning, create full working directory"
+msgstr "在克隆时,创建完整的工作目录"
+
+#: scalar.c
+msgid "only download metadata for the branch that will be checked out"
+msgstr "åªä¸‹è½½è¦æ£€å‡ºçš„分支的元信æ¯"
+
+#: scalar.c
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<选项>] [--] <仓库> [<目录>]"
+
+#: scalar.c
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "无法从 '%s' 猜测工作区å称"
+
+#: scalar.c
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "目录 '%s' 已存在"
+
+#: scalar.c
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "æ— æ³•èŽ·å– '%s' 的默认分支"
+
+#: scalar.c
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "无法在 '%s' 中é…置远程"
+
+#: scalar.c
+#, c-format
+msgid "could not configure '%s'"
+msgstr "无法é…ç½® '%s'"
+
+#: scalar.c
+msgid "partial clone failed; attempting full clone"
+msgstr "部分克隆失败;å°è¯•å®Œæ•´å…‹éš†"
+
+#: scalar.c
+msgid "could not configure for full clone"
+msgstr "无法é…置完整克隆"
+
+#: scalar.c
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<登记>]"
+
+#: scalar.c
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` ä¸å¸¦å‚æ•°"
+
+#: scalar.c
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<登记>]"
+
+#: scalar.c
+msgid "reconfigure all registered enlistments"
+msgstr "é‡æ–°é…置所有注册的登记"
+
+#: scalar.c
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <登记>]"
+
+#: scalar.c
+msgid "--all or <enlistment>, but not both"
+msgstr "--all 或者 <登记>,而ä¸æ˜¯ä¸¤ä¸ªä¸€èµ·"
+
+#: scalar.c
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "在 '%s' 的 git 仓库已消失"
+
+#: scalar.c
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <任务> [<登记>]\n"
+"任务:\n"
+
+#: scalar.c
+#, c-format
+msgid "no such task: '%s'"
+msgstr "没有此任务:'%s'"
+
+#: scalar.c
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<登记>]"
+
+#: scalar.c
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <登记>"
+
+#: scalar.c
+msgid "refusing to delete current working directory"
+msgstr "æ‹’ç»åˆ é™¤å½“å‰å·¥ä½œç›®å½•"
+
+#: scalar.c
+msgid "include Git version"
+msgstr "包括 Git 的版本"
+
+#: scalar.c
+msgid "include Git's build options"
+msgstr "包括 Git 的构建选项"
+
+#: scalar.c
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+#: scalar.c
+msgid "-C requires a <directory>"
+msgstr "-C éœ€è¦ <目录>"
+
+#: scalar.c
+#, c-format
+msgid "could not change to '%s'"
+msgstr "无法å˜æ›´åˆ° '%s'"
+
+#: scalar.c
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c éœ€è¦ <é”®>=<值> å‚æ•°"
+
+#: scalar.c
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <目录>] [-c <键>=<值>] <命令> [<选项>]\n"
+"\n"
+"命令:\n"
+
#: send-pack.c
msgid "unexpected flush packet while reading remote unpack status"
msgstr "读å–远程解包状æ€æ—¶æ”¶åˆ°æ„外的 flush 包"
@@ -23308,11 +23856,6 @@ msgstr "您的本地修改将被%s覆盖。"
msgid "commit your changes or stash them to proceed."
msgstr "æ交您的修改或贮è—åŽå†ç»§ç»­ã€‚"
-#: sequencer.c
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s:快进"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -23900,6 +24443,30 @@ msgid "merge: Unable to write new index file"
msgstr "åˆå¹¶ï¼šæ— æ³•å†™å…¥æ–°ç´¢å¼•æ–‡ä»¶"
#: sequencer.c
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "å¦ä¸€ä¸ª 'rebase' 进程似乎在è¿è¡Œï¼›'%s.lock' 已存在"
+
+#: sequencer.c
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"已用 %s 更新下列引用:\n"
+"%s"
+
+#: sequencer.c
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"无法用 %s 更新下列引用:\n"
+"%s"
+
+#: sequencer.c
msgid "Cannot autostash"
msgstr "无法自动贮è—"
@@ -24101,6 +24668,11 @@ msgstr "无法跳过ä¸å¿…è¦çš„拣选"
msgid "the script was already rearranged."
msgstr "脚本已ç»é‡æ–°ç¼–排。"
+#: sequencer.c
+#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "ä½äºŽ '%s' çš„ update-refs 文件无效"
+
#: setup.c
#, c-format
msgid "'%s' is outside repository at '%s'"
@@ -24243,18 +24815,23 @@ msgstr ""
#: setup.c
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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"
-"è¦ä¸ºæœ¬ä»“库创建特例,请使用:\n"
+"在 '%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')"
+
+#: setup.c
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -25278,6 +25855,22 @@ msgstr "无效的端å£å·"
msgid "invalid '..' path segment"
msgstr "无效的 '..' 路径片段"
+#: usage.c
+msgid "usage: "
+msgstr "用法:"
+
+#: usage.c
+msgid "fatal: "
+msgstr "致命错误:"
+
+#: usage.c
+msgid "error: "
+msgstr "错误:"
+
+#: usage.c
+msgid "warning: "
+msgstr "警告:"
+
#: walker.c
msgid "Fetching objects"
msgstr "正在获å–对象"
@@ -25970,7 +26563,7 @@ msgstr "å¦å¤–,您的索引中包å«æœªæ交的å˜æ›´ã€‚"
msgid "cannot %s: Your index contains uncommitted changes."
msgstr "ä¸èƒ½%s:您的索引中包å«æœªæ交的å˜æ›´ã€‚"
-#: git-merge-octopus.sh
+#: git-merge-octopus.sh git-merge-resolve.sh
msgid ""
"Error: Your local changes to the following files would be overwritten by "
"merge"
@@ -26259,26 +26852,6 @@ msgid "ignoring unmerged: %s\n"
msgstr "忽略未åˆå…¥çš„:%s\n"
#: git-add--interactive.perl
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "将模å¼å˜æ›´åº”用到工作区 [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "将删除æ“作应用到工作区 [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "将添加æ“作应用到工作区 [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "将该å—应用到工作区 [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
msgid "No other hunks to goto\n"
msgstr "没有其它å¯ä¾›è·³è½¬çš„å—\n"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 2f7d01c3031..29b80891417 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -22,8 +22,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-23 21:13+0800\n"
-"PO-Revision-Date: 2022-06-23 23:02+0800\n"
+"POT-Creation-Date: 2022-09-23 21:57+0000\n"
+"PO-Revision-Date: 2022-10-01 19:02+0800\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"
@@ -32,7 +32,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.1\n"
+"X-Generator: Poedit 3.1.1\n"
"X-ZhConverter: ç¹åŒ–姬 dict-f4bc617e-r910 @ 2019/11/16 20:23:12 | https://"
"zhconvert.org\n"
@@ -41,7 +41,7 @@ msgstr ""
msgid "Huh (%s)?"
msgstr "嗯(%s)?"
-#: add-interactive.c builtin/rebase.c reset.c sequencer.c
+#: add-interactive.c builtin/merge.c builtin/rebase.c reset.c sequencer.c
msgid "could not read index"
msgstr "無法讀å–索引"
@@ -219,8 +219,8 @@ msgid "unstaged"
msgstr "未快å–"
#: add-interactive.c apply.c builtin/am.c builtin/bugreport.c builtin/clone.c
-#: builtin/fetch.c builtin/merge.c builtin/pull.c builtin/submodule--helper.c
-#: git-add--interactive.perl
+#: builtin/diagnose.c builtin/fetch.c builtin/merge.c builtin/pull.c
+#: builtin/submodule--helper.c git-add--interactive.perl
msgid "path"
msgstr "路徑"
@@ -501,6 +501,26 @@ msgstr ""
"a - 套用此å€å¡Šå’Œæœ¬æª”案中後é¢çš„全部å€å¡Š\n"
"d - ä¸è¦å¥—用此å€å¡Šå’Œæœ¬æª”案中後é¢çš„全部å€å¡Š\n"
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "將模å¼è®Šæ›´å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "å°‡åˆªé™¤è®Šæ›´å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "å°‡æ–°å¢žè®Šæ›´å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
+
+#: add-patch.c git-add--interactive.perl
+#, c-format, perl-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "將此å€å¡Šå¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
+
#: add-patch.c
msgid ""
"y - apply this hunk to worktree\n"
@@ -521,11 +541,6 @@ msgid "could not parse hunk header '%.*s'"
msgstr "無法解æžå€å¡Šæ¨™é ­ '%.*s'"
#: add-patch.c
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "無法解æžä¸Šè‰²éŽçš„å€å¡Šæ¨™é ­ '%.*s'"
-
-#: add-patch.c
msgid "could not parse diff"
msgstr "無法解æžå·®ç•° (diff)"
@@ -589,6 +604,7 @@ msgstr ""
"è¦åˆªé™¤ '%c' 開始的行,刪除它們。\n"
"以 %c 開始的行將被刪除。\n"
+#. #-#-#-#-# git-add--interactive.perl.po #-#-#-#-#
#. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
#: add-patch.c git-add--interactive.perl
msgid ""
@@ -608,12 +624,14 @@ msgstr "無法解æžå€å¡Šæ¨™é ­"
msgid "'git apply --cached' failed"
msgstr "「git apply --cachedã€å¤±æ•—"
+#. #-#-#-#-# add-patch.c.po #-#-#-#-#
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input at this point.
#. Consider translating (saying "no" discards!) as
#. (saying "n" for "no" discards!) if the translation
#. of the word "no" does not start with n.
#.
+#. #-#-#-#-# git-add--interactive.perl.po #-#-#-#-#
#. TRANSLATORS: do not translate [y/n]
#. The program will only accept that input
#. at this point.
@@ -852,6 +870,26 @@ msgstr ""
"將組態變數 advice.detachedHead 設定為 false,å³å¯é—œé–‰æœ¬å»ºè­°\n"
"\n"
+#: advice.c
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"以下路徑已經移到稀ç–簽出定義之外的地方,\n"
+"但因為有本機更動,因此路徑ä¸æ˜¯ç¨€ç–的。\n"
+
+#: advice.c
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"è‹¥è¦æ›´æ­£é€™äº›è·¯å¾‘的稀ç–狀態,請:\n"
+"* 使用 `git add --sparse <路徑>` 更新索引\n"
+"* 使用 `git sparse-checkout reapply` 套用稀ç–è¦å‰‡"
+
#: alias.c
msgid "cmdline ends with \\"
msgstr "指令列以 \\ çµå°¾"
@@ -1081,7 +1119,7 @@ msgstr "到 '%s' 的二進ä½ä¿®è£œæª”產生了ä¸æ­£ç¢ºçš„çµæžœï¼ˆæ‡‰ç‚º %s,
msgid "patch failed: %s:%ld"
msgstr "打修補檔失敗:%s:%ld"
-#: apply.c
+#: apply.c builtin/mv.c
#, c-format
msgid "cannot checkout %s"
msgstr "ä¸èƒ½ç°½å‡º %s"
@@ -1470,6 +1508,11 @@ msgstr "ä¸èƒ½é–‹å•Ÿè³‡æ–™ç‰©ä»¶ %s"
msgid "unsupported file mode: 0%o (SHA1: %s)"
msgstr "ä¸æ”¯æ´çš„檔案模å¼ï¼š0%o (SHA1: %s)"
+#: archive-tar.c archive-zip.c builtin/pack-objects.c
+#, c-format
+msgid "deflate error (%d)"
+msgstr "壓縮錯誤 (%d)"
+
#: archive-tar.c
#, c-format
msgid "unable to start '%s' filter"
@@ -1494,11 +1537,6 @@ msgstr "路徑ä¸æ˜¯æœ‰æ•ˆçš„ UTF-8:%s"
msgid "path too long (%d chars, SHA1: %s): %s"
msgstr "路徑太長(%d 字元,SHA1:%s):%s"
-#: archive-zip.c builtin/pack-objects.c
-#, c-format
-msgid "deflate error (%d)"
-msgstr "壓縮錯誤 (%d)"
-
#: archive-zip.c
#, c-format
msgid "timestamp too large for this system: %<PRIuMAX>"
@@ -1812,8 +1850,8 @@ msgid "--reverse and --first-parent together require specified latest commit"
msgstr "--reverse å’Œ --first-parent 共用,需è¦æŒ‡å®šæœ€æ–°çš„æ交"
#: blame.c builtin/commit.c builtin/log.c builtin/merge.c
-#: builtin/pack-objects.c builtin/shortlog.c bundle.c midx.c ref-filter.c
-#: remote.c sequencer.c submodule.c
+#: builtin/pack-objects.c builtin/shortlog.c bundle.c midx.c pack-bitmap.c
+#: ref-filter.c remote.c sequencer.c submodule.c
msgid "revision walk setup failed"
msgstr "版本é歷設定失敗"
@@ -1888,10 +1926,12 @@ msgid "not tracking: ambiguous information for ref '%s'"
msgstr "未追蹤:「%sã€å¼•ç”¨æœ‰æ­§ç¾©"
# 譯者:為ä¿è­‰åœ¨è¼¸å‡ºä¸­å°é½Šï¼Œæ³¨æ„調整å¥ä¸­ç©ºæ ¼ï¼
+#. #-#-#-#-# branch.c.po #-#-#-#-#
#. TRANSLATORS: This is a line listing a remote with duplicate
#. refspecs in the advice message below. For RTL languages you'll
#. probably want to swap the "%s" and leading " " space around.
#.
+#. #-#-#-#-# object-name.c.po #-#-#-#-#
#. TRANSLATORS: This is line item of ambiguous object output
#. from describe_ambiguous_object() above. For RTL languages
#. you'll probably want to swap the "%s" and leading " " space
@@ -2272,7 +2312,7 @@ msgstr "fseek 失敗"
msgid "could not open '%s' for reading"
msgstr "無法開啟 '%s' 進行讀å–"
-#: builtin/am.c builtin/rebase.c strbuf.c wrapper.c
+#: builtin/am.c builtin/rebase.c sequencer.c strbuf.c wrapper.c
#, c-format
msgid "could not open '%s' for writing"
msgstr "無法開啟 '%s' 進行寫入"
@@ -2574,8 +2614,8 @@ msgid "n"
msgstr "n"
#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
-#: builtin/for-each-ref.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c
+#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c
msgid "format"
msgstr "æ ¼å¼"
@@ -2678,7 +2718,7 @@ msgstr "互動å¼æ¨¡å¼éœ€è¦æŒ‡ä»¤åˆ—上æ供修補檔"
msgid "git apply [<options>] [<patch>...]"
msgstr "git apply [<é¸é …>] [<修補檔>...]"
-#: builtin/archive.c contrib/scalar/scalar.c
+#: builtin/archive.c diagnose.c
msgid "could not redirect output"
msgstr "ä¸èƒ½é‡å®šå‘輸出"
@@ -3561,8 +3601,8 @@ msgstr "排åºå’ŒéŽæ¿¾å±¬æ–¼å¤§å°å¯«ä¸æ•æ„Ÿ"
msgid "recurse through submodules"
msgstr "在å­æ¨¡çµ„中éžè¿´"
-#: builtin/branch.c builtin/for-each-ref.c builtin/ls-tree.c builtin/tag.c
-#: builtin/verify-tag.c
+#: builtin/branch.c builtin/for-each-ref.c builtin/ls-files.c builtin/ls-tree.c
+#: builtin/tag.c builtin/verify-tag.c
msgid "format to use for the output"
msgstr "輸出格å¼"
@@ -3685,8 +3725,12 @@ msgid "not run from a git repository - no hooks to show\n"
msgstr "ä¸æ˜¯å¾ž git 版本庫執行 - 沒有å¯é¡¯ç¤ºçš„掛鉤\n"
#: builtin/bugreport.c
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr "git bugreport [-o|--output-directory <檔案>] [-s|--suffix <æ ¼å¼>]"
+msgid ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
+msgstr ""
+"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>] [--"
+"diagnose[=<mode>]"
#: builtin/bugreport.c
msgid ""
@@ -3722,19 +3766,34 @@ msgstr ""
"請檢閱臭蟲報告下方的剩餘部分。\n"
"您å¯åˆªé™¤ä»»ä½•æ‚¨ä¸æƒ³åˆ†äº«çš„地方。\n"
+#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c
+#: parse-options.h
+msgid "mode"
+msgstr "模å¼"
+
#: builtin/bugreport.c
-msgid "specify a destination for the bugreport file"
-msgstr "請指定 bugreport 檔案的目的地"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr "建立詳細診斷資訊的é¡å¤– zip å°å­˜æª”案(é è¨­å€¼æ˜¯ “statsâ€ï¼‰"
#: builtin/bugreport.c
-msgid "specify a strftime format suffix for the filename"
-msgstr "請指定檔案å稱的 strftime æ ¼å¼å¾Œç¶´"
+msgid "specify a destination for the bugreport file(s)"
+msgstr "指定錯誤報告檔案的目的地"
#: builtin/bugreport.c
+msgid "specify a strftime format suffix for the filename(s)"
+msgstr "指定檔å,strftime æ ¼å¼çš„後綴"
+
+#: builtin/bugreport.c builtin/diagnose.c
#, c-format
msgid "could not create leading directories for '%s'"
msgstr "無法建立 '%s' çš„å‰ç½®ç›®éŒ„"
+#: builtin/bugreport.c builtin/diagnose.c
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "無法建立 %s 診斷å°å­˜æª”"
+
#: builtin/bugreport.c
msgid "System Info"
msgstr "系統資訊"
@@ -3810,11 +3869,6 @@ msgstr "需è¦ç‰ˆæœ¬åº«æ‰èƒ½æ‹†åˆ†å¥—件。"
msgid "Unbundling objects"
msgstr "正在解包物件"
-#: builtin/bundle.c builtin/remote.c
-#, c-format
-msgid "Unknown subcommand: %s"
-msgstr "未知å­æŒ‡ä»¤ï¼š%s"
-
#: builtin/cat-file.c merge-recursive.c
#, c-format
msgid "cannot read object %s '%s'"
@@ -3912,6 +3966,10 @@ msgstr "顯示物件大å°"
msgid "allow -s and -t to work with broken/corrupt objects"
msgstr "å…許 -s å’Œ -t å°æ壞的物件生效"
+#: builtin/cat-file.c builtin/log.c
+msgid "use mail map file"
+msgstr "使用信件映射檔案"
+
#: builtin/cat-file.c
msgid "Batch objects requested on stdin (or --batch-all-objects)"
msgstr "æ‰¹æ¬¡è™•ç† stdin 上請求的物件(或 --batch-all-objects)"
@@ -3925,6 +3983,10 @@ msgid "like --batch, but don't emit <contents>"
msgstr "é¡žä¼¼ --batch 但ä¸è¼¸å‡º <contents>"
#: builtin/cat-file.c
+msgid "stdin is NUL-terminated"
+msgstr "標準輸入的çµå°¾æ˜¯ NUL"
+
+#: builtin/cat-file.c
msgid "read commands from stdin"
msgstr "從標準輸入讀å–命令"
@@ -4992,6 +5054,14 @@ msgid "initialize sparse-checkout file to include only files at root"
msgstr "åˆå§‹åŒ–稀ç–簽出檔案,åªåŒ…å«æ ¹ç›®éŒ„中的檔案"
#: builtin/clone.c
+msgid "uri"
+msgstr "uri"
+
+#: builtin/clone.c
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "在從 origin é ç«¯æŠ“å–å‰ï¼Œç”¨ä¾†ä¸‹è¼‰å¥—件的 URI"
+
+#: builtin/clone.c
#, c-format
msgid "info: Could not add alternate for '%s': %s\n"
msgstr "info: ä¸èƒ½ç‚º '%s' 新增一個備用:%s\n"
@@ -5065,8 +5135,8 @@ msgid "failed to initialize sparse-checkout"
msgstr "無法åˆå§‹åŒ–稀ç–簽出"
#: builtin/clone.c
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr "é ç«¯ HEAD 指å‘一個ä¸å­˜åœ¨çš„引用,無法簽出。\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
+msgstr "é ç«¯ HEAD 指å‘ä¸å­˜åœ¨çš„引用,無法簽出"
#: builtin/clone.c
msgid "unable to checkout working tree"
@@ -5088,7 +5158,7 @@ msgstr "無法刪除暫時的 alternates 檔案"
msgid "Too many arguments."
msgstr "太多åƒæ•¸ã€‚"
-#: builtin/clone.c contrib/scalar/scalar.c
+#: builtin/clone.c scalar.c
msgid "You must specify a repository to clone."
msgstr "您必須指定è¦è¤‡è£½çš„版本庫。"
@@ -5098,6 +5168,12 @@ msgid "options '%s' and '%s %s' cannot be used together"
msgstr "「%sã€å’Œã€Œ%s %sã€é¸é …ä¸å¾—åŒæ™‚使用"
#: builtin/clone.c
+msgid ""
+"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+"exclude"
+msgstr "--bundle-uri 與 --depthã€--shallow-since å’Œ --shallow-exclude ä¸ç›¸å®¹"
+
+#: builtin/clone.c
#, c-format
msgid "repository '%s' does not exist"
msgstr "版本庫 '%s' ä¸å­˜åœ¨"
@@ -5186,6 +5262,15 @@ msgid "cannot clone from filtered bundle"
msgstr "無法從éŽæ¿¾å¾Œçš„套件複製"
#: builtin/clone.c
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "無法åˆå§‹åŒ–版本庫,略éŽå¥—件 URI"
+
+#: builtin/clone.c
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "無法從套件 URL “%s†抓å–物件"
+
+#: builtin/clone.c
msgid "remote transport reported error"
msgstr "é ç«¯å‚³è¼¸å›žå ±éŒ¯èª¤"
@@ -5332,11 +5417,6 @@ msgstr "ä¸èƒ½åŒæ™‚使用 --reachableã€--stdin-commits 或 --stdin-packs"
msgid "Collecting commits from input"
msgstr "正在從輸入收集æ交"
-#: builtin/commit-graph.c builtin/multi-pack-index.c
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "未識別的å­æŒ‡ä»¤ï¼š%s"
-
#: builtin/commit-tree.c
msgid ""
"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
@@ -5769,10 +5849,6 @@ msgstr "以長格å¼é¡¯ç¤ºç‹€æ…‹ï¼ˆé è¨­ï¼‰"
msgid "terminate entries with NUL"
msgstr "æ¢ç›®ä»¥ NUL å­—å…ƒçµå°¾"
-#: builtin/commit.c builtin/fast-export.c builtin/rebase.c parse-options.h
-msgid "mode"
-msgstr "模å¼"
-
#: builtin/commit.c
msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
msgstr "顯示未追蹤的檔案,「模å¼ã€çš„å¯é¸åƒæ•¸ï¼šallã€normalã€no。(é è¨­å€¼ï¼šall)"
@@ -6513,6 +6589,26 @@ msgstr "沒有發ç¾å稱,無法æ述任何æ±è¥¿ã€‚"
msgid "option '%s' and commit-ishes cannot be used together"
msgstr "「%sã€é¸é …å’Œæ交號ä¸å¾—åŒæ™‚使用"
+#: builtin/diagnose.c
+msgid ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+msgstr ""
+"git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--"
+"mode=<mode>]"
+
+#: builtin/diagnose.c
+msgid "specify a destination for the diagnostics archive"
+msgstr "指定診斷å°å­˜æª”的目的地"
+
+#: builtin/diagnose.c
+msgid "specify a strftime format suffix for the filename"
+msgstr "請指定檔案å稱的 strftime æ ¼å¼å¾Œç¶´"
+
+#: builtin/diagnose.c
+msgid "specify the content of the diagnostic archive"
+msgstr "指定診斷å°å­˜æª”的內容"
+
#: builtin/diff-tree.c
msgid "--merge-base only works with two commits"
msgstr "--merge-base åªå° 2 個以上的æ交有用"
@@ -6984,12 +7080,8 @@ msgid "[rejected]"
msgstr "[已拒絕]"
#: builtin/fetch.c
-msgid "can't fetch in current branch"
-msgstr "ç›®å‰åˆ†æ”¯ä¸‹ä¸èƒ½åŸ·è¡Œå–得動作"
-
-#: builtin/fetch.c
-msgid "checked out in another worktree"
-msgstr "已在其他工作å€ç°½å‡º"
+msgid "can't fetch into checked-out branch"
+msgstr "無法抓å–至已簽出分支"
#: builtin/fetch.c
msgid "[tag update]"
@@ -7531,6 +7623,11 @@ msgid "non-tree in cache-tree"
msgstr "cache-tree 中éžæ¨¹ç‹€ç‰©ä»¶"
#: builtin/fsck.c
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo"
+msgstr "%s:resolve-undo çš„ sha1 指é‡ç„¡æ•ˆ"
+
+#: builtin/fsck.c
msgid "git fsck [<options>] [<object>...]"
msgstr "git fsck [<é¸é …>] [<物件>...]"
@@ -7946,12 +8043,16 @@ msgid "failed to run 'crontab -l'; your system might not support 'cron'"
msgstr "無法執行 “crontab -lâ€ï¼›æ‚¨çš„系統å¯èƒ½ä¸æ”¯æ´ “cronâ€"
#: builtin/gc.c
-msgid "failed to run 'crontab'; your system might not support 'cron'"
-msgstr "無法執行 “crontabâ€ï¼›æ‚¨çš„系統å¯èƒ½ä¸æ”¯æ´ “cronâ€"
+msgid "failed to create crontab temporary file"
+msgstr "無法建立 crontab 暫存檔"
#: builtin/gc.c
-msgid "failed to open stdin of 'crontab'"
-msgstr "無法開啟 ‘crontab’ 的標準輸入"
+msgid "failed to open temporary file"
+msgstr "無法開啟暫存檔"
+
+#: builtin/gc.c
+msgid "failed to run 'crontab'; your system might not support 'cron'"
+msgstr "無法執行 “crontabâ€ï¼›æ‚¨çš„系統å¯èƒ½ä¸æ”¯æ´ “cronâ€"
#: builtin/gc.c
msgid "'crontab' died"
@@ -8013,11 +8114,6 @@ msgstr "無法將版本庫加至全域設定"
msgid "git maintenance <subcommand> [<options>]"
msgstr "git maintenance <å­å‘½ä»¤> [<é¸é …>]"
-#: builtin/gc.c
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "無效å­å‘½ä»¤ï¼š%s"
-
#: builtin/grep.c
msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
msgstr "git grep [<é¸é …>] [-e] <模å¼> [<版本>...] [[--] <路徑>...]"
@@ -8032,6 +8128,7 @@ msgstr "grep:無法建立執行緒:%s"
msgid "invalid number of threads specified (%d) for %s"
msgstr "為 %2$s 設定的執行緒數 (%1$d) 無效"
+#. #-#-#-#-# grep.c.po #-#-#-#-#
#. TRANSLATORS: %s is the configuration
#. variable for tweaking threads, currently
#. grep.threads
@@ -8242,6 +8339,10 @@ msgid "allow calling of grep(1) (ignored by this build)"
msgstr "å…è¨±å‘¼å« grep(1)(本次組建忽略)"
#: builtin/grep.c
+msgid "maximum number of results per file"
+msgstr "æ¯å€‹æª”案的最多çµæžœæ•¸"
+
+#: builtin/grep.c
msgid "no pattern given"
msgstr "未æ供符åˆæ¨¡å¼"
@@ -8353,12 +8454,20 @@ msgid "print list of useful guides"
msgstr "顯示有用的指å—列表"
#: builtin/help.c
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr "輸出é¢å‘使用者的版本庫ã€å‘½ä»¤ï¼Œå’Œæª”案介é¢æ¸…å–®"
+
+#: builtin/help.c
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr "輸出檔案格å¼ã€é€šè¨Šå”定和其他開發者介é¢çš„清單"
+
+#: builtin/help.c
msgid "print all configuration variable names"
msgstr "列å°æ‰€æœ‰è¨­å®šè®Šæ•¸å稱"
#: builtin/help.c
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
#: builtin/help.c
#, c-format
@@ -8943,8 +9052,8 @@ msgid "show source"
msgstr "顯示來æº"
#: builtin/log.c
-msgid "use mail map file"
-msgstr "使用信件映射檔案"
+msgid "clear all previously-defined decoration filters"
+msgstr "清除所有先å‰å®šç¾©çš„è£é£¾éŽæ¿¾å™¨"
#: builtin/log.c
msgid "only decorate refs that match <pattern>"
@@ -9270,6 +9379,10 @@ msgid "percentage by which creation is weighted"
msgstr "建立權é‡çš„百分比"
#: builtin/log.c
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "顯示內文中的 From:å³ä¾¿å’Œä¿¡ä»¶æ¨™é ­çš„值相åŒ"
+
+#: builtin/log.c
#, c-format
msgid "invalid ident line: %s"
msgstr "包å«ç„¡æ•ˆçš„身份標記:%s"
@@ -9345,10 +9458,25 @@ msgid ""
msgstr "ä¸èƒ½æ‰¾åˆ°è¿½è¹¤çš„é ç«¯åˆ†æ”¯ï¼Œè«‹æ‰‹å‹•æŒ‡å®š <上游>。\n"
#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: element '%s' does not start with '('"
+msgstr "ls-files æ ¼å¼éŒ¯èª¤ï¼šâ€œ%s†元素ä¸ä»¥ “(†開頭"
+
+#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: element '%s' does not end in ')'"
+msgstr "ls-files æ ¼å¼éŒ¯èª¤ï¼šâ€œ%s†元素ä¸ä»¥ “)†çµå°¾"
+
+#: builtin/ls-files.c
+#, c-format
+msgid "bad ls-files format: %%%.*s"
+msgstr "ls-files æ ¼å¼éŒ¯èª¤ï¼š%%%.*s"
+
+#: builtin/ls-files.c
msgid "git ls-files [<options>] [<file>...]"
msgstr "git ls-files [<é¸é …>] [<檔案>...]"
-#: builtin/ls-files.c
+#: builtin/ls-files.c builtin/merge-tree.c
msgid "separate paths with the NUL character"
msgstr "用 NUL 字元分隔路徑"
@@ -9456,6 +9584,13 @@ msgstr "ä¸é¡¯ç¤ºé‡è¤‡é …ç›®"
msgid "show sparse directories in the presence of a sparse index"
msgstr "在稀ç–索引存在時顯示稀ç–目錄"
+#: builtin/ls-files.c
+msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format ä¸èƒ½å’Œ -sã€-oã€-kã€-tã€--resolve-undoã€--deduplicateã€--eol 一起使用"
+
#: builtin/ls-remote.c
msgid ""
"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -9738,6 +9873,50 @@ msgstr "無法解æžå¼•ç”¨ '%s'"
msgid "Merging %s with %s\n"
msgstr "åˆä½µ %s å’Œ %s\n"
+#: builtin/merge-tree.c builtin/merge.c
+msgid "not something we can merge"
+msgstr "ä¸èƒ½åˆä½µ"
+
+#: builtin/merge-tree.c builtin/merge.c
+msgid "refusing to merge unrelated histories"
+msgstr "拒絕åˆä½µç„¡é—œçš„æ­·å²"
+
+#: builtin/merge-tree.c
+msgid "failure to merge"
+msgstr "åˆä½µæ™‚發生錯誤"
+
+#: builtin/merge-tree.c
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+
+#: builtin/merge-tree.c
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+
+#: builtin/merge-tree.c
+msgid "do a real merge instead of a trivial merge"
+msgstr "執行真實åˆä½µï¼Œè€Œéžç°¡æ˜“åˆä½µ"
+
+#: builtin/merge-tree.c
+msgid "do a trivial merge only"
+msgstr "åªåŸ·è¡Œç°¡æ˜“åˆä½µ"
+
+#: builtin/merge-tree.c
+msgid "also show informational/conflict messages"
+msgstr "亦顯示資訊性或è¡çªè¨Šæ¯"
+
+#: builtin/merge-tree.c
+msgid "list filenames without modes/oids/stages"
+msgstr "列出檔å,但ä¸é™„加 modes/oids/stages"
+
+#: builtin/merge-tree.c builtin/merge.c builtin/pull.c
+msgid "allow merging unrelated histories"
+msgstr "å…許åˆä¸¦ä¸ç›¸é—œçš„æ­·å²"
+
+#: builtin/merge-tree.c
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge 和其他所有é¸é …都ä¸ç›¸å®¹"
+
#: builtin/merge.c
msgid "git merge [<options>] [<commit>...]"
msgstr "git merge [<é¸é …>] [<æ交>...]"
@@ -9844,10 +10023,6 @@ msgstr "--abort,但是ä¿ç•™ç´¢å¼•å’Œå·¥ä½œå€"
msgid "continue the current in-progress merge"
msgstr "繼續目å‰æ­£åœ¨é€²è¡Œçš„åˆä½µ"
-#: builtin/merge.c builtin/pull.c
-msgid "allow merging unrelated histories"
-msgstr "å…許åˆä¸¦ä¸ç›¸é—œçš„æ­·å²"
-
#: builtin/merge.c
msgid "bypass pre-merge-commit and commit-msg hooks"
msgstr "ç¹žéŽ pre-merge-commit å’Œ commit-msg 掛鉤"
@@ -9994,10 +10169,6 @@ msgid "not something we can merge in %s: %s"
msgstr "ä¸èƒ½åœ¨ %s 中åˆä½µï¼š%s"
#: builtin/merge.c
-msgid "not something we can merge"
-msgstr "ä¸èƒ½åˆä½µ"
-
-#: builtin/merge.c
msgid "--abort expects no arguments"
msgstr "--abort ä¸å¸¶åƒæ•¸"
@@ -10059,14 +10230,19 @@ msgid "Can merge only exactly one commit into empty head"
msgstr "åªèƒ½å°‡ä¸€å€‹æ交åˆä¸¦åˆ°ç©ºåˆ†æ”¯ä¸Š"
#: builtin/merge.c
-msgid "refusing to merge unrelated histories"
-msgstr "拒絕åˆä½µç„¡é—œçš„æ­·å²"
-
-#: builtin/merge.c
#, c-format
msgid "Updating %s..%s\n"
msgstr "æ›´æ–° %s..%s\n"
+#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c
+#, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+" %s"
+msgstr ""
+"您å°ä¸‹åˆ—檔案的本機修改將被åˆä½µå‹•ä½œè¦†è“‹ï¼š\n"
+" %s"
+
#: builtin/merge.c
#, c-format
msgid "Trying really trivial in-index merge...\n"
@@ -10107,6 +10283,11 @@ msgstr "使用 %s 策略,準備自行解決。\n"
msgid "Automatic merge went well; stopped before committing as requested\n"
msgstr "自動åˆä½µé€²å±•é †åˆ©ï¼ŒæŒ‰è¦æ±‚在æ交å‰åœæ­¢\n"
+#: builtin/merge.c
+#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
+msgstr "完æˆæ™‚,使用 `git stash pop` 套用儲è—更改\n"
+
#: builtin/mktag.c
#, c-format
msgid "warning: tag input does not pass fsck: %s"
@@ -10255,6 +10436,10 @@ msgid "bad source"
msgstr "來æºæ壞"
#: builtin/mv.c
+msgid "destination exists"
+msgstr "目的地已存在"
+
+#: builtin/mv.c
msgid "can not move directory into itself"
msgstr "ä¸èƒ½å°‡ç›®éŒ„移動到自身"
@@ -10275,10 +10460,6 @@ msgid "conflicted"
msgstr "è¡çª"
#: builtin/mv.c
-msgid "destination exists"
-msgstr "目的地已存在"
-
-#: builtin/mv.c
#, c-format
msgid "overwriting '%s'"
msgstr "覆蓋 '%s'"
@@ -10296,6 +10477,10 @@ msgid "destination directory does not exist"
msgstr "找ä¸åˆ°ç›®çš„地目錄"
#: builtin/mv.c
+msgid "destination exists in the index"
+msgstr "目的地已存在索引"
+
+#: builtin/mv.c
#, c-format
msgid "%s, source=%s, destination=%s"
msgstr "%s,來æº=%s,目的地=%s"
@@ -10737,10 +10922,10 @@ msgstr "註解引用"
msgid "use notes from <notes-ref>"
msgstr "從 <註解引用> 使用註解"
-#: builtin/notes.c builtin/stash.c
+#: builtin/notes.c builtin/remote.c parse-options.c
#, c-format
-msgid "unknown subcommand: %s"
-msgstr "未知å­æŒ‡ä»¤ï¼š%s"
+msgid "unknown subcommand: `%s'"
+msgstr "未知å­æŒ‡ä»¤ï¼šã€Œ%sã€"
#: builtin/pack-objects.c
msgid ""
@@ -11339,7 +11524,7 @@ msgstr "詳見 git-pull(1)。"
msgid "<remote>"
msgstr "<é ç«¯>"
-#: builtin/pull.c contrib/scalar/scalar.c
+#: builtin/pull.c scalar.c
msgid "<branch>"
msgstr "<分支>"
@@ -11795,12 +11980,18 @@ msgstr "åªç™¼å‡ºè·Ÿç¬¬äºŒå€‹ç¯„åœç›¸é—œçš„輸出"
#: builtin/range-diff.c
#, c-format
+msgid "not a revision: '%s'"
+msgstr "éžä¿®è¨‚版:「%sã€"
+
+#: builtin/range-diff.c
+#, c-format
msgid "not a commit range: '%s'"
msgstr "ä¸æ˜¯æ交範åœï¼šã€Œ%sã€"
#: builtin/range-diff.c
-msgid "single arg format must be symmetric range"
-msgstr "單個åƒæ•¸æ ¼å¼å¿…須是å°ç¨±ç¯„åœï¼ˆå³åŒ…å«...)"
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "ä¸æ˜¯å°ç¨±ç¯„åœï¼šã€Œ%sã€"
#: builtin/range-diff.c
msgid "need two commit ranges"
@@ -12136,6 +12327,10 @@ msgid "move commits that begin with squash!/fixup! under -i"
msgstr "在 -i 互動模å¼ä¸‹ï¼Œç§»å‹•ä»¥ squash!/fixup! é–‹é ­çš„æ交"
#: builtin/rebase.c
+msgid "update branches that point to commits that are being rebased"
+msgstr "更新指å‘正在é‡å®šåŸºåº•çš„æ交之分支"
+
+#: builtin/rebase.c
msgid "add exec lines after each commit of the editable list"
msgstr "å¯ç·¨è¼¯åˆ—表的æ¯ä¸€å€‹æ交下é¢å¢žåŠ ä¸€è¡Œ exec"
@@ -12758,6 +12953,10 @@ msgid " tracked"
msgstr " 已追蹤"
#: builtin/remote.c
+msgid " skipped"
+msgstr " ç•¥éŽ"
+
+#: builtin/remote.c
msgid " stale (use 'git remote prune' to remove)"
msgstr " éŽæ™‚(使用 'git remote prune' 移除)"
@@ -13599,12 +13798,17 @@ msgstr "ä¸èƒ½é‡è¨­ç´¢å¼•æª”案至版本 '%s'。"
msgid "Could not write new index file."
msgstr "ä¸èƒ½å¯«å…¥æ–°çš„索引檔案。"
-#: builtin/rev-list.c pack-bitmap.c
+#: builtin/rev-list.c
#, c-format
msgid "unable to get disk usage of %s"
msgstr "無法å–å¾— %s çš„ç£ç¢Ÿç”¨é‡"
#: builtin/rev-list.c
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "「%sã€çš„數值無效:「%sã€ï¼Œå”¯ä¸€å…許的格å¼æ˜¯ã€Œ%sã€"
+
+#: builtin/rev-list.c
msgid "rev-list does not support display of notes"
msgstr "rev-list ä¸æ”¯æ´é¡¯ç¤ºè¨»è§£"
@@ -13638,6 +13842,10 @@ msgid "no usage string given before the `--' separator"
msgstr "「--ã€åˆ†éš”符號å‰æœªæ供用法字串"
#: builtin/rev-parse.c
+msgid "missing opt-spec before option flags"
+msgstr "é¸é …旗標å‰ç¼ºå°‘ opt-spec"
+
+#: builtin/rev-parse.c
msgid "Needed a single revision"
msgstr "需è¦ä¸€å€‹ä¿®è¨‚版本"
@@ -14182,7 +14390,7 @@ msgstr "以 cone 模å¼åˆå§‹åŒ–稀ç–簽出"
msgid "toggle the use of a sparse index"
msgstr "切æ›æ˜¯å¦ä½¿ç”¨ç¨€ç–索引"
-#: builtin/sparse-checkout.c commit-graph.c midx.c
+#: builtin/sparse-checkout.c commit-graph.c midx.c sequencer.c
#, c-format
msgid "unable to create leading directories of %s"
msgstr "ä¸èƒ½ç‚º %s 建立先導目錄"
@@ -14579,20 +14787,17 @@ msgstr "期望一個完整的引用å稱,å»å¾—到 %s"
#: builtin/submodule--helper.c
#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "無法ç²å¾—å­æ¨¡çµ„ '%s' 的版本庫å¥æŸ„"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid ""
"could not look up configuration '%s'. Assuming this repository is its own "
"authoritative upstream."
msgstr "無法找到設定 '%s'。å‡å®šé€™å€‹ç‰ˆæœ¬åº«æ˜¯å…¶è‡ªèº«çš„官方上游。"
#: builtin/submodule--helper.c
-msgid "alternative anchor for relative paths"
-msgstr "相å°è·¯å¾‘的替代錨記(anchor)"
-
-#: builtin/submodule--helper.c
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=<路徑>] [<路徑>...]"
-
-#: builtin/submodule--helper.c
#, c-format
msgid "No url found for submodule path '%s' in .gitmodules"
msgstr "在 .gitmodules 中未找到å­æ¨¡çµ„ '%s' çš„ url"
@@ -14630,8 +14835,8 @@ msgid "recurse into nested submodules"
msgstr "éžè¿´é€²å…¥åµŒå¥—å­æ¨¡çµ„中"
#: builtin/submodule--helper.c
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--] <命令>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--] <command>"
#: builtin/submodule--helper.c
#, c-format
@@ -14658,8 +14863,8 @@ msgid "suppress output for initializing a submodule"
msgstr "éš±è—åˆå§‹åŒ–å­æ¨¡çµ„的輸出"
#: builtin/submodule--helper.c
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<é¸é …>] [<路徑>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<options>] [<path>]"
#: builtin/submodule--helper.c
#, c-format
@@ -14691,10 +14896,6 @@ msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
msgstr "git submodule status [--quiet] [--cached] [--recursive] [<路徑>...]"
#: builtin/submodule--helper.c
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name <路徑>"
-
-#: builtin/submodule--helper.c
#, c-format
msgid "* %s %s(blob)->%s(submodule)"
msgstr "* %s %s(blob)->%s(submodule)"
@@ -14736,8 +14937,8 @@ msgid "limit the summary size"
msgstr "é™åˆ¶æ‘˜è¦å¤§å°"
#: builtin/submodule--helper.c
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr "git submodule--helper summary [<é¸é …>] [<æ交>] [--] [<路徑>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
+msgstr "git submodule summary [<options>] [<commit>] [--] [<path>]"
#: builtin/submodule--helper.c
msgid "could not fetch a revision for HEAD"
@@ -14755,11 +14956,6 @@ msgstr "無法為å­æ¨¡çµ„路徑 '%s' 註冊 url"
#: builtin/submodule--helper.c
#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "無法得到å­æ¨¡çµ„ '%s' çš„é è¨­é ç«¯é—œè¯"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "failed to update remote for submodule '%s'"
msgstr "無法為å­æ¨¡çµ„ '%s' æ›´æ–°é ç«¯é—œè¯"
@@ -14768,8 +14964,8 @@ msgid "suppress output of synchronizing submodule url"
msgstr "éš±è—å­æ¨¡çµ„ URL åŒæ­¥çš„輸出"
#: builtin/submodule--helper.c
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [<路徑>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [<path>]"
#: builtin/submodule--helper.c
#, c-format
@@ -14838,6 +15034,11 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "無法å–å¾— gitdir “%s†的版本庫控點"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid "submodule '%s' cannot add alternate: %s"
msgstr "å­æ¨¡çµ„ '%s' ä¸èƒ½æ–°å¢žç‰ˆæœ¬åº«å‚™é¸ï¼š%s"
@@ -14872,6 +15073,10 @@ msgid "could not get submodule directory for '%s'"
msgstr "無法得到 '%s' çš„å­æ¨¡çµ„目錄"
#: builtin/submodule--helper.c
+msgid "alternative anchor for relative paths"
+msgstr "相å°è·¯å¾‘的替代錨記(anchor)"
+
+#: builtin/submodule--helper.c
msgid "where the new submodule will be cloned to"
msgstr "æ–°çš„å­æ¨¡çµ„å°‡è¦è¤‡è£½çš„路徑"
@@ -14907,11 +15112,6 @@ msgstr ""
#: builtin/submodule--helper.c
#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "å­æ¨¡çµ„ '%2$s' çš„æ›´æ–°æ¨¡å¼ '%1$s' 無效"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "Invalid update mode '%s' configured for submodule path '%s'"
msgstr "為å­æ¨¡çµ„ '%2$s' è¨­å®šçš„æ›´æ–°æ¨¡å¼ '%1$s' 無效"
@@ -14998,6 +15198,11 @@ msgstr "已經å–得「%sã€å­æ¨¡çµ„路徑,這個路徑å»æœªåŒ…å«ã€Œ%sã€ã€
#: builtin/submodule--helper.c
#, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "無法在「%sã€è·¯å¾‘åˆå§‹åŒ–å­æ¨¡çµ„"
+
+#: builtin/submodule--helper.c
+#, c-format
msgid ""
"Submodule (%s) branch configured to inherit branch from superproject, but "
"the superproject is not on any branch"
@@ -15005,11 +15210,6 @@ msgstr "å­æ¨¡çµ„(%s)的分支設定為繼承上級專案的分支,但是ä
#: builtin/submodule--helper.c
#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "無法ç²å¾—å­æ¨¡çµ„ '%s' 的版本庫å¥æŸ„"
-
-#: builtin/submodule--helper.c
-#, c-format
msgid "Unable to find current revision in submodule path '%s'"
msgstr "無法在å­æ¨¡çµ„路徑「%sã€ä¸­å°‹æ‰¾ç›®å‰çš„修訂版本"
@@ -15053,12 +15253,16 @@ msgid "path into the working tree"
msgstr "到工作å€çš„路徑"
#: builtin/submodule--helper.c
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "工作å€ä¸­çš„路徑,éžè¿´åµŒå¥—å­æ¨¡çµ„"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "使用 “checkout†更新策略(é è¨­å€¼ï¼‰"
#: builtin/submodule--helper.c
-msgid "rebase, merge, checkout or none"
-msgstr "rebaseã€mergeã€checkout 或 none"
+msgid "use the 'merge' update strategy"
+msgstr "使用 “merge†更新策略"
+
+#: builtin/submodule--helper.c
+msgid "use the 'rebase' update strategy"
+msgstr "使用 “rebase†更新策略"
#: builtin/submodule--helper.c
msgid "create a shallow clone truncated to the specified number of revisions"
@@ -15077,6 +15281,10 @@ msgid "don't print cloning progress"
msgstr "ä¸è¦è¼¸å‡ºè¤‡è£½é€²åº¦"
#: builtin/submodule--helper.c
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "ä¸å…許複製進éžç©ºç™½ç›®éŒ„ï¼Œéš±å« --init"
+
+#: builtin/submodule--helper.c
msgid ""
"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -15089,16 +15297,12 @@ msgstr ""
"[--] [<path>...]"
#: builtin/submodule--helper.c
-msgid "bad value for update parameter"
-msgstr "update åƒæ•¸å–值錯誤"
-
-#: builtin/submodule--helper.c
msgid "recurse into submodules"
msgstr "在å­æ¨¡çµ„中éžè¿´"
#: builtin/submodule--helper.c
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<é¸é …>] [<路徑>...]"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<options>] [<path>...]"
#: builtin/submodule--helper.c
msgid "check if it is safe to write to the .gitmodules file"
@@ -15125,8 +15329,8 @@ msgid "suppress output for setting url of a submodule"
msgstr "éš±è—å­æ¨¡çµ„設定 URL 的輸出"
#: builtin/submodule--helper.c
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] <路徑> <新 URL>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] <path> <newurl>"
#: builtin/submodule--helper.c
msgid "set the default tracking branch to master"
@@ -15137,14 +15341,12 @@ msgid "set the default tracking branch"
msgstr "設定é è¨­è¿½è¹¤åˆ†æ”¯"
#: builtin/submodule--helper.c
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
#: builtin/submodule--helper.c
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
#: builtin/submodule--helper.c
msgid "--branch or --default required"
@@ -15259,8 +15461,8 @@ msgid ""
msgstr "å°‡å­æ¨¡çµ„çš„å稱設為指定字串,而éžé è¨­ç‚ºå…¶è·¯å¾‘"
#: builtin/submodule--helper.c
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<é¸é …>] [--] <版本庫> [<路徑>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<options>] [--] <repository> [<path>]"
#: builtin/submodule--helper.c
msgid "Relative path can only be used from the toplevel of the working tree"
@@ -15514,6 +15716,19 @@ msgid "pack exceeds maximum allowed size"
msgstr "包超éŽäº†æœ€å¤§å…許值"
#: builtin/unpack-objects.c
+msgid "failed to write object in stream"
+msgstr "無法在串æµä¸­å¯«å…¥ç‰©ä»¶"
+
+#: builtin/unpack-objects.c
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "inflate 回傳 (%d)"
+
+#: builtin/unpack-objects.c
+msgid "invalid blob object from stream"
+msgstr "æºè‡ªä¸²æµçš„ blob 物件無效"
+
+#: builtin/unpack-objects.c
msgid "Unpacking objects"
msgstr "展開物件中"
@@ -16153,6 +16368,33 @@ msgstr "å°‡ <å‰ç¶´> å­ç›®éŒ„內容寫到一個樹狀物件"
msgid "only useful for debugging"
msgstr "åªå°é™¤éŒ¯æœ‰ç”¨"
+#: bulk-checkin.c
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch ä¸æ”¯æ´æœ¬å¹³å°"
+
+#: bundle-uri.c
+msgid "failed to create temporary file"
+msgstr "無法建立暫存檔"
+
+#: bundle-uri.c
+msgid "insufficient capabilities"
+msgstr "功能ä¸è¶³"
+
+#: bundle-uri.c
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "無法從 “%s†URI 下載套件"
+
+#: bundle-uri.c
+#, c-format
+msgid "file at URI '%s' is not a bundle"
+msgstr "ä½æ–¼ URI “%s†的檔案ä¸æ˜¯å¥—件"
+
+#: bundle-uri.c
+#, c-format
+msgid "failed to unbundle bundle from URI '%s'"
+msgstr "無法解開æºè‡ª URI “%s†的套件"
+
#: bundle.c
#, c-format
msgid "unrecognized bundle hash algorithm: %s"
@@ -16414,6 +16656,10 @@ msgid "Give an object a human readable name based on an available ref"
msgstr "基於一個ç¾å­˜çš„引用為一個物件起一個å¯è®€çš„å稱"
#: command-list.h
+msgid "Generate a zip archive of diagnostic information"
+msgstr "產生診斷資訊的 zip å°å­˜æª”"
+
+#: command-list.h
msgid "Show changes between commits, commit and working tree, etc"
msgstr "顯示æ交之間ã€æ交和工作å€ä¹‹é–“等的差異"
@@ -16582,8 +16828,8 @@ msgid "The standard helper program to use with git-merge-index"
msgstr "與 git-merge-index 一起使用的標準嚮導程å¼"
#: command-list.h
-msgid "Show three-way merge without touching index"
-msgstr "顯示三路åˆä½µè€Œä¸å‹•ç´¢å¼•"
+msgid "Perform merge without touching index or working tree"
+msgstr "在ä¸æŽ¥è§¸ç´¢å¼•æˆ–工作å€çš„情æ³ä¸‹åŸ·è¡Œåˆä½µ"
#: command-list.h
msgid "Run merge conflict resolution tools to resolve merge conflicts"
@@ -16844,6 +17090,10 @@ msgid "Check the GPG signature of tags"
msgstr "檢查標籤的 GPG ç°½å"
#: command-list.h
+msgid "Display version information about Git"
+msgstr "顯示 Git 的版本資訊"
+
+#: command-list.h
msgid "Show logs with difference each commit introduces"
msgstr "顯示æ¯ä¸€å€‹æ交引入的差異日誌"
@@ -16888,6 +17138,30 @@ msgid "Frequently asked questions about using Git"
msgstr "Git 使用的常見å•é¡Œ"
#: command-list.h
+msgid "The bundle file format"
+msgstr "套件檔案格å¼"
+
+#: command-list.h
+msgid "Chunk-based file formats"
+msgstr "以å€å¡Šç‚ºåŸºç¤Žçš„檔案格å¼"
+
+#: command-list.h
+msgid "Git commit graph format"
+msgstr "Git æ交圖格å¼"
+
+#: command-list.h
+msgid "Git index format"
+msgstr "Git 索引格å¼"
+
+#: command-list.h
+msgid "Git pack format"
+msgstr "Git å°åŒ…æ ¼å¼"
+
+#: command-list.h
+msgid "Git cryptographic signature formats"
+msgstr "Git 密碼編譯簽章格å¼"
+
+#: command-list.h
msgid "A Git Glossary"
msgstr "Git 詞彙表"
@@ -16916,6 +17190,26 @@ msgid "Git namespaces"
msgstr "Git å字空間"
#: command-list.h
+msgid "Protocol v0 and v1 capabilities"
+msgstr "v0 å’Œ v1 版通訊å”定功能"
+
+#: command-list.h
+msgid "Things common to various protocols"
+msgstr "å„種通訊å”定共通的部分"
+
+#: command-list.h
+msgid "Git HTTP-based protocols"
+msgstr "Git 以 HTTP 為基礎的通訊å”定"
+
+#: command-list.h
+msgid "How packs are transferred over-the-wire"
+msgstr "å°åŒ…在線上傳輸的方å¼"
+
+#: command-list.h
+msgid "Git Wire Protocol, Version 2"
+msgstr "Git Wire 通訊å”定,第 2 版"
+
+#: command-list.h
msgid "Helper programs to interact with remote repositories"
msgstr "用來與é ç«¯ç‰ˆæœ¬åº«äº’å‹•çš„å”助工具"
@@ -16947,6 +17241,10 @@ msgstr "Git web 介é¢ï¼ˆGit 版本庫的 web å‰ç«¯ï¼‰"
msgid "An overview of recommended workflows with Git"
msgstr "Git 推薦的工作æµæ¦‚覽"
+#: command-list.h
+msgid "A tool for managing large Git repositories"
+msgstr "用來管ç†å¤§åž‹ Git 版本庫的工具"
+
#: commit-graph.c
msgid "commit-graph file is too small"
msgstr "æ交圖形檔案太å°"
@@ -17233,6 +17531,16 @@ msgstr "沒有å¯ç”¨çš„編譯器資訊\n"
msgid "no libc information available\n"
msgstr "沒有å¯ç”¨çš„ libc 資訊\n"
+#: compat/disk.h
+#, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "無法判斷 “%s†的剩餘ç£ç¢Ÿå¤§å°"
+
+#: compat/disk.h
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "無法å–å¾— “%s†的資訊"
+
#: compat/fsmonitor/fsm-health-win32.c
#, c-format
msgid "[GLE %ld] health thread could not open '%ls'"
@@ -17301,6 +17609,16 @@ msgstr "在 “%sâ€ ä¸Šå‘¼å« GetOverlappedResult 失敗 [GLE %ld]"
msgid "could not read directory changes [GLE %ld]"
msgstr "無法讀å–目錄變化 [GLE %ld]"
+#: compat/fsmonitor/fsm-settings-win32.c
+#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] 無法開啟以讀å–「%lsã€"
+
+#: compat/fsmonitor/fsm-settings-win32.c
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] 無法å–得「%lsã€çš„通訊å”定資訊"
+
#: compat/mingw.c
#, c-format
msgid "failed to copy SID (%ld)"
@@ -17974,229 +18292,6 @@ msgstr "寫入 rev-list 失敗"
msgid "failed to close rev-list's stdin"
msgstr "關閉 rev-list 的標準輸入失敗"
-#: contrib/scalar/scalar.c worktree.c
-#, c-format
-msgid "'%s' does not exist"
-msgstr "'%s' ä¸å­˜åœ¨"
-
-#: contrib/scalar/scalar.c
-msgid "need a working directory"
-msgstr "需è¦å·¥ä½œç›®éŒ„"
-
-#: contrib/scalar/scalar.c
-msgid "could not find enlistment root"
-msgstr "找ä¸åˆ°ç·¨åˆ—å單的根目錄"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "無法切æ›è‡³ã€Œ%sã€"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "無法設定 %s=%s"
-
-#: contrib/scalar/scalar.c
-msgid "could not configure log.excludeDecoration"
-msgstr "無法設定 log.excludeDecoration"
-
-#: contrib/scalar/scalar.c
-msgid "Scalar enlistments require a worktree"
-msgstr "ç´”é‡ç·¨åˆ—å單需è¦å·¥ä½œç›®éŒ„"
-
-#: contrib/scalar/scalar.c dir.c
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "ä¸èƒ½é–‹å•Ÿç›®éŒ„ '%s'"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr "ç•¥éŽ â€œ%sâ€ï¼Œå…¶éžæª”案或目錄"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "無法判斷 “%s†的剩餘ç£ç¢Ÿå¤§å°"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "無法å–å¾— “%s†的資訊"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "é ç«¯ HEAD ä¸æ˜¯åˆ†æ”¯ï¼šã€Œ%.*sã€"
-
-#: contrib/scalar/scalar.c
-msgid "failed to get default branch name from remote; using local default"
-msgstr "無法從é ç«¯å–å¾—é è¨­åˆ†æ”¯å稱。改用本機é è¨­å稱"
-
-#: contrib/scalar/scalar.c
-msgid "failed to get default branch name"
-msgstr "無法å–å¾—é è¨­åˆ†æ”¯å稱"
-
-#: contrib/scalar/scalar.c
-msgid "failed to unregister repository"
-msgstr "無法å–消註冊版本庫"
-
-#: contrib/scalar/scalar.c
-msgid "failed to delete enlistment directory"
-msgstr "無法刪除編列å單目錄"
-
-#: contrib/scalar/scalar.c
-msgid "branch to checkout after clone"
-msgstr "複製後è¦ç°½å‡ºçš„分支"
-
-#: contrib/scalar/scalar.c
-msgid "when cloning, create full working directory"
-msgstr "複製時建立完整的工作目錄"
-
-#: contrib/scalar/scalar.c
-msgid "only download metadata for the branch that will be checked out"
-msgstr "åªä¸‹è¼‰æœƒç°½å‡ºçš„分支中介資料"
-
-#: contrib/scalar/scalar.c
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<options>] [--] <repo> [<dir>]"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "無法從「%sã€æŽ¨è«–工作å€å稱"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "「%sã€ç›®éŒ„已經存在"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "無法å–得「%sã€çš„é è¨­åˆ†æ”¯"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "無法設定「%sã€ä¸­çš„é ç«¯"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not configure '%s'"
-msgstr "無法設定「%sã€"
-
-#: contrib/scalar/scalar.c
-msgid "partial clone failed; attempting full clone"
-msgstr "部分複製失敗。嘗試完整複製"
-
-#: contrib/scalar/scalar.c
-msgid "could not configure for full clone"
-msgstr "無法設定完整複製"
-
-#: contrib/scalar/scalar.c
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<enlistment>]"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "無法建立 “%s†的目錄"
-
-#: contrib/scalar/scalar.c
-msgid "could not duplicate stdout"
-msgstr "無法複製 stdout"
-
-#: contrib/scalar/scalar.c
-msgid "failed to write archive"
-msgstr "無法寫入å°å­˜"
-
-#: contrib/scalar/scalar.c
-msgid "`scalar list` does not take arguments"
-msgstr "`scalar list` 未å–引數"
-
-#: contrib/scalar/scalar.c
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<enlistment>]"
-
-#: contrib/scalar/scalar.c
-msgid "reconfigure all registered enlistments"
-msgstr "é‡æ–°è¨­å®šæ‰€æœ‰è¨»å†Šçš„編列åå–®"
-
-#: contrib/scalar/scalar.c
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <enlistment>]"
-
-#: contrib/scalar/scalar.c
-msgid "--all or <enlistment>, but not both"
-msgstr "--all 或 <enlistment> 但ä¸èƒ½å‚³å…¥å…©è€…"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "git 版本庫在「%sã€éºå¤±"
-
-#: contrib/scalar/scalar.c
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <task> [<enlistment>]\n"
-"作業:\n"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "no such task: '%s'"
-msgstr "無此作業:「%sã€"
-
-#: contrib/scalar/scalar.c
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<enlistment>]"
-
-#: contrib/scalar/scalar.c
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <enlistment>"
-
-#: contrib/scalar/scalar.c
-msgid "refusing to delete current working directory"
-msgstr "拒絕刪除目å‰å·¥ä½œç›®éŒ„"
-
-#: contrib/scalar/scalar.c
-msgid "include Git version"
-msgstr "åŒ…å« Git 版本"
-
-#: contrib/scalar/scalar.c
-msgid "include Git's build options"
-msgstr "åŒ…å« Git 組建é¸é …"
-
-#: contrib/scalar/scalar.c
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-#: contrib/scalar/scalar.c
-msgid "-C requires a <directory>"
-msgstr "-C éœ€è¦ <directory>"
-
-#: contrib/scalar/scalar.c
-#, c-format
-msgid "could not change to '%s'"
-msgstr "無法更改為「%sã€"
-
-#: contrib/scalar/scalar.c
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c éœ€è¦ <key>=<value> 引數"
-
-#: contrib/scalar/scalar.c
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"命令:\n"
-
#: convert.c
#, c-format
msgid "illegal crlf_action %d"
@@ -18427,6 +18522,39 @@ msgstr "來自 config 的資料島常è¦è¡¨ç¤ºå¼æœ‰å¤ªå¤šçš„æ“·å–群組(最å
msgid "Marked %d islands, done.\n"
msgstr "已標記 %d 個資料島,çµæŸã€‚\n"
+#: diagnose.c
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "無效的 --%s 值「%sã€"
+
+#: diagnose.c
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "無法å°å­˜ä¸å­˜åœ¨çš„路徑「%sã€"
+
+#: diagnose.c dir.c
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "ä¸èƒ½é–‹å•Ÿç›®éŒ„ '%s'"
+
+#: diagnose.c
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "ç•¥éŽ â€œ%sâ€ï¼Œå…¶éžæª”案或目錄"
+
+#: diagnose.c
+msgid "could not duplicate stdout"
+msgstr "無法複製 stdout"
+
+#: diagnose.c
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "無法將「%sã€è·¯å¾‘加入å°å­˜å·¥å…·ä¸­"
+
+#: diagnose.c
+msgid "failed to write archive"
+msgstr "無法寫入å°å­˜"
+
#: diff-lib.c
msgid "--merge-base does not work with ranges"
msgstr "--merge-base 跟範åœç„¡æ³•æ­é…é‹ä½œ"
@@ -19177,6 +19305,10 @@ msgid "unable to write to remote"
msgstr "無法寫到é ç«¯"
#: fetch-pack.c
+msgid "Server supports filter"
+msgstr "伺æœå™¨æ”¯æ´ filter"
+
+#: fetch-pack.c
#, c-format
msgid "invalid shallow line: %s"
msgstr "無效的 shallow 訊æ¯ï¼š%s"
@@ -19318,10 +19450,6 @@ msgid "Server does not support shallow requests"
msgstr "伺æœå™¨ä¸æ”¯æ´ shallow 請求"
#: fetch-pack.c
-msgid "Server supports filter"
-msgstr "伺æœå™¨æ”¯æ´ filter"
-
-#: fetch-pack.c
msgid "unable to write request to remote"
msgstr "無法將請求寫到é ç«¯"
@@ -19736,6 +19864,14 @@ msgid "Low-level Commands / Internal Helpers"
msgstr "低級指令/內部å”助工具"
#: help.c
+msgid "User-facing repository, command and file interfaces"
+msgstr "é¢å‘使用者的版本庫ã€å‘½ä»¤å’Œæª”案介é¢"
+
+#: help.c
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "é¢å‘開發者的檔案格å¼ã€é€šè¨Šå”定和介é¢"
+
+#: help.c
#, c-format
msgid "available git commands in '%s'"
msgstr "在 '%s' 下å¯ç”¨çš„ git 指令"
@@ -19753,6 +19889,14 @@ msgid "The Git concept guides are:"
msgstr "Git 概念嚮導有:"
#: help.c
+msgid "User-facing repository, command and file interfaces:"
+msgstr "é¢å‘使用者的版本庫ã€å‘½ä»¤å’Œæª”案介é¢ï¼š"
+
+#: help.c
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "檔案格å¼ã€é€šè¨Šå”定和其他開發者介é¢ï¼š"
+
+#: help.c
msgid "External commands"
msgstr "外部指令"
@@ -19842,11 +19986,6 @@ msgstr ""
"因為沒有將掛鉤 '%s' 設定為å¯åŸ·è¡Œï¼ŒæŽ›é‰¤è¢«å¿½ç•¥ã€‚您å¯ä»¥é€éŽ\n"
"設定 `git config advice.ignoredHook false` 來關閉這æ¢è­¦å‘Šã€‚"
-#: hook.c
-#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "無法啟動「%sã€æŽ›é‰¤\n"
-
#: http-fetch.c
#, c-format
msgid "argument to --packfile must be a valid hash (got '%s')"
@@ -20066,20 +20205,16 @@ msgstr "在 ls-refs 引數之後應該有一個 flush 包"
msgid "quoted CRLF detected"
msgstr "åµæ¸¬åˆ°ç”±å¯åˆ—å°å­—å…ƒ (quoted) 所組æˆçš„ CRLF"
-#: merge-ort-wrappers.c merge-recursive.c
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-" %s"
-msgstr ""
-"您å°ä¸‹åˆ—檔案的本機修改將被åˆä½µå‹•ä½œè¦†è“‹ï¼š\n"
-" %s"
-
#: merge-ort.c merge-recursive.c
#, c-format
msgid "Failed to merge submodule %s (not checked out)"
msgstr "無法åˆä½µå­æ¨¡çµ„ %s (沒有簽出)"
+#: merge-ort.c
+#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "無法åˆä½µ %s å­æ¨¡çµ„(沒有åˆä½µåŸºåº•ï¼‰"
+
#: merge-ort.c merge-recursive.c
#, c-format
msgid "Failed to merge submodule %s (commits not present)"
@@ -20103,27 +20238,8 @@ msgstr "無法åˆä½µ %s å­æ¨¡çµ„"
#: merge-ort.c
#, c-format
msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-"無法åˆä½µ %s å­æ¨¡çµ„,但有找到一個å¯è¡Œçš„åˆä½µæ–¹æ¡ˆï¼š\n"
-"%s\n"
-
-#: merge-ort.c merge-recursive.c
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"正確的話,就能直接加進索引,例如執行下述命令:\n"
-"\n"
-" git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"接å—本建議。\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
+msgstr "無法åˆä½µ %s å­æ¨¡çµ„,但存在åˆä½µå¯è¡Œæ–¹æ¡ˆï¼š%s"
#: merge-ort.c
#, c-format
@@ -20302,12 +20418,45 @@ msgstr ""
"è¡çªï¼ˆä¿®æ”¹/刪除):%1$s 已在 %2$s 刪除和在 %3$s 修改。%5$s çš„ %4$s 版本留在樹"
"上。"
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. 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"
+#.
+#: merge-ort.c
+#, c-format
+msgid ""
+" - go to submodule (%s), and either merge commit %s\n"
+" or update to an existing commit which has merged those changes\n"
+msgstr ""
+" - å‰å¾€å­æ¨¡çµ„ (%s),並åˆä½µ %s æ交或\n"
+" 更新至已經åˆä½µé€™äº›æ›´æ”¹çš„æ交\n"
+
#: merge-ort.c
#, c-format
msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
-msgstr "註:%s ä¸æ˜¯æœ€æ–°ä¸”干擾到簽出è¡çªç‰ˆæœ¬ã€‚已將舊拷è²é‡æ–°å‘½å至 %s"
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+" git add %s\n"
+"\n"
+" to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"與å­æ¨¡çµ„進行éžè¿´åˆä½µï¼Œç›®å‰åƒ…支æ´ç°¡å–®çš„情æ³ã€‚\n"
+"請自行處ç†æ¯å€‹æœ‰è¡çªä¹‹å­æ¨¡çµ„çš„åˆä½µå•é¡Œã€‚\n"
+"處ç†æ­¥é©Ÿæœ‰ä»¥ä¸‹å¹¾æ­¥ï¼š\n"
+"%s - 回到上級專案,並執行:\n"
+"\n"
+" git add %s\n"
+"\n"
+" 來記錄上述的åˆä½µæˆ–æ›´æ–°\n"
+" - 解決上級專案中的其它è¡çª\n"
+" - 在上級專案中,æ交產生之索引資訊\n"
#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
#. base, and 2-3) the trees for the two trees we're merging.
@@ -20396,6 +20545,22 @@ msgstr "找到å­æ¨¡çµ„的一個å¯èƒ½çš„åˆä½µæ–¹æ¡ˆï¼š\n"
#: merge-recursive.c
#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"正確的話,就能直接加進索引,例如執行下述命令:\n"
+"\n"
+" git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"接å—本建議。\n"
+
+#: merge-recursive.c
+#, c-format
msgid "Failed to merge submodule %s (multiple merges found)"
msgstr "無法åˆä½µå­æ¨¡çµ„ %s (發ç¾å¤šå€‹åˆä½µï¼‰"
@@ -21031,6 +21196,26 @@ msgstr "被 %s çš„ä¸ç©©å®šç‰©ä»¶ä¾†æºè³‡æ–™æ··æ·†"
#: object-file.c
#, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "寫入串æµç‰©ä»¶ %ld != %<PRIuMAX>"
+
+#: object-file.c
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "ä¸èƒ½ä¸²æµå£“縮新物件 (%d)"
+
+#: object-file.c
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "串æµç‰©ä»¶ä¸Šçš„ deflateEnd 失敗 (%d)"
+
+#: object-file.c
+#, c-format
+msgid "unable to create directory %s"
+msgstr "無法建立 %s 目錄"
+
+#: object-file.c
+#, c-format
msgid "cannot read object for %s"
msgstr "ä¸èƒ½è®€å–物件 %s"
@@ -21109,7 +21294,7 @@ msgstr "%s [無效物件]"
#. 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"
#.
#: object-name.c
#, c-format
@@ -21119,7 +21304,7 @@ msgstr "%s æ交 %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.
@@ -21136,7 +21321,7 @@ msgstr "%s 標籤 %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]"
#.
#: object-name.c
#, c-format
@@ -21295,6 +21480,71 @@ msgstr "ä¸èƒ½è§£æžç‰©ä»¶ï¼š%s"
msgid "hash mismatch %s"
msgstr "雜湊值與 %s ä¸ç¬¦åˆ"
+#: pack-bitmap-write.c
+msgid "trying to write commit not in index"
+msgstr "嘗試寫入ä¸åœ¨ç´¢å¼•çš„æ交"
+
+#: pack-bitmap.c
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "無法載入ä½åœ–索引(æ壞?)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index (too small)"
+msgstr "ä½åœ–索引æ壞(éŽå°ï¼‰"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "ä½åœ–索引檔案æ壞(標頭錯誤)"
+
+#: pack-bitmap.c
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "ä½åœ–索引檔案的版本 “%d†ä¸æ”¯æ´"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr "ä½åœ–索引檔案æ壞(ä¸å¤ é•·ï¼Œç„¡æ³•ç½®å…¥é›œæ¹Šå¿«å–)"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr "ä½åœ–索引檔案æ壞(ä¸å¤ é•·ï¼Œç„¡æ³•ç½®å…¥æŸ¥è©¢è¡¨ï¼‰"
+
+#: pack-bitmap.c
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "ä½åœ–索引中有é‡è¤‡é …目:「%sã€"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "ewah ä½åœ–æ壞:項目 %d 的標頭é­æˆªæ–·"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "ewah ä½åœ–æ壞:æ交索引 %u 超出範åœ"
+
+#: pack-bitmap.c
+msgid "corrupted bitmap pack index"
+msgstr "ä½åœ–包索引æ壞"
+
+#: pack-bitmap.c
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "ä½åœ–包索引的 XOR å移無效"
+
+#: pack-bitmap.c
+msgid "cannot fstat bitmap file"
+msgstr "無法 fstat ä½åœ–檔案"
+
+#: pack-bitmap.c
+#, c-format
+msgid "ignoring extra bitmap file: '%s'"
+msgstr "忽略多出來的ä½åœ–檔案:「%sã€"
+
+#: pack-bitmap.c
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "總和檢查碼在 MIDX å’Œä½åœ–中無符åˆé …ç›®"
+
#: pack-bitmap.c
msgid "multi-pack bitmap is missing required reverse index"
msgstr "多包ä½åœ–缺少需è¦çš„åå‘索引"
@@ -21310,9 +21560,69 @@ msgid "preferred pack (%s) is invalid"
msgstr "å好的å°åŒ… (%s) 無效"
#: pack-bitmap.c
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "ä½åœ–查詢表æ壞:三元組ä½ç½®è¶…出索引"
+
+#: pack-bitmap.c
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr "ä½åœ–查詢表æ壞:XOR éˆè¶…出項目數"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr "ä½åœ–查詢表æ壞:æ交索引 %u 超出範åœ"
+
+#: pack-bitmap.c
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr "ewah ä½åœ–æ壞:æ交 “%s†之ä½åœ–的標頭é­æˆªæ–·"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "在類型ä½åœ–中,找ä¸åˆ°ã€Œ%sã€ç‰©ä»¶"
+
+#: pack-bitmap.c
#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "找ä¸åˆ° %2$s 包,å移ä½ç½® %3$<PRIuMAX> çš„ %1$s"
+msgid "object '%s' does not have a unique type"
+msgstr "「%sã€ç‰©ä»¶çš„é¡žåž‹ä¸å”¯ä¸€"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "「%sã€ç‰©ä»¶ï¼šå¯¦éš›é¡žåž‹æ˜¯ã€Œ%sã€ï¼Œä½†é æœŸæ˜¯ã€Œ%sã€"
+
+#: pack-bitmap.c
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "物件ä¸åœ¨ä½åœ–中:「%sã€"
+
+#: pack-bitmap.c
+msgid "failed to load bitmap indexes"
+msgstr "無法載入ä½åœ–索引"
+
+#: pack-bitmap.c
+msgid "you must specify exactly one commit to test"
+msgstr "您必須指定剛好一個è¦æ¸¬è©¦çš„æ交"
+
+#: pack-bitmap.c
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "æ交「%sã€ç„¡ç´¢å¼•éŽçš„ä½åœ–"
+
+#: pack-bitmap.c
+msgid "mismatch in bitmap results"
+msgstr "ä½åœ–çµæžœä¸­æœ‰ä¸ç¬¦é …ç›®"
+
+#: pack-bitmap.c
+#, c-format
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "在「%2$sã€å°åŒ…,ä½ç§» %3$<PRIuMAX> 的地方找ä¸åˆ°ã€Œ%1$sã€"
+
+#: pack-bitmap.c
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "無法å–得「%sã€çš„ç£ç¢Ÿç”¨é‡"
#: pack-mtimes.c
#, c-format
@@ -21468,6 +21778,10 @@ msgid "alias of --%s"
msgstr "--%s 的別å"
#: parse-options.c
+msgid "need a subcommand"
+msgstr "需è¦å­å‘½ä»¤"
+
+#: parse-options.c
#, c-format
msgid "unknown option `%s'"
msgstr "未知é¸é … `%s'"
@@ -21996,32 +22310,38 @@ msgid ""
"l, label <label> = label current HEAD with a name\n"
"t, reset <label> = reset HEAD to a label\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". create a merge commit using the original merge commit's\n"
-". message (or the oneline, if no original merge commit was\n"
-". specified); use -c <commit> to reword the commit message\n"
+" create a merge commit using the original merge commit's\n"
+" message (or the oneline, if no original merge commit was\n"
+" specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+" to this position in the new commits. The <ref> is\n"
+" updated at the end of the rebase\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n"
msgstr ""
"\n"
-"指令:\n"
+"命令:\n"
"p, pick <æ交> = 使用æ交\n"
"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"
+"x, exec <命令> = 使用 shell 執行命令(這一列的剩餘部分)\n"
+"b, break = 在此åœæ­¢ï¼ˆä½¿ç”¨ “git rebase --continue†繼續é‡å®šåŸºåº•ï¼‰\n"
"d, drop <æ交> = 移除æ交\n"
"l, label <標籤> = ç‚ºç›®å‰ HEAD 打上指定å字標籤\n"
"t, reset <標籤> = é‡è¨­ HEAD 到指定標籤\n"
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-". 建立一個åˆä½µæ交,並使用原始的åˆä½µæ交說明(如果沒有指定\n"
-". 原始æ交,使用備註部分的 oneline 作為æ交說明)。使用\n"
-". -c <commit> å¯ä»¥ç·¨è¼¯æ交說明。\n"
+" 建立一個åˆä½µæ交,並使用原始的åˆä½µæ交說明(如果沒有指定\n"
+" 原始æ交,則使用 <oneline> 作為æ交說明)。\n"
+" 使用 -c <commit> 編輯æ交說明。\n"
+"u, update-ref <ref> = 為 <ref> 引用設立佔ä½ç¬¦è™Ÿï¼Œ\n"
+" 以將這個引用更新為此處的新æ交。\n"
+" <ref> 會在é‡å®šåŸºåº•å¾Œæ›´æ–°ã€‚\n"
"\n"
-"å¯ä»¥å°é€™äº›è¡Œé‡æ–°æŽ’åºï¼Œæœƒå¾žä¸Šè‡³ä¸‹åŸ·è¡Œã€‚\n"
+"å¯ä»¥å°é€™äº›åˆ—é‡æ–°æŽ’åºï¼›åŸ·è¡Œé †åºç”±ä¸Šåˆ°ä¸‹ã€‚\n"
#: rebase-interactive.c
#, c-format
@@ -22586,6 +22906,15 @@ msgid "http transport does not support %s"
msgstr "http 傳輸å”定ä¸æ”¯æ´ %s"
#: remote-curl.c
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "å”定錯誤:é æœŸæ˜¯ã€Œ<URL> <路徑>ã€ï¼Œä½†ç¼ºå°‘空白"
+
+#: remote-curl.c
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "無法下載ä½æ–¼ URL “%s†的檔案"
+
+#: remote-curl.c
msgid "git-http-push failed"
msgstr "git-http-push 失敗"
@@ -22990,6 +23319,16 @@ msgid "failed to find tree of %s"
msgstr "無法找到 %s 指å‘的樹"
#: revision.c
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo ä¸å­˜åœ¨çš„「%sã€è¨˜éŒ„"
+
+#: revision.c
+#, c-format
+msgid "could not get commit for ancestry-path argument %s"
+msgstr "無法å–å¾— ancestry-path 引數 %s çš„æ交"
+
+#: revision.c
msgid "--unpacked=<packfile> no longer supported"
msgstr "--unpacked=<packfile> å·²ä¸å—支æ´"
@@ -23015,6 +23354,220 @@ msgstr "-L å°šä¸æ”¯æ´ -p å’Œ -s 之外的差異格å¼"
msgid "cannot create async thread: %s"
msgstr "ä¸èƒ½å»ºç«‹ async 執行緒:%s"
+#: scalar.c worktree.c
+#, c-format
+msgid "'%s' does not exist"
+msgstr "'%s' ä¸å­˜åœ¨"
+
+#: scalar.c
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "無法切æ›è‡³ã€Œ%sã€"
+
+#: scalar.c
+msgid "need a working directory"
+msgstr "需è¦å·¥ä½œç›®éŒ„"
+
+#: scalar.c
+msgid "Scalar enlistments require a worktree"
+msgstr "ç´”é‡ç·¨åˆ—å單需è¦å·¥ä½œç›®éŒ„"
+
+#: scalar.c
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "無法設定 %s=%s"
+
+#: scalar.c
+msgid "could not configure log.excludeDecoration"
+msgstr "無法設定 log.excludeDecoration"
+
+#: scalar.c
+msgid "could not add enlistment"
+msgstr "無法加入編列清單"
+
+#: scalar.c
+msgid "could not set recommended config"
+msgstr "無法設定建議組態"
+
+#: scalar.c
+msgid "could not turn on maintenance"
+msgstr "無法開啟維護模å¼"
+
+#: scalar.c
+msgid "could not start the FSMonitor daemon"
+msgstr "無法啟動 FSMonitor 守護程å¼"
+
+#: scalar.c
+msgid "could not turn off maintenance"
+msgstr "無法關閉維護模å¼"
+
+#: scalar.c
+msgid "could not remove enlistment"
+msgstr "無法移除編列清單"
+
+#: scalar.c
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "é ç«¯ HEAD ä¸æ˜¯åˆ†æ”¯ï¼šã€Œ%.*sã€"
+
+#: scalar.c
+msgid "failed to get default branch name from remote; using local default"
+msgstr "無法從é ç«¯å–å¾—é è¨­åˆ†æ”¯å稱。改用本機é è¨­å稱"
+
+#: scalar.c
+msgid "failed to get default branch name"
+msgstr "無法å–å¾—é è¨­åˆ†æ”¯å稱"
+
+#: scalar.c
+msgid "failed to unregister repository"
+msgstr "無法å–消註冊版本庫"
+
+#: scalar.c
+msgid "failed to stop the FSMonitor daemon"
+msgstr "無法åœæ­¢ FSMonitor 守護程å¼"
+
+#: scalar.c
+msgid "failed to delete enlistment directory"
+msgstr "無法刪除編列å單目錄"
+
+#: scalar.c
+msgid "branch to checkout after clone"
+msgstr "複製後è¦ç°½å‡ºçš„分支"
+
+#: scalar.c
+msgid "when cloning, create full working directory"
+msgstr "複製時建立完整的工作目錄"
+
+#: scalar.c
+msgid "only download metadata for the branch that will be checked out"
+msgstr "åªä¸‹è¼‰æœƒç°½å‡ºçš„分支中介資料"
+
+#: scalar.c
+msgid "scalar clone [<options>] [--] <repo> [<dir>]"
+msgstr "scalar clone [<options>] [--] <repo> [<dir>]"
+
+#: scalar.c
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "無法從「%sã€æŽ¨è«–工作å€å稱"
+
+#: scalar.c
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "「%sã€ç›®éŒ„已經存在"
+
+#: scalar.c
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "無法å–得「%sã€çš„é è¨­åˆ†æ”¯"
+
+#: scalar.c
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "無法設定「%sã€ä¸­çš„é ç«¯"
+
+#: scalar.c
+#, c-format
+msgid "could not configure '%s'"
+msgstr "無法設定「%sã€"
+
+#: scalar.c
+msgid "partial clone failed; attempting full clone"
+msgstr "部分複製失敗。嘗試完整複製"
+
+#: scalar.c
+msgid "could not configure for full clone"
+msgstr "無法設定完整複製"
+
+#: scalar.c
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<enlistment>]"
+
+#: scalar.c
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` 未å–引數"
+
+#: scalar.c
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<enlistment>]"
+
+#: scalar.c
+msgid "reconfigure all registered enlistments"
+msgstr "é‡æ–°è¨­å®šæ‰€æœ‰è¨»å†Šçš„編列åå–®"
+
+#: scalar.c
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <enlistment>]"
+
+#: scalar.c
+msgid "--all or <enlistment>, but not both"
+msgstr "--all 或 <enlistment> 但ä¸èƒ½å‚³å…¥å…©è€…"
+
+#: scalar.c
+#, c-format
+msgid "git repository gone in '%s'"
+msgstr "git 版本庫在「%sã€éºå¤±"
+
+#: scalar.c
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <task> [<enlistment>]\n"
+"作業:\n"
+
+#: scalar.c
+#, c-format
+msgid "no such task: '%s'"
+msgstr "無此作業:「%sã€"
+
+#: scalar.c
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<enlistment>]"
+
+#: scalar.c
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <enlistment>"
+
+#: scalar.c
+msgid "refusing to delete current working directory"
+msgstr "拒絕刪除目å‰å·¥ä½œç›®éŒ„"
+
+#: scalar.c
+msgid "include Git version"
+msgstr "åŒ…å« Git 版本"
+
+#: scalar.c
+msgid "include Git's build options"
+msgstr "åŒ…å« Git 組建é¸é …"
+
+#: scalar.c
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+#: scalar.c
+msgid "-C requires a <directory>"
+msgstr "-C éœ€è¦ <directory>"
+
+#: scalar.c
+#, c-format
+msgid "could not change to '%s'"
+msgstr "無法更改為「%sã€"
+
+#: scalar.c
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c éœ€è¦ <key>=<value> 引數"
+
+#: scalar.c
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"命令:\n"
+
#: send-pack.c
msgid "unexpected flush packet while reading remote unpack status"
msgstr "讀å–é ç«¯è§£åŒ…狀態時收到æ„外的 flush 包"
@@ -23159,11 +23712,6 @@ msgstr "您的本機修改將被%s覆蓋。"
msgid "commit your changes or stash them to proceed."
msgstr "æ交您的修改或儲è—後å†ç¹¼çºŒã€‚"
-#: sequencer.c
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s:快轉"
-
#. TRANSLATORS: %s will be "revert", "cherry-pick" or
#. "rebase".
#.
@@ -23752,6 +24300,30 @@ msgid "merge: Unable to write new index file"
msgstr "åˆä½µï¼šç„¡æ³•å¯«å…¥æ–°ç´¢å¼•æª”案"
#: sequencer.c
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "似乎有å¦ä¸€å€‹ “rebase†程åºæ­£åœ¨é€²è¡Œï¼›â€œ%s.lock†已經存在"
+
+#: sequencer.c
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"已使用 %s 更新下述引用:\n"
+"%s"
+
+#: sequencer.c
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"無法使用 %s 更新下述引用:\n"
+"%s"
+
+#: sequencer.c
msgid "Cannot autostash"
msgstr "無法 autostash"
@@ -23953,6 +24525,11 @@ msgstr "無法略éŽä¸å¿…è¦çš„æ€é¸"
msgid "the script was already rearranged."
msgstr "腳本已經é‡æ–°ç·¨æŽ’。"
+#: sequencer.c
+#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "ä½æ–¼ã€Œ%sã€çš„ update-refs 檔案無效"
+
#: setup.c
#, c-format
msgid "'%s' is outside repository at '%s'"
@@ -24093,18 +24670,23 @@ msgstr ""
#: setup.c
#, c-format
msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"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"
-"è‹¥è¦æ”¾è¡Œæœ¬ç›®éŒ„,請呼å«ï¼š\n"
+"在ä½æ–¼ã€Œ%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â€ï¼‰"
+
+#: setup.c
+#, c-format
msgid ""
"problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
@@ -25126,6 +25708,22 @@ msgstr "無效的埠號"
msgid "invalid '..' path segment"
msgstr "無效的 '..' 路徑å€å¡Š"
+#: usage.c
+msgid "usage: "
+msgstr "用法:"
+
+#: usage.c
+msgid "fatal: "
+msgstr "致命錯誤:"
+
+#: usage.c
+msgid "error: "
+msgstr "錯誤:"
+
+#: usage.c
+msgid "warning: "
+msgstr "警告:"
+
#: walker.c
msgid "Fetching objects"
msgstr "正在抓å–物件"
@@ -25818,7 +26416,7 @@ msgstr "å¦å¤–,您的索引中包å«æœªæ交的變更。"
msgid "cannot %s: Your index contains uncommitted changes."
msgstr "ä¸èƒ½%s:您的索引中包å«æœªæ交的變更。"
-#: git-merge-octopus.sh
+#: git-merge-octopus.sh git-merge-resolve.sh
msgid ""
"Error: Your local changes to the following files would be overwritten by "
"merge"
@@ -26106,26 +26704,6 @@ msgid "ignoring unmerged: %s\n"
msgstr "忽略未套用的:%s\n"
#: git-add--interactive.perl
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "將模å¼è®Šæ›´å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "å°‡åˆªé™¤è®Šæ›´å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "å°‡æ–°å¢žè®Šæ›´å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "將此å€å¡Šå¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? "
-
-#: git-add--interactive.perl
msgid "No other hunks to goto\n"
msgstr "沒有其它å¯ä¾›è·³è½‰çš„å€å¡Š\n"
diff --git a/ppc/sha1.c b/ppc/sha1.c
deleted file mode 100644
index 1b705cee1fe..00000000000
--- a/ppc/sha1.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SHA-1 implementation.
- *
- * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
- *
- * This version assumes we are running on a big-endian machine.
- * It calls an external sha1_core() to process blocks of 64 bytes.
- */
-#include <stdio.h>
-#include <string.h>
-#include "sha1.h"
-
-void ppc_sha1_core(uint32_t *hash, const unsigned char *p,
- unsigned int nblocks);
-
-int ppc_SHA1_Init(ppc_SHA_CTX *c)
-{
- c->hash[0] = 0x67452301;
- c->hash[1] = 0xEFCDAB89;
- c->hash[2] = 0x98BADCFE;
- c->hash[3] = 0x10325476;
- c->hash[4] = 0xC3D2E1F0;
- c->len = 0;
- c->cnt = 0;
- return 0;
-}
-
-int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *ptr, unsigned long n)
-{
- unsigned long nb;
- const unsigned char *p = ptr;
-
- c->len += (uint64_t) n << 3;
- while (n != 0) {
- if (c->cnt || n < 64) {
- nb = 64 - c->cnt;
- if (nb > n)
- nb = n;
- memcpy(&c->buf.b[c->cnt], p, nb);
- if ((c->cnt += nb) == 64) {
- ppc_sha1_core(c->hash, c->buf.b, 1);
- c->cnt = 0;
- }
- } else {
- nb = n >> 6;
- ppc_sha1_core(c->hash, p, nb);
- nb <<= 6;
- }
- n -= nb;
- p += nb;
- }
- return 0;
-}
-
-int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c)
-{
- unsigned int cnt = c->cnt;
-
- c->buf.b[cnt++] = 0x80;
- if (cnt > 56) {
- if (cnt < 64)
- memset(&c->buf.b[cnt], 0, 64 - cnt);
- ppc_sha1_core(c->hash, c->buf.b, 1);
- cnt = 0;
- }
- if (cnt < 56)
- memset(&c->buf.b[cnt], 0, 56 - cnt);
- c->buf.l[7] = c->len;
- ppc_sha1_core(c->hash, c->buf.b, 1);
- memcpy(hash, c->hash, 20);
- return 0;
-}
diff --git a/ppc/sha1.h b/ppc/sha1.h
deleted file mode 100644
index 9b24b326159..00000000000
--- a/ppc/sha1.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SHA-1 implementation.
- *
- * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
- */
-#include <stdint.h>
-
-typedef struct {
- uint32_t hash[5];
- uint32_t cnt;
- uint64_t len;
- union {
- unsigned char b[64];
- uint64_t l[8];
- } buf;
-} ppc_SHA_CTX;
-
-int ppc_SHA1_Init(ppc_SHA_CTX *c);
-int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *p, unsigned long n);
-int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c);
-
-#define platform_SHA_CTX ppc_SHA_CTX
-#define platform_SHA1_Init ppc_SHA1_Init
-#define platform_SHA1_Update ppc_SHA1_Update
-#define platform_SHA1_Final ppc_SHA1_Final
diff --git a/ppc/sha1ppc.S b/ppc/sha1ppc.S
deleted file mode 100644
index 1711eef6e71..00000000000
--- a/ppc/sha1ppc.S
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * SHA-1 implementation for PowerPC.
- *
- * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
- */
-
-/*
- * PowerPC calling convention:
- * %r0 - volatile temp
- * %r1 - stack pointer.
- * %r2 - reserved
- * %r3-%r12 - Incoming arguments & return values; volatile.
- * %r13-%r31 - Callee-save registers
- * %lr - Return address, volatile
- * %ctr - volatile
- *
- * Register usage in this routine:
- * %r0 - temp
- * %r3 - argument (pointer to 5 words of SHA state)
- * %r4 - argument (pointer to data to hash)
- * %r5 - Constant K in SHA round (initially number of blocks to hash)
- * %r6-%r10 - Working copies of SHA variables A..E (actually E..A order)
- * %r11-%r26 - Data being hashed W[].
- * %r27-%r31 - Previous copies of A..E, for final add back.
- * %ctr - loop count
- */
-
-
-/*
- * We roll the registers for A, B, C, D, E around on each
- * iteration; E on iteration t is D on iteration t+1, and so on.
- * We use registers 6 - 10 for this. (Registers 27 - 31 hold
- * the previous values.)
- */
-#define RA(t) (((t)+4)%5+6)
-#define RB(t) (((t)+3)%5+6)
-#define RC(t) (((t)+2)%5+6)
-#define RD(t) (((t)+1)%5+6)
-#define RE(t) (((t)+0)%5+6)
-
-/* We use registers 11 - 26 for the W values */
-#define W(t) ((t)%16+11)
-
-/* Register 5 is used for the constant k */
-
-/*
- * The basic SHA-1 round function is:
- * E += ROTL(A,5) + F(B,C,D) + W[i] + K; B = ROTL(B,30)
- * Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).
- *
- * Every 20 rounds, the function F() and the constant K changes:
- * - 20 rounds of f0(b,c,d) = "bit wise b ? c : d" = (^b & d) + (b & c)
- * - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c
- * - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)
- * - 20 more rounds of f1(b,c,d)
- *
- * These are all scheduled for near-optimal performance on a G4.
- * The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only
- * *consider* starting the oldest 3 instructions per cycle. So to get
- * maximum performance out of it, you have to treat it as an in-order
- * machine. Which means interleaving the computation round t with the
- * computation of W[t+4].
- *
- * The first 16 rounds use W values loaded directly from memory, while the
- * remaining 64 use values computed from those first 16. We preload
- * 4 values before starting, so there are three kinds of rounds:
- * - The first 12 (all f0) also load the W values from memory.
- * - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.
- * - The last 4 (all f1) do not do anything with W.
- *
- * Therefore, we have 6 different round functions:
- * STEPD0_LOAD(t,s) - Perform round t and load W(s). s < 16
- * STEPD0_UPDATE(t,s) - Perform round t and compute W(s). s >= 16.
- * STEPD1_UPDATE(t,s)
- * STEPD2_UPDATE(t,s)
- * STEPD1(t) - Perform round t with no load or update.
- *
- * The G5 is more fully out-of-order, and can find the parallelism
- * by itself. The big limit is that it has a 2-cycle ALU latency, so
- * even though it's 2-way, the code has to be scheduled as if it's
- * 4-way, which can be a limit. To help it, we try to schedule the
- * read of RA(t) as late as possible so it doesn't stall waiting for
- * the previous round's RE(t-1), and we try to rotate RB(t) as early
- * as possible while reading RC(t) (= RB(t-1)) as late as possible.
- */
-
-/* the initial loads. */
-#define LOADW(s) \
- lwz W(s),(s)*4(%r4)
-
-/*
- * Perform a step with F0, and load W(s). Uses W(s) as a temporary
- * before loading it.
- * This is actually 10 instructions, which is an awkward fit.
- * It can execute grouped as listed, or delayed one instruction.
- * (If delayed two instructions, there is a stall before the start of the
- * second line.) Thus, two iterations take 7 cycles, 3.5 cycles per round.
- */
-#define STEPD0_LOAD(t,s) \
-add RE(t),RE(t),W(t); andc %r0,RD(t),RB(t); and W(s),RC(t),RB(t); \
-add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; rotlwi RB(t),RB(t),30; \
-add RE(t),RE(t),W(s); add %r0,%r0,%r5; lwz W(s),(s)*4(%r4); \
-add RE(t),RE(t),%r0
-
-/*
- * This is likewise awkward, 13 instructions. However, it can also
- * execute starting with 2 out of 3 possible moduli, so it does 2 rounds
- * in 9 cycles, 4.5 cycles/round.
- */
-#define STEPD0_UPDATE(t,s,loadk...) \
-add RE(t),RE(t),W(t); andc %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
-add RE(t),RE(t),%r0; and %r0,RC(t),RB(t); xor W(s),W(s),W((s)-8); \
-add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; xor W(s),W(s),W((s)-14); \
-add RE(t),RE(t),%r5; loadk; rotlwi RB(t),RB(t),30; rotlwi W(s),W(s),1; \
-add RE(t),RE(t),%r0
-
-/* Nicely optimal. Conveniently, also the most common. */
-#define STEPD1_UPDATE(t,s,loadk...) \
-add RE(t),RE(t),W(t); xor %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
-add RE(t),RE(t),%r5; loadk; xor %r0,%r0,RC(t); xor W(s),W(s),W((s)-8); \
-add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; xor W(s),W(s),W((s)-14); \
-add RE(t),RE(t),%r0; rotlwi RB(t),RB(t),30; rotlwi W(s),W(s),1
-
-/*
- * The naked version, no UPDATE, for the last 4 rounds. 3 cycles per.
- * We could use W(s) as a temp register, but we don't need it.
- */
-#define STEPD1(t) \
- add RE(t),RE(t),W(t); xor %r0,RD(t),RB(t); \
-rotlwi RB(t),RB(t),30; add RE(t),RE(t),%r5; xor %r0,%r0,RC(t); \
-add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; /* spare slot */ \
-add RE(t),RE(t),%r0
-
-/*
- * 14 instructions, 5 cycles per. The majority function is a bit
- * awkward to compute. This can execute with a 1-instruction delay,
- * but it causes a 2-instruction delay, which triggers a stall.
- */
-#define STEPD2_UPDATE(t,s,loadk...) \
-add RE(t),RE(t),W(t); and %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
-add RE(t),RE(t),%r0; xor %r0,RD(t),RB(t); xor W(s),W(s),W((s)-8); \
-add RE(t),RE(t),%r5; loadk; and %r0,%r0,RC(t); xor W(s),W(s),W((s)-14); \
-add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; rotlwi W(s),W(s),1; \
-add RE(t),RE(t),%r0; rotlwi RB(t),RB(t),30
-
-#define STEP0_LOAD4(t,s) \
- STEPD0_LOAD(t,s); \
- STEPD0_LOAD((t+1),(s)+1); \
- STEPD0_LOAD((t)+2,(s)+2); \
- STEPD0_LOAD((t)+3,(s)+3)
-
-#define STEPUP4(fn, t, s, loadk...) \
- STEP##fn##_UPDATE(t,s,); \
- STEP##fn##_UPDATE((t)+1,(s)+1,); \
- STEP##fn##_UPDATE((t)+2,(s)+2,); \
- STEP##fn##_UPDATE((t)+3,(s)+3,loadk)
-
-#define STEPUP20(fn, t, s, loadk...) \
- STEPUP4(fn, t, s,); \
- STEPUP4(fn, (t)+4, (s)+4,); \
- STEPUP4(fn, (t)+8, (s)+8,); \
- STEPUP4(fn, (t)+12, (s)+12,); \
- STEPUP4(fn, (t)+16, (s)+16, loadk)
-
- .globl ppc_sha1_core
-ppc_sha1_core:
- stwu %r1,-80(%r1)
- stmw %r13,4(%r1)
-
- /* Load up A - E */
- lmw %r27,0(%r3)
-
- mtctr %r5
-
-1:
- LOADW(0)
- lis %r5,0x5a82
- mr RE(0),%r31
- LOADW(1)
- mr RD(0),%r30
- mr RC(0),%r29
- LOADW(2)
- ori %r5,%r5,0x7999 /* K0-19 */
- mr RB(0),%r28
- LOADW(3)
- mr RA(0),%r27
-
- STEP0_LOAD4(0, 4)
- STEP0_LOAD4(4, 8)
- STEP0_LOAD4(8, 12)
- STEPUP4(D0, 12, 16,)
- STEPUP4(D0, 16, 20, lis %r5,0x6ed9)
-
- ori %r5,%r5,0xeba1 /* K20-39 */
- STEPUP20(D1, 20, 24, lis %r5,0x8f1b)
-
- ori %r5,%r5,0xbcdc /* K40-59 */
- STEPUP20(D2, 40, 44, lis %r5,0xca62)
-
- ori %r5,%r5,0xc1d6 /* K60-79 */
- STEPUP4(D1, 60, 64,)
- STEPUP4(D1, 64, 68,)
- STEPUP4(D1, 68, 72,)
- STEPUP4(D1, 72, 76,)
- addi %r4,%r4,64
- STEPD1(76)
- STEPD1(77)
- STEPD1(78)
- STEPD1(79)
-
- /* Add results to original values */
- add %r31,%r31,RE(0)
- add %r30,%r30,RD(0)
- add %r29,%r29,RC(0)
- add %r28,%r28,RB(0)
- add %r27,%r27,RA(0)
-
- bdnz 1b
-
- /* Save final hash, restore registers, and return */
- stmw %r27,0(%r3)
- lmw %r13,4(%r1)
- addi %r1,%r1,80
- blr
diff --git a/pretty.c b/pretty.c
index 6d819103fbf..6cb363ae1c9 100644
--- a/pretty.c
+++ b/pretty.c
@@ -43,7 +43,8 @@ static void save_user_format(struct rev_info *rev, const char *cp, int is_tforma
rev->commit_format = CMIT_FMT_USERFORMAT;
}
-static int git_pretty_formats_config(const char *var, const char *value, void *cb)
+static int git_pretty_formats_config(const char *var, const char *value,
+ void *cb UNUSED)
{
struct cmt_fmt_map *commit_format = NULL;
const char *name;
@@ -477,6 +478,16 @@ end:
}
}
+static int use_in_body_from(const struct pretty_print_context *pp,
+ const struct ident_split *ident)
+{
+ if (pp->rev && pp->rev->force_in_body_from)
+ return 1;
+ if (ident_cmp(pp->from_ident, ident))
+ return 1;
+ return 0;
+}
+
void pp_user_info(struct pretty_print_context *pp,
const char *what, struct strbuf *sb,
const char *line, const char *encoding)
@@ -503,7 +514,7 @@ void pp_user_info(struct pretty_print_context *pp,
map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
if (cmit_fmt_is_mail(pp->fmt)) {
- if (pp->from_ident && ident_cmp(pp->from_ident, &ident)) {
+ if (pp->from_ident && use_in_body_from(pp, &ident)) {
struct strbuf buf = STRBUF_INIT;
strbuf_addstr(&buf, "From: ");
diff --git a/promisor-remote.c b/promisor-remote.c
index 68f46f5ec70..faa7612941c 100644
--- a/promisor-remote.c
+++ b/promisor-remote.c
@@ -4,6 +4,7 @@
#include "config.h"
#include "transport.h"
#include "strvec.h"
+#include "packfile.h"
struct promisor_remote_config {
struct promisor_remote *promisors;
@@ -230,18 +231,18 @@ static int remove_fetched_oids(struct repository *repo,
return remaining_nr;
}
-int promisor_remote_get_direct(struct repository *repo,
- const struct object_id *oids,
- int oid_nr)
+void promisor_remote_get_direct(struct repository *repo,
+ const struct object_id *oids,
+ int oid_nr)
{
struct promisor_remote *r;
struct object_id *remaining_oids = (struct object_id *)oids;
int remaining_nr = oid_nr;
int to_free = 0;
- int res = -1;
+ int i;
if (oid_nr == 0)
- return 0;
+ return;
promisor_remote_init(repo);
@@ -256,12 +257,16 @@ int promisor_remote_get_direct(struct repository *repo,
continue;
}
}
- res = 0;
- break;
+ goto all_fetched;
}
+ for (i = 0; i < remaining_nr; i++) {
+ if (is_promisor_object(&remaining_oids[i]))
+ die(_("could not fetch %s from promisor remote"),
+ oid_to_hex(&remaining_oids[i]));
+ }
+
+all_fetched:
if (to_free)
free(remaining_oids);
-
- return res;
}
diff --git a/promisor-remote.h b/promisor-remote.h
index edc45ab0f5f..df36eb08efc 100644
--- a/promisor-remote.h
+++ b/promisor-remote.h
@@ -39,13 +39,12 @@ static inline int has_promisor_remote(void)
/*
* Fetches all requested objects from all promisor remotes, trying them one at
- * a time until all objects are fetched. Returns 0 upon success, and non-zero
- * otherwise.
+ * a time until all objects are fetched.
*
- * If oid_nr is 0, this function returns 0 (success) immediately.
+ * If oid_nr is 0, this function returns immediately.
*/
-int promisor_remote_get_direct(struct repository *repo,
- const struct object_id *oids,
- int oid_nr);
+void promisor_remote_get_direct(struct repository *repo,
+ const struct object_id *oids,
+ int oid_nr);
#endif /* PROMISOR_REMOTE_H */
diff --git a/range-diff.c b/range-diff.c
index f63b3ffc200..8b7d81adc1b 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -57,9 +57,9 @@ static int read_patches(const char *range, struct string_list *list,
"--pretty=medium",
"--notes",
NULL);
+ strvec_push(&cp.args, range);
if (other_arg)
strvec_pushv(&cp.args, other_arg->v);
- strvec_push(&cp.args, range);
cp.out = -1;
cp.no_stdin = 1;
cp.git_cmd = 1;
@@ -224,8 +224,10 @@ cleanup:
return ret;
}
-static int patch_util_cmp(const void *dummy, const struct patch_util *a,
- const struct patch_util *b, const char *keydata)
+static int patch_util_cmp(const void *cmp_data UNUSED,
+ const struct patch_util *a,
+ const struct patch_util *b,
+ const char *keydata)
{
return strcmp(a->diff, keydata ? keydata : b->diff);
}
diff --git a/read-cache.c b/read-cache.c
index b09128b1884..32024029274 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1873,9 +1873,20 @@ static int read_index_extension(struct index_state *istate,
return 0;
}
+/*
+ * Parses the contents of the cache entry contained within the 'ondisk' buffer
+ * into a new incore 'cache_entry'.
+ *
+ * Note that 'char *ondisk' may not be aligned to a 4-byte address interval in
+ * index v4, so we cannot cast it to 'struct ondisk_cache_entry *' and access
+ * its members. Instead, we use the byte offsets of members within the struct to
+ * identify where 'get_be16()', 'get_be32()', and 'oidread()' (which can all
+ * read from an unaligned memory buffer) should read from the 'ondisk' buffer
+ * into the corresponding incore 'cache_entry' members.
+ */
static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
unsigned int version,
- struct ondisk_cache_entry *ondisk,
+ const char *ondisk,
unsigned long *ent_size,
const struct cache_entry *previous_ce)
{
@@ -1883,7 +1894,7 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
size_t len;
const char *name;
const unsigned hashsz = the_hash_algo->rawsz;
- const uint16_t *flagsp = (const uint16_t *)(ondisk->data + hashsz);
+ const char *flagsp = ondisk + offsetof(struct ondisk_cache_entry, data) + hashsz;
unsigned int flags;
size_t copy_len = 0;
/*
@@ -1901,15 +1912,15 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
if (flags & CE_EXTENDED) {
int extended_flags;
- extended_flags = get_be16(flagsp + 1) << 16;
+ extended_flags = get_be16(flagsp + sizeof(uint16_t)) << 16;
/* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
if (extended_flags & ~CE_EXTENDED_FLAGS)
die(_("unknown index entry format 0x%08x"), extended_flags);
flags |= extended_flags;
- name = (const char *)(flagsp + 2);
+ name = (const char *)(flagsp + 2 * sizeof(uint16_t));
}
else
- name = (const char *)(flagsp + 1);
+ name = (const char *)(flagsp + sizeof(uint16_t));
if (expand_name_field) {
const unsigned char *cp = (const unsigned char *)name;
@@ -1935,20 +1946,32 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
ce = mem_pool__ce_alloc(ce_mem_pool, len);
- ce->ce_stat_data.sd_ctime.sec = get_be32(&ondisk->ctime.sec);
- ce->ce_stat_data.sd_mtime.sec = get_be32(&ondisk->mtime.sec);
- ce->ce_stat_data.sd_ctime.nsec = get_be32(&ondisk->ctime.nsec);
- ce->ce_stat_data.sd_mtime.nsec = get_be32(&ondisk->mtime.nsec);
- ce->ce_stat_data.sd_dev = get_be32(&ondisk->dev);
- ce->ce_stat_data.sd_ino = get_be32(&ondisk->ino);
- ce->ce_mode = get_be32(&ondisk->mode);
- ce->ce_stat_data.sd_uid = get_be32(&ondisk->uid);
- ce->ce_stat_data.sd_gid = get_be32(&ondisk->gid);
- ce->ce_stat_data.sd_size = get_be32(&ondisk->size);
+ /*
+ * NEEDSWORK: using 'offsetof()' is cumbersome and should be replaced
+ * with something more akin to 'load_bitmap_entries_v1()'s use of
+ * 'read_be16'/'read_be32'. For consistency with the corresponding
+ * ondisk entry write function ('copy_cache_entry_to_ondisk()'), this
+ * should be done at the same time as removing references to
+ * 'ondisk_cache_entry' there.
+ */
+ ce->ce_stat_data.sd_ctime.sec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ctime)
+ + offsetof(struct cache_time, sec));
+ ce->ce_stat_data.sd_mtime.sec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mtime)
+ + offsetof(struct cache_time, sec));
+ ce->ce_stat_data.sd_ctime.nsec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ctime)
+ + offsetof(struct cache_time, nsec));
+ ce->ce_stat_data.sd_mtime.nsec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mtime)
+ + offsetof(struct cache_time, nsec));
+ ce->ce_stat_data.sd_dev = get_be32(ondisk + offsetof(struct ondisk_cache_entry, dev));
+ ce->ce_stat_data.sd_ino = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ino));
+ ce->ce_mode = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mode));
+ ce->ce_stat_data.sd_uid = get_be32(ondisk + offsetof(struct ondisk_cache_entry, uid));
+ ce->ce_stat_data.sd_gid = get_be32(ondisk + offsetof(struct ondisk_cache_entry, gid));
+ ce->ce_stat_data.sd_size = get_be32(ondisk + offsetof(struct ondisk_cache_entry, size));
ce->ce_flags = flags & ~CE_NAMEMASK;
ce->ce_namelen = len;
ce->index = 0;
- oidread(&ce->oid, ondisk->data);
+ oidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data));
if (expand_name_field) {
if (copy_len)
@@ -2117,12 +2140,12 @@ static unsigned long load_cache_entry_block(struct index_state *istate,
unsigned long src_offset = start_offset;
for (i = offset; i < offset + nr; i++) {
- struct ondisk_cache_entry *disk_ce;
struct cache_entry *ce;
unsigned long consumed;
- disk_ce = (struct ondisk_cache_entry *)(mmap + src_offset);
- ce = create_from_disk(ce_mem_pool, istate->version, disk_ce, &consumed, previous_ce);
+ ce = create_from_disk(ce_mem_pool, istate->version,
+ mmap + src_offset,
+ &consumed, previous_ce);
set_index_entry(istate, i, ce);
src_offset += consumed;
diff --git a/ref-filter.c b/ref-filter.c
index bdf39fa761e..9dc2cd14519 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -89,7 +89,7 @@ struct ref_to_worktree_entry {
struct worktree *wt; /* key is wt->head_ref */
};
-static int ref_to_worktree_map_cmpfnc(const void *unused_lookupdata,
+static int ref_to_worktree_map_cmpfnc(const void *lookupdata UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *kptr,
const void *keydata_aka_refname)
@@ -1375,12 +1375,12 @@ static void find_subpos(const char *buf,
/* subject is first non-empty line */
*sub = buf;
/* subject goes to first empty line before signature begins */
- if ((eol = strstr(*sub, "\n\n"))) {
+ if ((eol = strstr(*sub, "\n\n")) ||
+ (eol = strstr(*sub, "\r\n\r\n"))) {
eol = eol < sigstart ? eol : sigstart;
- /* check if message uses CRLF */
- } else if (! (eol = strstr(*sub, "\r\n\r\n"))) {
+ } else {
/* treat whole message as subject */
- eol = strrchr(*sub, '\0');
+ eol = sigstart;
}
buf = eol;
*sublen = buf - *sub;
@@ -1722,6 +1722,8 @@ char *get_head_description(void)
} else
strbuf_addstr(&desc, _("(no branch)"));
+ wt_status_state_free_buffers(&state);
+
return strbuf_detach(&desc, NULL);
}
diff --git a/reflog-walk.c b/reflog-walk.c
index 7aa6595a51f..8a4d8fa3bd5 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -55,7 +55,7 @@ static void free_complete_reflog(struct complete_reflogs *array)
free(array);
}
-static void complete_reflogs_clear(void *util, const char *str)
+static void complete_reflogs_clear(void *util, const char *str UNUSED)
{
struct complete_reflogs *array = util;
free_complete_reflog(array);
diff --git a/reflog.c b/reflog.c
index 135a1a6e41c..78e9350e205 100644
--- a/reflog.c
+++ b/reflog.c
@@ -240,8 +240,9 @@ static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit
* Return true iff the specified reflog entry should be expired.
*/
int should_expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+ const char *email UNUSED,
+ timestamp_t timestamp, int tz UNUSED,
+ const char *message UNUSED, void *cb_data)
{
struct expire_reflog_policy_cb *cb = cb_data;
struct commit *old_commit, *new_commit;
@@ -294,7 +295,8 @@ int should_expire_reflog_ent_verbose(struct object_id *ooid,
return expire;
}
-static int push_tip_to_list(const char *refname, const struct object_id *oid,
+static int push_tip_to_list(const char *refname UNUSED,
+ const struct object_id *oid,
int flags, void *cb_data)
{
struct commit_list **list = cb_data;
@@ -310,16 +312,9 @@ static int push_tip_to_list(const char *refname, const struct object_id *oid,
static int is_head(const char *refname)
{
- switch (ref_type(refname)) {
- case REF_TYPE_OTHER_PSEUDOREF:
- case REF_TYPE_MAIN_PSEUDOREF:
- if (parse_worktree_ref(refname, NULL, NULL, &refname))
- BUG("not a worktree ref: %s", refname);
- break;
- default:
- break;
- }
- return !strcmp(refname, "HEAD");
+ const char *stripped_refname;
+ parse_worktree_ref(refname, NULL, NULL, &stripped_refname);
+ return !strcmp(stripped_refname, "HEAD");
}
void reflog_expiry_prepare(const char *refname,
@@ -378,9 +373,11 @@ void reflog_expiry_cleanup(void *cb_data)
}
}
-int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+int count_reflog_ent(struct object_id *ooid UNUSED,
+ struct object_id *noid UNUSED,
+ const char *email UNUSED,
+ timestamp_t timestamp, int tz UNUSED,
+ const char *message UNUSED, void *cb_data)
{
struct cmd_reflog_expire_cb *cb = cb_data;
if (!cb->expire_total || timestamp < cb->expire_total)
diff --git a/refs.c b/refs.c
index 92819732ab7..1491ae937eb 100644
--- a/refs.c
+++ b/refs.c
@@ -441,7 +441,8 @@ struct warn_if_dangling_data {
const char *msg_fmt;
};
-static int warn_if_dangling_symref(const char *refname, const struct object_id *oid,
+static int warn_if_dangling_symref(const char *refname,
+ const struct object_id *oid UNUSED,
int flags, void *cb_data)
{
struct warn_if_dangling_data *d = cb_data;
@@ -810,7 +811,7 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **log)
return repo_dwim_log(the_repository, str, len, oid, log);
}
-static int is_per_worktree_ref(const char *refname)
+int is_per_worktree_ref(const char *refname)
{
return starts_with(refname, "refs/worktree/") ||
starts_with(refname, "refs/bisect/") ||
@@ -826,37 +827,63 @@ static int is_pseudoref_syntax(const char *refname)
return 0;
}
+ /*
+ * HEAD is not a pseudoref, but it certainly uses the
+ * pseudoref syntax.
+ */
return 1;
}
-static int is_main_pseudoref_syntax(const char *refname)
-{
- return skip_prefix(refname, "main-worktree/", &refname) &&
- *refname &&
- is_pseudoref_syntax(refname);
+static int is_current_worktree_ref(const char *ref) {
+ return is_pseudoref_syntax(ref) || is_per_worktree_ref(ref);
}
-static int is_other_pseudoref_syntax(const char *refname)
+enum ref_worktree_type parse_worktree_ref(const char *maybe_worktree_ref,
+ const char **worktree_name, int *worktree_name_length,
+ const char **bare_refname)
{
- if (!skip_prefix(refname, "worktrees/", &refname))
- return 0;
- refname = strchr(refname, '/');
- if (!refname || !refname[1])
- return 0;
- return is_pseudoref_syntax(refname + 1);
-}
+ const char *name_dummy;
+ int name_length_dummy;
+ const char *ref_dummy;
-enum ref_type ref_type(const char *refname)
-{
- if (is_per_worktree_ref(refname))
- return REF_TYPE_PER_WORKTREE;
- if (is_pseudoref_syntax(refname))
- return REF_TYPE_PSEUDOREF;
- if (is_main_pseudoref_syntax(refname))
- return REF_TYPE_MAIN_PSEUDOREF;
- if (is_other_pseudoref_syntax(refname))
- return REF_TYPE_OTHER_PSEUDOREF;
- return REF_TYPE_NORMAL;
+ if (!worktree_name)
+ worktree_name = &name_dummy;
+ if (!worktree_name_length)
+ worktree_name_length = &name_length_dummy;
+ if (!bare_refname)
+ bare_refname = &ref_dummy;
+
+ if (skip_prefix(maybe_worktree_ref, "worktrees/", bare_refname)) {
+ const char *slash = strchr(*bare_refname, '/');
+
+ *worktree_name = *bare_refname;
+ if (!slash) {
+ *worktree_name_length = strlen(*worktree_name);
+
+ /* This is an error condition, and the caller tell because the bare_refname is "" */
+ *bare_refname = *worktree_name + *worktree_name_length;
+ return REF_WORKTREE_OTHER;
+ }
+
+ *worktree_name_length = slash - *bare_refname;
+ *bare_refname = slash + 1;
+
+ if (is_current_worktree_ref(*bare_refname))
+ return REF_WORKTREE_OTHER;
+ }
+
+ *worktree_name = NULL;
+ *worktree_name_length = 0;
+
+ if (skip_prefix(maybe_worktree_ref, "main-worktree/", bare_refname)
+ && is_current_worktree_ref(*bare_refname))
+ return REF_WORKTREE_MAIN;
+
+ *bare_refname = maybe_worktree_ref;
+ if (is_current_worktree_ref(maybe_worktree_ref))
+ return REF_WORKTREE_CURRENT;
+
+ return REF_WORKTREE_SHARED;
}
long get_files_ref_lock_timeout_ms(void)
@@ -981,8 +1008,9 @@ static void set_read_ref_cutoffs(struct read_ref_at_cb *cb,
}
static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+ const char *email UNUSED,
+ timestamp_t timestamp, int tz,
+ const char *message, void *cb_data)
{
struct read_ref_at_cb *cb = cb_data;
int reached_count;
@@ -1022,9 +1050,11 @@ static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
return cb->found_it;
}
-static int read_ref_at_ent_newest(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp,
- int tz, const char *message, void *cb_data)
+static int read_ref_at_ent_newest(struct object_id *ooid UNUSED,
+ struct object_id *noid,
+ const char *email UNUSED,
+ timestamp_t timestamp, int tz,
+ const char *message, void *cb_data)
{
struct read_ref_at_cb *cb = cb_data;
@@ -1035,8 +1065,9 @@ static int read_ref_at_ent_newest(struct object_id *ooid, struct object_id *noid
}
static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp,
- int tz, const char *message, void *cb_data)
+ const char *email UNUSED,
+ timestamp_t timestamp, int tz,
+ const char *message, void *cb_data)
{
struct read_ref_at_cb *cb = cb_data;
@@ -1899,7 +1930,7 @@ struct ref_store_hash_entry
char name[FLEX_ARRAY];
};
-static int ref_store_hash_cmp(const void *unused_cmp_data,
+static int ref_store_hash_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
diff --git a/refs.h b/refs.h
index d6575b8c2bd..8958717a17d 100644
--- a/refs.h
+++ b/refs.h
@@ -820,15 +820,34 @@ int parse_hide_refs_config(const char *var, const char *value, const char *);
*/
int ref_is_hidden(const char *, const char *);
-enum ref_type {
- REF_TYPE_PER_WORKTREE, /* refs inside refs/ but not shared */
- REF_TYPE_PSEUDOREF, /* refs outside refs/ in current worktree */
- REF_TYPE_MAIN_PSEUDOREF, /* pseudo refs from the main worktree */
- REF_TYPE_OTHER_PSEUDOREF, /* pseudo refs from other worktrees */
- REF_TYPE_NORMAL, /* normal/shared refs inside refs/ */
+/* Is this a per-worktree ref living in the refs/ namespace? */
+int is_per_worktree_ref(const char *refname);
+
+/* Describes how a refname relates to worktrees */
+enum ref_worktree_type {
+ REF_WORKTREE_CURRENT, /* implicitly per worktree, eg. HEAD or
+ refs/bisect/SOMETHING */
+ REF_WORKTREE_MAIN, /* explicitly in main worktree, eg.
+ main-worktree/HEAD */
+ REF_WORKTREE_OTHER, /* explicitly in named worktree, eg.
+ worktrees/bla/HEAD */
+ REF_WORKTREE_SHARED, /* the default, eg. refs/heads/main */
};
-enum ref_type ref_type(const char *refname);
+/*
+ * Parse a `maybe_worktree_ref` as a ref that possibly refers to a worktree ref
+ * (ie. either REFNAME, main-worktree/REFNAME or worktree/WORKTREE/REFNAME). It
+ * returns what kind of ref was found, and in case of REF_WORKTREE_OTHER, the
+ * worktree name is returned in `worktree_name` (pointing into
+ * `maybe_worktree_ref`) and `worktree_name_length`. The bare refname (the
+ * refname stripped of prefixes) is returned in `bare_refname`. The
+ * `worktree_name`, `worktree_name_length` and `bare_refname` arguments may be
+ * NULL.
+ */
+enum ref_worktree_type parse_worktree_ref(const char *maybe_worktree_ref,
+ const char **worktree_name,
+ int *worktree_name_length,
+ const char **bare_refname);
enum expire_reflog_flags {
EXPIRE_REFLOGS_DRY_RUN = 1 << 0,
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 8db7882aacb..b89954355de 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -138,44 +138,30 @@ static struct files_ref_store *files_downcast(struct ref_store *ref_store,
return refs;
}
-static void files_reflog_path_other_worktrees(struct files_ref_store *refs,
- struct strbuf *sb,
- const char *refname)
-{
- const char *real_ref;
- const char *worktree_name;
- int length;
-
- if (parse_worktree_ref(refname, &worktree_name, &length, &real_ref))
- BUG("refname %s is not a other-worktree ref", refname);
-
- if (worktree_name)
- strbuf_addf(sb, "%s/worktrees/%.*s/logs/%s", refs->gitcommondir,
- length, worktree_name, real_ref);
- else
- strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir,
- real_ref);
-}
-
static void files_reflog_path(struct files_ref_store *refs,
struct strbuf *sb,
const char *refname)
{
- switch (ref_type(refname)) {
- case REF_TYPE_PER_WORKTREE:
- case REF_TYPE_PSEUDOREF:
+ const char *bare_refname;
+ const char *wtname;
+ int wtname_len;
+ enum ref_worktree_type wt_type = parse_worktree_ref(
+ refname, &wtname, &wtname_len, &bare_refname);
+
+ switch (wt_type) {
+ case REF_WORKTREE_CURRENT:
strbuf_addf(sb, "%s/logs/%s", refs->base.gitdir, refname);
break;
- case REF_TYPE_OTHER_PSEUDOREF:
- case REF_TYPE_MAIN_PSEUDOREF:
- files_reflog_path_other_worktrees(refs, sb, refname);
+ case REF_WORKTREE_SHARED:
+ case REF_WORKTREE_MAIN:
+ strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, bare_refname);
break;
- case REF_TYPE_NORMAL:
- strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
+ case REF_WORKTREE_OTHER:
+ strbuf_addf(sb, "%s/worktrees/%.*s/logs/%s", refs->gitcommondir,
+ wtname_len, wtname, bare_refname);
break;
default:
- BUG("unknown ref type %d of ref %s",
- ref_type(refname), refname);
+ BUG("unknown ref type %d of ref %s", wt_type, refname);
}
}
@@ -183,22 +169,25 @@ static void files_ref_path(struct files_ref_store *refs,
struct strbuf *sb,
const char *refname)
{
- switch (ref_type(refname)) {
- case REF_TYPE_PER_WORKTREE:
- case REF_TYPE_PSEUDOREF:
+ const char *bare_refname;
+ const char *wtname;
+ int wtname_len;
+ enum ref_worktree_type wt_type = parse_worktree_ref(
+ refname, &wtname, &wtname_len, &bare_refname);
+ switch (wt_type) {
+ case REF_WORKTREE_CURRENT:
strbuf_addf(sb, "%s/%s", refs->base.gitdir, refname);
break;
- case REF_TYPE_MAIN_PSEUDOREF:
- if (!skip_prefix(refname, "main-worktree/", &refname))
- BUG("ref %s is not a main pseudoref", refname);
- /* fallthrough */
- case REF_TYPE_OTHER_PSEUDOREF:
- case REF_TYPE_NORMAL:
- strbuf_addf(sb, "%s/%s", refs->gitcommondir, refname);
+ case REF_WORKTREE_OTHER:
+ strbuf_addf(sb, "%s/worktrees/%.*s/%s", refs->gitcommondir,
+ wtname_len, wtname, bare_refname);
+ break;
+ case REF_WORKTREE_SHARED:
+ case REF_WORKTREE_MAIN:
+ strbuf_addf(sb, "%s/%s", refs->gitcommondir, bare_refname);
break;
default:
- BUG("unknown ref type %d of ref %s",
- ref_type(refname), refname);
+ BUG("unknown ref type %d of ref %s", wt_type, refname);
}
}
@@ -771,7 +760,8 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator)
while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
- ref_type(iter->iter0->refname) != REF_TYPE_PER_WORKTREE)
+ parse_worktree_ref(iter->iter0->refname, NULL, NULL,
+ NULL) != REF_WORKTREE_CURRENT)
continue;
if ((iter->flags & DO_FOR_EACH_OMIT_DANGLING_SYMREFS) &&
@@ -1178,7 +1168,8 @@ static int should_pack_ref(const char *refname,
unsigned int pack_flags)
{
/* Do not pack per-worktree refs: */
- if (ref_type(refname) != REF_TYPE_NORMAL)
+ if (parse_worktree_ref(refname, NULL, NULL, NULL) !=
+ REF_WORKTREE_SHARED)
return 0;
/* Do not pack non-tags unless PACK_REFS_ALL is set: */
@@ -2202,8 +2193,8 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
return ok;
}
-static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator,
- struct object_id *peeled)
+static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
+ struct object_id *peeled UNUSED)
{
BUG("ref_iterator_peel() called for reflog_iterator");
}
@@ -2257,7 +2248,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store,
static enum iterator_selection reflog_iterator_select(
struct ref_iterator *iter_worktree,
struct ref_iterator *iter_common,
- void *cb_data)
+ void *cb_data UNUSED)
{
if (iter_worktree) {
/*
@@ -2267,7 +2258,8 @@ static enum iterator_selection reflog_iterator_select(
*/
return ITER_SELECT_0;
} else if (iter_common) {
- if (ref_type(iter_common->refname) == REF_TYPE_NORMAL)
+ if (parse_worktree_ref(iter_common->refname, NULL, NULL,
+ NULL) == REF_WORKTREE_SHARED)
return ITER_SELECT_1;
/*
@@ -2985,7 +2977,7 @@ cleanup:
static int files_transaction_abort(struct ref_store *ref_store,
struct ref_transaction *transaction,
- struct strbuf *err)
+ struct strbuf *err UNUSED)
{
struct files_ref_store *refs =
files_downcast(ref_store, 0, "ref_transaction_abort");
@@ -2995,7 +2987,9 @@ static int files_transaction_abort(struct ref_store *ref_store,
}
static int ref_present(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags UNUSED,
+ void *cb_data)
{
struct string_list *affected_refnames = cb_data;
@@ -3259,7 +3253,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
return -1;
}
-static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
+static int files_init_db(struct ref_store *ref_store, struct strbuf *err UNUSED)
{
struct files_ref_store *refs =
files_downcast(ref_store, REF_STORE_WRITE, "init_db");
diff --git a/refs/iterator.c b/refs/iterator.c
index b2e56bae1c6..c9fd0bcaf90 100644
--- a/refs/iterator.c
+++ b/refs/iterator.c
@@ -51,8 +51,8 @@ static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
return ref_iterator_abort(ref_iterator);
}
-static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator,
- struct object_id *peeled)
+static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
+ struct object_id *peeled UNUSED)
{
BUG("peel called for empty iterator");
}
@@ -238,7 +238,7 @@ struct ref_iterator *merge_ref_iterator_begin(
*/
static enum iterator_selection overlay_iterator_select(
struct ref_iterator *front, struct ref_iterator *back,
- void *cb_data)
+ void *cb_data UNUSED)
{
int cmp;
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 97b68377673..c1c71d183ea 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -726,7 +726,7 @@ static struct snapshot *get_snapshot(struct packed_ref_store *refs)
}
static int packed_read_raw_ref(struct ref_store *ref_store, const char *refname,
- struct object_id *oid, struct strbuf *referent,
+ struct object_id *oid, struct strbuf *referent UNUSED,
unsigned int *type, int *failure_errno)
{
struct packed_ref_store *refs =
@@ -862,7 +862,7 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator)
while ((ok = next_record(iter)) == ITER_OK) {
if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
- ref_type(iter->base.refname) != REF_TYPE_PER_WORKTREE)
+ !is_per_worktree_ref(iter->base.refname))
continue;
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
@@ -1078,7 +1078,8 @@ int packed_refs_is_locked(struct ref_store *ref_store)
static const char PACKED_REFS_HEADER[] =
"# pack-refs with: peeled fully-peeled sorted \n";
-static int packed_init_db(struct ref_store *ref_store, struct strbuf *err)
+static int packed_init_db(struct ref_store *ref_store UNUSED,
+ struct strbuf *err UNUSED)
{
/* Nothing to do. */
return 0;
@@ -1473,7 +1474,7 @@ failure:
static int packed_transaction_abort(struct ref_store *ref_store,
struct ref_transaction *transaction,
- struct strbuf *err)
+ struct strbuf *err UNUSED)
{
struct packed_ref_store *refs = packed_downcast(
ref_store,
@@ -1512,7 +1513,7 @@ cleanup:
return ret;
}
-static int packed_initial_transaction_commit(struct ref_store *ref_store,
+static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED,
struct ref_transaction *transaction,
struct strbuf *err)
{
@@ -1568,7 +1569,8 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
return ret;
}
-static int packed_pack_refs(struct ref_store *ref_store, unsigned int flags)
+static int packed_pack_refs(struct ref_store *ref_store UNUSED,
+ unsigned int flags UNUSED)
{
/*
* Packed refs are already packed. It might be that loose refs
@@ -1578,7 +1580,7 @@ static int packed_pack_refs(struct ref_store *ref_store, unsigned int flags)
return 0;
}
-static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store)
+static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store UNUSED)
{
return empty_ref_iterator_begin();
}
diff --git a/reftable/merged.c b/reftable/merged.c
index 2a6efa110d5..5ded470c086 100644
--- a/reftable/merged.c
+++ b/reftable/merged.c
@@ -36,7 +36,7 @@ static int merged_iter_init(struct merged_iter *mi)
.rec = rec,
.index = i,
};
- merged_iter_pqueue_add(&mi->pq, e);
+ merged_iter_pqueue_add(&mi->pq, &e);
}
}
@@ -71,7 +71,7 @@ static int merged_iter_advance_nonnull_subiter(struct merged_iter *mi,
return 0;
}
- merged_iter_pqueue_add(&mi->pq, e);
+ merged_iter_pqueue_add(&mi->pq, &e);
return 0;
}
diff --git a/reftable/pq.c b/reftable/pq.c
index 96ca6dd37b3..dcefeb793a9 100644
--- a/reftable/pq.c
+++ b/reftable/pq.c
@@ -71,7 +71,7 @@ struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq)
return e;
}
-void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, struct pq_entry e)
+void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e)
{
int i = 0;
@@ -81,7 +81,7 @@ void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, struct pq_entry e)
pq->cap * sizeof(struct pq_entry));
}
- pq->heap[pq->len++] = e;
+ pq->heap[pq->len++] = *e;
i = pq->len - 1;
while (i > 0) {
int j = (i - 1) / 2;
diff --git a/reftable/pq.h b/reftable/pq.h
index 56fc1b6d873..e85bac9b52e 100644
--- a/reftable/pq.h
+++ b/reftable/pq.h
@@ -26,7 +26,7 @@ struct pq_entry merged_iter_pqueue_top(struct merged_iter_pqueue pq);
int merged_iter_pqueue_is_empty(struct merged_iter_pqueue pq);
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, struct pq_entry e);
+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);
int pq_less(struct pq_entry *a, struct pq_entry *b);
diff --git a/reftable/pq_test.c b/reftable/pq_test.c
index 7de5e886f35..011b5c75028 100644
--- a/reftable/pq_test.c
+++ b/reftable/pq_test.c
@@ -46,7 +46,7 @@ static void test_pq(void)
.u.ref = {
.refname = names[i],
} } };
- merged_iter_pqueue_add(&pq, e);
+ merged_iter_pqueue_add(&pq, &e);
merged_iter_pqueue_check(pq);
i = (i * 7) % N;
} while (i != 1);
diff --git a/remote-curl.c b/remote-curl.c
index b8758757ece..72dfb8fb86a 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -1286,6 +1286,29 @@ static void parse_fetch(struct strbuf *buf)
strbuf_reset(buf);
}
+static void parse_get(const char *arg)
+{
+ struct strbuf url = STRBUF_INIT;
+ struct strbuf path = STRBUF_INIT;
+ const char *space;
+
+ space = strchr(arg, ' ');
+
+ if (!space)
+ die(_("protocol error: expected '<url> <path>', missing space"));
+
+ strbuf_add(&url, arg, space - arg);
+ strbuf_addstr(&path, space + 1);
+
+ if (http_get_file(url.buf, path.buf, NULL))
+ die(_("failed to download file at URL '%s'"), url.buf);
+
+ strbuf_release(&url);
+ strbuf_release(&path);
+ printf("\n");
+ fflush(stdout);
+}
+
static int push_dav(int nr_spec, const char **specs)
{
struct child_process child = CHILD_PROCESS_INIT;
@@ -1564,9 +1587,14 @@ int cmd_main(int argc, const char **argv)
printf("unsupported\n");
fflush(stdout);
+ } else if (skip_prefix(buf.buf, "get ", &arg)) {
+ parse_get(arg);
+ fflush(stdout);
+
} else if (!strcmp(buf.buf, "capabilities")) {
printf("stateless-connect\n");
printf("fetch\n");
+ printf("get\n");
printf("option\n");
printf("push\n");
printf("check-connectivity\n");
diff --git a/remote.c b/remote.c
index 618ad5a0f16..60869beebe7 100644
--- a/remote.c
+++ b/remote.c
@@ -86,7 +86,7 @@ struct remotes_hash_key {
int len;
};
-static int remotes_hash_cmp(const void *unused_cmp_data,
+static int remotes_hash_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
@@ -170,7 +170,7 @@ struct branches_hash_key {
int len;
};
-static int branches_hash_cmp(const void *unused_cmp_data,
+static int branches_hash_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
@@ -2320,7 +2320,8 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb,
}
static int one_local_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data)
{
struct ref ***local_tail = cb_data;
struct ref *ref;
@@ -2576,19 +2577,22 @@ struct check_and_collect_until_cb_data {
};
/* Get the timestamp of the latest entry. */
-static int peek_reflog(struct object_id *o_oid, struct object_id *n_oid,
- const char *ident, timestamp_t timestamp,
- int tz, const char *message, void *cb_data)
+static int peek_reflog(struct object_id *o_oid UNUSED,
+ struct object_id *n_oid UNUSED,
+ const char *ident UNUSED,
+ timestamp_t timestamp, int tz UNUSED,
+ const char *message UNUSED, void *cb_data)
{
timestamp_t *ts = cb_data;
*ts = timestamp;
return 1;
}
-static int check_and_collect_until(struct object_id *o_oid,
+static int check_and_collect_until(struct object_id *o_oid UNUSED,
struct object_id *n_oid,
- const char *ident, timestamp_t timestamp,
- int tz, const char *message, void *cb_data)
+ const char *ident UNUSED,
+ timestamp_t timestamp, int tz UNUSED,
+ const char *message UNUSED, void *cb_data)
{
struct commit *commit;
struct check_and_collect_until_cb_data *cb = cb_data;
diff --git a/replace-object.c b/replace-object.c
index 7bd9aba6ee6..320be2522d8 100644
--- a/replace-object.c
+++ b/replace-object.c
@@ -9,7 +9,8 @@
static int register_replace_ref(struct repository *r,
const char *refname,
const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data UNUSED)
{
/* Get sha1 from refname */
const char *slash = strrchr(refname, '/');
diff --git a/repo-settings.c b/repo-settings.c
index 43bc881bfc9..3021921c53d 100644
--- a/repo-settings.c
+++ b/repo-settings.c
@@ -22,7 +22,7 @@ void prepare_repo_settings(struct repository *r)
{
int experimental;
int value;
- char *strval;
+ const char *strval;
int manyfiles;
if (!r->gitdir)
@@ -43,6 +43,7 @@ void prepare_repo_settings(struct repository *r)
/* Defaults modified by feature.* */
if (experimental) {
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
+ r->settings.gc_cruft_packs = 1;
}
if (manyfiles) {
r->settings.index_version = 4;
@@ -77,7 +78,7 @@ void prepare_repo_settings(struct repository *r)
if (!repo_config_get_int(r, "index.version", &value))
r->settings.index_version = value;
- if (!repo_config_get_string(r, "core.untrackedcache", &strval)) {
+ if (!repo_config_get_string_tmp(r, "core.untrackedcache", &strval)) {
int v = git_parse_maybe_bool(strval);
/*
@@ -88,10 +89,9 @@ void prepare_repo_settings(struct repository *r)
if (v >= 0)
r->settings.core_untracked_cache = v ?
UNTRACKED_CACHE_WRITE : UNTRACKED_CACHE_REMOVE;
- free(strval);
}
- if (!repo_config_get_string(r, "fetch.negotiationalgorithm", &strval)) {
+ if (!repo_config_get_string_tmp(r, "fetch.negotiationalgorithm", &strval)) {
int fetch_default = r->settings.fetch_negotiation_algorithm;
if (!strcasecmp(strval, "skipping"))
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
diff --git a/repository.h b/repository.h
index 797f471cce9..6c461c5b9de 100644
--- a/repository.h
+++ b/repository.h
@@ -1,6 +1,7 @@
#ifndef REPOSITORY_H
#define REPOSITORY_H
+#include "git-compat-util.h"
#include "path.h"
struct config_set;
@@ -33,6 +34,7 @@ struct repo_settings {
int commit_graph_generation_version;
int commit_graph_read_changed_paths;
int gc_write_commit_graph;
+ int gc_cruft_packs;
int fetch_write_commit_graph;
int command_requires_full_index;
int sparse_index;
@@ -186,6 +188,7 @@ void repo_set_gitdir(struct repository *repo, const char *root,
void repo_set_worktree(struct repository *repo, const char *path);
void repo_set_hash_algo(struct repository *repo, int algo);
void initialize_the_repository(void);
+RESULT_MUST_BE_USED
int repo_init(struct repository *r, const char *gitdir, const char *worktree);
/*
@@ -197,6 +200,7 @@ int repo_init(struct repository *r, const char *gitdir, const char *worktree);
* Return 0 upon success and a non-zero value upon failure.
*/
struct object_id;
+RESULT_MUST_BE_USED
int repo_submodule_init(struct repository *subrepo,
struct repository *superproject,
const char *path,
diff --git a/revision.c b/revision.c
index ee702e498a0..c6b39965834 100644
--- a/revision.c
+++ b/revision.c
@@ -47,13 +47,6 @@ static inline int want_ancestry(const struct rev_info *revs);
void show_object_with_name(FILE *out, struct object *obj, const char *name)
{
fprintf(out, "%s ", oid_to_hex(&obj->oid));
- /*
- * This "for (const char *p = ..." is made as a first step towards
- * making use of such declarations elsewhere in our codebase. If
- * it causes compilation problems on your platform, please report
- * it to the Git mailing list at git@vger.kernel.org. In the meantime,
- * adding -std=gnu99 to CFLAGS may help if you are with older GCC.
- */
for (const char *p = name; *p && *p != '\n'; p++)
fputc(*p, out);
fputc('\n', out);
@@ -119,10 +112,10 @@ struct path_and_oids_entry {
struct oidset trees;
};
-static int path_and_oids_cmp(const void *hashmap_cmp_fn_data,
+static int path_and_oids_cmp(const void *hashmap_cmp_fn_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *keydata)
+ const void *keydata UNUSED)
{
const struct path_and_oids_entry *e1, *e2;
@@ -373,18 +366,10 @@ static struct object *get_reference(struct rev_info *revs, const char *name,
unsigned int flags)
{
struct object *object;
- struct commit *commit;
- /*
- * If the repository has commit graphs, we try to opportunistically
- * look up the object ID in those graphs. Like this, we can avoid
- * parsing commit data from disk.
- */
- commit = lookup_commit_in_graph(revs->repo, oid);
- if (commit)
- object = &commit->object;
- else
- object = parse_object(revs->repo, oid);
+ object = parse_object_with_flags(revs->repo, oid,
+ revs->verify_objects ? 0 :
+ PARSE_OBJECT_SKIP_HASH_CHECK);
if (!object) {
if (revs->ignore_missing)
@@ -1554,7 +1539,8 @@ int ref_excluded(struct string_list *ref_excludes, const char *path)
}
static int handle_one_ref(const char *path, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data)
{
struct all_refs_cb *cb = cb_data;
struct object *object;
@@ -1629,8 +1615,11 @@ static void handle_one_reflog_commit(struct object_id *oid, void *cb_data)
}
static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+ const char *email UNUSED,
+ timestamp_t timestamp UNUSED,
+ int tz UNUSED,
+ const char *message UNUSED,
+ void *cb_data)
{
handle_one_reflog_commit(ooid, cb_data);
handle_one_reflog_commit(noid, cb_data);
@@ -1638,8 +1627,8 @@ static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
}
static int handle_one_reflog(const char *refname_in_wt,
- const struct object_id *oid,
- int flag, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cb_data)
{
struct all_refs_cb *cb = cb_data;
struct strbuf refname = STRBUF_INIT;
@@ -1876,30 +1865,15 @@ void repo_init_revisions(struct repository *r,
struct rev_info *revs,
const char *prefix)
{
- memset(revs, 0, sizeof(*revs));
+ struct rev_info blank = REV_INFO_INIT;
+ memcpy(revs, &blank, sizeof(*revs));
revs->repo = r;
- revs->abbrev = DEFAULT_ABBREV;
- revs->simplify_history = 1;
revs->pruning.repo = r;
- revs->pruning.flags.recursive = 1;
- revs->pruning.flags.quick = 1;
revs->pruning.add_remove = file_add_remove;
revs->pruning.change = file_change;
revs->pruning.change_fn_data = revs;
- revs->sort_order = REV_SORT_IN_GRAPH_ORDER;
- revs->dense = 1;
revs->prefix = prefix;
- revs->max_age = -1;
- revs->max_age_as_filter = -1;
- revs->min_age = -1;
- revs->skip_count = -1;
- revs->max_count = -1;
- revs->max_parents = -1;
- revs->expand_tabs_in_log = -1;
-
- revs->commit_format = CMIT_FMT_DEFAULT;
- revs->expand_tabs_in_log_default = 8;
grep_init(&revs->grep_filter, revs->repo);
revs->grep_filter.status_only = 1;
@@ -1911,6 +1885,7 @@ void repo_init_revisions(struct repository *r,
}
init_display_notes(&revs->notes_opt);
+ list_objects_filter_init(&revs->filter);
}
static void add_pending_commit_list(struct rev_info *revs,
@@ -2123,9 +2098,8 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
int exclude_parent = 1;
if (mark[2]) {
- char *end;
- exclude_parent = strtoul(mark + 2, &end, 10);
- if (*end != '\0' || !exclude_parent)
+ if (strtol_i(mark + 2, 10, &exclude_parent) ||
+ exclude_parent < 1)
return -1;
}
@@ -2426,6 +2400,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->tree_objects = 1;
revs->blob_objects = 1;
revs->verify_objects = 1;
+ disable_commit_graph(revs->repo);
} else if (!strcmp(arg, "--unpacked")) {
revs->unpacked = 1;
} else if (starts_with(arg, "--unpacked=")) {
diff --git a/revision.h b/revision.h
index 61a9b1316b8..8493a3f3b93 100644
--- a/revision.h
+++ b/revision.h
@@ -229,6 +229,7 @@ struct rev_info {
missing_newline:1,
date_mode_explicit:1,
preserve_subject:1,
+ force_in_body_from:1,
encode_email_headers:1,
include_header:1;
unsigned int disable_stdin:1;
@@ -356,7 +357,23 @@ struct rev_info {
* called before release_revisions() the "struct rev_info" can be left
* uninitialized.
*/
-#define REV_INFO_INIT { 0 }
+#define REV_INFO_INIT { \
+ .abbrev = DEFAULT_ABBREV, \
+ .simplify_history = 1, \
+ .pruning.flags.recursive = 1, \
+ .pruning.flags.quick = 1, \
+ .sort_order = REV_SORT_IN_GRAPH_ORDER, \
+ .dense = 1, \
+ .max_age = -1, \
+ .max_age_as_filter = -1, \
+ .min_age = -1, \
+ .skip_count = -1, \
+ .max_count = -1, \
+ .max_parents = -1, \
+ .expand_tabs_in_log = -1, \
+ .commit_format = CMIT_FMT_DEFAULT, \
+ .expand_tabs_in_log_default = 8, \
+}
/**
* Initialize a rev_info structure with default values. The third parameter may
diff --git a/run-command.c b/run-command.c
index 5ec3a46dccf..48b9ba6d6f0 100644
--- a/run-command.c
+++ b/run-command.c
@@ -1004,41 +1004,6 @@ int run_command(struct child_process *cmd)
return finish_command(cmd);
}
-int run_command_v_opt(const char **argv, int opt)
-{
- return run_command_v_opt_cd_env(argv, opt, NULL, NULL);
-}
-
-int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class)
-{
- return run_command_v_opt_cd_env_tr2(argv, opt, NULL, NULL, tr2_class);
-}
-
-int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)
-{
- return run_command_v_opt_cd_env_tr2(argv, opt, dir, env, NULL);
-}
-
-int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir,
- const char *const *env, const char *tr2_class)
-{
- struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushv(&cmd.args, argv);
- cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
- cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
- cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
- cmd.silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;
- cmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0;
- cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0;
- cmd.wait_after_clean = opt & RUN_WAIT_AFTER_CLEAN ? 1 : 0;
- cmd.close_object_store = opt & RUN_CLOSE_OBJECT_STORE ? 1 : 0;
- cmd.dir = dir;
- if (env)
- strvec_pushv(&cmd.env, (const char **)env);
- cmd.trace2_child_class = tr2_class;
- return run_command(&cmd);
-}
-
#ifndef NO_PTHREADS
static pthread_t main_thread;
static int main_thread_set;
@@ -1496,16 +1461,8 @@ enum child_state {
GIT_CP_WAIT_CLEANUP,
};
-int run_processes_parallel_ungroup;
struct parallel_processes {
- void *data;
-
- int max_processes;
- int nr_processes;
-
- get_next_task_fn get_next_task;
- start_failure_fn start_failure;
- task_finished_fn task_finished;
+ size_t nr_processes;
struct {
enum child_state state;
@@ -1520,81 +1477,60 @@ struct parallel_processes {
struct pollfd *pfd;
unsigned shutdown : 1;
- unsigned ungroup : 1;
- int output_owner;
+ size_t output_owner;
struct strbuf buffered_output; /* of finished children */
};
-static int default_start_failure(struct strbuf *out,
- void *pp_cb,
- void *pp_task_cb)
-{
- return 0;
-}
+struct parallel_processes_for_signal {
+ const struct run_process_parallel_opts *opts;
+ const struct parallel_processes *pp;
+};
-static int default_task_finished(int result,
- struct strbuf *out,
- void *pp_cb,
- void *pp_task_cb)
+static void kill_children(const struct parallel_processes *pp,
+ const struct run_process_parallel_opts *opts,
+ int signo)
{
- return 0;
+ for (size_t i = 0; i < opts->processes; i++)
+ if (pp->children[i].state == GIT_CP_WORKING)
+ kill(pp->children[i].process.pid, signo);
}
-static void kill_children(struct parallel_processes *pp, int signo)
+static void kill_children_signal(const struct parallel_processes_for_signal *pp_sig,
+ int signo)
{
- int i, n = pp->max_processes;
-
- for (i = 0; i < n; i++)
- if (pp->children[i].state == GIT_CP_WORKING)
- kill(pp->children[i].process.pid, signo);
+ kill_children(pp_sig->pp, pp_sig->opts, signo);
}
-static struct parallel_processes *pp_for_signal;
+static struct parallel_processes_for_signal *pp_for_signal;
static void handle_children_on_signal(int signo)
{
- kill_children(pp_for_signal, signo);
+ kill_children_signal(pp_for_signal, signo);
sigchain_pop(signo);
raise(signo);
}
static void pp_init(struct parallel_processes *pp,
- int n,
- get_next_task_fn get_next_task,
- start_failure_fn start_failure,
- task_finished_fn task_finished,
- void *data, int ungroup)
+ const struct run_process_parallel_opts *opts,
+ struct parallel_processes_for_signal *pp_sig)
{
- int i;
-
- if (n < 1)
- n = online_cpus();
+ const size_t n = opts->processes;
- pp->max_processes = n;
+ if (!n)
+ BUG("you must provide a non-zero number of processes!");
- trace_printf("run_processes_parallel: preparing to run up to %d tasks", n);
+ trace_printf("run_processes_parallel: preparing to run up to %"PRIuMAX" tasks",
+ (uintmax_t)n);
- pp->data = data;
- if (!get_next_task)
+ if (!opts->get_next_task)
BUG("you need to specify a get_next_task function");
- pp->get_next_task = get_next_task;
- pp->start_failure = start_failure ? start_failure : default_start_failure;
- pp->task_finished = task_finished ? task_finished : default_task_finished;
-
- pp->nr_processes = 0;
- pp->output_owner = 0;
- pp->shutdown = 0;
- pp->ungroup = ungroup;
CALLOC_ARRAY(pp->children, n);
- if (pp->ungroup)
- pp->pfd = NULL;
- else
+ if (!opts->ungroup)
CALLOC_ARRAY(pp->pfd, n);
- strbuf_init(&pp->buffered_output, 0);
- for (i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
strbuf_init(&pp->children[i].err, 0);
child_process_init(&pp->children[i].process);
if (pp->pfd) {
@@ -1603,16 +1539,17 @@ static void pp_init(struct parallel_processes *pp,
}
}
- pp_for_signal = pp;
+ pp_sig->pp = pp;
+ pp_sig->opts = opts;
+ pp_for_signal = pp_sig;
sigchain_push_common(handle_children_on_signal);
}
-static void pp_cleanup(struct parallel_processes *pp)
+static void pp_cleanup(struct parallel_processes *pp,
+ const struct run_process_parallel_opts *opts)
{
- int i;
-
trace_printf("run_processes_parallel: done");
- for (i = 0; i < pp->max_processes; i++) {
+ for (size_t i = 0; i < opts->processes; i++) {
strbuf_release(&pp->children[i].err);
child_process_clear(&pp->children[i].process);
}
@@ -1637,39 +1574,45 @@ static void pp_cleanup(struct parallel_processes *pp)
* <0 no new job was started, user wishes to shutdown early. Use negative code
* to signal the children.
*/
-static int pp_start_one(struct parallel_processes *pp)
+static int pp_start_one(struct parallel_processes *pp,
+ const struct run_process_parallel_opts *opts)
{
- int i, code;
+ size_t i;
+ int code;
- for (i = 0; i < pp->max_processes; i++)
+ for (i = 0; i < opts->processes; i++)
if (pp->children[i].state == GIT_CP_FREE)
break;
- if (i == pp->max_processes)
+ if (i == opts->processes)
BUG("bookkeeping is hard");
- code = pp->get_next_task(&pp->children[i].process,
- pp->ungroup ? NULL : &pp->children[i].err,
- pp->data,
- &pp->children[i].data);
+ code = opts->get_next_task(&pp->children[i].process,
+ opts->ungroup ? NULL : &pp->children[i].err,
+ opts->data,
+ &pp->children[i].data);
if (!code) {
- if (!pp->ungroup) {
+ if (!opts->ungroup) {
strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
strbuf_reset(&pp->children[i].err);
}
return 1;
}
- if (!pp->ungroup) {
+ if (!opts->ungroup) {
pp->children[i].process.err = -1;
pp->children[i].process.stdout_to_stderr = 1;
}
pp->children[i].process.no_stdin = 1;
if (start_command(&pp->children[i].process)) {
- code = pp->start_failure(pp->ungroup ? NULL :
- &pp->children[i].err,
- pp->data,
- pp->children[i].data);
- if (!pp->ungroup) {
+ if (opts->start_failure)
+ code = opts->start_failure(opts->ungroup ? NULL :
+ &pp->children[i].err,
+ opts->data,
+ pp->children[i].data);
+ else
+ code = 0;
+
+ if (!opts->ungroup) {
strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
strbuf_reset(&pp->children[i].err);
}
@@ -1685,19 +1628,21 @@ static int pp_start_one(struct parallel_processes *pp)
return 0;
}
-static void pp_buffer_stderr(struct parallel_processes *pp, int output_timeout)
+static void pp_buffer_stderr(struct parallel_processes *pp,
+ const struct run_process_parallel_opts *opts,
+ int output_timeout)
{
int i;
- while ((i = poll(pp->pfd, pp->max_processes, output_timeout)) < 0) {
+ while ((i = poll(pp->pfd, opts->processes, output_timeout) < 0)) {
if (errno == EINTR)
continue;
- pp_cleanup(pp);
+ pp_cleanup(pp, opts);
die_errno("poll");
}
/* Buffer output from all pipes. */
- for (i = 0; i < pp->max_processes; i++) {
+ for (size_t i = 0; i < opts->processes; i++) {
if (pp->children[i].state == GIT_CP_WORKING &&
pp->pfd[i].revents & (POLLIN | POLLHUP)) {
int n = strbuf_read_once(&pp->children[i].err,
@@ -1712,9 +1657,9 @@ static void pp_buffer_stderr(struct parallel_processes *pp, int output_timeout)
}
}
-static void pp_output(struct parallel_processes *pp)
+static void pp_output(const struct parallel_processes *pp)
{
- int i = pp->output_owner;
+ size_t i = pp->output_owner;
if (pp->children[i].state == GIT_CP_WORKING &&
pp->children[i].err.len) {
@@ -1723,24 +1668,28 @@ static void pp_output(struct parallel_processes *pp)
}
}
-static int pp_collect_finished(struct parallel_processes *pp)
+static int pp_collect_finished(struct parallel_processes *pp,
+ const struct run_process_parallel_opts *opts)
{
- int i, code;
- int n = pp->max_processes;
+ int code;
+ size_t i;
int result = 0;
while (pp->nr_processes > 0) {
- for (i = 0; i < pp->max_processes; i++)
+ for (i = 0; i < opts->processes; i++)
if (pp->children[i].state == GIT_CP_WAIT_CLEANUP)
break;
- if (i == pp->max_processes)
+ if (i == opts->processes)
break;
code = finish_command(&pp->children[i].process);
- code = pp->task_finished(code, pp->ungroup ? NULL :
- &pp->children[i].err, pp->data,
- pp->children[i].data);
+ if (opts->task_finished)
+ code = opts->task_finished(code, opts->ungroup ? NULL :
+ &pp->children[i].err, opts->data,
+ pp->children[i].data);
+ else
+ code = 0;
if (code)
result = code;
@@ -1753,12 +1702,14 @@ static int pp_collect_finished(struct parallel_processes *pp)
pp->pfd[i].fd = -1;
child_process_init(&pp->children[i].process);
- if (pp->ungroup) {
+ if (opts->ungroup) {
; /* no strbuf_*() work to do here */
} else if (i != pp->output_owner) {
strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
strbuf_reset(&pp->children[i].err);
} else {
+ const size_t n = opts->processes;
+
strbuf_write(&pp->children[i].err, stderr);
strbuf_reset(&pp->children[i].err);
@@ -1783,76 +1734,60 @@ static int pp_collect_finished(struct parallel_processes *pp)
return result;
}
-int run_processes_parallel(int n,
- get_next_task_fn get_next_task,
- start_failure_fn start_failure,
- task_finished_fn task_finished,
- void *pp_cb)
+void run_processes_parallel(const struct run_process_parallel_opts *opts)
{
int i, code;
int output_timeout = 100;
int spawn_cap = 4;
- int ungroup = run_processes_parallel_ungroup;
- struct parallel_processes pp;
-
- /* unset for the next API user */
- run_processes_parallel_ungroup = 0;
-
- pp_init(&pp, n, get_next_task, start_failure, task_finished, pp_cb,
- ungroup);
+ struct parallel_processes_for_signal pp_sig;
+ struct parallel_processes pp = {
+ .buffered_output = STRBUF_INIT,
+ };
+ /* options */
+ const char *tr2_category = opts->tr2_category;
+ const char *tr2_label = opts->tr2_label;
+ const int do_trace2 = tr2_category && tr2_label;
+
+ if (do_trace2)
+ trace2_region_enter_printf(tr2_category, tr2_label, NULL,
+ "max:%d", opts->processes);
+
+ pp_init(&pp, opts, &pp_sig);
while (1) {
for (i = 0;
i < spawn_cap && !pp.shutdown &&
- pp.nr_processes < pp.max_processes;
+ pp.nr_processes < opts->processes;
i++) {
- code = pp_start_one(&pp);
+ code = pp_start_one(&pp, opts);
if (!code)
continue;
if (code < 0) {
pp.shutdown = 1;
- kill_children(&pp, -code);
+ kill_children(&pp, opts, -code);
}
break;
}
if (!pp.nr_processes)
break;
- if (ungroup) {
- int i;
-
- for (i = 0; i < pp.max_processes; i++)
+ if (opts->ungroup) {
+ for (size_t i = 0; i < opts->processes; i++)
pp.children[i].state = GIT_CP_WAIT_CLEANUP;
} else {
- pp_buffer_stderr(&pp, output_timeout);
+ pp_buffer_stderr(&pp, opts, output_timeout);
pp_output(&pp);
}
- code = pp_collect_finished(&pp);
+ code = pp_collect_finished(&pp, opts);
if (code) {
pp.shutdown = 1;
if (code < 0)
- kill_children(&pp, -code);
+ kill_children(&pp, opts,-code);
}
}
- pp_cleanup(&pp);
- return 0;
-}
-
-int run_processes_parallel_tr2(int n, get_next_task_fn get_next_task,
- start_failure_fn start_failure,
- task_finished_fn task_finished, void *pp_cb,
- const char *tr2_category, const char *tr2_label)
-{
- int result;
-
- trace2_region_enter_printf(tr2_category, tr2_label, NULL, "max:%d",
- ((n < 1) ? online_cpus() : n));
+ pp_cleanup(&pp, opts);
- result = run_processes_parallel(n, get_next_task, start_failure,
- task_finished, pp_cb);
-
- trace2_region_leave(tr2_category, tr2_label, NULL);
-
- return result;
+ if (do_trace2)
+ trace2_region_leave(tr2_category, tr2_label, NULL);
}
int run_auto_maintenance(int quiet)
diff --git a/run-command.h b/run-command.h
index 0e85e5846a5..072db56a4df 100644
--- a/run-command.h
+++ b/run-command.h
@@ -150,9 +150,7 @@ struct child_process {
}
/**
- * The functions: child_process_init, start_command, finish_command,
- * run_command, run_command_v_opt, run_command_v_opt_cd_env, child_process_clear
- * do the following:
+ * The functions: start_command, finish_command, run_command do the following:
*
* - If a system call failed, errno is set and -1 is returned. A diagnostic
* is printed.
@@ -224,36 +222,6 @@ int run_command(struct child_process *);
*/
int run_auto_maintenance(int quiet);
-#define RUN_COMMAND_NO_STDIN (1<<0)
-#define RUN_GIT_CMD (1<<1)
-#define RUN_COMMAND_STDOUT_TO_STDERR (1<<2)
-#define RUN_SILENT_EXEC_FAILURE (1<<3)
-#define RUN_USING_SHELL (1<<4)
-#define RUN_CLEAN_ON_EXIT (1<<5)
-#define RUN_WAIT_AFTER_CLEAN (1<<6)
-#define RUN_CLOSE_OBJECT_STORE (1<<7)
-
-/**
- * Convenience functions that encapsulate a sequence of
- * start_command() followed by finish_command(). The argument argv
- * specifies the program and its arguments. The argument opt is zero
- * or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`,
- * `RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE`
- * that correspond to the members .no_stdin, .git_cmd,
- * .stdout_to_stderr, .silent_exec_failure of `struct child_process`.
- * The argument dir corresponds the member .dir. The argument env
- * corresponds to the member .env.
- */
-int run_command_v_opt(const char **argv, int opt);
-int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class);
-/*
- * env (the environment) is to be formatted like environ: "VAR=VALUE".
- * To unset an environment variable use just "VAR".
- */
-int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env);
-int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir,
- const char *const *env, const char *tr2_class);
-
/**
* Execute the given command, sending "in" to its stdin, and capturing its
* stdout and stderr in the "out" and "err" strbufs. Any of the three may
@@ -459,17 +427,64 @@ typedef int (*task_finished_fn)(int result,
void *pp_task_cb);
/**
- * Runs up to n processes at the same time. Whenever a process can be
- * started, the callback get_next_task_fn is called to obtain the data
+ * Option used by run_processes_parallel(), { 0 }-initialized means no
+ * options.
+ */
+struct run_process_parallel_opts
+{
+ /**
+ * tr2_category & tr2_label: sets the trace2 category and label for
+ * logging. These must either be unset, or both of them must be set.
+ */
+ const char *tr2_category;
+ const char *tr2_label;
+
+ /**
+ * processes: see 'processes' in run_processes_parallel() below.
+ */
+ size_t processes;
+
+ /**
+ * ungroup: see 'ungroup' in run_processes_parallel() below.
+ */
+ unsigned int ungroup:1;
+
+ /**
+ * get_next_task: See get_next_task_fn() above. This must be
+ * specified.
+ */
+ get_next_task_fn get_next_task;
+
+ /**
+ * start_failure: See start_failure_fn() above. This can be
+ * NULL to omit any special handling.
+ */
+ start_failure_fn start_failure;
+
+ /**
+ * task_finished: See task_finished_fn() above. This can be
+ * NULL to omit any special handling.
+ */
+ task_finished_fn task_finished;
+
+ /**
+ * data: user data, will be passed as "pp_cb" to the callback
+ * parameters.
+ */
+ void *data;
+};
+
+/**
+ * Options are passed via the "struct run_process_parallel_opts" above.
+ *
+ * Runs N 'processes' at the same time. Whenever a process can be
+ * started, the callback opts.get_next_task is called to obtain the data
* required to start another child process.
*
* The children started via this function run in parallel. Their output
* (both stdout and stderr) is routed to stderr in a manner that output
* from different tasks does not interleave (but see "ungroup" below).
*
- * start_failure_fn and task_finished_fn can be NULL to omit any
- * special handling.
- *
* If the "ungroup" option isn't specified, the API will set the
* "stdout_to_stderr" parameter in "struct child_process" and provide
* the callbacks with a "struct strbuf *out" parameter to write output
@@ -479,20 +494,8 @@ typedef int (*task_finished_fn)(int result,
* NULL "struct strbuf *out" parameter, and are responsible for
* emitting their own output, including dealing with any race
* conditions due to writing in parallel to stdout and stderr.
- * The "ungroup" option can be enabled by setting the global
- * "run_processes_parallel_ungroup" to "1" before invoking
- * run_processes_parallel(), it will be set back to "0" as soon as the
- * API reads that setting.
*/
-extern int run_processes_parallel_ungroup;
-int run_processes_parallel(int n,
- get_next_task_fn,
- start_failure_fn,
- task_finished_fn,
- void *pp_cb);
-int run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn,
- task_finished_fn, void *pp_cb,
- const char *tr2_category, const char *tr2_label);
+void run_processes_parallel(const struct run_process_parallel_opts *opts);
/**
* Convenience function which prepares env for a command to be run in a
diff --git a/contrib/scalar/scalar.c b/scalar.c
index 642d16124eb..6c52243cdf1 100644
--- a/contrib/scalar/scalar.c
+++ b/scalar.c
@@ -69,21 +69,18 @@ static void setup_enlistment_directory(int argc, const char **argv,
static int run_git(const char *arg, ...)
{
- struct strvec argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
va_list args;
const char *p;
- int res;
va_start(args, arg);
- strvec_push(&argv, arg);
+ strvec_push(&cmd.args, arg);
while ((p = va_arg(args, const char *)))
- strvec_push(&argv, p);
+ strvec_push(&cmd.args, p);
va_end(args);
- res = run_command_v_opt(argv.v, RUN_GIT_CMD);
-
- strvec_clear(&argv);
- return res;
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
struct scalar_config {
@@ -207,7 +204,10 @@ static int set_recommended_config(int reconfigure)
static int toggle_maintenance(int enable)
{
- return run_git("maintenance", enable ? "start" : "unregister", NULL);
+ return run_git("maintenance",
+ enable ? "start" : "unregister",
+ enable ? NULL : "--force",
+ NULL);
}
static int add_or_remove_enlistment(int add)
@@ -596,6 +596,24 @@ static int get_scalar_repos(const char *key, const char *value, void *data)
return 0;
}
+static int remove_deleted_enlistment(struct strbuf *path)
+{
+ int res = 0;
+ strbuf_realpath_forgiving(path, path->buf, 1);
+
+ if (run_git("config", "--global",
+ "--unset", "--fixed-value",
+ "scalar.repo", path->buf, NULL) < 0)
+ res = -1;
+
+ if (run_git("config", "--global",
+ "--unset", "--fixed-value",
+ "maintenance.repo", path->buf, NULL) < 0)
+ res = -1;
+
+ return res;
+}
+
static int cmd_reconfigure(int argc, const char **argv)
{
int all = 0;
@@ -635,8 +653,22 @@ static int cmd_reconfigure(int argc, const char **argv)
strbuf_reset(&gitdir);
if (chdir(dir) < 0) {
- warning_errno(_("could not switch to '%s'"), dir);
- res = -1;
+ struct strbuf buf = STRBUF_INIT;
+
+ if (errno != ENOENT) {
+ warning_errno(_("could not switch to '%s'"), dir);
+ res = -1;
+ continue;
+ }
+
+ strbuf_addstr(&buf, dir);
+ if (remove_deleted_enlistment(&buf))
+ res = error(_("could not remove stale "
+ "scalar.repo '%s'"), dir);
+ else
+ warning(_("removing stale scalar.repo '%s'"),
+ dir);
+ strbuf_release(&buf);
} else if (discover_git_directory(&commondir, &gitdir) < 0) {
warning_errno(_("git repository gone in '%s'"), dir);
res = -1;
@@ -722,24 +754,6 @@ static int cmd_run(int argc, const char **argv)
return 0;
}
-static int remove_deleted_enlistment(struct strbuf *path)
-{
- int res = 0;
- strbuf_realpath_forgiving(path, path->buf, 1);
-
- if (run_git("config", "--global",
- "--unset", "--fixed-value",
- "scalar.repo", path->buf, NULL) < 0)
- res = -1;
-
- if (run_git("config", "--global",
- "--unset", "--fixed-value",
- "maintenance.repo", path->buf, NULL) < 0)
- res = -1;
-
- return res;
-}
-
static int cmd_unregister(int argc, const char **argv)
{
struct option options[] = {
@@ -819,6 +833,25 @@ static int cmd_delete(int argc, const char **argv)
return res;
}
+static int cmd_help(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END(),
+ };
+ const char * const usage[] = {
+ "scalar help",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, NULL, options,
+ usage, 0);
+
+ if (argc != 0)
+ usage_with_options(usage, options);
+
+ return run_git("help", "scalar", NULL);
+}
+
static int cmd_version(int argc, const char **argv)
{
int verbose = 0, build_options = 0;
@@ -858,6 +891,7 @@ static struct {
{ "run", cmd_run },
{ "reconfigure", cmd_reconfigure },
{ "delete", cmd_delete },
+ { "help", cmd_help },
{ "version", cmd_version },
{ "diagnose", cmd_diagnose },
{ NULL, NULL},
diff --git a/send-pack.c b/send-pack.c
index 662f7c2aeb9..f2e19838c9c 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -266,7 +266,7 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
return ret;
}
-static int sideband_demux(int in, int out, void *data)
+static int sideband_demux(int in UNUSED, int out, void *data)
{
int *fd = data, ret;
if (async_with_fork())
diff --git a/sequencer.c b/sequencer.c
index 79dad522f56..edb01643e12 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -915,7 +915,7 @@ int read_author_script(const char *path, char **name, char **email, char **date,
error(_("missing 'GIT_AUTHOR_EMAIL'"));
if (date_i == -2)
error(_("missing 'GIT_AUTHOR_DATE'"));
- if (date_i < 0 || email_i < 0 || date_i < 0 || err)
+ if (name_i < 0 || email_i < 0 || date_i < 0 || err)
goto finish;
*name = kv.items[name_i].util;
*email = kv.items[email_i].util;
@@ -3183,18 +3183,15 @@ static int rollback_is_safe(void)
static int reset_merge(const struct object_id *oid)
{
- int ret;
- struct strvec argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
- strvec_pushl(&argv, "reset", "--merge", NULL);
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "reset", "--merge", NULL);
if (!is_null_oid(oid))
- strvec_push(&argv, oid_to_hex(oid));
-
- ret = run_command_v_opt(argv.v, RUN_GIT_CMD);
- strvec_clear(&argv);
+ strvec_push(&cmd.args, oid_to_hex(oid));
- return ret;
+ return run_command(&cmd);
}
static int rollback_single_pick(struct repository *r)
@@ -3558,12 +3555,13 @@ static int error_failed_squash(struct repository *r,
static int do_exec(struct repository *r, const char *command_line)
{
- const char *child_argv[] = { NULL, NULL };
+ struct child_process cmd = CHILD_PROCESS_INIT;
int dirty, status;
fprintf(stderr, _("Executing: %s\n"), command_line);
- child_argv[0] = command_line;
- status = run_command_v_opt(child_argv, RUN_USING_SHELL);
+ cmd.use_shell = 1;
+ strvec_push(&cmd.args, command_line);
+ status = run_command(&cmd);
/* force re-reading of the cache */
if (discard_index(r->index) < 0 || repo_read_index(r) < 0)
@@ -4130,11 +4128,14 @@ static int write_update_refs_state(struct string_list *refs_to_oids)
struct string_list_item *item;
char *path;
- if (!refs_to_oids->nr)
- return 0;
-
path = rebase_path_update_refs(the_repository->gitdir);
+ if (!refs_to_oids->nr) {
+ if (unlink(path) && errno != ENOENT)
+ result = error_errno(_("could not unlink: %s"), path);
+ goto cleanup;
+ }
+
if (safe_create_leading_directories(path)) {
result = error(_("unable to create leading directories of %s"),
path);
@@ -4867,14 +4868,14 @@ cleanup_head_ref:
static int continue_single_pick(struct repository *r, struct replay_opts *opts)
{
- struct strvec argv = STRVEC_INIT;
- int ret;
+ struct child_process cmd = CHILD_PROCESS_INIT;
if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))
return error(_("no cherry-pick or revert in progress"));
- strvec_push(&argv, "commit");
+ cmd.git_cmd = 1;
+ strvec_push(&cmd.args, "commit");
/*
* continue_single_pick() handles the case of recovering from a
@@ -4887,11 +4888,9 @@ static int continue_single_pick(struct repository *r, struct replay_opts *opts)
* Include --cleanup=strip as well because we don't want the
* "# Conflicts:" messages.
*/
- strvec_pushl(&argv, "--no-edit", "--cleanup=strip", NULL);
+ strvec_pushl(&cmd.args, "--no-edit", "--cleanup=strip", NULL);
- ret = run_command_v_opt(argv.v, RUN_GIT_CMD);
- strvec_clear(&argv);
- return ret;
+ return run_command(&cmd);
}
static int commit_staged_changes(struct repository *r,
@@ -5050,6 +5049,8 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
if (read_populate_opts(opts))
return -1;
if (is_rebase_i(opts)) {
+ char *previous_reflog_action;
+
if ((res = read_populate_todo(r, &todo_list, opts)))
goto release_todo_list;
@@ -5060,10 +5061,13 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
unlink(rebase_path_dropped());
}
+ previous_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));
+ setenv(GIT_REFLOG_ACTION, reflog_message(opts, "continue", NULL), 1);
if (commit_staged_changes(r, opts, &todo_list)) {
res = -1;
goto release_todo_list;
}
+ setenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);
} else if (!file_exists(get_todo_path(opts)))
return continue_single_pick(r, opts);
else if ((res = read_populate_todo(r, &todo_list, opts)))
@@ -5254,7 +5258,8 @@ struct labels_entry {
char label[FLEX_ARRAY];
};
-static int labels_cmp(const void *fndata, const struct hashmap_entry *eptr,
+static int labels_cmp(const void *fndata UNUSED,
+ const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key, const void *key)
{
const struct labels_entry *a, *b;
@@ -6131,7 +6136,7 @@ struct subject2item_entry {
char subject[FLEX_ARRAY];
};
-static int subject2item_cmp(const void *fndata,
+static int subject2item_cmp(const void *fndata UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *key)
@@ -6202,8 +6207,6 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
return error(_("the script was already rearranged."));
}
- *commit_todo_item_at(&commit_todo, item->commit) = item;
-
parse_commit(item->commit);
commit_buffer = logmsg_reencode(item->commit, NULL, "UTF-8");
find_commit_subject(commit_buffer, &subject);
@@ -6270,6 +6273,8 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
strhash(entry->subject));
hashmap_put(&subject2item, &entry->entry);
}
+
+ *commit_todo_item_at(&commit_todo, item->commit) = item;
}
if (rearranged) {
diff --git a/server-info.c b/server-info.c
index 7701d7c20a1..0ec6c0c1654 100644
--- a/server-info.c
+++ b/server-info.c
@@ -147,7 +147,8 @@ out:
}
static int add_info_ref(const char *path, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data)
{
struct update_info_ctx *uic = cb_data;
struct object *o = parse_object(the_repository, oid);
diff --git a/sha1dc_git.h b/sha1dc_git.h
index 41e1c3fd3f7..60e3ce84395 100644
--- a/sha1dc_git.h
+++ b/sha1dc_git.h
@@ -17,6 +17,7 @@ void git_SHA1DCInit(SHA1_CTX *);
void git_SHA1DCFinal(unsigned char [20], SHA1_CTX *);
void git_SHA1DCUpdate(SHA1_CTX *ctx, const void *data, unsigned long len);
+#define platform_SHA_IS_SHA1DC /* used by "test-tool sha1-is-sha1dc" */
#define platform_SHA_CTX SHA1_CTX
#define platform_SHA1_Init git_SHA1DCInit
#define platform_SHA1_Update git_SHA1DCUpdate
diff --git a/shallow.c b/shallow.c
index 8cb768ee5f8..17f9bcdb5f3 100644
--- a/shallow.c
+++ b/shallow.c
@@ -604,8 +604,10 @@ static void paint_down(struct paint_info *info, const struct object_id *oid,
free(tmp);
}
-static int mark_uninteresting(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+static int mark_uninteresting(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flags UNUSED,
+ void *cb_data UNUSED)
{
struct commit *commit = lookup_commit_reference_gently(the_repository,
oid, 1);
@@ -715,8 +717,10 @@ struct commit_array {
int nr, alloc;
};
-static int add_ref(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+static int add_ref(const char *refname UNUSED,
+ const struct object_id *oid,
+ int flags UNUSED,
+ void *cb_data)
{
struct commit_array *ca = cb_data;
ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc);
diff --git a/shell.c b/shell.c
index 811e13b9c95..af0d7c734f8 100644
--- a/shell.c
+++ b/shell.c
@@ -47,42 +47,71 @@ static void cd_to_homedir(void)
die("could not chdir to user's home directory");
}
+#define MAX_INTERACTIVE_COMMAND (4*1024*1024)
+
static void run_shell(void)
{
int done = 0;
- static const char *help_argv[] = { HELP_COMMAND, NULL };
+ struct child_process help_cmd = CHILD_PROCESS_INIT;
if (!access(NOLOGIN_COMMAND, F_OK)) {
/* Interactive login disabled. */
- const char *argv[] = { NOLOGIN_COMMAND, NULL };
+ struct child_process nologin_cmd = CHILD_PROCESS_INIT;
int status;
- status = run_command_v_opt(argv, 0);
+ strvec_push(&nologin_cmd.args, NOLOGIN_COMMAND);
+ status = run_command(&nologin_cmd);
if (status < 0)
exit(127);
exit(status);
}
/* Print help if enabled */
- run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE);
+ help_cmd.silent_exec_failure = 1;
+ strvec_push(&help_cmd.args, HELP_COMMAND);
+ run_command(&help_cmd);
do {
- struct strbuf line = STRBUF_INIT;
const char *prog;
char *full_cmd;
char *rawargs;
+ size_t len;
char *split_args;
const char **argv;
int code;
int count;
fprintf(stderr, "git> ");
- if (git_read_line_interactively(&line) == EOF) {
+
+ /*
+ * Avoid using a strbuf or git_read_line_interactively() here.
+ * We don't want to allocate arbitrary amounts of memory on
+ * behalf of a possibly untrusted client, and we're subject to
+ * OS limits on command length anyway.
+ */
+ fflush(stdout);
+ rawargs = xmalloc(MAX_INTERACTIVE_COMMAND);
+ if (!fgets(rawargs, MAX_INTERACTIVE_COMMAND, stdin)) {
fprintf(stderr, "\n");
- strbuf_release(&line);
+ free(rawargs);
break;
}
- rawargs = strbuf_detach(&line, NULL);
+ len = strlen(rawargs);
+
+ /*
+ * If we truncated due to our input buffer size, reject the
+ * command. That's better than running bogus input, and
+ * there's a good chance it's just malicious garbage anyway.
+ */
+ if (len >= MAX_INTERACTIVE_COMMAND - 1)
+ die("invalid command format: input too long");
+
+ if (len > 0 && rawargs[len - 1] == '\n') {
+ if (--len > 0 && rawargs[len - 1] == '\r')
+ --len;
+ rawargs[len] = '\0';
+ }
+
split_args = xstrdup(rawargs);
count = split_cmdline(split_args, &argv);
if (count < 0) {
@@ -99,9 +128,13 @@ static void run_shell(void)
!strcmp(prog, "exit") || !strcmp(prog, "bye")) {
done = 1;
} else if (is_valid_cmd_name(prog)) {
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
full_cmd = make_cmd(prog);
argv[0] = full_cmd;
- code = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE);
+ cmd.silent_exec_failure = 1;
+ strvec_pushv(&cmd.args, argv);
+ code = run_command(&cmd);
if (code == -1 && errno == ENOENT) {
fprintf(stderr, "unrecognized command '%s'\n", prog);
}
diff --git a/shortlog.h b/shortlog.h
index 3f7e9aabcae..28d04f951af 100644
--- a/shortlog.h
+++ b/shortlog.h
@@ -2,6 +2,7 @@
#define SHORTLOG_H
#include "string-list.h"
+#include "date.h"
struct commit;
@@ -15,13 +16,16 @@ struct shortlog {
int in2;
int user_format;
int abbrev;
+ struct date_mode date_mode;
enum {
SHORTLOG_GROUP_AUTHOR = (1 << 0),
SHORTLOG_GROUP_COMMITTER = (1 << 1),
SHORTLOG_GROUP_TRAILER = (1 << 2),
+ SHORTLOG_GROUP_FORMAT = (1 << 3),
} groups;
struct string_list trailers;
+ struct string_list format;
int email;
struct string_list mailmap;
@@ -29,6 +33,7 @@ struct shortlog {
};
void shortlog_init(struct shortlog *log);
+void shortlog_finish_setup(struct shortlog *log);
void shortlog_add_commit(struct shortlog *log, struct commit *commit);
diff --git a/sparse-index.c b/sparse-index.c
index e4a54ce1943..8c269dab803 100644
--- a/sparse-index.c
+++ b/sparse-index.c
@@ -493,24 +493,42 @@ void clear_skip_worktree_from_present_files(struct index_state *istate)
int dir_found = 1;
int i;
+ int path_count[2] = {0, 0};
+ int restarted = 0;
if (!core_apply_sparse_checkout ||
sparse_expect_files_outside_of_patterns)
return;
+ trace2_region_enter("index", "clear_skip_worktree_from_present_files",
+ istate->repo);
restart:
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
- if (ce_skip_worktree(ce) &&
- path_found(ce->name, &last_dirname, &dir_len, &dir_found)) {
- if (S_ISSPARSEDIR(ce->ce_mode)) {
- ensure_full_index(istate);
- goto restart;
+ if (ce_skip_worktree(ce)) {
+ path_count[restarted]++;
+ if (path_found(ce->name, &last_dirname, &dir_len, &dir_found)) {
+ if (S_ISSPARSEDIR(ce->ce_mode)) {
+ if (restarted)
+ BUG("ensure-full-index did not fully flatten?");
+ ensure_full_index(istate);
+ restarted = 1;
+ goto restart;
+ }
+ ce->ce_flags &= ~CE_SKIP_WORKTREE;
}
- 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",
+ istate->repo);
}
/*
diff --git a/strbuf.c b/strbuf.c
index dd9eb85527a..0890b1405c5 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -436,7 +436,7 @@ void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn,
size_t strbuf_expand_literal_cb(struct strbuf *sb,
const char *placeholder,
- void *context)
+ void *context UNUSED)
{
int ch;
diff --git a/streaming.c b/streaming.c
index fe54665d86e..7b2f8b2b938 100644
--- a/streaming.c
+++ b/streaming.c
@@ -328,9 +328,9 @@ static int close_istream_pack_non_delta(struct git_istream *st)
}
static int open_istream_pack_non_delta(struct git_istream *st,
- struct repository *r,
- const struct object_id *oid,
- enum object_type *type)
+ struct repository *r UNUSED,
+ const struct object_id *oid UNUSED,
+ enum object_type *type UNUSED)
{
struct pack_window *window;
enum object_type in_pack_type;
diff --git a/string-list.c b/string-list.c
index 549fc416d68..42bacaec55b 100644
--- a/string-list.c
+++ b/string-list.c
@@ -156,7 +156,7 @@ void filter_string_list(struct string_list *list, int free_util,
list->nr = dst;
}
-static int item_is_not_empty(struct string_list_item *item, void *unused)
+static int item_is_not_empty(struct string_list_item *item, void *data UNUSED)
{
return *item->string != '\0';
}
diff --git a/string-list.h b/string-list.h
index d5a744e1438..c7b0d5d0008 100644
--- a/string-list.h
+++ b/string-list.h
@@ -141,7 +141,12 @@ void string_list_clear_func(struct string_list *list, string_list_clear_func_t c
int for_each_string_list(struct string_list *list,
string_list_each_func_t func, void *cb_data);
-/** Iterate over each item, as a macro. */
+/**
+ * Iterate over each item, as a macro.
+ *
+ * Be sure that 'list' is non-NULL. The macro cannot perform NULL
+ * checks due to -Werror=address errors.
+ */
#define for_each_string_list_item(item,list) \
for (item = (list)->items; \
item && item < (list)->items + (list)->nr; \
diff --git a/strmap.c b/strmap.c
index ee486357082..c7b9c52174c 100644
--- a/strmap.c
+++ b/strmap.c
@@ -2,10 +2,10 @@
#include "strmap.h"
#include "mem-pool.h"
-int cmp_strmap_entry(const void *hashmap_cmp_fn_data,
+int cmp_strmap_entry(const void *hashmap_cmp_fn_data UNUSED,
const struct hashmap_entry *entry1,
const struct hashmap_entry *entry2,
- const void *keydata)
+ const void *keydata UNUSED)
{
const struct strmap_entry *e1, *e2;
diff --git a/sub-process.c b/sub-process.c
index cae56ae6b80..6d4232294db 100644
--- a/sub-process.c
+++ b/sub-process.c
@@ -5,10 +5,10 @@
#include "sigchain.h"
#include "pkt-line.h"
-int cmd2process_cmp(const void *unused_cmp_data,
+int cmd2process_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct subprocess_entry *e1, *e2;
diff --git a/submodule-config.c b/submodule-config.c
index c2ac7e7bf39..4dc61b3a78a 100644
--- a/submodule-config.c
+++ b/submodule-config.c
@@ -38,10 +38,10 @@ enum lookup_type {
lookup_path
};
-static int config_path_cmp(const void *unused_cmp_data,
+static int config_path_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct submodule_entry *a, *b;
@@ -52,10 +52,10 @@ static int config_path_cmp(const void *unused_cmp_data,
!oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
}
-static int config_name_cmp(const void *unused_cmp_data,
+static int config_name_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct submodule_entry *a, *b;
@@ -303,6 +303,8 @@ int parse_submodule_fetchjobs(const char *var, const char *value)
int fetchjobs = git_config_int(var, value);
if (fetchjobs < 0)
die(_("negative values not allowed for submodule.fetchJobs"));
+ if (!fetchjobs)
+ fetchjobs = online_cpus();
return fetchjobs;
}
diff --git a/submodule.c b/submodule.c
index 3fa5db3ecdf..8fa2ad457b2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -213,7 +213,8 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
}
/* Cheap function that only determines if we're interested in submodules at all */
-int git_default_submodule_config(const char *var, const char *value, void *cb)
+int git_default_submodule_config(const char *var, const char *value,
+ void *cb UNUSED)
{
if (!strcmp(var, "submodule.recurse")) {
int v = git_config_bool(var, value) ?
@@ -415,10 +416,9 @@ int parse_submodule_update_strategy(const char *value,
return 0;
}
-const char *submodule_strategy_to_string(const struct submodule_update_strategy *s)
+const char *submodule_update_type_to_string(enum submodule_update_type type)
{
- struct strbuf sb = STRBUF_INIT;
- switch (s->type) {
+ switch (type) {
case SM_UPDATE_CHECKOUT:
return "checkout";
case SM_UPDATE_MERGE:
@@ -428,12 +428,11 @@ const char *submodule_strategy_to_string(const struct submodule_update_strategy
case SM_UPDATE_NONE:
return "none";
case SM_UPDATE_UNSPECIFIED:
- return NULL;
case SM_UPDATE_COMMAND:
- strbuf_addf(&sb, "!%s", s->command);
- return strbuf_detach(&sb, NULL);
+ BUG("init_submodule() should handle type %d", type);
+ default:
+ BUG("unexpected update strategy type: %d", type);
}
- return NULL;
}
void handle_ignore_submodules_arg(struct diff_options *diffopt,
@@ -940,8 +939,9 @@ static void free_submodules_data(struct string_list *submodules)
string_list_clear(submodules, 1);
}
-static int has_remote(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+static int has_remote(const char *refname UNUSED,
+ const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data UNUSED)
{
return 1;
}
@@ -1243,8 +1243,9 @@ int push_unpushed_submodules(struct repository *r,
return ret;
}
-static int append_oid_to_array(const char *ref, const struct object_id *oid,
- int flags, void *data)
+static int append_oid_to_array(const char *ref UNUSED,
+ const struct object_id *oid,
+ int flags UNUSED, void *data)
{
struct oid_array *array = data;
oid_array_append(array, oid);
@@ -1818,6 +1819,17 @@ int fetch_submodules(struct repository *r,
{
int i;
struct submodule_parallel_fetch spf = SPF_INIT;
+ const struct run_process_parallel_opts opts = {
+ .tr2_category = "submodule",
+ .tr2_label = "parallel/fetch",
+
+ .processes = max_parallel_jobs,
+
+ .get_next_task = get_next_submodule,
+ .start_failure = fetch_start_failure,
+ .task_finished = fetch_finish,
+ .data = &spf,
+ };
spf.r = r;
spf.command_line_option = command_line_option;
@@ -1839,12 +1851,7 @@ int fetch_submodules(struct repository *r,
calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
string_list_sort(&spf.changed_submodule_names);
- run_processes_parallel_tr2(max_parallel_jobs,
- get_next_submodule,
- fetch_start_failure,
- fetch_finish,
- &spf,
- "submodule", "parallel/fetch");
+ run_processes_parallel(&opts);
if (spf.submodules_with_errors.len > 0)
fprintf(stderr, _("Errors during submodule fetch:\n%s"),
@@ -2132,8 +2139,7 @@ int submodule_move_head(const char *path,
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
if (old_head) {
if (!submodule_uses_gitfile(path))
- absorb_git_dir_into_superproject(path,
- ABSORB_GITDIR_RECURSE_SUBMODULES);
+ absorb_git_dir_into_superproject(path);
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2303,13 +2309,29 @@ static void relocate_single_git_dir_into_superproject(const char *path)
strbuf_release(&new_gitdir);
}
+static void absorb_git_dir_into_superproject_recurse(const char *path)
+{
+
+ struct child_process cp = CHILD_PROCESS_INIT;
+
+ cp.dir = path;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/",
+ get_super_prefix_or_empty(), path);
+ strvec_pushl(&cp.args, "submodule--helper",
+ "absorbgitdirs", NULL);
+ prepare_submodule_repo_env(&cp.env);
+ if (run_command(&cp))
+ die(_("could not recurse into submodule '%s'"), path);
+}
+
/*
* Migrate the git directory of the submodule given by path from
* having its git directory within the working tree to the git dir nested
* in its superprojects git dir under modules/.
*/
-void absorb_git_dir_into_superproject(const char *path,
- unsigned flags)
+void absorb_git_dir_into_superproject(const char *path)
{
int err_code;
const char *sub_git_dir;
@@ -2358,29 +2380,7 @@ void absorb_git_dir_into_superproject(const char *path,
}
strbuf_release(&gitdir);
- if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) {
- struct child_process cp = CHILD_PROCESS_INIT;
- struct strbuf sb = STRBUF_INIT;
-
- if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES)
- BUG("we don't know how to pass the flags down?");
-
- strbuf_addstr(&sb, get_super_prefix_or_empty());
- strbuf_addstr(&sb, path);
- strbuf_addch(&sb, '/');
-
- cp.dir = path;
- cp.git_cmd = 1;
- cp.no_stdin = 1;
- strvec_pushl(&cp.args, "--super-prefix", sb.buf,
- "submodule--helper",
- "absorbgitdirs", NULL);
- prepare_submodule_repo_env(&cp.env);
- if (run_command(&cp))
- die(_("could not recurse into submodule '%s'"), path);
-
- strbuf_release(&sb);
- }
+ absorb_git_dir_into_superproject_recurse(path);
}
int get_superproject_working_tree(struct strbuf *buf)
diff --git a/submodule.h b/submodule.h
index bfaa9da1868..b52a4ff1e73 100644
--- a/submodule.h
+++ b/submodule.h
@@ -72,7 +72,7 @@ void die_path_inside_submodule(struct index_state *istate,
enum submodule_update_type parse_submodule_update_type(const char *value);
int parse_submodule_update_strategy(const char *value,
struct submodule_update_strategy *dst);
-const char *submodule_strategy_to_string(const struct submodule_update_strategy *s);
+const char *submodule_update_type_to_string(enum submodule_update_type type);
void handle_ignore_submodules_arg(struct diff_options *, const char *);
void show_submodule_diff_summary(struct diff_options *o, const char *path,
struct object_id *one, struct object_id *two,
@@ -164,9 +164,7 @@ void submodule_unset_core_worktree(const struct submodule *sub);
*/
void prepare_submodule_repo_env(struct strvec *env);
-#define ABSORB_GITDIR_RECURSE_SUBMODULES (1<<0)
-void absorb_git_dir_into_superproject(const char *path,
- unsigned flags);
+void absorb_git_dir_into_superproject(const char *path);
/*
* Return the absolute path of the working tree of the superproject, which this
diff --git a/t/Makefile b/t/Makefile
index 1c80c0c79a0..882782a519c 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -36,14 +36,21 @@ CHAINLINTTMP_SQ = $(subst ','\'',$(CHAINLINTTMP))
T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))
+TLIBS = $(sort $(wildcard lib-*.sh)) annotate-tests.sh
TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
+TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
-CHAINLINT = sed -f chainlint.sed
+CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
+
+# `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`)
+# checks all tests in all scripts via a single invocation, so tell individual
+# scripts not to "chainlint" themselves
+CHAINLINTSUPPRESS = GIT_TEST_CHAIN_LINT=0 && export GIT_TEST_CHAIN_LINT &&
all: $(DEFAULT_TEST_TARGET)
test: pre-clean check-chainlint $(TEST_LINT)
- $(MAKE) aggregate-results-and-cleanup
+ $(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup
failed:
@failed=$$(cd '$(TEST_RESULTS_DIRECTORY_SQ)' && \
@@ -52,7 +59,7 @@ failed:
test -z "$$failed" || $(MAKE) $$failed
prove: pre-clean check-chainlint $(TEST_LINT)
- @echo "*** prove ***"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
+ @echo "*** prove ***"; $(CHAINLINTSUPPRESS) $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
$(MAKE) clean-except-prove-cache
$(T):
@@ -66,6 +73,7 @@ clean-except-prove-cache: clean-chainlint
$(RM) -r valgrind/bin
clean: clean-except-prove-cache
+ $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
$(RM) .prove
clean-chainlint:
@@ -73,13 +81,35 @@ clean-chainlint:
check-chainlint:
@mkdir -p '$(CHAINLINTTMP_SQ)' && \
- sed -e '/^# LINT: /d' $(patsubst %,chainlint/%.test,$(CHAINLINTTESTS)) >'$(CHAINLINTTMP_SQ)'/tests && \
- sed -e '/^[ ]*$$/d' $(patsubst %,chainlint/%.expect,$(CHAINLINTTESTS)) >'$(CHAINLINTTMP_SQ)'/expect && \
- $(CHAINLINT) '$(CHAINLINTTMP_SQ)'/tests | grep -v '^[ ]*$$' >'$(CHAINLINTTMP_SQ)'/actual && \
- diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual
+ 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" && \
+ sed -e '/^[ ]*$$/d' chainlint/$$i.expect; \
+ done \
+ } >'$(CHAINLINTTMP_SQ)'/expect && \
+ $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests | \
+ grep -v '^[ ]*$$' >'$(CHAINLINTTMP_SQ)'/actual && \
+ if test -f ../GIT-BUILD-OPTIONS; then \
+ . ../GIT-BUILD-OPTIONS; \
+ fi && \
+ if test -x ../git$$X; then \
+ DIFFW="../git$$X --no-pager diff -w --no-index"; \
+ else \
+ DIFFW="diff -w -u"; \
+ fi && \
+ $$DIFFW '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual
test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \
test-lint-filenames
+ifneq ($(GIT_TEST_CHAIN_LINT),0)
+test-lint: test-chainlint
+endif
test-lint-duplicates:
@dups=`echo $(T) $(TPERF) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
@@ -102,6 +132,9 @@ test-lint-filenames:
test -z "$$bad" || { \
echo >&2 "non-portable file name(s): $$bad"; exit 1; }
+test-chainlint:
+ @$(CHAINLINT) $(T) $(TLIBS) $(TPERF) $(TINTEROP)
+
aggregate-results-and-cleanup: $(T)
$(MAKE) aggregate-results
$(MAKE) clean
@@ -117,4 +150,5 @@ valgrind:
perf:
$(MAKE) -C perf/ all
-.PHONY: pre-clean $(T) aggregate-results clean valgrind perf check-chainlint clean-chainlint
+.PHONY: pre-clean $(T) aggregate-results clean valgrind perf \
+ check-chainlint clean-chainlint test-chainlint
diff --git a/t/README b/t/README
index 2f439f96589..fc0daef2e41 100644
--- a/t/README
+++ b/t/README
@@ -196,11 +196,6 @@ appropriately before running "make". Short options can be bundled, i.e.
this feature by setting the GIT_TEST_CHAIN_LINT environment
variable to "1" or "0", respectively.
- A few test scripts disable some of the more advanced
- chain-linting detection in the name of efficiency. You can
- override this by setting the GIT_TEST_CHAIN_LINT_HARDER
- environment variable to "1".
-
--stress::
Run the test script repeatedly in multiple parallel jobs until
one of them fails. Useful for reproducing rare failures in
@@ -236,6 +231,9 @@ override the location of the dashed-form subcommands (what
GIT_EXEC_PATH would be used for during normal operation).
GIT_TEST_EXEC_PATH defaults to `$GIT_TEST_INSTALLED/git --exec-path`.
+Similar to GIT_TEST_INSTALLED, GIT_TEST_BUILD_DIR can be pointed to
+another git.git checkout's build directory, to test its built binaries
+against the tests in this checkout.
Skipping Tests
--------------
diff --git a/t/chainlint.pl b/t/chainlint.pl
new file mode 100755
index 00000000000..976db4b8a01
--- /dev/null
+++ b/t/chainlint.pl
@@ -0,0 +1,770 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2021-2022 Eric Sunshine <sunshine@sunshineco.com>
+#
+# This tool scans shell scripts for test definitions and checks those tests for
+# problems, such as broken &&-chains, which might hide bugs in the tests
+# themselves or in behaviors being exercised by the tests.
+#
+# Input arguments are pathnames of shell scripts containing test definitions,
+# or globs referencing a collection of scripts. For each problem discovered,
+# the pathname of the script containing the test is printed along with the test
+# name and the test body with a `?!FOO?!` annotation at the location of each
+# detected problem, where "FOO" is a tag such as "AMP" which indicates a broken
+# &&-chain. Returns zero if no problems are discovered, otherwise non-zero.
+
+use warnings;
+use strict;
+use Config;
+use File::Glob;
+use Getopt::Long;
+
+my $jobs = -1;
+my $show_stats;
+my $emit_all;
+
+# Lexer tokenizes POSIX shell scripts. It is roughly modeled after section 2.3
+# "Token Recognition" of POSIX chapter 2 "Shell Command Language". Although
+# similar to lexical analyzers for other languages, this one differs in a few
+# substantial ways due to quirks of the shell command language.
+#
+# For instance, in many languages, newline is just whitespace like space or
+# TAB, but in shell a newline is a command separator, thus a distinct lexical
+# token. A newline is significant and returned as a distinct token even at the
+# end of a shell comment.
+#
+# In other languages, `1+2` would typically be scanned as three tokens
+# (`1`, `+`, and `2`), but in shell it is a single token. However, the similar
+# `1 + 2`, which embeds whitepace, is scanned as three token in shell, as well.
+# In shell, several characters with special meaning lose that meaning when not
+# surrounded by whitespace. For instance, the negation operator `!` is special
+# when standing alone surrounded by whitespace; whereas in `foo!uucp` it is
+# just a plain character in the longer token "foo!uucp". In many other
+# languages, `"string"/foo:'string'` might be scanned as five tokens ("string",
+# `/`, `foo`, `:`, and 'string'), but in shell, it is just a single token.
+#
+# The lexical analyzer for the shell command language is also somewhat unusual
+# in that it recursively invokes the parser to handle the body of `$(...)`
+# expressions which can contain arbitrary shell code. Such expressions may be
+# encountered both inside and outside of double-quoted strings.
+#
+# The lexical analyzer is responsible for consuming shell here-doc bodies which
+# extend from the line following a `<<TAG` operator until a line consisting
+# solely of `TAG`. Here-doc consumption begins when a newline is encountered.
+# It is legal for multiple here-doc `<<TAG` operators to be present on a single
+# line, in which case their bodies must be present one following the next, and
+# are consumed in the (left-to-right) order the `<<TAG` operators appear on the
+# line. A special complication is that the bodies of all here-docs must be
+# consumed when the newline is encountered even if the parse context depth has
+# changed. For instance, in `cat <<A && x=$(cat <<B &&\n`, bodies of here-docs
+# "A" and "B" must be consumed even though "A" was introduced outside the
+# recursive parse context in which "B" was introduced and in which the newline
+# is encountered.
+package Lexer;
+
+sub new {
+ my ($class, $parser, $s) = @_;
+ bless {
+ parser => $parser,
+ buff => $s,
+ heretags => []
+ } => $class;
+}
+
+sub scan_heredoc_tag {
+ my $self = shift @_;
+ ${$self->{buff}} =~ /\G(-?)/gc;
+ my $indented = $1;
+ my $tag = $self->scan_token();
+ $tag =~ s/['"\\]//g;
+ push(@{$self->{heretags}}, $indented ? "\t$tag" : "$tag");
+ return "<<$indented$tag";
+}
+
+sub scan_op {
+ my ($self, $c) = @_;
+ my $b = $self->{buff};
+ return $c unless $$b =~ /\G(.)/sgc;
+ my $cc = $c . $1;
+ return scan_heredoc_tag($self) if $cc eq '<<';
+ return $cc if $cc =~ /^(?:&&|\|\||>>|;;|<&|>&|<>|>\|)$/;
+ pos($$b)--;
+ return $c;
+}
+
+sub scan_sqstring {
+ my $self = shift @_;
+ ${$self->{buff}} =~ /\G([^']*'|.*\z)/sgc;
+ return "'" . $1;
+}
+
+sub scan_dqstring {
+ my $self = shift @_;
+ my $b = $self->{buff};
+ my $s = '"';
+ while (1) {
+ # slurp up non-special characters
+ $s .= $1 if $$b =~ /\G([^"\$\\]+)/gc;
+ # handle special characters
+ last unless $$b =~ /\G(.)/sgc;
+ my $c = $1;
+ $s .= '"', last if $c eq '"';
+ $s .= '$' . $self->scan_dollar(), next if $c eq '$';
+ if ($c eq '\\') {
+ $s .= '\\', last unless $$b =~ /\G(.)/sgc;
+ $c = $1;
+ next if $c eq "\n"; # line splice
+ # backslash escapes only $, `, ", \ in dq-string
+ $s .= '\\' unless $c =~ /^[\$`"\\]$/;
+ $s .= $c;
+ next;
+ }
+ die("internal error scanning dq-string '$c'\n");
+ }
+ return $s;
+}
+
+sub scan_balanced {
+ my ($self, $c1, $c2) = @_;
+ my $b = $self->{buff};
+ my $depth = 1;
+ my $s = $c1;
+ while ($$b =~ /\G([^\Q$c1$c2\E]*(?:[\Q$c1$c2\E]|\z))/gc) {
+ $s .= $1;
+ $depth++, next if $s =~ /\Q$c1\E$/;
+ $depth--;
+ last if $depth == 0;
+ }
+ return $s;
+}
+
+sub scan_subst {
+ my $self = shift @_;
+ my @tokens = $self->{parser}->parse(qr/^\)$/);
+ $self->{parser}->next_token(); # closing ")"
+ return @tokens;
+}
+
+sub scan_dollar {
+ my $self = shift @_;
+ my $b = $self->{buff};
+ return $self->scan_balanced('(', ')') if $$b =~ /\G\((?=\()/gc; # $((...))
+ return '(' . join(' ', $self->scan_subst()) . ')' if $$b =~ /\G\(/gc; # $(...)
+ return $self->scan_balanced('{', '}') if $$b =~ /\G\{/gc; # ${...}
+ return $1 if $$b =~ /\G(\w+)/gc; # $var
+ return $1 if $$b =~ /\G([@*#?$!0-9-])/gc; # $*, $1, $$, etc.
+ return '';
+}
+
+sub swallow_heredocs {
+ my $self = shift @_;
+ my $b = $self->{buff};
+ my $tags = $self->{heretags};
+ while (my $tag = shift @$tags) {
+ my $indent = $tag =~ s/^\t// ? '\\s*' : '';
+ $$b =~ /(?:\G|\n)$indent\Q$tag\E(?:\n|\z)/gc;
+ }
+}
+
+sub scan_token {
+ my $self = shift @_;
+ my $b = $self->{buff};
+ my $token = '';
+RESTART:
+ $$b =~ /\G[ \t]+/gc; # skip whitespace (but not newline)
+ return "\n" if $$b =~ /\G#[^\n]*(?:\n|\z)/gc; # comment
+ while (1) {
+ # slurp up non-special characters
+ $token .= $1 if $$b =~ /\G([^\\;&|<>(){}'"\$\s]+)/gc;
+ # handle special characters
+ last unless $$b =~ /\G(.)/sgc;
+ my $c = $1;
+ last if $c =~ /^[ \t]$/; # whitespace ends token
+ pos($$b)--, last if length($token) && $c =~ /^[;&|<>(){}\n]$/;
+ $token .= $self->scan_sqstring(), next if $c eq "'";
+ $token .= $self->scan_dqstring(), next if $c eq '"';
+ $token .= $c . $self->scan_dollar(), next if $c eq '$';
+ $self->swallow_heredocs(), $token = $c, last if $c eq "\n";
+ $token = $self->scan_op($c), last if $c =~ /^[;&|<>]$/;
+ $token = $c, last if $c =~ /^[(){}]$/;
+ if ($c eq '\\') {
+ $token .= '\\', last unless $$b =~ /\G(.)/sgc;
+ $c = $1;
+ next if $c eq "\n" && length($token); # line splice
+ goto RESTART if $c eq "\n"; # line splice
+ $token .= '\\' . $c;
+ next;
+ }
+ die("internal error scanning character '$c'\n");
+ }
+ return length($token) ? $token : undef;
+}
+
+# ShellParser parses POSIX shell scripts (with minor extensions for Bash). It
+# is a recursive descent parser very roughly modeled after section 2.10 "Shell
+# Grammar" of POSIX chapter 2 "Shell Command Language".
+package ShellParser;
+
+sub new {
+ my ($class, $s) = @_;
+ my $self = bless {
+ buff => [],
+ stop => [],
+ output => []
+ } => $class;
+ $self->{lexer} = Lexer->new($self, $s);
+ return $self;
+}
+
+sub next_token {
+ my $self = shift @_;
+ return pop(@{$self->{buff}}) if @{$self->{buff}};
+ return $self->{lexer}->scan_token();
+}
+
+sub untoken {
+ my $self = shift @_;
+ push(@{$self->{buff}}, @_);
+}
+
+sub peek {
+ my $self = shift @_;
+ my $token = $self->next_token();
+ return undef unless defined($token);
+ $self->untoken($token);
+ return $token;
+}
+
+sub stop_at {
+ my ($self, $token) = @_;
+ return 1 unless defined($token);
+ my $stop = ${$self->{stop}}[-1] if @{$self->{stop}};
+ return defined($stop) && $token =~ $stop;
+}
+
+sub expect {
+ my ($self, $expect) = @_;
+ my $token = $self->next_token();
+ return $token if defined($token) && $token eq $expect;
+ push(@{$self->{output}}, "?!ERR?! expected '$expect' but found '" . (defined($token) ? $token : "<end-of-input>") . "'\n");
+ $self->untoken($token) if defined($token);
+ return ();
+}
+
+sub optional_newlines {
+ my $self = shift @_;
+ my @tokens;
+ while (my $token = $self->peek()) {
+ last unless $token eq "\n";
+ push(@tokens, $self->next_token());
+ }
+ return @tokens;
+}
+
+sub parse_group {
+ my $self = shift @_;
+ return ($self->parse(qr/^}$/),
+ $self->expect('}'));
+}
+
+sub parse_subshell {
+ my $self = shift @_;
+ return ($self->parse(qr/^\)$/),
+ $self->expect(')'));
+}
+
+sub parse_case_pattern {
+ my $self = shift @_;
+ my @tokens;
+ while (defined(my $token = $self->next_token())) {
+ push(@tokens, $token);
+ last if $token eq ')';
+ }
+ return @tokens;
+}
+
+sub parse_case {
+ my $self = shift @_;
+ my @tokens;
+ push(@tokens,
+ $self->next_token(), # subject
+ $self->optional_newlines(),
+ $self->expect('in'),
+ $self->optional_newlines());
+ while (1) {
+ my $token = $self->peek();
+ last unless defined($token) && $token ne 'esac';
+ push(@tokens,
+ $self->parse_case_pattern(),
+ $self->optional_newlines(),
+ $self->parse(qr/^(?:;;|esac)$/)); # item body
+ $token = $self->peek();
+ last unless defined($token) && $token ne 'esac';
+ push(@tokens,
+ $self->expect(';;'),
+ $self->optional_newlines());
+ }
+ push(@tokens, $self->expect('esac'));
+ return @tokens;
+}
+
+sub parse_for {
+ my $self = shift @_;
+ my @tokens;
+ push(@tokens,
+ $self->next_token(), # variable
+ $self->optional_newlines());
+ my $token = $self->peek();
+ if (defined($token) && $token eq 'in') {
+ push(@tokens,
+ $self->expect('in'),
+ $self->optional_newlines());
+ }
+ push(@tokens,
+ $self->parse(qr/^do$/), # items
+ $self->expect('do'),
+ $self->optional_newlines(),
+ $self->parse_loop_body(),
+ $self->expect('done'));
+ return @tokens;
+}
+
+sub parse_if {
+ my $self = shift @_;
+ my @tokens;
+ while (1) {
+ push(@tokens,
+ $self->parse(qr/^then$/), # if/elif condition
+ $self->expect('then'),
+ $self->optional_newlines(),
+ $self->parse(qr/^(?:elif|else|fi)$/)); # if/elif body
+ my $token = $self->peek();
+ last unless defined($token) && $token eq 'elif';
+ push(@tokens, $self->expect('elif'));
+ }
+ my $token = $self->peek();
+ if (defined($token) && $token eq 'else') {
+ push(@tokens,
+ $self->expect('else'),
+ $self->optional_newlines(),
+ $self->parse(qr/^fi$/)); # else body
+ }
+ push(@tokens, $self->expect('fi'));
+ return @tokens;
+}
+
+sub parse_loop_body {
+ my $self = shift @_;
+ return $self->parse(qr/^done$/);
+}
+
+sub parse_loop {
+ my $self = shift @_;
+ return ($self->parse(qr/^do$/), # condition
+ $self->expect('do'),
+ $self->optional_newlines(),
+ $self->parse_loop_body(),
+ $self->expect('done'));
+}
+
+sub parse_func {
+ my $self = shift @_;
+ return ($self->expect('('),
+ $self->expect(')'),
+ $self->optional_newlines(),
+ $self->parse_cmd()); # body
+}
+
+sub parse_bash_array_assignment {
+ my $self = shift @_;
+ my @tokens = $self->expect('(');
+ while (defined(my $token = $self->next_token())) {
+ push(@tokens, $token);
+ last if $token eq ')';
+ }
+ return @tokens;
+}
+
+my %compound = (
+ '{' => \&parse_group,
+ '(' => \&parse_subshell,
+ 'case' => \&parse_case,
+ 'for' => \&parse_for,
+ 'if' => \&parse_if,
+ 'until' => \&parse_loop,
+ 'while' => \&parse_loop);
+
+sub parse_cmd {
+ my $self = shift @_;
+ my $cmd = $self->next_token();
+ return () unless defined($cmd);
+ return $cmd if $cmd eq "\n";
+
+ my $token;
+ my @tokens = $cmd;
+ if ($cmd eq '!') {
+ push(@tokens, $self->parse_cmd());
+ return @tokens;
+ } elsif (my $f = $compound{$cmd}) {
+ push(@tokens, $self->$f());
+ } elsif (defined($token = $self->peek()) && $token eq '(') {
+ if ($cmd !~ /\w=$/) {
+ push(@tokens, $self->parse_func());
+ return @tokens;
+ }
+ $tokens[-1] .= join(' ', $self->parse_bash_array_assignment());
+ }
+
+ while (defined(my $token = $self->next_token())) {
+ $self->untoken($token), last if $self->stop_at($token);
+ push(@tokens, $token);
+ last if $token =~ /^(?:[;&\n|]|&&|\|\|)$/;
+ }
+ push(@tokens, $self->next_token()) if $tokens[-1] ne "\n" && defined($token = $self->peek()) && $token eq "\n";
+ return @tokens;
+}
+
+sub accumulate {
+ my ($self, $tokens, $cmd) = @_;
+ push(@$tokens, @$cmd);
+}
+
+sub parse {
+ my ($self, $stop) = @_;
+ push(@{$self->{stop}}, $stop);
+ goto DONE if $self->stop_at($self->peek());
+ my @tokens;
+ while (my @cmd = $self->parse_cmd()) {
+ $self->accumulate(\@tokens, \@cmd);
+ last if $self->stop_at($self->peek());
+ }
+DONE:
+ pop(@{$self->{stop}});
+ return @tokens;
+}
+
+# TestParser is a subclass of ShellParser which, beyond parsing shell script
+# code, is also imbued with semantic knowledge of test construction, and checks
+# tests for common problems (such as broken &&-chains) which might hide bugs in
+# the tests themselves or in behaviors being exercised by the tests. As such,
+# TestParser is only called upon to parse test bodies, not the top-level
+# scripts in which the tests are defined.
+package TestParser;
+
+use base 'ShellParser';
+
+sub find_non_nl {
+ my $tokens = shift @_;
+ my $n = shift @_;
+ $n = $#$tokens if !defined($n);
+ $n-- while $n >= 0 && $$tokens[$n] eq "\n";
+ return $n;
+}
+
+sub ends_with {
+ my ($tokens, $needles) = @_;
+ my $n = find_non_nl($tokens);
+ for my $needle (reverse(@$needles)) {
+ return undef if $n < 0;
+ $n = find_non_nl($tokens, $n), next if $needle eq "\n";
+ return undef if $$tokens[$n] !~ $needle;
+ $n--;
+ }
+ return 1;
+}
+
+sub match_ending {
+ my ($tokens, $endings) = @_;
+ for my $needles (@$endings) {
+ next if @$tokens < scalar(grep {$_ ne "\n"} @$needles);
+ return 1 if ends_with($tokens, $needles);
+ }
+ return undef;
+}
+
+sub parse_loop_body {
+ my $self = shift @_;
+ my @tokens = $self->SUPER::parse_loop_body(@_);
+ # did loop signal failure via "|| return" or "|| exit"?
+ return @tokens if !@tokens || grep(/^(?:return|exit|\$\?)$/, @tokens);
+ # did loop upstream of a pipe signal failure via "|| echo 'impossible
+ # text'" as the final command in the loop body?
+ return @tokens if ends_with(\@tokens, [qr/^\|\|$/, "\n", qr/^echo$/, qr/^.+$/]);
+ # flag missing "return/exit" handling explicit failure in loop body
+ my $n = find_non_nl(\@tokens);
+ splice(@tokens, $n + 1, 0, '?!LOOP?!');
+ return @tokens;
+}
+
+my @safe_endings = (
+ [qr/^(?:&&|\|\||\||&)$/],
+ [qr/^(?:exit|return)$/, qr/^(?:\d+|\$\?)$/],
+ [qr/^(?:exit|return)$/, qr/^(?:\d+|\$\?)$/, qr/^;$/],
+ [qr/^(?:exit|return|continue)$/],
+ [qr/^(?:exit|return|continue)$/, qr/^;$/]);
+
+sub accumulate {
+ my ($self, $tokens, $cmd) = @_;
+ goto DONE unless @$tokens;
+ goto DONE if @$cmd == 1 && $$cmd[0] eq "\n";
+
+ # did previous command end with "&&", "|", "|| return" or similar?
+ goto DONE if match_ending($tokens, \@safe_endings);
+
+ # if this command handles "$?" specially, then okay for previous
+ # command to be missing "&&"
+ for my $token (@$cmd) {
+ goto DONE if $token =~ /\$\?/;
+ }
+
+ # if this command is "false", "return 1", or "exit 1" (which signal
+ # failure explicitly), then okay for all preceding commands to be
+ # missing "&&"
+ if ($$cmd[0] =~ /^(?:false|return|exit)$/) {
+ @$tokens = grep(!/^\?!AMP\?!$/, @$tokens);
+ goto DONE;
+ }
+
+ # flag missing "&&" at end of previous command
+ my $n = find_non_nl($tokens);
+ splice(@$tokens, $n + 1, 0, '?!AMP?!') unless $n < 0;
+
+DONE:
+ $self->SUPER::accumulate($tokens, $cmd);
+}
+
+# ScriptParser is a subclass of ShellParser which identifies individual test
+# definitions within test scripts, and passes each test body through TestParser
+# to identify possible problems. ShellParser detects test definitions not only
+# at the top-level of test scripts but also within compound commands such as
+# loops and function definitions.
+package ScriptParser;
+
+use base 'ShellParser';
+
+sub new {
+ my $class = shift @_;
+ my $self = $class->SUPER::new(@_);
+ $self->{ntests} = 0;
+ return $self;
+}
+
+# extract the raw content of a token, which may be a single string or a
+# composition of multiple strings and non-string character runs; for instance,
+# `"test body"` unwraps to `test body`; `word"a b"42'c d'` to `worda b42c d`
+sub unwrap {
+ my $token = @_ ? shift @_ : $_;
+ # simple case: 'sqstring' or "dqstring"
+ return $token if $token =~ s/^'([^']*)'$/$1/;
+ return $token if $token =~ s/^"([^"]*)"$/$1/;
+
+ # composite case
+ my ($s, $q, $escaped);
+ while (1) {
+ # slurp up non-special characters
+ $s .= $1 if $token =~ /\G([^\\'"]*)/gc;
+ # handle special characters
+ last unless $token =~ /\G(.)/sgc;
+ my $c = $1;
+ $q = undef, next if defined($q) && $c eq $q;
+ $q = $c, next if !defined($q) && $c =~ /^['"]$/;
+ if ($c eq '\\') {
+ last unless $token =~ /\G(.)/sgc;
+ $c = $1;
+ $s .= '\\' if $c eq "\n"; # preserve line splice
+ }
+ $s .= $c;
+ }
+ return $s
+}
+
+sub check_test {
+ my $self = shift @_;
+ my ($title, $body) = map(unwrap, @_);
+ $self->{ntests}++;
+ my $parser = TestParser->new(\$body);
+ my @tokens = $parser->parse();
+ return unless $emit_all || grep(/\?![^?]+\?!/, @tokens);
+ my $c = main::fd_colors(1);
+ my $checked = join(' ', @tokens);
+ $checked =~ s/^\n//;
+ $checked =~ s/^ //mg;
+ $checked =~ s/ $//mg;
+ $checked =~ s/(\?![^?]+\?!)/$c->{rev}$c->{red}$1$c->{reset}/mg;
+ $checked .= "\n" unless $checked =~ /\n$/;
+ push(@{$self->{output}}, "$c->{blue}# chainlint: $title$c->{reset}\n$checked");
+}
+
+sub parse_cmd {
+ my $self = shift @_;
+ my @tokens = $self->SUPER::parse_cmd();
+ return @tokens unless @tokens && $tokens[0] =~ /^test_expect_(?:success|failure)$/;
+ my $n = $#tokens;
+ $n-- while $n >= 0 && $tokens[$n] =~ /^(?:[;&\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
+ return @tokens;
+}
+
+# main contains high-level functionality for processing command-line switches,
+# feeding input test scripts to ScriptParser, and reporting results.
+package main;
+
+my $getnow = sub { return time(); };
+my $interval = sub { return time() - shift; };
+if (eval {require Time::HiRes; Time::HiRes->import(); 1;}) {
+ $getnow = sub { return [Time::HiRes::gettimeofday()]; };
+ $interval = sub { return Time::HiRes::tv_interval(shift); };
+}
+
+# Restore TERM if test framework set it to "dumb" so 'tput' will work; do this
+# outside of get_colors() since under 'ithreads' all threads use %ENV of main
+# thread and ignore %ENV changes in subthreads.
+$ENV{TERM} = $ENV{USER_TERM} if $ENV{USER_TERM};
+
+my @NOCOLORS = (bold => '', rev => '', reset => '', blue => '', green => '', red => '');
+my %COLORS = ();
+sub get_colors {
+ return \%COLORS if %COLORS;
+ if (exists($ENV{NO_COLOR}) ||
+ system("tput sgr0 >/dev/null 2>&1") != 0 ||
+ system("tput bold >/dev/null 2>&1") != 0 ||
+ system("tput rev >/dev/null 2>&1") != 0 ||
+ system("tput setaf 1 >/dev/null 2>&1") != 0) {
+ %COLORS = @NOCOLORS;
+ return \%COLORS;
+ }
+ %COLORS = (bold => `tput bold`,
+ rev => `tput rev`,
+ reset => `tput sgr0`,
+ blue => `tput setaf 4`,
+ green => `tput setaf 2`,
+ red => `tput setaf 1`);
+ chomp(%COLORS);
+ return \%COLORS;
+}
+
+my %FD_COLORS = ();
+sub fd_colors {
+ my $fd = shift;
+ return $FD_COLORS{$fd} if exists($FD_COLORS{$fd});
+ $FD_COLORS{$fd} = -t $fd ? get_colors() : {@NOCOLORS};
+ return $FD_COLORS{$fd};
+}
+
+sub ncores {
+ # Windows
+ return $ENV{NUMBER_OF_PROCESSORS} if exists($ENV{NUMBER_OF_PROCESSORS});
+ # Linux / MSYS2 / Cygwin / WSL
+ do { local @ARGV='/proc/cpuinfo'; return scalar(grep(/^processor\s*:/, <>)); } if -r '/proc/cpuinfo';
+ # macOS & BSD
+ return qx/sysctl -n hw.ncpu/ if $^O =~ /(?:^darwin$|bsd)/;
+ return 1;
+}
+
+sub show_stats {
+ my ($start_time, $stats) = @_;
+ my $walltime = $interval->($start_time);
+ my ($usertime) = times();
+ my ($total_workers, $total_scripts, $total_tests, $total_errs) = (0, 0, 0, 0);
+ my $c = fd_colors(2);
+ print(STDERR $c->{green});
+ for (@$stats) {
+ my ($worker, $nscripts, $ntests, $nerrs) = @$_;
+ print(STDERR "worker $worker: $nscripts scripts, $ntests tests, $nerrs errors\n");
+ $total_workers++;
+ $total_scripts += $nscripts;
+ $total_tests += $ntests;
+ $total_errs += $nerrs;
+ }
+ printf(STDERR "total: %d workers, %d scripts, %d tests, %d errors, %.2fs/%.2fs (wall/user)$c->{reset}\n", $total_workers, $total_scripts, $total_tests, $total_errs, $walltime, $usertime);
+}
+
+sub check_script {
+ my ($id, $next_script, $emit) = @_;
+ my ($nscripts, $ntests, $nerrs) = (0, 0, 0);
+ while (my $path = $next_script->()) {
+ $nscripts++;
+ my $fh;
+ unless (open($fh, "<", $path)) {
+ $emit->("?!ERR?! $path: $!\n");
+ next;
+ }
+ my $s = do { local $/; <$fh> };
+ close($fh);
+ my $parser = ScriptParser->new(\$s);
+ 1 while $parser->parse_cmd();
+ if (@{$parser->{output}}) {
+ my $c = fd_colors(1);
+ my $s = join('', @{$parser->{output}});
+ $emit->("$c->{bold}$c->{blue}# chainlint: $path$c->{reset}\n" . $s);
+ $nerrs += () = $s =~ /\?![^?]+\?!/g;
+ }
+ $ntests += $parser->{ntests};
+ }
+ return [$id, $nscripts, $ntests, $nerrs];
+}
+
+sub exit_code {
+ my $stats = shift @_;
+ for (@$stats) {
+ my ($worker, $nscripts, $ntests, $nerrs) = @$_;
+ return 1 if $nerrs;
+ }
+ return 0;
+}
+
+Getopt::Long::Configure(qw{bundling});
+GetOptions(
+ "emit-all!" => \$emit_all,
+ "jobs|j=i" => \$jobs,
+ "stats|show-stats!" => \$show_stats) or die("option error\n");
+$jobs = ncores() if $jobs < 1;
+
+my $start_time = $getnow->();
+my @stats;
+
+my @scripts;
+push(@scripts, File::Glob::bsd_glob($_)) for (@ARGV);
+unless (@scripts) {
+ show_stats($start_time, \@stats) if $show_stats;
+ exit;
+}
+
+unless ($Config{useithreads} && eval {
+ require threads; threads->import();
+ require Thread::Queue; Thread::Queue->import();
+ 1;
+ }) {
+ push(@stats, check_script(1, sub { shift(@scripts); }, sub { print(@_); }));
+ show_stats($start_time, \@stats) if $show_stats;
+ exit(exit_code(\@stats));
+}
+
+my $script_queue = Thread::Queue->new();
+my $output_queue = Thread::Queue->new();
+
+sub next_script { return $script_queue->dequeue(); }
+sub emit { $output_queue->enqueue(@_); }
+
+sub monitor {
+ while (my $s = $output_queue->dequeue()) {
+ print($s);
+ }
+}
+
+my $mon = threads->create({'context' => 'void'}, \&monitor);
+threads->create({'context' => 'list'}, \&check_script, $_, \&next_script, \&emit) for 1..$jobs;
+
+$script_queue->enqueue(@scripts);
+$script_queue->end();
+
+for (threads->list()) {
+ push(@stats, $_->join()) unless $_ == $mon;
+}
+
+$output_queue->end();
+$mon->join();
+
+show_stats($start_time, \@stats) if $show_stats;
+exit(exit_code(\@stats));
diff --git a/t/chainlint.sed b/t/chainlint.sed
deleted file mode 100644
index dc4ce37cb51..00000000000
--- a/t/chainlint.sed
+++ /dev/null
@@ -1,399 +0,0 @@
-#------------------------------------------------------------------------------
-# Detect broken &&-chains in tests.
-#
-# At present, only &&-chains in subshells are examined by this linter;
-# top-level &&-chains are instead checked directly by the test framework. Like
-# the top-level &&-chain linter, the subshell linter (intentionally) does not
-# check &&-chains within {...} blocks.
-#
-# Checking for &&-chain breakage is done line-by-line by pure textual
-# inspection.
-#
-# Incomplete lines (those ending with "\") are stitched together with following
-# lines to simplify processing, particularly of "one-liner" statements.
-# Top-level here-docs are swallowed to avoid false positives within the
-# here-doc body, although the statement to which the here-doc is attached is
-# retained.
-#
-# Heuristics are used to detect end-of-subshell when the closing ")" is cuddled
-# with the final subshell statement on the same line:
-#
-# (cd foo &&
-# bar)
-#
-# in order to avoid misinterpreting the ")" in constructs such as "x=$(...)"
-# and "case $x in *)" as ending the subshell.
-#
-# Lines missing a final "&&" are flagged with "?!AMP?!", as are lines which
-# chain commands with ";" internally rather than "&&". A line may be flagged
-# for both violations.
-#
-# Detection of a missing &&-link in a multi-line subshell is complicated by the
-# fact that the last statement before the closing ")" must not end with "&&".
-# Since processing is line-by-line, it is not known whether a missing "&&" is
-# legitimate or not until the _next_ line is seen. To accommodate this, within
-# multi-line subshells, each line is stored in sed's "hold" area until after
-# the next line is seen and processed. If the next line is a stand-alone ")",
-# then a missing "&&" on the previous line is legitimate; otherwise a missing
-# "&&" is a break in the &&-chain.
-#
-# (
-# cd foo &&
-# bar
-# )
-#
-# In practical terms, when "bar" is encountered, it is flagged with "?!AMP?!",
-# but when the stand-alone ")" line is seen which closes the subshell, the
-# "?!AMP?!" violation is removed from the "bar" line (retrieved from the "hold"
-# area) since the final statement of a subshell must not end with "&&". The
-# final line of a subshell may still break the &&-chain by using ";" internally
-# to chain commands together rather than "&&", but an internal "?!AMP?!" is
-# never removed from a line even though a line-ending "?!AMP?!" might be.
-#
-# Care is taken to recognize the last _statement_ of a multi-line subshell, not
-# necessarily the last textual _line_ within the subshell, since &&-chaining
-# applies to statements, not to lines. Consequently, blank lines, comment
-# lines, and here-docs are swallowed (but not the command to which the here-doc
-# is attached), leaving the last statement in the "hold" area, not the last
-# line, thus simplifying &&-link checking.
-#
-# The final statement before "done" in for- and while-loops, and before "elif",
-# "else", and "fi" in if-then-else likewise must not end with "&&", thus
-# receives similar treatment.
-#
-# Swallowing here-docs with arbitrary tags requires a bit of finesse. When a
-# line such as "cat <<EOF" is seen, the here-doc tag is copied to the front of
-# the line enclosed in angle brackets as a sentinel, giving "<EOF>cat <<EOF".
-# As each subsequent line is read, it is appended to the target line and a
-# (whitespace-loose) back-reference match /^<(.*)>\n\1$/ is attempted to see if
-# the content inside "<...>" matches the entirety of the newly-read line. For
-# instance, if the next line read is "some data", when concatenated with the
-# target line, it becomes "<EOF>cat <<EOF\nsome data", and a match is attempted
-# to see if "EOF" matches "some data". Since it doesn't, the next line is
-# attempted. When a line consisting of only "EOF" (and possible whitespace) is
-# encountered, it is appended to the target line giving "<EOF>cat <<EOF\nEOF",
-# in which case the "EOF" inside "<...>" does match the text following the
-# newline, thus the closing here-doc tag has been found. The closing tag line
-# and the "<...>" prefix on the target line are then discarded, leaving just
-# the target line "cat <<EOF".
-#------------------------------------------------------------------------------
-
-# incomplete line -- slurp up next line
-:squash
-/\\$/ {
- N
- s/\\\n//
- bsquash
-}
-
-# here-doc -- swallow it to avoid false hits within its body (but keep the
-# command to which it was attached)
-/<<-*[ ]*[\\'"]*[A-Za-z0-9_]/ {
- /"[^"]*<<[^"]*"/bnotdoc
- s/^\(.*<<-*[ ]*\)[\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1\2/
- :hered
- N
- /^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
- s/\n.*$//
- bhered
- }
- s/^<[^>]*>//
- s/\n.*$//
-}
-:notdoc
-
-# one-liner "(...) &&"
-/^[ ]*!*[ ]*(..*)[ ]*&&[ ]*$/boneline
-
-# same as above but without trailing "&&"
-/^[ ]*!*[ ]*(..*)[ ]*$/boneline
-
-# one-liner "(...) >x" (or "2>x" or "<x" or "|x" or "&"
-/^[ ]*!*[ ]*(..*)[ ]*[0-9]*[<>|&]/boneline
-
-# multi-line "(...\n...)"
-/^[ ]*(/bsubsh
-
-# innocuous line -- print it and advance to next line
-b
-
-# found one-liner "(...)" -- mark suspect if it uses ";" internally rather than
-# "&&" (but not ";" in a string)
-:oneline
-/;/{
- /"[^"]*;[^"]*"/!s/;/; ?!AMP?!/
-}
-b
-
-:subsh
-# bare "(" line? -- stash for later printing
-/^[ ]*([ ]*$/ {
- h
- bnextln
-}
-# "(..." line -- "(" opening subshell cuddled with command; temporarily replace
-# "(" with sentinel "^" and process the line as if "(" had been seen solo on
-# the preceding line; this temporary replacement prevents several rules from
-# accidentally thinking "(" introduces a nested subshell; "^" is changed back
-# to "(" at output time
-x
-s/.*//
-x
-s/(/^/
-bslurp
-
-:nextln
-N
-s/.*\n//
-
-:slurp
-# incomplete line "...\"
-/\\$/bicmplte
-# multi-line quoted string "...\n..."?
-/"/bdqstr
-# multi-line quoted string '...\n...'? (but not contraction in string "it's")
-/'/{
- /"[^'"]*'[^'"]*"/!bsqstr
-}
-:folded
-# here-doc -- swallow it (but not "<<" in a string)
-/<<-*[ ]*[\\'"]*[A-Za-z0-9_]/{
- /"[^"]*<<[^"]*"/!bheredoc
-}
-# comment or empty line -- discard since final non-comment, non-empty line
-# before closing ")", "done", "elsif", "else", or "fi" will need to be
-# re-visited to drop "suspect" marking since final line of those constructs
-# legitimately lacks "&&", so "suspect" mark must be removed
-/^[ ]*#/bnextln
-/^[ ]*$/bnextln
-# in-line comment -- strip it (but not "#" in a string, Bash ${#...} array
-# length, or Perforce "//depot/path#42" revision in filespec)
-/[ ]#/{
- /"[^"]*#[^"]*"/!s/[ ]#.*$//
-}
-# one-liner "case ... esac"
-/^[ ^]*case[ ]*..*esac/bchkchn
-# multi-line "case ... esac"
-/^[ ^]*case[ ]..*[ ]in/bcase
-# multi-line "for ... done" or "while ... done"
-/^[ ^]*for[ ]..*[ ]in/bcont
-/^[ ^]*while[ ]/bcont
-/^[ ]*do[ ]/bcont
-/^[ ]*do[ ]*$/bcont
-/;[ ]*do/bcont
-/^[ ]*done[ ]*&&[ ]*$/bdone
-/^[ ]*done[ ]*$/bdone
-/^[ ]*done[ ]*[<>|]/bdone
-/^[ ]*done[ ]*)/bdone
-/||[ ]*exit[ ]/bcont
-/||[ ]*exit[ ]*$/bcont
-# multi-line "if...elsif...else...fi"
-/^[ ^]*if[ ]/bcont
-/^[ ]*then[ ]/bcont
-/^[ ]*then[ ]*$/bcont
-/;[ ]*then/bcont
-/^[ ]*elif[ ]/belse
-/^[ ]*elif[ ]*$/belse
-/^[ ]*else[ ]/belse
-/^[ ]*else[ ]*$/belse
-/^[ ]*fi[ ]*&&[ ]*$/bdone
-/^[ ]*fi[ ]*$/bdone
-/^[ ]*fi[ ]*[<>|]/bdone
-/^[ ]*fi[ ]*)/bdone
-# nested one-liner "(...) &&"
-/^[ ^]*(.*)[ ]*&&[ ]*$/bchkchn
-# nested one-liner "(...)"
-/^[ ^]*(.*)[ ]*$/bchkchn
-# nested one-liner "(...) >x" (or "2>x" or "<x" or "|x")
-/^[ ^]*(.*)[ ]*[0-9]*[<>|]/bchkchn
-# nested multi-line "(...\n...)"
-/^[ ^]*(/bnest
-# multi-line "{...\n...}"
-/^[ ^]*{/bblock
-# closing ")" on own line -- exit subshell
-/^[ ]*)/bclssolo
-# "$((...))" -- arithmetic expansion; not closing ")"
-/\$(([^)][^)]*))[^)]*$/bchkchn
-# "$(...)" -- command substitution; not closing ")"
-/\$([^)][^)]*)[^)]*$/bchkchn
-# multi-line "$(...\n...)" -- command substitution; treat as nested subshell
-/\$([^)]*$/bnest
-# "=(...)" -- Bash array assignment; not closing ")"
-/=(/bchkchn
-# closing "...) &&"
-/)[ ]*&&[ ]*$/bclose
-# closing "...)"
-/)[ ]*$/bclose
-# closing "...) >x" (or "2>x" or "<x" or "|x")
-/)[ ]*[<>|]/bclose
-:chkchn
-# mark suspect if line uses ";" internally rather than "&&" (but not ";" in a
-# string and not ";;" in one-liner "case...esac")
-/;/{
- /;;/!{
- /"[^"]*;[^"]*"/!s/;/; ?!AMP?!/
- }
-}
-# line ends with pipe "...|" -- valid; not missing "&&"
-/|[ ]*$/bcont
-# missing end-of-line "&&" -- mark suspect
-/&&[ ]*$/!s/$/ ?!AMP?!/
-:cont
-# retrieve and print previous line
-x
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-n
-bslurp
-
-# found incomplete line "...\" -- slurp up next line
-:icmplte
-N
-s/\\\n//
-bslurp
-
-# check for multi-line double-quoted string "...\n..." -- fold to one line
-:dqstr
-# remove all quote pairs
-s/"\([^"]*\)"/@!\1@!/g
-# done if no dangling quote
-/"/!bdqdone
-# otherwise, slurp next line and try again
-N
-s/\n//
-bdqstr
-:dqdone
-s/@!/"/g
-bfolded
-
-# check for multi-line single-quoted string '...\n...' -- fold to one line
-:sqstr
-# remove all quote pairs
-s/'\([^']*\)'/@!\1@!/g
-# done if no dangling quote
-/'/!bsqdone
-# otherwise, slurp next line and try again
-N
-s/\n//
-bsqstr
-:sqdone
-s/@!/'/g
-bfolded
-
-# found here-doc -- swallow it to avoid false hits within its body (but keep
-# the command to which it was attached)
-:heredoc
-s/^\(.*\)<<\(-*[ ]*\)[\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\3>\1?!HERE?!\2\3/
-:hdocsub
-N
-/^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
- s/\n.*$//
- bhdocsub
-}
-s/^<[^>]*>//
-s/\n.*$//
-bfolded
-
-# found "case ... in" -- pass through untouched
-:case
-x
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-n
-:cascom
-/^[ ]*#/{
- N
- s/.*\n//
- bcascom
-}
-/^[ ]*esac/bslurp
-bcase
-
-# found "else" or "elif" -- drop "suspect" from final line before "else" since
-# that line legitimately lacks "&&"
-:else
-x
-s/\( ?!AMP?!\)* ?!AMP?!$//
-x
-bcont
-
-# found "done" closing for-loop or while-loop, or "fi" closing if-then -- drop
-# "suspect" from final contained line since that line legitimately lacks "&&"
-:done
-x
-s/\( ?!AMP?!\)* ?!AMP?!$//
-x
-# is 'done' or 'fi' cuddled with ")" to close subshell?
-/done.*)/bclose
-/fi.*)/bclose
-bchkchn
-
-# found nested multi-line "(...\n...)" -- pass through untouched
-:nest
-x
-:nstslrp
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-n
-:nstcom
-# comment -- not closing ")" if in comment
-/^[ ]*#/{
- N
- s/.*\n//
- bnstcom
-}
-# closing ")" on own line -- stop nested slurp
-/^[ ]*)/bnstcl
-# "$((...))" -- arithmetic expansion; not closing ")"
-/\$(([^)][^)]*))[^)]*$/bnstcnt
-# "$(...)" -- command substitution; not closing ")"
-/\$([^)][^)]*)[^)]*$/bnstcnt
-# closing "...)" -- stop nested slurp
-/)/bnstcl
-:nstcnt
-x
-bnstslrp
-:nstcl
-# is it "))" which closes nested and parent subshells?
-/)[ ]*)/bslurp
-bchkchn
-
-# found multi-line "{...\n...}" block -- pass through untouched
-:block
-x
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-n
-:blkcom
-/^[ ]*#/{
- N
- s/.*\n//
- bblkcom
-}
-# closing "}" -- stop block slurp
-/}/bchkchn
-bblock
-
-# found closing ")" on own line -- drop "suspect" from final line of subshell
-# since that line legitimately lacks "&&" and exit subshell loop
-:clssolo
-x
-s/\( ?!AMP?!\)* ?!AMP?!$//
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-p
-x
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-b
-
-# found closing "...)" -- exit subshell loop
-:close
-x
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-p
-x
-s/^\([ ]*\)^/\1(/
-s/?!HERE?!/<</g
-b
diff --git a/t/chainlint/blank-line-before-esac.expect b/t/chainlint/blank-line-before-esac.expect
new file mode 100644
index 00000000000..48ed4eb1246
--- /dev/null
+++ b/t/chainlint/blank-line-before-esac.expect
@@ -0,0 +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
+}
diff --git a/t/chainlint/blank-line-before-esac.test b/t/chainlint/blank-line-before-esac.test
new file mode 100644
index 00000000000..cecccad19f5
--- /dev/null
+++ b/t/chainlint/blank-line-before-esac.test
@@ -0,0 +1,19 @@
+# LINT: blank line before "esac"
+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
+}
diff --git a/t/chainlint/block.expect b/t/chainlint/block.expect
index da60257ebc4..a3bcea492a9 100644
--- a/t/chainlint/block.expect
+++ b/t/chainlint/block.expect
@@ -1,7 +1,7 @@
(
foo &&
{
- echo a
+ echo a ?!AMP?!
echo b
} &&
bar &&
@@ -9,4 +9,15 @@
echo c
} ?!AMP?!
baz
-)
+) &&
+
+{
+ echo a ; ?!AMP?! echo b
+} &&
+{ echo a ; ?!AMP?! echo b ; } &&
+
+{
+ echo "${var}9" &&
+ echo "done"
+} &&
+finis
diff --git a/t/chainlint/block.test b/t/chainlint/block.test
index 0a82fd579f6..4ab69a4afc4 100644
--- a/t/chainlint/block.test
+++ b/t/chainlint/block.test
@@ -11,4 +11,17 @@
echo c
}
baz
-)
+) &&
+
+# LINT: ";" not allowed in place of "&&"
+{
+ echo a; echo b
+} &&
+{ echo a; echo b; } &&
+
+# LINT: "}" inside string not mistaken as end of block
+{
+ echo "${var}9" &&
+ echo "done"
+} &&
+finis
diff --git a/t/chainlint/chain-break-background.expect b/t/chainlint/chain-break-background.expect
new file mode 100644
index 00000000000..28f9114f42d
--- /dev/null
+++ b/t/chainlint/chain-break-background.expect
@@ -0,0 +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
diff --git a/t/chainlint/chain-break-background.test b/t/chainlint/chain-break-background.test
new file mode 100644
index 00000000000..e10f656b055
--- /dev/null
+++ b/t/chainlint/chain-break-background.test
@@ -0,0 +1,10 @@
+JGIT_DAEMON_PID= &&
+git init --bare empty.git &&
+>empty.git/git-daemon-export-ok &&
+mkfifo jgit_daemon_output &&
+{
+# LINT: exit status of "&" is always 0 so &&-chaining immaterial
+ 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
diff --git a/t/chainlint/chain-break-continue.expect b/t/chainlint/chain-break-continue.expect
new file mode 100644
index 00000000000..47a34577100
--- /dev/null
+++ b/t/chainlint/chain-break-continue.expect
@@ -0,0 +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
diff --git a/t/chainlint/chain-break-continue.test b/t/chainlint/chain-break-continue.test
new file mode 100644
index 00000000000..f0af71d8bd9
--- /dev/null
+++ b/t/chainlint/chain-break-continue.test
@@ -0,0 +1,13 @@
+git ls-tree --name-only -r refs/notes/many_notes |
+while read path
+do
+# LINT: broken &&-chain okay if explicit "continue"
+ 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
diff --git a/t/chainlint/chain-break-false.expect b/t/chainlint/chain-break-false.expect
new file mode 100644
index 00000000000..989766fb856
--- /dev/null
+++ b/t/chainlint/chain-break-false.expect
@@ -0,0 +1,9 @@
+if condition not satisified
+then
+ echo it did not work...
+ echo failed!
+ false
+else
+ echo it went okay ?!AMP?!
+ congratulate user
+fi
diff --git a/t/chainlint/chain-break-false.test b/t/chainlint/chain-break-false.test
new file mode 100644
index 00000000000..a5aaff8c8a4
--- /dev/null
+++ b/t/chainlint/chain-break-false.test
@@ -0,0 +1,10 @@
+# LINT: broken &&-chain okay if explicit "false" signals failure
+if condition not satisified
+then
+ echo it did not work...
+ echo failed!
+ false
+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
new file mode 100644
index 00000000000..1732d221c32
--- /dev/null
+++ b/t/chainlint/chain-break-return-exit.expect
@@ -0,0 +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
diff --git a/t/chainlint/chain-break-return-exit.test b/t/chainlint/chain-break-return-exit.test
new file mode 100644
index 00000000000..46542edf881
--- /dev/null
+++ b/t/chainlint/chain-break-return-exit.test
@@ -0,0 +1,23 @@
+case "$(git ls-files)" in
+one) echo pass one ;;
+# LINT: broken &&-chain okay if explicit "return 1" signals failuire
+*) echo bad one; return 1 ;;
+esac &&
+(
+ case "$(git ls-files)" in
+ two) echo pass two ;;
+# LINT: broken &&-chain okay if explicit "exit 1" signals failuire
+ *) echo bad two; exit 1 ;;
+ esac
+) &&
+case "$(git ls-files)" in
+dir/two"$LF"one) echo pass both ;;
+# LINT: broken &&-chain okay if explicit "return 1" signals failuire
+*) echo bad; return 1 ;;
+esac &&
+
+for i in 1 2 3 4 ; do
+# LINT: broken &&-chain okay if explicit "return $?" signals failure
+ 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
new file mode 100644
index 00000000000..f4bada94632
--- /dev/null
+++ b/t/chainlint/chain-break-status.expect
@@ -0,0 +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
diff --git a/t/chainlint/chain-break-status.test b/t/chainlint/chain-break-status.test
new file mode 100644
index 00000000000..a6602a7b99c
--- /dev/null
+++ b/t/chainlint/chain-break-status.test
@@ -0,0 +1,11 @@
+# LINT: broken &&-chain okay if next command handles "$?" explicitly
+OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
+test_match_signal 13 "$OUT" &&
+
+# LINT: broken &&-chain okay if next command handles "$?" explicitly
+{ test-tool sigchain >actual; ret=$?; } &&
+{
+ test_match_signal 15 "$ret" ||
+ test "$ret" = 3
+} &&
+test_cmp expect actual
diff --git a/t/chainlint/chained-block.expect b/t/chainlint/chained-block.expect
new file mode 100644
index 00000000000..574cdceb071
--- /dev/null
+++ b/t/chainlint/chained-block.expect
@@ -0,0 +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"
+}
diff --git a/t/chainlint/chained-block.test b/t/chainlint/chained-block.test
new file mode 100644
index 00000000000..86f81ece639
--- /dev/null
+++ b/t/chainlint/chained-block.test
@@ -0,0 +1,11 @@
+# LINT: start of block chained to preceding command
+echo nobody home && {
+ test the doohicky
+ right now
+} &&
+
+# LINT: preceding command pipes to block on same line
+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
new file mode 100644
index 00000000000..af0369d3285
--- /dev/null
+++ b/t/chainlint/chained-subshell.expect
@@ -0,0 +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 )
diff --git a/t/chainlint/chained-subshell.test b/t/chainlint/chained-subshell.test
new file mode 100644
index 00000000000..4ff6ddd8cbd
--- /dev/null
+++ b/t/chainlint/chained-subshell.test
@@ -0,0 +1,13 @@
+# LINT: start of subshell chained to preceding command
+mkdir sub && (
+ cd sub &&
+ foo the bar
+ nuff said
+) &&
+
+# LINT: preceding command pipes to subshell on same line
+cut "-d " -f actual | (read s1 s2 s3 &&
+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/command-substitution-subsubshell.expect b/t/chainlint/command-substitution-subsubshell.expect
new file mode 100644
index 00000000000..ab2f79e8457
--- /dev/null
+++ b/t/chainlint/command-substitution-subsubshell.expect
@@ -0,0 +1,2 @@
+OUT=$(( ( large_git 1 >& 3 ) | : ) 3 >& 1) &&
+test_match_signal 13 "$OUT"
diff --git a/t/chainlint/command-substitution-subsubshell.test b/t/chainlint/command-substitution-subsubshell.test
new file mode 100644
index 00000000000..321de2951ce
--- /dev/null
+++ b/t/chainlint/command-substitution-subsubshell.test
@@ -0,0 +1,3 @@
+# 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/complex-if-in-cuddled-loop.expect b/t/chainlint/complex-if-in-cuddled-loop.expect
index 2fca1834095..dac2d0fd1d9 100644
--- a/t/chainlint/complex-if-in-cuddled-loop.expect
+++ b/t/chainlint/complex-if-in-cuddled-loop.expect
@@ -4,6 +4,6 @@
:
else
echo >file
- fi
+ fi ?!LOOP?!
done) &&
test ! -f file
diff --git a/t/chainlint/double-here-doc.expect b/t/chainlint/double-here-doc.expect
new file mode 100644
index 00000000000..75477bb1add
--- /dev/null
+++ b/t/chainlint/double-here-doc.expect
@@ -0,0 +1,2 @@
+run_sub_test_lib_test_err run-inv-range-start "--run invalid range start" --run="a-5" <<-EOF &&
+check_sub_test_lib_test_err run-inv-range-start <<-EOF_OUT 3 <<-EOF_ERR
diff --git a/t/chainlint/double-here-doc.test b/t/chainlint/double-here-doc.test
new file mode 100644
index 00000000000..cd584a43573
--- /dev/null
+++ b/t/chainlint/double-here-doc.test
@@ -0,0 +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
diff --git a/t/chainlint/dqstring-line-splice.expect b/t/chainlint/dqstring-line-splice.expect
new file mode 100644
index 00000000000..bf9ced60d4c
--- /dev/null
+++ b/t/chainlint/dqstring-line-splice.expect
@@ -0,0 +1,3 @@
+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
diff --git a/t/chainlint/dqstring-line-splice.test b/t/chainlint/dqstring-line-splice.test
new file mode 100644
index 00000000000..b40714439f6
--- /dev/null
+++ b/t/chainlint/dqstring-line-splice.test
@@ -0,0 +1,7 @@
+# LINT: line-splice within DQ-string
+'"
+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
+"'
diff --git a/t/chainlint/dqstring-no-interpolate.expect b/t/chainlint/dqstring-no-interpolate.expect
new file mode 100644
index 00000000000..10724987a5f
--- /dev/null
+++ b/t/chainlint/dqstring-no-interpolate.expect
@@ -0,0 +1,11 @@
+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
diff --git a/t/chainlint/dqstring-no-interpolate.test b/t/chainlint/dqstring-no-interpolate.test
new file mode 100644
index 00000000000..d2f4219cbbb
--- /dev/null
+++ b/t/chainlint/dqstring-no-interpolate.test
@@ -0,0 +1,15 @@
+# LINT: regex dollar-sign eol anchor in double-quoted string not special
+grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
+
+# LINT: escaped "$" not mistaken for variable expansion
+grep "^\\.git\$" output.txt &&
+
+'"
+(
+ cd client$version &&
+# LINT: escaped dollar-sign in double-quoted test body
+ GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. \$(cat ../input)
+) >output &&
+ 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
new file mode 100644
index 00000000000..f42f2d41ba8
--- /dev/null
+++ b/t/chainlint/empty-here-doc.expect
@@ -0,0 +1,3 @@
+git ls-tree $tree path > current &&
+cat > expected <<EOF &&
+test_output
diff --git a/t/chainlint/empty-here-doc.test b/t/chainlint/empty-here-doc.test
new file mode 100644
index 00000000000..24fc165de3f
--- /dev/null
+++ b/t/chainlint/empty-here-doc.test
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 00000000000..2d961a58c66
--- /dev/null
+++ b/t/chainlint/exclamation.expect
@@ -0,0 +1,4 @@
+if ! condition ; then echo nope ; else yep ; fi &&
+test_prerequisite !MINGW &&
+mail uucp!address &&
+echo !whatever!
diff --git a/t/chainlint/exclamation.test b/t/chainlint/exclamation.test
new file mode 100644
index 00000000000..323595b5bd8
--- /dev/null
+++ b/t/chainlint/exclamation.test
@@ -0,0 +1,8 @@
+# LINT: "! word" is two tokens
+if ! condition; then echo nope; else yep; fi &&
+# LINT: "!word" is single token, not two tokens "!" and "word"
+test_prerequisite !MINGW &&
+# LINT: "word!word" is single token, not three tokens "word", "!", and "word"
+mail uucp!address &&
+# LINT: "!word!" is single token, not three tokens "!", "word", and "!"
+echo !whatever!
diff --git a/t/chainlint/for-loop-abbreviated.expect b/t/chainlint/for-loop-abbreviated.expect
new file mode 100644
index 00000000000..a21007a63f1
--- /dev/null
+++ b/t/chainlint/for-loop-abbreviated.expect
@@ -0,0 +1,5 @@
+for it
+do
+ path=$(expr "$it" : ( [^:]*) ) &&
+ git update-index --add "$path" || exit
+done
diff --git a/t/chainlint/for-loop-abbreviated.test b/t/chainlint/for-loop-abbreviated.test
new file mode 100644
index 00000000000..1084eccb89c
--- /dev/null
+++ b/t/chainlint/for-loop-abbreviated.test
@@ -0,0 +1,6 @@
+# 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 6671b8cd842..a5810c9bddd 100644
--- a/t/chainlint/for-loop.expect
+++ b/t/chainlint/for-loop.expect
@@ -2,10 +2,10 @@
for i in a b c
do
echo $i ?!AMP?!
- cat <<-EOF
+ cat <<-EOF ?!LOOP?!
done ?!AMP?!
for i in a b c; do
echo $i &&
- cat $i
+ cat $i ?!LOOP?!
done
)
diff --git a/t/chainlint/function.expect b/t/chainlint/function.expect
new file mode 100644
index 00000000000..a14388e6b9f
--- /dev/null
+++ b/t/chainlint/function.expect
@@ -0,0 +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
diff --git a/t/chainlint/function.test b/t/chainlint/function.test
new file mode 100644
index 00000000000..5ee59562c93
--- /dev/null
+++ b/t/chainlint/function.test
@@ -0,0 +1,13 @@
+# LINT: "()" in function definition not mistaken for subshell
+sha1_file() {
+ echo "$*" | sed "s#..#.git/objects/&/#"
+} &&
+
+# LINT: broken &&-chain in function and after function
+remove_object() {
+ file=$(sha1_file "$*") &&
+ test -e "$file"
+ rm -f "$file"
+}
+
+sha1_file arg && remove_object arg
diff --git a/t/chainlint/here-doc-indent-operator.expect b/t/chainlint/here-doc-indent-operator.expect
new file mode 100644
index 00000000000..fb6cf7285d0
--- /dev/null
+++ b/t/chainlint/here-doc-indent-operator.expect
@@ -0,0 +1,5 @@
+cat > expect <<-EOF &&
+
+cat > expect <<-EOF ?!AMP?!
+
+cleanup
diff --git a/t/chainlint/here-doc-indent-operator.test b/t/chainlint/here-doc-indent-operator.test
new file mode 100644
index 00000000000..c8a6f18eb45
--- /dev/null
+++ b/t/chainlint/here-doc-indent-operator.test
@@ -0,0 +1,13 @@
+# LINT: whitespace between operator "<<-" and tag legal
+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
+
+# LINT: not an indented here-doc; just a plain here-doc with tag named "-EOF"
+cat >expect << -EOF
+this is not indented
+-EOF
+
+cleanup
diff --git a/t/chainlint/here-doc-multi-line-string.expect b/t/chainlint/here-doc-multi-line-string.expect
index 2578191ca8a..be64b26869a 100644
--- a/t/chainlint/here-doc-multi-line-string.expect
+++ b/t/chainlint/here-doc-multi-line-string.expect
@@ -1,4 +1,5 @@
(
- cat <<-TXT && echo "multi-line string" ?!AMP?!
+ cat <<-TXT && echo "multi-line
+ string" ?!AMP?!
bap
)
diff --git a/t/chainlint/if-condition-split.expect b/t/chainlint/if-condition-split.expect
new file mode 100644
index 00000000000..ee745ef8d7f
--- /dev/null
+++ b/t/chainlint/if-condition-split.expect
@@ -0,0 +1,7 @@
+if bob &&
+ marcia ||
+ kevin
+then
+ echo "nomads" ?!AMP?!
+ echo "for sure"
+fi
diff --git a/t/chainlint/if-condition-split.test b/t/chainlint/if-condition-split.test
new file mode 100644
index 00000000000..240daa9fd5d
--- /dev/null
+++ b/t/chainlint/if-condition-split.test
@@ -0,0 +1,8 @@
+# LINT: "if" condition split across multiple lines at "&&" or "||"
+if bob &&
+ marcia ||
+ kevin
+then
+ echo "nomads"
+ echo "for sure"
+fi
diff --git a/t/chainlint/if-in-loop.expect b/t/chainlint/if-in-loop.expect
index 03b82a3e58c..d6514ae7492 100644
--- a/t/chainlint/if-in-loop.expect
+++ b/t/chainlint/if-in-loop.expect
@@ -3,7 +3,7 @@
do
if false
then
- echo "err" ?!AMP?!
+ echo "err"
exit 1
fi ?!AMP?!
foo
diff --git a/t/chainlint/if-in-loop.test b/t/chainlint/if-in-loop.test
index f0cf19cfada..90c23976fec 100644
--- a/t/chainlint/if-in-loop.test
+++ b/t/chainlint/if-in-loop.test
@@ -3,7 +3,7 @@
do
if false
then
-# LINT: missing "&&" on "echo"
+# LINT: missing "&&" on "echo" okay since "exit 1" signals error explicitly
echo "err"
exit 1
# LINT: missing "&&" on "fi"
diff --git a/t/chainlint/loop-detect-failure.expect b/t/chainlint/loop-detect-failure.expect
new file mode 100644
index 00000000000..a66025c39d4
--- /dev/null
+++ b/t/chainlint/loop-detect-failure.expect
@@ -0,0 +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
diff --git a/t/chainlint/loop-detect-failure.test b/t/chainlint/loop-detect-failure.test
new file mode 100644
index 00000000000..b9791cc802e
--- /dev/null
+++ b/t/chainlint/loop-detect-failure.test
@@ -0,0 +1,17 @@
+git init r1 &&
+# LINT: loop handles failure explicitly with "|| return 1"
+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 &&
+# LINT: loop fails to handle failure explicitly with "|| return 1"
+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"
+done
diff --git a/t/chainlint/loop-detect-status.expect b/t/chainlint/loop-detect-status.expect
new file mode 100644
index 00000000000..0ad23bb35e4
--- /dev/null
+++ b/t/chainlint/loop-detect-status.expect
@@ -0,0 +1,18 @@
+( while test $i -le $blobcount
+do
+ printf "Generating blob $i/$blobcount\r" >& 2 &&
+ printf "blob\nmark :$i\ndata $blobsize\n" &&
+
+ 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
diff --git a/t/chainlint/loop-detect-status.test b/t/chainlint/loop-detect-status.test
new file mode 100644
index 00000000000..1c6c23cfc9e
--- /dev/null
+++ b/t/chainlint/loop-detect-status.test
@@ -0,0 +1,19 @@
+# LINT: "$?" handled explicitly within loop body
+(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
diff --git a/t/chainlint/loop-in-if.expect b/t/chainlint/loop-in-if.expect
index e1be42376c5..6c5d6e5b243 100644
--- a/t/chainlint/loop-in-if.expect
+++ b/t/chainlint/loop-in-if.expect
@@ -4,7 +4,7 @@
while true
do
echo "pop" ?!AMP?!
- echo "glup"
+ echo "glup" ?!LOOP?!
done ?!AMP?!
foo
fi ?!AMP?!
diff --git a/t/chainlint/loop-upstream-pipe.expect b/t/chainlint/loop-upstream-pipe.expect
new file mode 100644
index 00000000000..0b82ecc4b96
--- /dev/null
+++ b/t/chainlint/loop-upstream-pipe.expect
@@ -0,0 +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 &&
diff --git a/t/chainlint/loop-upstream-pipe.test b/t/chainlint/loop-upstream-pipe.test
new file mode 100644
index 00000000000..efb77da897c
--- /dev/null
+++ b/t/chainlint/loop-upstream-pipe.test
@@ -0,0 +1,11 @@
+(
+ git rev-list --objects --no-object-names base..loose |
+ while read oid
+ do
+# LINT: "|| echo" signals failure in loop upstream of a pipe
+ 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 &&
diff --git a/t/chainlint/multi-line-string.expect b/t/chainlint/multi-line-string.expect
index ab0dadf748e..27ff95218e7 100644
--- a/t/chainlint/multi-line-string.expect
+++ b/t/chainlint/multi-line-string.expect
@@ -1,9 +1,14 @@
(
- x="line 1 line 2 line 3" &&
- y="line 1 line2" ?!AMP?!
+ x="line 1
+ line 2
+ line 3" &&
+ y="line 1
+ line2" ?!AMP?!
foobar
) &&
(
- echo "xyz" "abc def ghi" &&
+ echo "xyz" "abc
+ def
+ ghi" &&
barfoo
)
diff --git a/t/chainlint/nested-loop-detect-failure.expect b/t/chainlint/nested-loop-detect-failure.expect
new file mode 100644
index 00000000000..4793a0e8e12
--- /dev/null
+++ b/t/chainlint/nested-loop-detect-failure.expect
@@ -0,0 +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
diff --git a/t/chainlint/nested-loop-detect-failure.test b/t/chainlint/nested-loop-detect-failure.test
new file mode 100644
index 00000000000..e6f0c1acfb8
--- /dev/null
+++ b/t/chainlint/nested-loop-detect-failure.test
@@ -0,0 +1,35 @@
+# LINT: neither loop handles failure explicitly with "|| return 1"
+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"
+ done
+done &&
+
+# LINT: inner loop handles failure explicitly with "|| return 1"
+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 &&
+
+# LINT: outer loop handles failure explicitly with "|| return 1"
+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"
+ done || return 1
+done &&
+
+# LINT: inner & outer loops handles failure explicitly with "|| return 1"
+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
diff --git a/t/chainlint/nested-subshell.expect b/t/chainlint/nested-subshell.expect
index 41a48adaa2b..02e0a9f1bb5 100644
--- a/t/chainlint/nested-subshell.expect
+++ b/t/chainlint/nested-subshell.expect
@@ -6,7 +6,7 @@
) >file &&
cd foo &&
(
- echo a
+ echo a ?!AMP?!
echo b
) >file
)
diff --git a/t/chainlint/one-liner-for-loop.expect b/t/chainlint/one-liner-for-loop.expect
new file mode 100644
index 00000000000..51a3dc7c544
--- /dev/null
+++ b/t/chainlint/one-liner-for-loop.expect
@@ -0,0 +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" &&
+)
diff --git a/t/chainlint/one-liner-for-loop.test b/t/chainlint/one-liner-for-loop.test
new file mode 100644
index 00000000000..4bd8c066c79
--- /dev/null
+++ b/t/chainlint/one-liner-for-loop.test
@@ -0,0 +1,10 @@
+git init dir-rename-and-content &&
+(
+ cd dir-rename-and-content &&
+ test_write_lines 1 2 3 4 5 >foo &&
+ mkdir olddir &&
+# LINT: one-liner for-loop missing "|| exit"; also broken &&-chain
+ for i in a b c; do echo $i >olddir/$i; done
+ git add foo olddir &&
+ git commit -m "original" &&
+)
diff --git a/t/chainlint/return-loop.expect b/t/chainlint/return-loop.expect
new file mode 100644
index 00000000000..cfc0549befe
--- /dev/null
+++ b/t/chainlint/return-loop.expect
@@ -0,0 +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
diff --git a/t/chainlint/return-loop.test b/t/chainlint/return-loop.test
new file mode 100644
index 00000000000..f90b1713005
--- /dev/null
+++ b/t/chainlint/return-loop.test
@@ -0,0 +1,6 @@
+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 ed0b3707ae9..3aa2259f36c 100644
--- a/t/chainlint/semicolon.expect
+++ b/t/chainlint/semicolon.expect
@@ -15,5 +15,5 @@
) &&
(cd foo &&
for i in a b c; do
- echo;
+ echo; ?!LOOP?!
done)
diff --git a/t/chainlint/sqstring-in-sqstring.expect b/t/chainlint/sqstring-in-sqstring.expect
new file mode 100644
index 00000000000..cf0b591cf7d
--- /dev/null
+++ b/t/chainlint/sqstring-in-sqstring.expect
@@ -0,0 +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
diff --git a/t/chainlint/sqstring-in-sqstring.test b/t/chainlint/sqstring-in-sqstring.test
new file mode 100644
index 00000000000..77a425e0c79
--- /dev/null
+++ b/t/chainlint/sqstring-in-sqstring.test
@@ -0,0 +1,5 @@
+# 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/t7900-subtree.expect b/t/chainlint/t7900-subtree.expect
index 1cccc7bf7e1..69167da2f27 100644
--- a/t/chainlint/t7900-subtree.expect
+++ b/t/chainlint/t7900-subtree.expect
@@ -1,10 +1,17 @@
(
- chks="sub1sub2sub3sub4" &&
+ chks="sub1
+sub2
+sub3
+sub4" &&
chks_sub=$(cat <<TXT | sed "s,^,sub dir/,"
) &&
- chkms="main-sub1main-sub2main-sub3main-sub4" &&
+ chkms="main-sub1
+main-sub2
+main-sub3
+main-sub4" &&
chkms_sub=$(cat <<TXT | sed "s,^,sub dir/,"
) &&
subfiles=$(git ls-files) &&
- check_equal "$subfiles" "$chkms$chks"
+ check_equal "$subfiles" "$chkms
+$chks"
)
diff --git a/t/chainlint/token-pasting.expect b/t/chainlint/token-pasting.expect
new file mode 100644
index 00000000000..342360bcd05
--- /dev/null
+++ b/t/chainlint/token-pasting.expect
@@ -0,0 +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'
+)
diff --git a/t/chainlint/token-pasting.test b/t/chainlint/token-pasting.test
new file mode 100644
index 00000000000..b4610ce815a
--- /dev/null
+++ b/t/chainlint/token-pasting.test
@@ -0,0 +1,32 @@
+# LINT: single token; composite of multiple strings
+git config filter.rot13.smudge ./rot13.sh &&
+git config filter.rot13.clean ./rot13.sh &&
+
+{
+ echo "*.t filter=rot13"
+ echo "*.i ident"
+} >.gitattributes &&
+
+{
+ echo a b c d e f g h i j k l m
+ echo n o p q r s t u v w x y z
+# LINT: exit/enter string context and escaped-quote outside of string
+ 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 &&
+# LINT: exit/enter string context and escaped-quote outside of string
+echo "content-test3 - filename with special characters" >"test3 '\''sq'\'',\$x=.o"
+
+# LINT: single token; composite of multiple strings
+downstream_url_for_sed=$(
+ printf "%s\n" "$downstream_url" |
+# LINT: exit/enter string context; "&" inside string not command terminator
+ sed -e '\''s/\\/\\\\/g'\'' -e '\''s/[[/.*^$]/\\&/g'\''
+)
diff --git a/t/chainlint/while-loop.expect b/t/chainlint/while-loop.expect
index 0d3a9b3d128..f272aa21fee 100644
--- a/t/chainlint/while-loop.expect
+++ b/t/chainlint/while-loop.expect
@@ -2,10 +2,10 @@
while true
do
echo foo ?!AMP?!
- cat <<-EOF
+ cat <<-EOF ?!LOOP?!
done ?!AMP?!
while true; do
echo foo &&
- cat bar
+ cat bar ?!LOOP?!
done
)
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index fd3303552be..dd8107cd7da 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -45,6 +45,7 @@ while (<>) {
/\bhead\s+-c\b/ and err 'head -c is not portable (use test_copy_bytes BYTES <file >out)';
/(?:\$\(seq|^\s*seq\b)/ and err 'seq is not portable (use test_seq)';
/\bgrep\b.*--file\b/ and err 'grep --file FILE is not portable (use grep -f FILE)';
+ /\b[ef]grep\b/ and err 'egrep/fgrep obsolescent (use grep -E/-F)';
/\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
/^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
err '"FOO=bar shell_func" assignment extends beyond "shell_func"';
diff --git a/t/helper/test-bundle-uri.c b/t/helper/test-bundle-uri.c
new file mode 100644
index 00000000000..25afd393428
--- /dev/null
+++ b/t/helper/test-bundle-uri.c
@@ -0,0 +1,95 @@
+#include "test-tool.h"
+#include "parse-options.h"
+#include "bundle-uri.h"
+#include "strbuf.h"
+#include "string-list.h"
+
+enum input_mode {
+ KEY_VALUE_PAIRS,
+ CONFIG_FILE,
+};
+
+static int cmd__bundle_uri_parse(int argc, const char **argv, enum input_mode mode)
+{
+ const char *key_value_usage[] = {
+ "test-tool bundle-uri parse-key-values <input>",
+ NULL
+ };
+ const char *config_usage[] = {
+ "test-tool bundle-uri parse-config <input>",
+ NULL
+ };
+ const char **usage = key_value_usage;
+ struct option options[] = {
+ OPT_END(),
+ };
+ struct strbuf sb = STRBUF_INIT;
+ struct bundle_list list;
+ int err = 0;
+ FILE *fp;
+
+ if (mode == CONFIG_FILE)
+ usage = config_usage;
+
+ argc = parse_options(argc, argv, NULL, options, usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ init_bundle_list(&list);
+
+ switch (mode) {
+ case KEY_VALUE_PAIRS:
+ if (argc != 1)
+ goto usage;
+ fp = fopen(argv[0], "r");
+ if (!fp)
+ die("failed to open '%s'", argv[0]);
+ while (strbuf_getline(&sb, fp) != EOF) {
+ if (bundle_uri_parse_line(&list, sb.buf))
+ err = error("bad line: '%s'", sb.buf);
+ }
+ fclose(fp);
+ break;
+
+ case CONFIG_FILE:
+ if (argc != 1)
+ goto usage;
+ err = bundle_uri_parse_config_format("<uri>", argv[0], &list);
+ break;
+ }
+ strbuf_release(&sb);
+
+ print_bundle_list(stdout, &list);
+
+ clear_bundle_list(&list);
+
+ return !!err;
+
+usage:
+ usage_with_options(usage, options);
+}
+
+int cmd__bundle_uri(int argc, const char **argv)
+{
+ const char *usage[] = {
+ "test-tool bundle-uri <subcommand> [<options>]",
+ NULL
+ };
+ struct option options[] = {
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage,
+ PARSE_OPT_STOP_AT_NON_OPTION |
+ PARSE_OPT_KEEP_ARGV0);
+ if (argc == 1)
+ goto usage;
+
+ if (!strcmp(argv[1], "parse-key-values"))
+ return cmd__bundle_uri_parse(argc - 1, argv + 1, KEY_VALUE_PAIRS);
+ if (!strcmp(argv[1], "parse-config"))
+ return cmd__bundle_uri_parse(argc - 1, argv + 1, CONFIG_FILE);
+ error("there is no test-tool bundle-uri tool '%s'", argv[1]);
+
+usage:
+ usage_with_options(usage, options);
+}
diff --git a/t/helper/test-config.c b/t/helper/test-config.c
index a6e936721fe..4ba9eb65606 100644
--- a/t/helper/test-config.c
+++ b/t/helper/test-config.c
@@ -37,7 +37,7 @@
*
*/
-static int iterate_cb(const char *var, const char *value, void *data)
+static int iterate_cb(const char *var, const char *value, void *data UNUSED)
{
static int nr;
diff --git a/t/helper/test-crontab.c b/t/helper/test-crontab.c
index e7c0137a477..e6c1b1e22bb 100644
--- a/t/helper/test-crontab.c
+++ b/t/helper/test-crontab.c
@@ -2,33 +2,34 @@
#include "cache.h"
/*
- * Usage: test-tool cron <file> [-l]
+ * Usage: test-tool crontab <file> -l|<input>
*
* If -l is specified, then write the contents of <file> to stdout.
- * Otherwise, write from stdin into <file>.
+ * Otherwise, copy the contents of <input> into <file>.
*/
int cmd__crontab(int argc, const char **argv)
{
int a;
FILE *from, *to;
- if (argc == 3 && !strcmp(argv[2], "-l")) {
+ if (argc != 3)
+ usage("test-tool crontab <file> -l|<input>");
+
+ if (!strcmp(argv[2], "-l")) {
from = fopen(argv[1], "r");
if (!from)
return 0;
to = stdout;
- } else if (argc == 2) {
- from = stdin;
- to = fopen(argv[1], "w");
- } else
- return error("unknown arguments");
+ } else {
+ from = xfopen(argv[2], "r");
+ to = xfopen(argv[1], "w");
+ }
while ((a = fgetc(from)) != EOF)
fputc(a, to);
- if (argc == 3)
- fclose(from);
- else
+ fclose(from);
+ if (to != stdout)
fclose(to);
return 0;
diff --git a/t/helper/test-fake-ssh.c b/t/helper/test-fake-ssh.c
index 12beee99ad2..2e576bcc11e 100644
--- a/t/helper/test-fake-ssh.c
+++ b/t/helper/test-fake-ssh.c
@@ -8,7 +8,7 @@ int cmd_main(int argc, const char **argv)
struct strbuf buf = STRBUF_INIT;
FILE *f;
int i;
- const char *child_argv[] = { NULL, NULL };
+ struct child_process cmd = CHILD_PROCESS_INIT;
/* First, print all parameters into $TRASH_DIRECTORY/ssh-output */
if (!trash_directory)
@@ -25,6 +25,7 @@ int cmd_main(int argc, const char **argv)
/* Now, evaluate the *last* parameter */
if (argc < 2)
return 0;
- child_argv[0] = argv[argc - 1];
- return run_command_v_opt(child_argv, RUN_USING_SHELL);
+ cmd.use_shell = 1;
+ strvec_push(&cmd.args, argv[argc - 1]);
+ return run_command(&cmd);
}
diff --git a/t/helper/test-mergesort.c b/t/helper/test-mergesort.c
index 202e54a7ffc..335e5bb3a90 100644
--- a/t/helper/test-mergesort.c
+++ b/t/helper/test-mergesort.c
@@ -22,21 +22,35 @@ static int compare_strings(const struct line *x, const struct line *y)
static int sort_stdin(void)
{
- struct line *line, *p = NULL, *lines = NULL;
+ struct line *lines;
+ struct line **tail = &lines;
struct strbuf sb = STRBUF_INIT;
-
- while (!strbuf_getline(&sb, stdin)) {
- line = xmalloc(sizeof(struct line));
- line->text = strbuf_detach(&sb, NULL);
- if (p) {
- line->next = p->next;
- p->next = line;
- } else {
- line->next = NULL;
- lines = line;
- }
- p = line;
+ struct mem_pool lines_pool;
+ char *p;
+
+ strbuf_read(&sb, 0, 0);
+
+ /*
+ * Split by newline, but don't create an item
+ * for the empty string after the last separator.
+ */
+ if (sb.len && sb.buf[sb.len - 1] == '\n')
+ strbuf_setlen(&sb, sb.len - 1);
+
+ mem_pool_init(&lines_pool, 0);
+ p = sb.buf;
+ for (;;) {
+ char *eol = strchr(p, '\n');
+ struct line *line = mem_pool_alloc(&lines_pool, sizeof(*line));
+ line->text = p;
+ *tail = line;
+ tail = &line->next;
+ if (!eol)
+ break;
+ *eol = '\0';
+ p = eol + 1;
}
+ *tail = NULL;
sort_lines(&lines, compare_strings);
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index 48d3cf6692d..506835521a4 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -192,3 +192,131 @@ int cmd__parse_options(int argc, const char **argv)
return ret;
}
+
+static void print_args(int argc, const char **argv)
+{
+ int i;
+ for (i = 0; i < argc; i++)
+ printf("arg %02d: %s\n", i, argv[i]);
+}
+
+static int parse_options_flags__cmd(int argc, const char **argv,
+ enum parse_opt_flags test_flags)
+{
+ const char *usage[] = {
+ "<...> cmd [options]",
+ NULL
+ };
+ int opt = 0;
+ const struct option options[] = {
+ OPT_INTEGER('o', "opt", &opt, "an integer option"),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage, test_flags);
+
+ printf("opt: %d\n", opt);
+ print_args(argc, argv);
+
+ return 0;
+}
+
+static enum parse_opt_flags test_flags = 0;
+static const struct option test_flag_options[] = {
+ OPT_GROUP("flag-options:"),
+ OPT_BIT(0, "keep-dashdash", &test_flags,
+ "pass PARSE_OPT_KEEP_DASHDASH to parse_options()",
+ PARSE_OPT_KEEP_DASHDASH),
+ OPT_BIT(0, "stop-at-non-option", &test_flags,
+ "pass PARSE_OPT_STOP_AT_NON_OPTION to parse_options()",
+ PARSE_OPT_STOP_AT_NON_OPTION),
+ OPT_BIT(0, "keep-argv0", &test_flags,
+ "pass PARSE_OPT_KEEP_ARGV0 to parse_options()",
+ PARSE_OPT_KEEP_ARGV0),
+ OPT_BIT(0, "keep-unknown-opt", &test_flags,
+ "pass PARSE_OPT_KEEP_UNKNOWN_OPT to parse_options()",
+ PARSE_OPT_KEEP_UNKNOWN_OPT),
+ OPT_BIT(0, "no-internal-help", &test_flags,
+ "pass PARSE_OPT_NO_INTERNAL_HELP to parse_options()",
+ PARSE_OPT_NO_INTERNAL_HELP),
+ OPT_BIT(0, "subcommand-optional", &test_flags,
+ "pass PARSE_OPT_SUBCOMMAND_OPTIONAL to parse_options()",
+ PARSE_OPT_SUBCOMMAND_OPTIONAL),
+ OPT_END()
+};
+
+int cmd__parse_options_flags(int argc, const char **argv)
+{
+ const char *usage[] = {
+ "test-tool parse-options-flags [flag-options] cmd [options]",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, NULL, test_flag_options, usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ if (!argc || strcmp(argv[0], "cmd")) {
+ error("'cmd' is mandatory");
+ usage_with_options(usage, test_flag_options);
+ }
+
+ return parse_options_flags__cmd(argc, argv, test_flags);
+}
+
+static int subcmd_one(int argc, const char **argv, const char *prefix)
+{
+ printf("fn: subcmd_one\n");
+ print_args(argc, argv);
+ return 0;
+}
+
+static int subcmd_two(int argc, const char **argv, const char *prefix)
+{
+ printf("fn: subcmd_two\n");
+ print_args(argc, argv);
+ return 0;
+}
+
+static int parse_subcommand__cmd(int argc, const char **argv,
+ enum parse_opt_flags test_flags)
+{
+ const char *usage[] = {
+ "<...> cmd subcmd-one",
+ "<...> cmd subcmd-two",
+ NULL
+ };
+ parse_opt_subcommand_fn *fn = NULL;
+ int opt = 0;
+ struct option options[] = {
+ OPT_SUBCOMMAND("subcmd-one", &fn, subcmd_one),
+ OPT_SUBCOMMAND("subcmd-two", &fn, subcmd_two),
+ OPT_INTEGER('o', "opt", &opt, "an integer option"),
+ OPT_END()
+ };
+
+ if (test_flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
+ fn = subcmd_one;
+ argc = parse_options(argc, argv, NULL, options, usage, test_flags);
+
+ printf("opt: %d\n", opt);
+
+ return fn(argc, argv, NULL);
+}
+
+int cmd__parse_subcommand(int argc, const char **argv)
+{
+ const char *usage[] = {
+ "test-tool parse-subcommand [flag-options] cmd <subcommand>",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, NULL, test_flag_options, usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ if (!argc || strcmp(argv[0], "cmd")) {
+ error("'cmd' is mandatory");
+ usage_with_options(usage, test_flag_options);
+ }
+
+ return parse_subcommand__cmd(argc, argv, test_flags);
+}
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index d20e1b7a18d..f69709d674f 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -8,7 +8,8 @@
* GIT_CEILING_DIRECTORIES. If the path is unusable for some reason,
* die with an explanation.
*/
-static int normalize_ceiling_entry(struct string_list_item *item, void *unused)
+static int normalize_ceiling_entry(struct string_list_item *item,
+ void *data UNUSED)
{
char *ceil = item->string;
diff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c
index cc08506cf0b..a4b305f4947 100644
--- a/t/helper/test-proc-receive.c
+++ b/t/helper/test-proc-receive.c
@@ -6,7 +6,7 @@
#include "test-tool.h"
static const char *proc_receive_usage[] = {
- "test-tool proc-receive [<options>...]",
+ "test-tool proc-receive [<options>]",
NULL
};
diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c
index 4d18bfb1ca5..ae8a5648daf 100644
--- a/t/helper/test-ref-store.c
+++ b/t/helper/test-ref-store.c
@@ -161,7 +161,7 @@ static int cmd_rename_ref(struct ref_store *refs, const char **argv)
}
static int each_ref(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+ int flags, void *cb_data UNUSED)
{
printf("%s %s 0x%x\n", oid_to_hex(oid), refname, flags);
return 0;
@@ -207,7 +207,7 @@ static int cmd_for_each_reflog(struct ref_store *refs, const char **argv)
static int each_reflog(struct object_id *old_oid, struct object_id *new_oid,
const char *committer, timestamp_t timestamp,
- int tz, const char *msg, void *cb_data)
+ int tz, const char *msg, void *cb_data UNUSED)
{
printf("%s %s %s %" PRItime " %+05d%s%s", oid_to_hex(old_oid),
oid_to_hex(new_oid), committer, timestamp, tz,
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index c9283b47afa..3ecb830f4a8 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -136,7 +136,7 @@ static const char * const testsuite_usage[] = {
static int testsuite(int argc, const char **argv)
{
struct testsuite suite = TESTSUITE_INIT;
- int max_jobs = 1, i, ret;
+ int max_jobs = 1, i, ret = 0;
DIR *dir;
struct dirent *d;
struct option options[] = {
@@ -152,6 +152,12 @@ static int testsuite(int argc, const char **argv)
"write JUnit-style XML files"),
OPT_END()
};
+ struct run_process_parallel_opts opts = {
+ .get_next_task = next_test,
+ .start_failure = test_failed,
+ .task_finished = test_finished,
+ .data = &suite,
+ };
argc = parse_options(argc, argv, NULL, options,
testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION);
@@ -192,8 +198,8 @@ static int testsuite(int argc, const char **argv)
fprintf(stderr, "Running %"PRIuMAX" tests (%d at a time)\n",
(uintmax_t)suite.tests.nr, max_jobs);
- ret = run_processes_parallel(max_jobs, next_test, test_failed,
- test_finished, &suite);
+ opts.processes = max_jobs;
+ run_processes_parallel(&opts);
if (suite.failed.nr > 0) {
ret = 1;
@@ -206,7 +212,7 @@ static int testsuite(int argc, const char **argv)
string_list_clear(&suite.tests, 0);
string_list_clear(&suite.failed, 0);
- return !!ret;
+ return ret;
}
static uint64_t my_random_next = 1234;
@@ -381,13 +387,17 @@ int cmd__run_command(int argc, const char **argv)
{
struct child_process proc = CHILD_PROCESS_INIT;
int jobs;
+ int ret;
+ struct run_process_parallel_opts opts = {
+ .data = &proc,
+ };
if (argc > 1 && !strcmp(argv[1], "testsuite"))
- exit(testsuite(argc - 1, argv + 1));
+ return testsuite(argc - 1, argv + 1);
if (!strcmp(argv[1], "inherited-handle"))
- exit(inherit_handle(argv[0]));
+ return inherit_handle(argv[0]);
if (!strcmp(argv[1], "inherited-handle-child"))
- exit(inherit_handle_child());
+ return inherit_handle_child();
if (argc >= 2 && !strcmp(argv[1], "quote-stress-test"))
return !!quote_stress_test(argc - 1, argv + 1);
@@ -404,41 +414,52 @@ int cmd__run_command(int argc, const char **argv)
argv += 2;
argc -= 2;
}
- if (argc < 3)
- return 1;
+ if (argc < 3) {
+ ret = 1;
+ goto cleanup;
+ }
strvec_pushv(&proc.args, (const char **)argv + 2);
if (!strcmp(argv[1], "start-command-ENOENT")) {
- if (start_command(&proc) < 0 && errno == ENOENT)
- return 0;
+ if (start_command(&proc) < 0 && errno == ENOENT) {
+ ret = 0;
+ goto cleanup;
+ }
fprintf(stderr, "FAIL %s\n", argv[1]);
return 1;
}
- if (!strcmp(argv[1], "run-command"))
- exit(run_command(&proc));
+ if (!strcmp(argv[1], "run-command")) {
+ ret = run_command(&proc);
+ goto cleanup;
+ }
if (!strcmp(argv[1], "--ungroup")) {
argv += 1;
argc -= 1;
- run_processes_parallel_ungroup = 1;
+ opts.ungroup = 1;
}
jobs = atoi(argv[2]);
strvec_clear(&proc.args);
strvec_pushv(&proc.args, (const char **)argv + 3);
- if (!strcmp(argv[1], "run-command-parallel"))
- exit(run_processes_parallel(jobs, parallel_next,
- NULL, NULL, &proc));
-
- if (!strcmp(argv[1], "run-command-abort"))
- exit(run_processes_parallel(jobs, parallel_next,
- NULL, task_finished, &proc));
-
- if (!strcmp(argv[1], "run-command-no-jobs"))
- exit(run_processes_parallel(jobs, no_job,
- NULL, task_finished, &proc));
-
- fprintf(stderr, "check usage\n");
- return 1;
+ if (!strcmp(argv[1], "run-command-parallel")) {
+ opts.get_next_task = parallel_next;
+ } else if (!strcmp(argv[1], "run-command-abort")) {
+ opts.get_next_task = parallel_next;
+ opts.task_finished = task_finished;
+ } else if (!strcmp(argv[1], "run-command-no-jobs")) {
+ opts.get_next_task = no_job;
+ opts.task_finished = task_finished;
+ } else {
+ ret = 1;
+ fprintf(stderr, "check usage\n");
+ goto cleanup;
+ }
+ opts.processes = jobs;
+ run_processes_parallel(&opts);
+ ret = 0;
+cleanup:
+ child_process_clear(&proc);
+ return ret;
}
diff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c
index 28e905afc36..824e5c0a958 100644
--- a/t/helper/test-serve-v2.c
+++ b/t/helper/test-serve-v2.c
@@ -24,7 +24,7 @@ int cmd__serve_v2(int argc, const char **argv)
/* ignore all unknown cmdline switches for now */
argc = parse_options(argc, argv, prefix, options, serve_usage,
PARSE_OPT_KEEP_DASHDASH |
- PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
if (advertise_capabilities)
protocol_v2_advertise_capabilities();
diff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c
index d860c387c38..71fe5c61455 100644
--- a/t/helper/test-sha1.c
+++ b/t/helper/test-sha1.c
@@ -5,3 +5,11 @@ int cmd__sha1(int ac, const char **av)
{
return cmd_hash_impl(ac, av, GIT_HASH_SHA1);
}
+
+int cmd__sha1_is_sha1dc(int argc UNUSED, const char **argv UNUSED)
+{
+#ifdef platform_SHA_IS_SHA1DC
+ return 0;
+#endif
+ return 1;
+}
diff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c
index e2692746dfd..22a41c40926 100644
--- a/t/helper/test-submodule-config.c
+++ b/t/helper/test-submodule-config.c
@@ -15,14 +15,11 @@ int cmd__submodule_config(int argc, const char **argv)
{
const char **arg = argv;
int my_argc = argc;
- int output_url = 0;
int lookup_name = 0;
arg++;
my_argc--;
while (arg[0] && starts_with(arg[0], "--")) {
- if (!strcmp(arg[0], "--url"))
- output_url = 1;
if (!strcmp(arg[0], "--name"))
lookup_name = 1;
arg++;
@@ -57,12 +54,8 @@ int cmd__submodule_config(int argc, const char **argv)
if (!submodule)
die_usage(argc, argv, "Submodule not found.");
- if (output_url)
- printf("Submodule url: '%s' for path '%s'\n",
- submodule->url, submodule->path);
- else
- printf("Submodule name: '%s' for path '%s'\n",
- submodule->name, submodule->path);
+ printf("Submodule name: '%s' for path '%s'\n", submodule->name,
+ submodule->path);
arg += 2;
}
diff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c
new file mode 100644
index 00000000000..e060cc62268
--- /dev/null
+++ b/t/helper/test-submodule.c
@@ -0,0 +1,224 @@
+#include "test-tool.h"
+#include "test-tool-utils.h"
+#include "cache.h"
+#include "parse-options.h"
+#include "remote.h"
+#include "submodule-config.h"
+#include "submodule.h"
+
+#define TEST_TOOL_CHECK_NAME_USAGE \
+ "test-tool submodule check-name <name>"
+static const char *submodule_check_name_usage[] = {
+ TEST_TOOL_CHECK_NAME_USAGE,
+ NULL
+};
+
+#define TEST_TOOL_IS_ACTIVE_USAGE \
+ "test-tool submodule is-active <name>"
+static const char *submodule_is_active_usage[] = {
+ TEST_TOOL_IS_ACTIVE_USAGE,
+ NULL
+};
+
+#define TEST_TOOL_RESOLVE_RELATIVE_URL_USAGE \
+ "test-tool submodule resolve-relative-url <up_path> <remoteurl> <url>"
+static const char *submodule_resolve_relative_url_usage[] = {
+ TEST_TOOL_RESOLVE_RELATIVE_URL_USAGE,
+ NULL,
+};
+
+static const char *submodule_usage[] = {
+ TEST_TOOL_CHECK_NAME_USAGE,
+ TEST_TOOL_IS_ACTIVE_USAGE,
+ TEST_TOOL_RESOLVE_RELATIVE_URL_USAGE,
+ NULL
+};
+
+/*
+ * Exit non-zero if any of the submodule names given on the command line is
+ * invalid. If no names are given, filter stdin to print only valid names
+ * (which is primarily intended for testing).
+ */
+static int check_name(int argc, const char **argv)
+{
+ if (argc > 1) {
+ while (*++argv) {
+ if (check_submodule_name(*argv) < 0)
+ return 1;
+ }
+ } else {
+ struct strbuf buf = STRBUF_INIT;
+ while (strbuf_getline(&buf, stdin) != EOF) {
+ if (!check_submodule_name(buf.buf))
+ printf("%s\n", buf.buf);
+ }
+ strbuf_release(&buf);
+ }
+ return 0;
+}
+
+static int cmd__submodule_check_name(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ argc = parse_options(argc, argv, "test-tools", options,
+ submodule_check_name_usage, 0);
+ if (argc)
+ usage_with_options(submodule_check_name_usage, options);
+
+ return check_name(argc, argv);
+}
+
+static int cmd__submodule_is_active(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ argc = parse_options(argc, argv, "test-tools", options,
+ submodule_is_active_usage, 0);
+ if (argc != 1)
+ usage_with_options(submodule_is_active_usage, options);
+
+ setup_git_directory();
+
+ return !is_submodule_active(the_repository, argv[0]);
+}
+
+static int cmd__submodule_resolve_relative_url(int argc, const char **argv)
+{
+ char *remoteurl, *res;
+ const char *up_path, *url;
+ struct option options[] = {
+ OPT_END()
+ };
+ argc = parse_options(argc, argv, "test-tools", options,
+ submodule_resolve_relative_url_usage, 0);
+ if (argc != 3)
+ usage_with_options(submodule_resolve_relative_url_usage, options);
+
+ up_path = argv[0];
+ remoteurl = xstrdup(argv[1]);
+ url = argv[2];
+
+ if (!strcmp(up_path, "(null)"))
+ up_path = NULL;
+
+ res = relative_url(remoteurl, url, up_path);
+ puts(res);
+ free(res);
+ free(remoteurl);
+ return 0;
+}
+
+static int cmd__submodule_config_list(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-list <key>",
+ NULL
+ };
+ argc = parse_options(argc, argv, "test-tools", options, usage,
+ PARSE_OPT_KEEP_ARGV0);
+
+ setup_git_directory();
+
+ if (argc == 2)
+ return print_config_from_gitmodules(the_repository, argv[1]);
+ usage_with_options(usage, options);
+}
+
+static int cmd__submodule_config_set(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-set <key> <value>",
+ NULL
+ };
+ argc = parse_options(argc, argv, "test-tools", options, usage,
+ PARSE_OPT_KEEP_ARGV0);
+
+ setup_git_directory();
+
+ /* Equivalent to ACTION_SET in builtin/config.c */
+ if (argc == 3) {
+ if (!is_writing_gitmodules_ok())
+ die("please make sure that the .gitmodules file is in the working tree");
+
+ return config_set_in_gitmodules_file_gently(argv[1], argv[2]);
+ }
+ usage_with_options(usage, options);
+}
+
+static int cmd__submodule_config_unset(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-unset <key>",
+ NULL
+ };
+
+ setup_git_directory();
+
+ if (argc == 2) {
+ if (!is_writing_gitmodules_ok())
+ die("please make sure that the .gitmodules file is in the working tree");
+ return config_set_in_gitmodules_file_gently(argv[1], NULL);
+ }
+ usage_with_options(usage, options);
+}
+
+static int cmd__submodule_config_writeable(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-writeable",
+ NULL
+ };
+ setup_git_directory();
+
+ if (argc == 1)
+ return is_writing_gitmodules_ok() ? 0 : -1;
+
+ usage_with_options(usage, options);
+}
+
+static struct test_cmd cmds[] = {
+ { "check-name", cmd__submodule_check_name },
+ { "is-active", cmd__submodule_is_active },
+ { "resolve-relative-url", cmd__submodule_resolve_relative_url},
+ { "config-list", cmd__submodule_config_list },
+ { "config-set", cmd__submodule_config_set },
+ { "config-unset", cmd__submodule_config_unset },
+ { "config-writeable", cmd__submodule_config_writeable },
+};
+
+int cmd__submodule(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ size_t i;
+
+ argc = parse_options(argc, argv, "test-tools", options, submodule_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+ if (argc < 1)
+ usage_with_options(submodule_usage, options);
+
+ for (i = 0; i < ARRAY_SIZE(cmds); i++)
+ if (!strcmp(cmds[i].name, argv[0]))
+ return cmds[i].fn(argc, argv);
+
+ usage_msg_optf("unknown subcommand '%s'", submodule_usage, options,
+ argv[0]);
+
+ return 0;
+}
diff --git a/t/helper/test-tool-utils.h b/t/helper/test-tool-utils.h
new file mode 100644
index 00000000000..6a0e5e0074f
--- /dev/null
+++ b/t/helper/test-tool-utils.h
@@ -0,0 +1,9 @@
+#ifndef TEST_TOOL_UTILS_H
+#define TEST_TOOL_UTILS_H
+
+struct test_cmd {
+ const char *name;
+ int (*fn)(int argc, const char **argv);
+};
+
+#endif
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index d6a560f8325..775854c9f96 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -1,5 +1,6 @@
#include "git-compat-util.h"
#include "test-tool.h"
+#include "test-tool-utils.h"
#include "trace2.h"
#include "parse-options.h"
@@ -8,15 +9,11 @@ static const char * const test_tool_usage[] = {
NULL
};
-struct test_cmd {
- const char *name;
- int (*fn)(int argc, const char **argv);
-};
-
static struct test_cmd cmds[] = {
{ "advise", cmd__advise_if_enabled },
{ "bitmap", cmd__bitmap },
{ "bloom", cmd__bloom },
+ { "bundle-uri", cmd__bundle_uri },
{ "chmtime", cmd__chmtime },
{ "config", cmd__config },
{ "crontab", cmd__crontab },
@@ -51,7 +48,9 @@ static struct test_cmd cmds[] = {
{ "online-cpus", cmd__online_cpus },
{ "pack-mtimes", cmd__pack_mtimes },
{ "parse-options", cmd__parse_options },
+ { "parse-options-flags", cmd__parse_options_flags },
{ "parse-pathspec-file", cmd__parse_pathspec_file },
+ { "parse-subcommand", cmd__parse_subcommand },
{ "partial-clone", cmd__partial_clone },
{ "path-utils", cmd__path_utils },
{ "pcre2-config", cmd__pcre2_config },
@@ -74,11 +73,13 @@ static struct test_cmd cmds[] = {
{ "scrap-cache-tree", cmd__scrap_cache_tree },
{ "serve-v2", cmd__serve_v2 },
{ "sha1", cmd__sha1 },
+ { "sha1-is-sha1dc", cmd__sha1_is_sha1dc },
{ "sha256", cmd__sha256 },
{ "sigchain", cmd__sigchain },
{ "simple-ipc", cmd__simple_ipc },
{ "strcmp-offset", cmd__strcmp_offset },
{ "string-list", cmd__string_list },
+ { "submodule", cmd__submodule },
{ "submodule-config", cmd__submodule_config },
{ "submodule-nested-repo-config", cmd__submodule_nested_repo_config },
{ "subprocess", cmd__subprocess },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 21a91b10195..7cf84eca12e 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -7,6 +7,7 @@
int cmd__advise_if_enabled(int argc, const char **argv);
int cmd__bitmap(int argc, const char **argv);
int cmd__bloom(int argc, const char **argv);
+int cmd__bundle_uri(int argc, const char **argv);
int cmd__chmtime(int argc, const char **argv);
int cmd__config(int argc, const char **argv);
int cmd__crontab(int argc, const char **argv);
@@ -41,7 +42,9 @@ int cmd__oidtree(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);
+int cmd__parse_options_flags(int argc, const char **argv);
int cmd__parse_pathspec_file(int argc, const char** argv);
+int cmd__parse_subcommand(int argc, const char **argv);
int cmd__partial_clone(int argc, const char **argv);
int cmd__path_utils(int argc, const char **argv);
int cmd__pcre2_config(int argc, const char **argv);
@@ -63,12 +66,14 @@ int cmd__run_command(int argc, const char **argv);
int cmd__scrap_cache_tree(int argc, const char **argv);
int cmd__serve_v2(int argc, const char **argv);
int cmd__sha1(int argc, const char **argv);
+int cmd__sha1_is_sha1dc(int argc, const char **argv);
int cmd__oid_array(int argc, const char **argv);
int cmd__sha256(int argc, const char **argv);
int cmd__sigchain(int argc, const char **argv);
int cmd__simple_ipc(int argc, const char **argv);
int cmd__strcmp_offset(int argc, const char **argv);
int cmd__string_list(int argc, const char **argv);
+int cmd__submodule(int argc, const char **argv);
int cmd__submodule_config(int argc, const char **argv);
int cmd__submodule_nested_repo_config(int argc, const char **argv);
int cmd__subprocess(int argc, const char **argv);
diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c
index a714130ece7..f374c21ec32 100644
--- a/t/helper/test-trace2.c
+++ b/t/helper/test-trace2.c
@@ -132,6 +132,7 @@ static int ut_003error(int argc, const char **argv)
*/
static int ut_004child(int argc, const char **argv)
{
+ struct child_process cmd = CHILD_PROCESS_INIT;
int result;
/*
@@ -141,7 +142,8 @@ static int ut_004child(int argc, const char **argv)
if (!argc)
return 0;
- result = run_command_v_opt(argv, 0);
+ strvec_pushv(&cmd.args, argv);
+ result = run_command(&cmd);
exit(result);
}
@@ -229,6 +231,187 @@ static int ut_010bug_BUG(int argc, const char **argv)
}
/*
+ * Single-threaded timer test. Create several intervals using the
+ * TEST1 timer. The test script can verify that an aggregate Trace2
+ * "timer" event is emitted indicating that we started+stopped the
+ * timer the requested number of times.
+ */
+static int ut_100timer(int argc, const char **argv)
+{
+ const char *usage_error =
+ "expect <count> <ms_delay>";
+
+ int count = 0;
+ int delay = 0;
+ int k;
+
+ if (argc != 2)
+ die("%s", usage_error);
+ if (get_i(&count, argv[0]))
+ die("%s", usage_error);
+ if (get_i(&delay, argv[1]))
+ die("%s", usage_error);
+
+ for (k = 0; k < count; k++) {
+ trace2_timer_start(TRACE2_TIMER_ID_TEST1);
+ sleep_millisec(delay);
+ trace2_timer_stop(TRACE2_TIMER_ID_TEST1);
+ }
+
+ return 0;
+}
+
+struct ut_101_data {
+ int count;
+ int delay;
+};
+
+static void *ut_101timer_thread_proc(void *_ut_101_data)
+{
+ struct ut_101_data *data = _ut_101_data;
+ int k;
+
+ trace2_thread_start("ut_101");
+
+ for (k = 0; k < data->count; k++) {
+ trace2_timer_start(TRACE2_TIMER_ID_TEST2);
+ sleep_millisec(data->delay);
+ trace2_timer_stop(TRACE2_TIMER_ID_TEST2);
+ }
+
+ trace2_thread_exit();
+ return NULL;
+}
+
+/*
+ * Multi-threaded timer test. Create several threads that each create
+ * several intervals using the TEST2 timer. The test script can verify
+ * that an individual Trace2 "th_timer" events for each thread and an
+ * aggregate "timer" event are generated.
+ */
+static int ut_101timer(int argc, const char **argv)
+{
+ const char *usage_error =
+ "expect <count> <ms_delay> <threads>";
+
+ struct ut_101_data data = { 0, 0 };
+ int nr_threads = 0;
+ int k;
+ pthread_t *pids = NULL;
+
+ if (argc != 3)
+ die("%s", usage_error);
+ if (get_i(&data.count, argv[0]))
+ die("%s", usage_error);
+ if (get_i(&data.delay, argv[1]))
+ die("%s", usage_error);
+ if (get_i(&nr_threads, argv[2]))
+ die("%s", usage_error);
+
+ CALLOC_ARRAY(pids, nr_threads);
+
+ for (k = 0; k < nr_threads; k++) {
+ if (pthread_create(&pids[k], NULL, ut_101timer_thread_proc, &data))
+ die("failed to create thread[%d]", k);
+ }
+
+ for (k = 0; k < nr_threads; k++) {
+ if (pthread_join(pids[k], NULL))
+ die("failed to join thread[%d]", k);
+ }
+
+ free(pids);
+
+ return 0;
+}
+
+/*
+ * Single-threaded counter test. Add several values to the TEST1 counter.
+ * The test script can verify that the final sum is reported in the "counter"
+ * event.
+ */
+static int ut_200counter(int argc, const char **argv)
+{
+ const char *usage_error =
+ "expect <v1> [<v2> [...]]";
+ int value;
+ int k;
+
+ if (argc < 1)
+ die("%s", usage_error);
+
+ for (k = 0; k < argc; k++) {
+ if (get_i(&value, argv[k]))
+ die("invalid value[%s] -- %s",
+ argv[k], usage_error);
+ trace2_counter_add(TRACE2_COUNTER_ID_TEST1, value);
+ }
+
+ return 0;
+}
+
+/*
+ * Multi-threaded counter test. Create seveal threads that each increment
+ * the TEST2 global counter. The test script can verify that an individual
+ * "th_counter" event is generated with a partial sum for each thread and
+ * that a final aggregate "counter" event is generated.
+ */
+
+struct ut_201_data {
+ int v1;
+ int v2;
+};
+
+static void *ut_201counter_thread_proc(void *_ut_201_data)
+{
+ struct ut_201_data *data = _ut_201_data;
+
+ trace2_thread_start("ut_201");
+
+ trace2_counter_add(TRACE2_COUNTER_ID_TEST2, data->v1);
+ trace2_counter_add(TRACE2_COUNTER_ID_TEST2, data->v2);
+
+ trace2_thread_exit();
+ return NULL;
+}
+
+static int ut_201counter(int argc, const char **argv)
+{
+ const char *usage_error =
+ "expect <v1> <v2> <threads>";
+
+ struct ut_201_data data = { 0, 0 };
+ int nr_threads = 0;
+ int k;
+ pthread_t *pids = NULL;
+
+ if (argc != 3)
+ die("%s", usage_error);
+ if (get_i(&data.v1, argv[0]))
+ die("%s", usage_error);
+ if (get_i(&data.v2, argv[1]))
+ die("%s", usage_error);
+ if (get_i(&nr_threads, argv[2]))
+ die("%s", usage_error);
+
+ CALLOC_ARRAY(pids, nr_threads);
+
+ for (k = 0; k < nr_threads; k++) {
+ if (pthread_create(&pids[k], NULL, ut_201counter_thread_proc, &data))
+ die("failed to create thread[%d]", k);
+ }
+
+ for (k = 0; k < nr_threads; k++) {
+ if (pthread_join(pids[k], NULL))
+ die("failed to join thread[%d]", k);
+ }
+
+ free(pids);
+
+ return 0;
+}
+
+/*
* Usage:
* test-tool trace2 <ut_name_1> <ut_usage_1>
* test-tool trace2 <ut_name_2> <ut_usage_2>
@@ -248,6 +431,12 @@ static struct unit_test ut_table[] = {
{ ut_008bug, "008bug", "" },
{ ut_009bug_BUG, "009bug_BUG","" },
{ ut_010bug_BUG, "010bug_BUG","" },
+
+ { ut_100timer, "100timer", "<count> <ms_delay>" },
+ { ut_101timer, "101timer", "<count> <ms_delay> <threads>" },
+
+ { ut_200counter, "200counter", "<v1> [<v2> [<v3> [...]]]" },
+ { ut_201counter, "201counter", "<v1> <v2> <threads>" },
};
/* clang-format on */
diff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c
index f013f8a31e5..a2b56b9cae5 100644
--- a/t/helper/test-userdiff.c
+++ b/t/helper/test-userdiff.c
@@ -12,7 +12,7 @@ static int driver_cb(struct userdiff_driver *driver,
return 0;
}
-static int cmd__userdiff_config(const char *var, const char *value, void *cb)
+static int cmd__userdiff_config(const char *var, const char *value, void *cb UNUSED)
{
if (userdiff_config(var, value) < 0)
return -1;
diff --git a/t/lib-bitmap.sh b/t/lib-bitmap.sh
index a95537e759b..f5959370941 100644
--- a/t/lib-bitmap.sh
+++ b/t/lib-bitmap.sh
@@ -440,7 +440,7 @@ midx_bitmap_partial_tests () {
test_commit packed &&
git repack &&
test_commit loose &&
- git multi-pack-index write --bitmap 2>err &&
+ git multi-pack-index write --bitmap &&
test_path_is_file $midx &&
test_path_is_file $midx-$(midx_checksum $objdir).bitmap
'
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index cc6bb2cdeaa..dcd6e9c3f75 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -7,7 +7,7 @@
. ./test-lib.sh
GIT_TEXTDOMAINDIR="$GIT_BUILD_DIR/po/build/locale"
-GIT_PO_PATH="$GIT_BUILD_DIR/po"
+GIT_PO_PATH="$GIT_SOURCE_DIR/po"
export GIT_TEXTDOMAINDIR GIT_PO_PATH
if test -n "$GIT_TEST_INSTALLED"
diff --git a/t/lib-gitweb.sh b/t/lib-gitweb.sh
index 1f32ca66ea5..6f68df247af 100644
--- a/t/lib-gitweb.sh
+++ b/t/lib-gitweb.sh
@@ -49,7 +49,7 @@ EOF
error "Cannot find gitweb at $GITWEB_TEST_INSTALLED."
say "# Testing $SCRIPT_NAME"
else # normal case, use source version of gitweb
- SCRIPT_NAME="$GIT_BUILD_DIR/gitweb/gitweb.perl"
+ SCRIPT_NAME="$GIT_SOURCE_DIR/gitweb/gitweb.perl"
fi
export SCRIPT_NAME
}
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 497b9b9d927..706799391bd 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -80,6 +80,8 @@ PassEnv LSAN_OPTIONS
PassEnv GIT_TRACE
PassEnv GIT_CONFIG_NOSYSTEM
PassEnv GIT_TEST_SIDEBAND_ALL
+PassEnv LANG
+PassEnv LC_ALL
Alias /dumb/ www/
Alias /auth/dumb/ www/auth/dumb/
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 03e0abbdb83..2d31fcfda1f 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -197,6 +197,7 @@ test_git_directory_exists () {
# the submodule repo if it doesn't exist and configures the most problematic
# settings for diff.ignoreSubmodules.
prolog () {
+ test_config_global protocol.file.allow always &&
(test -d submodule_update_repo || create_lib_submodule_repo) &&
test_config_global diff.ignoreSubmodules all &&
test_config diff.ignoreSubmodules all
diff --git a/t/perf/README b/t/perf/README
index fb9127a66f7..8f217d7be7d 100644
--- a/t/perf/README
+++ b/t/perf/README
@@ -95,6 +95,10 @@ You can set the following variables (also in your config.mak):
Git (e.g., performance of index-pack as the number of threads
changes). These can be enabled with GIT_PERF_EXTRA.
+ GIT_PERF_USE_SCALAR
+ Boolean indicating whether to register test repo(s) with Scalar
+ before executing tests.
+
You can also pass the options taken by ordinary git tests; the most
useful one is:
diff --git a/t/perf/lib-bitmap.sh b/t/perf/lib-bitmap.sh
index 63d3bc7cece..55a8feb1dc4 100644
--- a/t/perf/lib-bitmap.sh
+++ b/t/perf/lib-bitmap.sh
@@ -67,3 +67,34 @@ test_partial_bitmap () {
--filter=tree:0 >/dev/null
'
}
+
+test_pack_bitmap () {
+ test_perf "repack to disk" '
+ git repack -ad
+ '
+
+ test_full_bitmap
+
+ test_expect_success "create partial bitmap state" '
+ # pick a commit to represent the repo tip in the past
+ cutoff=$(git rev-list HEAD~100 -1) &&
+ orig_tip=$(git rev-parse HEAD) &&
+
+ # now kill off all of the refs and pretend we had
+ # just the one tip
+ rm -rf .git/logs .git/refs/* .git/packed-refs &&
+ git update-ref HEAD $cutoff &&
+
+ # and then repack, which will leave us with a nice
+ # big bitmap pack of the "old" history, and all of
+ # the new history will be loose, as if it had been pushed
+ # up incrementally and exploded via unpack-objects
+ git repack -Ad &&
+
+ # and now restore our original tip, as if the pushes
+ # had happened
+ git update-ref HEAD $orig_tip
+ '
+
+ test_partial_bitmap
+}
diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh
index fce8151d41c..3242cfe91a0 100755
--- a/t/perf/p2000-sparse-operations.sh
+++ b/t/perf/p2000-sparse-operations.sh
@@ -124,5 +124,6 @@ test_perf_on_all git read-tree -mu HEAD
test_perf_on_all git checkout-index -f --all
test_perf_on_all git update-index --add --remove $SPARSE_CONE/a
test_perf_on_all "git rm -f $SPARSE_CONE/a && git checkout HEAD -- $SPARSE_CONE/a"
+test_perf_on_all git grep --cached --sparse bogus -- "f2/f1/f1/*"
test_done
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index 7ad4f237bc3..b1399f1007e 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -4,51 +4,37 @@ test_description='Tests pack performance using bitmaps'
. ./perf-lib.sh
. "${TEST_DIRECTORY}/perf/lib-bitmap.sh"
-test_perf_large_repo
-
-# note that we do everything through config,
-# since we want to be able to compare bitmap-aware
-# git versus non-bitmap git
-#
-# We intentionally use the deprecated pack.writebitmaps
-# config so that we can test against older versions of git.
-test_expect_success 'setup bitmap config' '
- git config pack.writebitmaps true
-'
-
-# we need to create the tag up front such that it is covered by the repack and
-# thus by generated bitmaps.
-test_expect_success 'create tags' '
- git tag --message="tag pointing to HEAD" perf-tag HEAD
-'
-
-test_perf 'repack to disk' '
- git repack -ad
-'
-
-test_full_bitmap
-
-test_expect_success 'create partial bitmap state' '
- # pick a commit to represent the repo tip in the past
- cutoff=$(git rev-list HEAD~100 -1) &&
- orig_tip=$(git rev-parse HEAD) &&
-
- # now kill off all of the refs and pretend we had
- # just the one tip
- rm -rf .git/logs .git/refs/* .git/packed-refs &&
- git update-ref HEAD $cutoff &&
-
- # and then repack, which will leave us with a nice
- # big bitmap pack of the "old" history, and all of
- # the new history will be loose, as if it had been pushed
- # up incrementally and exploded via unpack-objects
- git repack -Ad &&
-
- # and now restore our original tip, as if the pushes
- # had happened
- git update-ref HEAD $orig_tip
-'
-
-test_partial_bitmap
+test_lookup_pack_bitmap () {
+ test_expect_success 'start the test from scratch' '
+ rm -rf * .git
+ '
+
+ test_perf_large_repo
+
+ # note that we do everything through config,
+ # since we want to be able to compare bitmap-aware
+ # git versus non-bitmap git
+ #
+ # We intentionally use the deprecated pack.writebitmaps
+ # config so that we can test against older versions of git.
+ test_expect_success 'setup bitmap config' '
+ git config pack.writebitmaps true
+ '
+
+ # we need to create the tag up front such that it is covered by the repack and
+ # thus by generated bitmaps.
+ test_expect_success 'create tags' '
+ git tag --message="tag pointing to HEAD" perf-tag HEAD
+ '
+
+ test_perf "enable lookup table: $1" '
+ git config pack.writeBitmapLookupTable '"$1"'
+ '
+
+ test_pack_bitmap
+}
+
+test_lookup_pack_bitmap false
+test_lookup_pack_bitmap true
test_done
diff --git a/t/perf/p5311-pack-bitmaps-fetch.sh b/t/perf/p5311-pack-bitmaps-fetch.sh
index 47c3fd7581c..426fab87e32 100755
--- a/t/perf/p5311-pack-bitmaps-fetch.sh
+++ b/t/perf/p5311-pack-bitmaps-fetch.sh
@@ -3,42 +3,52 @@
test_description='performance of fetches from bitmapped packs'
. ./perf-lib.sh
-test_perf_default_repo
-
-test_expect_success 'create bitmapped server repo' '
- git config pack.writebitmaps true &&
- git repack -ad
-'
-
-# simulate a fetch from a repository that last fetched N days ago, for
-# various values of N. We do so by following the first-parent chain,
-# and assume the first entry in the chain that is N days older than the current
-# HEAD is where the HEAD would have been then.
-for days in 1 2 4 8 16 32 64 128; do
- title=$(printf '%10s' "($days days)")
- test_expect_success "setup revs from $days days ago" '
- now=$(git log -1 --format=%ct HEAD) &&
- then=$(($now - ($days * 86400))) &&
- tip=$(git rev-list -1 --first-parent --until=$then HEAD) &&
- {
- echo HEAD &&
- echo ^$tip
- } >revs
+test_fetch_bitmaps () {
+ test_expect_success 'setup test directory' '
+ rm -fr * .git
'
- test_perf "server $title" '
- git pack-objects --stdout --revs \
- --thin --delta-base-offset \
- <revs >tmp.pack
- '
+ test_perf_default_repo
- test_size "size $title" '
- wc -c <tmp.pack
+ test_expect_success 'create bitmapped server repo' '
+ git config pack.writebitmaps true &&
+ git config pack.writeBitmapLookupTable '"$1"' &&
+ git repack -ad
'
- test_perf "client $title" '
- git index-pack --stdin --fix-thin <tmp.pack
- '
-done
+ # simulate a fetch from a repository that last fetched N days ago, for
+ # various values of N. We do so by following the first-parent chain,
+ # and assume the first entry in the chain that is N days older than the current
+ # HEAD is where the HEAD would have been then.
+ for days in 1 2 4 8 16 32 64 128; do
+ title=$(printf '%10s' "($days days)")
+ test_expect_success "setup revs from $days days ago" '
+ now=$(git log -1 --format=%ct HEAD) &&
+ then=$(($now - ($days * 86400))) &&
+ tip=$(git rev-list -1 --first-parent --until=$then HEAD) &&
+ {
+ echo HEAD &&
+ echo ^$tip
+ } >revs
+ '
+
+ test_perf "server $title (lookup=$1)" '
+ git pack-objects --stdout --revs \
+ --thin --delta-base-offset \
+ <revs >tmp.pack
+ '
+
+ test_size "size $title" '
+ wc -c <tmp.pack
+ '
+
+ test_perf "client $title (lookup=$1)" '
+ git index-pack --stdin --fix-thin <tmp.pack
+ '
+ done
+}
+
+test_fetch_bitmaps true
+test_fetch_bitmaps false
test_done
diff --git a/t/perf/p5312-pack-bitmaps-revs.sh b/t/perf/p5312-pack-bitmaps-revs.sh
new file mode 100755
index 00000000000..0684b690af0
--- /dev/null
+++ b/t/perf/p5312-pack-bitmaps-revs.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+test_description='Tests pack performance using bitmaps (rev index enabled)'
+. ./perf-lib.sh
+. "${TEST_DIRECTORY}/perf/lib-bitmap.sh"
+
+test_lookup_pack_bitmap () {
+ test_expect_success 'start the test from scratch' '
+ rm -rf * .git
+ '
+
+ test_perf_large_repo
+
+ test_expect_success 'setup bitmap config' '
+ git config pack.writebitmaps true &&
+ git config pack.writeReverseIndex true
+ '
+
+ # we need to create the tag up front such that it is covered by the repack and
+ # thus by generated bitmaps.
+ test_expect_success 'create tags' '
+ git tag --message="tag pointing to HEAD" perf-tag HEAD
+ '
+
+ test_perf "enable lookup table: $1" '
+ git config pack.writeBitmapLookupTable '"$1"'
+ '
+
+ test_pack_bitmap
+}
+
+test_lookup_pack_bitmap false
+test_lookup_pack_bitmap true
+
+test_done
diff --git a/t/perf/p5326-multi-pack-bitmaps.sh b/t/perf/p5326-multi-pack-bitmaps.sh
index f2fa228f16a..d082e6cacbe 100755
--- a/t/perf/p5326-multi-pack-bitmaps.sh
+++ b/t/perf/p5326-multi-pack-bitmaps.sh
@@ -4,49 +4,64 @@ test_description='Tests performance using midx bitmaps'
. ./perf-lib.sh
. "${TEST_DIRECTORY}/perf/lib-bitmap.sh"
-test_perf_large_repo
-
-# we need to create the tag up front such that it is covered by the repack and
-# thus by generated bitmaps.
-test_expect_success 'create tags' '
- git tag --message="tag pointing to HEAD" perf-tag HEAD
-'
-
-test_expect_success 'start with bitmapped pack' '
- git repack -adb
-'
-
-test_perf 'setup multi-pack index' '
- git multi-pack-index write --bitmap
-'
-
-test_expect_success 'drop pack bitmap' '
- rm -f .git/objects/pack/pack-*.bitmap
-'
-
-test_full_bitmap
-
-test_expect_success 'create partial bitmap state' '
- # pick a commit to represent the repo tip in the past
- cutoff=$(git rev-list HEAD~100 -1) &&
- orig_tip=$(git rev-parse HEAD) &&
-
- # now pretend we have just one tip
- rm -rf .git/logs .git/refs/* .git/packed-refs &&
- git update-ref HEAD $cutoff &&
-
- # and then repack, which will leave us with a nice
- # big bitmap pack of the "old" history, and all of
- # the new history will be loose, as if it had been pushed
- # up incrementally and exploded via unpack-objects
- git repack -Ad &&
- git multi-pack-index write --bitmap &&
-
- # and now restore our original tip, as if the pushes
- # had happened
- git update-ref HEAD $orig_tip
-'
-
-test_partial_bitmap
+test_bitmap () {
+ local enabled="$1"
+
+ test_expect_success "remove existing repo (lookup=$enabled)" '
+ rm -fr * .git
+ '
+
+ test_perf_large_repo
+
+ # we need to create the tag up front such that it is covered by the repack and
+ # thus by generated bitmaps.
+ test_expect_success 'create tags' '
+ git tag --message="tag pointing to HEAD" perf-tag HEAD
+ '
+
+ test_expect_success "use lookup table: $enabled" '
+ git config pack.writeBitmapLookupTable '"$enabled"'
+ '
+
+ test_expect_success "start with bitmapped pack (lookup=$enabled)" '
+ git repack -adb
+ '
+
+ test_perf "setup multi-pack index (lookup=$enabled)" '
+ git multi-pack-index write --bitmap
+ '
+
+ test_expect_success "drop pack bitmap (lookup=$enabled)" '
+ rm -f .git/objects/pack/pack-*.bitmap
+ '
+
+ test_full_bitmap
+
+ test_expect_success "create partial bitmap state (lookup=$enabled)" '
+ # pick a commit to represent the repo tip in the past
+ cutoff=$(git rev-list HEAD~100 -1) &&
+ orig_tip=$(git rev-parse HEAD) &&
+
+ # now pretend we have just one tip
+ rm -rf .git/logs .git/refs/* .git/packed-refs &&
+ git update-ref HEAD $cutoff &&
+
+ # and then repack, which will leave us with a nice
+ # big bitmap pack of the "old" history, and all of
+ # the new history will be loose, as if it had been pushed
+ # up incrementally and exploded via unpack-objects
+ git repack -Ad &&
+ git multi-pack-index write --bitmap &&
+
+ # and now restore our original tip, as if the pushes
+ # had happened
+ git update-ref HEAD $orig_tip
+ '
+
+ test_partial_bitmap
+}
+
+test_bitmap false
+test_bitmap true
test_done
diff --git a/t/perf/p9210-scalar.sh b/t/perf/p9210-scalar.sh
new file mode 100755
index 00000000000..265f7cd1fe2
--- /dev/null
+++ b/t/perf/p9210-scalar.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+test_description='test scalar performance'
+. ./perf-lib.sh
+
+test_perf_large_repo "$TRASH_DIRECTORY/to-clone"
+
+test_expect_success 'enable server-side partial clone' '
+ git -C to-clone config uploadpack.allowFilter true &&
+ git -C to-clone config uploadpack.allowAnySHA1InWant true
+'
+
+test_perf 'scalar clone' '
+ rm -rf scalar-clone &&
+ scalar clone "file://$(pwd)/to-clone" scalar-clone
+'
+
+test_perf 'git clone' '
+ rm -rf git-clone &&
+ git clone "file://$(pwd)/to-clone" git-clone
+'
+
+test_compare_perf () {
+ command=$1
+ shift
+ args=$*
+ test_perf "$command $args (scalar)" "
+ $command -C scalar-clone/src $args
+ "
+
+ test_perf "$command $args (non-scalar)" "
+ $command -C git-clone $args
+ "
+}
+
+test_compare_perf git status
+test_compare_perf test_commit --append --no-tag A
+
+test_done
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index 27c28017921..e7786775a90 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -49,6 +49,9 @@ export TEST_DIRECTORY TRASH_DIRECTORY GIT_BUILD_DIR GIT_TEST_CMP
MODERN_GIT=$GIT_BUILD_DIR/bin-wrappers/git
export MODERN_GIT
+MODERN_SCALAR=$GIT_BUILD_DIR/bin-wrappers/scalar
+export MODERN_SCALAR
+
perf_results_dir=$TEST_RESULTS_DIR
test -n "$GIT_PERF_SUBSECTION" && perf_results_dir="$perf_results_dir/$GIT_PERF_SUBSECTION"
mkdir -p "$perf_results_dir"
@@ -120,6 +123,10 @@ test_perf_create_repo_from () {
# status" due to a locked index. Since we have
# a copy it's fine to remove the lock.
rm .git/index.lock
+ fi &&
+ if test_bool_env GIT_PERF_USE_SCALAR false
+ then
+ "$MODERN_SCALAR" register
fi
) || error "failed to copy repository '$source' to '$repo'"
}
@@ -130,7 +137,11 @@ test_perf_fresh_repo () {
"$MODERN_GIT" init -q "$repo" &&
(
cd "$repo" &&
- test_perf_do_repo_symlink_config_
+ test_perf_do_repo_symlink_config_ &&
+ if test_bool_env GIT_PERF_USE_SCALAR false
+ then
+ "$MODERN_SCALAR" register
+ fi
)
}
diff --git a/t/perf/run b/t/perf/run
index 55219aa4056..34115edec35 100755
--- a/t/perf/run
+++ b/t/perf/run
@@ -171,6 +171,9 @@ run_subsection () {
get_var_from_env_or_config "GIT_PERF_MAKE_COMMAND" "perf" "makeCommand"
get_var_from_env_or_config "GIT_PERF_MAKE_OPTS" "perf" "makeOpts"
+ get_var_from_env_or_config "GIT_PERF_USE_SCALAR" "perf" "useScalar" "--bool"
+ export GIT_PERF_USE_SCALAR
+
get_var_from_env_or_config "GIT_PERF_REPO_NAME" "perf" "repoName"
export GIT_PERF_REPO_NAME
@@ -229,10 +232,10 @@ then
)
elif test -n "$GIT_PERF_SUBSECTION"
then
- egrep "^$GIT_PERF_SUBSECTION\$" "$TEST_RESULTS_DIR"/run_subsections.names >/dev/null ||
+ grep -E "^$GIT_PERF_SUBSECTION\$" "$TEST_RESULTS_DIR"/run_subsections.names >/dev/null ||
die "subsection '$GIT_PERF_SUBSECTION' not found in '$GIT_PERF_CONFIG_FILE'"
- egrep "^$GIT_PERF_SUBSECTION\$" "$TEST_RESULTS_DIR"/run_subsections.names | while read -r subsec
+ grep -E "^$GIT_PERF_SUBSECTION\$" "$TEST_RESULTS_DIR"/run_subsections.names | while read -r subsec
do
(
GIT_PERF_SUBSECTION="$subsec"
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index 4ed2f242eb2..dbfc5c82676 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -231,7 +231,7 @@ test_expect_success "'git help -a' section spacing" '
User-facing repository, command and file interfaces
- Developer-facing file file formats, protocols and interfaces
+ Developer-facing file formats, protocols and other interfaces
EOF
test_cmp expect actual
'
diff --git a/t/t0013-sha1dc.sh b/t/t0013-sha1dc.sh
index 9ad76080aa4..53240476896 100755
--- a/t/t0013-sha1dc.sh
+++ b/t/t0013-sha1dc.sh
@@ -6,9 +6,11 @@ TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
TEST_DATA="$TEST_DIRECTORY/t0013"
-if test -z "$DC_SHA1"
+test_lazy_prereq SHA1_IS_SHA1DC 'test-tool sha1-is-sha1dc'
+
+if ! test_have_prereq SHA1_IS_SHA1DC
then
- skip_all='skipping sha1 collision tests, DC_SHA1 not set'
+ skip_all='skipping sha1 collision tests, not using sha1collisiondetection'
test_done
fi
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index a22e0e1382c..a94ac1eae37 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -387,9 +387,7 @@ test_expect_success 'setup main' '
test_tick
'
-# Disable extra chain-linting for the next set of tests. There are many
-# auto-generated ones that are not worth checking over and over.
-GIT_TEST_CHAIN_LINT_HARDER_DEFAULT=0
+
warn_LF_CRLF="LF will be replaced by CRLF"
warn_CRLF_LF="CRLF will be replaced by LF"
@@ -606,9 +604,6 @@ do
checkout_files "" "$id" "crlf" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
done
-# The rest of the tests are unique; do the usual linting.
-unset GIT_TEST_CHAIN_LINT_HARDER_DEFAULT
-
# Should be the last test case: remove some files from the worktree
test_expect_success 'ls-files --eol -d -z' '
rm crlf_false_attr__CRLF.txt crlf_false_attr__CRLF_mix_LF.txt crlf_false_attr__LF.txt .gitattributes &&
diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh
index aecb308cf66..dc3496897ab 100755
--- a/t/t0033-safe-directory.sh
+++ b/t/t0033-safe-directory.sh
@@ -71,4 +71,13 @@ test_expect_success 'safe.directory=*, but is reset' '
expect_rejected_dir
'
+test_expect_success 'safe.directory in included file' '
+ cat >gitconfig-include <<-EOF &&
+ [safe]
+ directory = "$(pwd)"
+ EOF
+ git config --global --add include.path "$(pwd)/gitconfig-include" &&
+ git status
+'
+
test_done
diff --git a/t/t0035-safe-bare-repository.sh b/t/t0035-safe-bare-repository.sh
index ecbdc8238db..11c15a48aab 100755
--- a/t/t0035-safe-bare-repository.sh
+++ b/t/t0035-safe-bare-repository.sh
@@ -51,4 +51,13 @@ test_expect_success 'safe.bareRepository on the command line' '
-c safe.bareRepository=all
'
+test_expect_success 'safe.bareRepository in included file' '
+ cat >gitconfig-include <<-\EOF &&
+ [safe]
+ bareRepository = explicit
+ EOF
+ git config --global --add include.path "$(pwd)/gitconfig-include" &&
+ expect_rejected -C outer-repo/bare-repo
+'
+
test_done
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index ed2fb620a9d..5cc62306e39 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -456,4 +456,257 @@ test_expect_success '--end-of-options treats remainder as args' '
--end-of-options --verbose
'
+test_expect_success 'KEEP_DASHDASH works' '
+ test-tool parse-options-flags --keep-dashdash cmd --opt=1 -- --opt=2 --unknown >actual &&
+ cat >expect <<-\EOF &&
+ opt: 1
+ arg 00: --
+ arg 01: --opt=2
+ arg 02: --unknown
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'KEEP_ARGV0 works' '
+ test-tool parse-options-flags --keep-argv0 cmd arg0 --opt=3 >actual &&
+ cat >expect <<-\EOF &&
+ opt: 3
+ arg 00: cmd
+ arg 01: arg0
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'STOP_AT_NON_OPTION works' '
+ test-tool parse-options-flags --stop-at-non-option cmd --opt=4 arg0 --opt=5 --unknown >actual &&
+ cat >expect <<-\EOF &&
+ opt: 4
+ arg 00: arg0
+ arg 01: --opt=5
+ arg 02: --unknown
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'KEEP_UNKNOWN_OPT works' '
+ test-tool parse-options-flags --keep-unknown-opt cmd --unknown=1 --opt=6 -u2 >actual &&
+ cat >expect <<-\EOF &&
+ opt: 6
+ arg 00: --unknown=1
+ arg 01: -u2
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'NO_INTERNAL_HELP works for -h' '
+ test_expect_code 129 test-tool parse-options-flags --no-internal-help cmd -h 2>err &&
+ grep "^error: unknown switch \`h$SQ" err &&
+ grep "^usage: " err
+'
+
+for help_opt in help help-all
+do
+ test_expect_success "NO_INTERNAL_HELP works for --$help_opt" "
+ test_expect_code 129 test-tool parse-options-flags --no-internal-help cmd --$help_opt 2>err &&
+ grep '^error: unknown option \`'$help_opt\' err &&
+ grep '^usage: ' err
+ "
+done
+
+test_expect_success 'KEEP_UNKNOWN_OPT | NO_INTERNAL_HELP works' '
+ test-tool parse-options-flags --keep-unknown-opt --no-internal-help cmd -h --help --help-all >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ arg 00: -h
+ arg 01: --help
+ arg 02: --help-all
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - no subcommand shows error and usage' '
+ test_expect_code 129 test-tool parse-subcommand cmd 2>err &&
+ grep "^error: need a subcommand" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - subcommand after -- shows error and usage' '
+ test_expect_code 129 test-tool parse-subcommand cmd -- subcmd-one 2>err &&
+ grep "^error: need a subcommand" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - subcommand after --end-of-options shows error and usage' '
+ test_expect_code 129 test-tool parse-subcommand cmd --end-of-options subcmd-one 2>err &&
+ grep "^error: need a subcommand" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - unknown subcommand shows error and usage' '
+ test_expect_code 129 test-tool parse-subcommand cmd nope 2>err &&
+ grep "^error: unknown subcommand: \`nope$SQ" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - subcommands cannot be abbreviated' '
+ test_expect_code 129 test-tool parse-subcommand cmd subcmd-o 2>err &&
+ grep "^error: unknown subcommand: \`subcmd-o$SQ$" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - no negated subcommands' '
+ test_expect_code 129 test-tool parse-subcommand cmd no-subcmd-one 2>err &&
+ grep "^error: unknown subcommand: \`no-subcmd-one$SQ" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - simple' '
+ test-tool parse-subcommand cmd subcmd-two >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_two
+ arg 00: subcmd-two
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - stop parsing at the first subcommand' '
+ test-tool parse-subcommand cmd --opt=1 subcmd-two subcmd-one --opt=2 >actual &&
+ cat >expect <<-\EOF &&
+ opt: 1
+ fn: subcmd_two
+ arg 00: subcmd-two
+ arg 01: subcmd-one
+ arg 02: --opt=2
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - KEEP_ARGV0' '
+ test-tool parse-subcommand --keep-argv0 cmd subcmd-two >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_two
+ arg 00: cmd
+ arg 01: subcmd-two
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL + subcommand not given' '
+ test-tool parse-subcommand --subcommand-optional cmd >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL + given subcommand' '
+ test-tool parse-subcommand --subcommand-optional cmd subcmd-two branch file >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_two
+ arg 00: subcmd-two
+ arg 01: branch
+ arg 02: file
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL + subcommand not given + unknown dashless args' '
+ test-tool parse-subcommand --subcommand-optional cmd branch file >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ arg 00: branch
+ arg 01: file
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL + subcommand not given + unknown option' '
+ test_expect_code 129 test-tool parse-subcommand --subcommand-optional cmd --subcommand-opt 2>err &&
+ grep "^error: unknown option" err &&
+ grep ^usage: err
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL | KEEP_UNKNOWN_OPT + subcommand not given + unknown option' '
+ test-tool parse-subcommand --subcommand-optional --keep-unknown-opt cmd --subcommand-opt >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ arg 00: --subcommand-opt
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL | KEEP_UNKNOWN_OPT + subcommand ignored after unknown option' '
+ test-tool parse-subcommand --subcommand-optional --keep-unknown-opt cmd --subcommand-opt subcmd-two >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ arg 00: --subcommand-opt
+ arg 01: subcmd-two
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL | KEEP_UNKNOWN_OPT + command and subcommand options cannot be mixed' '
+ test-tool parse-subcommand --subcommand-optional --keep-unknown-opt cmd --subcommand-opt branch --opt=1 >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ arg 00: --subcommand-opt
+ arg 01: branch
+ arg 02: --opt=1
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL | KEEP_UNKNOWN_OPT | KEEP_ARGV0' '
+ test-tool parse-subcommand --subcommand-optional --keep-unknown-opt --keep-argv0 cmd --subcommand-opt branch >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ arg 00: cmd
+ arg 01: --subcommand-opt
+ arg 02: branch
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - SUBCOMMAND_OPTIONAL | KEEP_UNKNOWN_OPT | KEEP_DASHDASH' '
+ test-tool parse-subcommand --subcommand-optional --keep-unknown-opt --keep-dashdash cmd -- --subcommand-opt file >actual &&
+ cat >expect <<-\EOF &&
+ opt: 0
+ fn: subcmd_one
+ arg 00: --
+ arg 01: --subcommand-opt
+ arg 02: file
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommand - completion helper' '
+ test-tool parse-subcommand cmd --git-completion-helper >actual &&
+ echo "subcmd-one subcmd-two --opt= --no-opt" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'subcommands are incompatible with STOP_AT_NON_OPTION' '
+ test_must_fail test-tool parse-subcommand --stop-at-non-option cmd subcmd-one 2>err &&
+ grep ^BUG err
+'
+
+test_expect_success 'subcommands are incompatible with KEEP_UNKNOWN_OPT unless in combination with SUBCOMMAND_OPTIONAL' '
+ test_must_fail test-tool parse-subcommand --keep-unknown-opt cmd subcmd-two 2>err &&
+ grep ^BUG err
+'
+
+test_expect_success 'subcommands are incompatible with KEEP_DASHDASH unless in combination with SUBCOMMAND_OPTIONAL' '
+ test_must_fail test-tool parse-subcommand --keep-dashdash cmd subcmd-two 2>err &&
+ grep ^BUG err
+'
+
test_done
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 1f2007e62b7..68e29c904a6 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -22,7 +22,7 @@ relative_path() {
test_submodule_relative_url() {
test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
- actual=\$(git submodule--helper resolve-relative-url-test '$1' '$2' '$3') &&
+ actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
test \"\$actual\" = '$4'
"
}
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index 7b5423eebda..e2411f6a9bd 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -130,7 +130,8 @@ World
EOF
test_expect_success 'run_command runs in parallel with more jobs available than tasks' '
- test-tool run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+ test-tool run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>actual &&
+ test_must_be_empty out &&
test_cmp expect actual
'
@@ -141,7 +142,8 @@ test_expect_success 'run_command runs ungrouped in parallel with more jobs avail
'
test_expect_success 'run_command runs in parallel with as many jobs as tasks' '
- test-tool run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+ test-tool run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>actual &&
+ test_must_be_empty out &&
test_cmp expect actual
'
@@ -152,7 +154,8 @@ test_expect_success 'run_command runs ungrouped in parallel with as many jobs as
'
test_expect_success 'run_command runs in parallel with more tasks than jobs available' '
- test-tool run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+ test-tool run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>actual &&
+ test_must_be_empty out &&
test_cmp expect actual
'
@@ -172,7 +175,8 @@ asking for a quick stop
EOF
test_expect_success 'run_command is asked to abort gracefully' '
- test-tool run-command run-command-abort 3 false 2>actual &&
+ test-tool run-command run-command-abort 3 false >out 2>actual &&
+ test_must_be_empty out &&
test_cmp expect actual
'
@@ -187,7 +191,8 @@ no further jobs available
EOF
test_expect_success 'run_command outputs ' '
- test-tool run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+ test-tool run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>actual &&
+ test_must_be_empty out &&
test_cmp expect actual
'
diff --git a/t/t0068-for-each-repo.sh b/t/t0068-for-each-repo.sh
index 4675e852517..c6e0d655630 100755
--- a/t/t0068-for-each-repo.sh
+++ b/t/t0068-for-each-repo.sh
@@ -8,9 +8,11 @@ test_expect_success 'run based on configured value' '
git init one &&
git init two &&
git init three &&
+ git init ~/four &&
git -C two commit --allow-empty -m "DID NOT RUN" &&
git config run.key "$TRASH_DIRECTORY/one" &&
git config --add run.key "$TRASH_DIRECTORY/three" &&
+ git config --add run.key "~/four" &&
git for-each-repo --config=run.key commit --allow-empty -m "ran" &&
git -C one log -1 --pretty=format:%s >message &&
grep ran message &&
@@ -18,12 +20,16 @@ test_expect_success 'run based on configured value' '
! grep ran message &&
git -C three log -1 --pretty=format:%s >message &&
grep ran message &&
+ git -C ~/four log -1 --pretty=format:%s >message &&
+ grep ran message &&
git for-each-repo --config=run.key -- commit --allow-empty -m "ran again" &&
git -C one log -1 --pretty=format:%s >message &&
grep again message &&
git -C two log -1 --pretty=format:%s >message &&
! grep again message &&
git -C three log -1 --pretty=format:%s >message &&
+ grep again message &&
+ git -C ~/four log -1 --pretty=format:%s >message &&
grep again message
'
diff --git a/t/t0092-diagnose.sh b/t/t0092-diagnose.sh
index fca9b58489c..133e5747d61 100755
--- a/t/t0092-diagnose.sh
+++ b/t/t0092-diagnose.sh
@@ -28,12 +28,23 @@ test_expect_success UNZIP 'creates diagnostics zip archive' '
! "$GIT_UNZIP" -l "$zip_path" | grep ".git/"
'
+test_expect_success UNZIP 'counts loose objects' '
+ test_commit A &&
+
+ # After committing, should have non-zero loose objects
+ git diagnose -o test-count -s 1 >out &&
+ zip_path=test-count/git-diagnostics-1.zip &&
+ "$GIT_UNZIP" -p "$zip_path" objects-local.txt >out &&
+ grep "^Total: [1-9][0-9]* loose objects" out
+'
+
test_expect_success UNZIP '--mode=stats excludes .git dir contents' '
test_when_finished rm -rf report &&
git diagnose -o report -s test --mode=stats >out &&
# Includes pack quantity/size info
+ zip_path=report/git-diagnostics-test.zip &&
"$GIT_UNZIP" -p "$zip_path" packs-local.txt >out &&
grep ".git/objects" out &&
@@ -47,6 +58,7 @@ test_expect_success UNZIP '--mode=all includes .git dir contents' '
git diagnose -o report -s test --mode=all >out &&
# Includes pack quantity/size info
+ zip_path=report/git-diagnostics-test.zip &&
"$GIT_UNZIP" -p "$zip_path" packs-local.txt >out &&
grep ".git/objects" out &&
diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh
index 22d0845544e..0b3436e8cac 100755
--- a/t/t0211-trace2-perf.sh
+++ b/t/t0211-trace2-perf.sh
@@ -173,4 +173,99 @@ test_expect_success 'using global config, perf stream, return code 0' '
test_cmp expect actual
'
+# Exercise the stopwatch timers in a loop and confirm that we have
+# as many start/stop intervals as expected. We cannot really test the
+# actual (total, min, max) timer values, so we have to assume that they
+# are good, but we can verify the interval count.
+#
+# The timer "test/test1" should only emit a global summary "timer" event.
+# The timer "test/test2" should emit per-thread "th_timer" events and a
+# global summary "timer" event.
+
+have_timer_event () {
+ thread=$1 event=$2 category=$3 name=$4 intervals=$5 file=$6 &&
+
+ pattern="d0|${thread}|${event}||||${category}|name:${name} intervals:${intervals}" &&
+
+ grep "${pattern}" ${file}
+}
+
+test_expect_success 'stopwatch timer test/test1' '
+ test_when_finished "rm trace.perf actual" &&
+ test_config_global trace2.perfBrief 1 &&
+ test_config_global trace2.perfTarget "$(pwd)/trace.perf" &&
+
+ # Use the timer "test1" 5 times from "main".
+ test-tool trace2 100timer 5 10 &&
+
+ perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
+
+ have_timer_event "main" "timer" "test" "test1" 5 actual
+'
+
+test_expect_success 'stopwatch timer test/test2' '
+ test_when_finished "rm trace.perf actual" &&
+ test_config_global trace2.perfBrief 1 &&
+ test_config_global trace2.perfTarget "$(pwd)/trace.perf" &&
+
+ # Use the timer "test2" 5 times each in 3 threads.
+ test-tool trace2 101timer 5 10 3 &&
+
+ perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
+
+ # So we should have 3 per-thread events of 5 each.
+ have_timer_event "th01:ut_101" "th_timer" "test" "test2" 5 actual &&
+ have_timer_event "th02:ut_101" "th_timer" "test" "test2" 5 actual &&
+ have_timer_event "th03:ut_101" "th_timer" "test" "test2" 5 actual &&
+
+ # And we should have 15 total uses.
+ have_timer_event "main" "timer" "test" "test2" 15 actual
+'
+
+# Exercise the global counters and confirm that we get the expected values.
+#
+# The counter "test/test1" should only emit a global summary "counter" event.
+# The counter "test/test2" could emit per-thread "th_counter" events and a
+# global summary "counter" event.
+
+have_counter_event () {
+ thread=$1 event=$2 category=$3 name=$4 value=$5 file=$6 &&
+
+ pattern="d0|${thread}|${event}||||${category}|name:${name} value:${value}" &&
+
+ grep "${patern}" ${file}
+}
+
+test_expect_success 'global counter test/test1' '
+ test_when_finished "rm trace.perf actual" &&
+ test_config_global trace2.perfBrief 1 &&
+ test_config_global trace2.perfTarget "$(pwd)/trace.perf" &&
+
+ # Use the counter "test1" and add n integers.
+ test-tool trace2 200counter 1 2 3 4 5 &&
+
+ perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
+
+ have_counter_event "main" "counter" "test" "test1" 15 actual
+'
+
+test_expect_success 'global counter test/test2' '
+ test_when_finished "rm trace.perf actual" &&
+ test_config_global trace2.perfBrief 1 &&
+ test_config_global trace2.perfTarget "$(pwd)/trace.perf" &&
+
+ # Add 2 integers to the counter "test2" in each of 3 threads.
+ test-tool trace2 201counter 7 13 3 &&
+
+ perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
+
+ # So we should have 3 per-thread events of 5 each.
+ have_counter_event "th01:ut_201" "th_counter" "test" "test2" 20 actual &&
+ have_counter_event "th02:ut_201" "th_counter" "test" "test2" 20 actual &&
+ have_counter_event "th03:ut_201" "th_counter" "test" "test2" 20 actual &&
+
+ # And we should have a single event with the total across all threads.
+ have_counter_event "main" "counter" "test" "test2" 60 actual
+'
+
test_done
diff --git a/t/t0211/scrub_perf.perl b/t/t0211/scrub_perf.perl
index 299999f0f89..7a50bae6463 100644
--- a/t/t0211/scrub_perf.perl
+++ b/t/t0211/scrub_perf.perl
@@ -64,6 +64,12 @@ while (<>) {
goto SKIP_LINE;
}
}
+ elsif ($tokens[$col_event] =~ m/timer/) {
+ # This also captures "th_timer" events
+ $tokens[$col_rest] =~ s/ total:\d+\.\d*/ total:_T_TOTAL_/;
+ $tokens[$col_rest] =~ s/ min:\d+\.\d*/ min:_T_MIN_/;
+ $tokens[$col_rest] =~ s/ max:\d+\.\d*/ max:_T_MAX_/;
+ }
# t_abs and t_rel are either blank or a float. Replace the float
# with a constant for matching the HEREDOC in the test script.
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index 1e864cf3172..5b7bee888d5 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -215,6 +215,20 @@ test_expect_success 'fetching of missing objects' '
grep "$HASH" out
'
+test_expect_success 'fetching of a promised object that promisor remote no longer has' '
+ rm -f err &&
+ test_create_repo unreliable-server &&
+ git -C unreliable-server config uploadpack.allowanysha1inwant 1 &&
+ git -C unreliable-server config uploadpack.allowfilter 1 &&
+ test_commit -C unreliable-server foo &&
+
+ git clone --filter=blob:none --no-checkout "file://$(pwd)/unreliable-server" unreliable-client &&
+
+ rm -rf unreliable-server/.git/objects/* &&
+ test_must_fail git -C unreliable-client checkout HEAD 2>err &&
+ grep "could not fetch.*from promisor remote" err
+'
+
test_expect_success 'fetching of missing objects works with ref-in-want enabled' '
# ref-in-want requires protocol version 2
git -C server config protocol.version 2 &&
diff --git a/t/t0450-txt-doc-vs-help.sh b/t/t0450-txt-doc-vs-help.sh
new file mode 100755
index 00000000000..cd3969e852b
--- /dev/null
+++ b/t/t0450-txt-doc-vs-help.sh
@@ -0,0 +1,172 @@
+#!/bin/sh
+
+test_description='assert (unbuilt) Documentation/*.txt and -h output
+
+Run this with --debug to see a summary of where we still fail to make
+the two versions consistent with one another.'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success 'setup: list of builtins' '
+ git --list-cmds=builtins >builtins
+'
+
+test_expect_success 'list of txt and help mismatches is sorted' '
+ sort -u "$TEST_DIRECTORY"/t0450/txt-help-mismatches >expect &&
+ if ! test_cmp expect "$TEST_DIRECTORY"/t0450/txt-help-mismatches
+ then
+ BUG "please keep the list of txt and help mismatches sorted"
+ fi
+'
+
+help_to_synopsis () {
+ builtin="$1" &&
+ out_dir="out/$builtin" &&
+ out="$out_dir/help.synopsis" &&
+ if test -f "$out"
+ then
+ echo "$out" &&
+ return 0
+ fi &&
+ mkdir -p "$out_dir" &&
+ test_expect_code 129 git $builtin -h >"$out.raw" 2>&1 &&
+ sed -n \
+ -e '1,/^$/ {
+ /^$/d;
+ s/^usage: //;
+ s/^ *or: //;
+ p;
+ }' <"$out.raw" >"$out" &&
+ echo "$out"
+}
+
+builtin_to_txt () {
+ echo "$GIT_BUILD_DIR/Documentation/git-$1.txt"
+}
+
+txt_to_synopsis () {
+ builtin="$1" &&
+ out_dir="out/$builtin" &&
+ out="$out_dir/txt.synopsis" &&
+ if test -f "$out"
+ then
+ echo "$out" &&
+ return 0
+ fi &&
+ b2t="$(builtin_to_txt "$builtin")" &&
+ sed -n \
+ -e '/^\[verse\]$/,/^$/ {
+ /^$/d;
+ /^\[verse\]$/d;
+
+ s/{litdd}/--/g;
+ s/'\''\(git[ a-z-]*\)'\''/\1/g;
+
+ p;
+ }' \
+ <"$b2t" >"$out" &&
+ echo "$out"
+}
+
+check_dashed_labels () {
+ ! grep -E "<[^>_-]+_" "$1"
+}
+
+HT=" "
+
+align_after_nl () {
+ builtin="$1" &&
+ len=$(printf "git %s " "$builtin" | wc -c) &&
+ pad=$(printf "%${len}s" "") &&
+
+ sed "s/^[ $HT][ $HT]*/$pad/"
+}
+
+test_debug '>failing'
+while read builtin
+do
+ # -h output assertions
+ test_expect_success "$builtin -h output has no \t" '
+ h2s="$(help_to_synopsis "$builtin")" &&
+ ! grep "$HT" "$h2s"
+ '
+
+ test_expect_success "$builtin -h output has dashed labels" '
+ check_dashed_labels "$(help_to_synopsis "$builtin")"
+ '
+
+ test_expect_success "$builtin -h output has consistent spacing" '
+ h2s="$(help_to_synopsis "$builtin")" &&
+ sed -n \
+ -e "/^ / {
+ s/[^ ].*//;
+ p;
+ }" \
+ <"$h2s" >help &&
+ sort -u help >help.ws &&
+ if test -s help.ws
+ then
+ test_line_count = 1 help.ws
+ fi
+ '
+
+ txt="$(builtin_to_txt "$builtin")" &&
+ preq="$(echo BUILTIN_TXT_$builtin | tr '[:lower:]-' '[:upper:]_')" &&
+
+ if test -f "$txt"
+ then
+ test_set_prereq "$preq"
+ fi &&
+
+ # *.txt output assertions
+ test_expect_success "$preq" "$builtin *.txt SYNOPSIS has dashed labels" '
+ check_dashed_labels "$(txt_to_synopsis "$builtin")"
+ '
+
+ # *.txt output consistency assertions
+ result=
+ if grep -q "^$builtin$" "$TEST_DIRECTORY"/t0450/txt-help-mismatches
+ then
+ result=failure
+ else
+ result=success
+ fi &&
+ test_expect_$result "$preq" "$builtin -h output and SYNOPSIS agree" '
+ t2s="$(txt_to_synopsis "$builtin")" &&
+ if test "$builtin" = "merge-tree"
+ then
+ test_when_finished "rm -f t2s.new" &&
+ sed -e '\''s/ (deprecated)$//g'\'' <"$t2s" >t2s.new
+ t2s=t2s.new
+ fi &&
+ h2s="$(help_to_synopsis "$builtin")" &&
+
+ # The *.txt and -h use different spacing for the
+ # alignment of continued usage output, normalize it.
+ align_after_nl "$builtin" <"$t2s" >txt &&
+ align_after_nl "$builtin" <"$h2s" >help &&
+ test_cmp txt help
+ '
+
+ if test_have_prereq "$preq" && test -e txt && test -e help
+ then
+ test_debug '
+ if test_cmp txt help >cmp 2>/dev/null
+ then
+ echo "=== DONE: $builtin ==="
+ else
+ echo "=== TODO: $builtin ===" &&
+ cat cmp
+ fi >>failing
+ '
+
+ # Not in test_expect_success in case --run is being
+ # used with --debug
+ rm -f txt help tmp 2>/dev/null
+ fi
+done <builtins
+
+test_debug 'say "$(cat failing)"'
+
+test_done
diff --git a/t/t0450/txt-help-mismatches b/t/t0450/txt-help-mismatches
new file mode 100644
index 00000000000..a0777acd667
--- /dev/null
+++ b/t/t0450/txt-help-mismatches
@@ -0,0 +1,58 @@
+add
+am
+apply
+archive
+bisect
+blame
+branch
+check-ref-format
+checkout
+checkout-index
+clone
+column
+config
+credential
+credential-cache
+credential-store
+fast-export
+fast-import
+fetch-pack
+fmt-merge-msg
+for-each-ref
+format-patch
+fsck-objects
+fsmonitor--daemon
+gc
+grep
+index-pack
+init-db
+log
+ls-files
+ls-tree
+mailinfo
+mailsplit
+maintenance
+merge
+merge-file
+merge-index
+merge-one-file
+multi-pack-index
+name-rev
+notes
+pack-objects
+push
+range-diff
+rebase
+remote
+remote-ext
+remote-fd
+repack
+reset
+restore
+rev-parse
+show
+stage
+switch
+update-index
+update-ref
+whatchanged
diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh
index bd5313caec9..cdc077ce12d 100755
--- a/t/t1002-read-tree-m-u-2way.sh
+++ b/t/t1002-read-tree-m-u-2way.sh
@@ -154,7 +154,7 @@ test_expect_success \
read_tree_u_must_succeed --reset -u $treeH &&
echo frotz frotz >frotz &&
git update-index --add frotz &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
test_expect_success \
'9 - conflicting addition.' \
@@ -163,7 +163,7 @@ test_expect_success \
echo frotz frotz >frotz &&
git update-index --add frotz &&
echo frotz >frotz &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
test_expect_success \
'10 - path removed.' \
@@ -186,7 +186,7 @@ test_expect_success \
echo rezrov >rezrov &&
git update-index --add rezrov &&
echo rezrov rezrov >rezrov &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
test_expect_success \
'12 - unmatching local changes being removed.' \
@@ -194,7 +194,7 @@ test_expect_success \
read_tree_u_must_succeed --reset -u $treeH &&
echo rezrov rezrov >rezrov &&
git update-index --add rezrov &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
test_expect_success \
'13 - unmatching local changes being removed.' \
@@ -203,7 +203,7 @@ test_expect_success \
echo rezrov rezrov >rezrov &&
git update-index --add rezrov &&
echo rezrov >rezrov &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
cat >expected <<EOF
-100644 X 0 nitfol
@@ -251,7 +251,7 @@ test_expect_success \
read_tree_u_must_succeed --reset -u $treeH &&
echo bozbar bozbar >bozbar &&
git update-index --add bozbar &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
test_expect_success \
'17 - conflicting local change.' \
@@ -260,7 +260,7 @@ test_expect_success \
echo bozbar bozbar >bozbar &&
git update-index --add bozbar &&
echo bozbar bozbar bozbar >bozbar &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
test_expect_success \
'18 - local change already having a good result.' \
@@ -316,7 +316,7 @@ test_expect_success \
echo bozbar >bozbar &&
git update-index --add bozbar &&
echo gnusto gnusto >bozbar &&
- if read_tree_u_must_succeed -m -u $treeH $treeM; then false; else :; fi'
+ ! read_tree_u_must_succeed -m -u $treeH $treeM'
# Also make sure we did not break DF vs DF/DF case.
test_expect_success \
diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh
index 5b8e47e346c..35261afc9d6 100755
--- a/t/t1060-object-corruption.sh
+++ b/t/t1060-object-corruption.sh
@@ -139,4 +139,11 @@ test_expect_success 'internal tree objects are not "missing"' '
)
'
+test_expect_success 'partial clone of corrupted repository' '
+ test_config -C misnamed uploadpack.allowFilter true &&
+ git clone --no-local --no-checkout --filter=blob:none \
+ misnamed corrupt-partial && \
+ test_must_fail git -C corrupt-partial checkout --force
+'
+
test_done
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index de1ec89007d..b563d6c263e 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -560,7 +560,8 @@ test_expect_success 'interaction with submodules' '
(
cd super &&
mkdir modules &&
- git submodule add ../repo modules/child &&
+ git -c protocol.file.allow=always \
+ submodule add ../repo modules/child &&
git add . &&
git commit -m "add submodule" &&
git sparse-checkout init --cone &&
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 0302e36fd66..801919009e1 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -162,6 +162,19 @@ init_repos () {
git -C sparse-index sparse-checkout set deep
}
+init_repos_as_submodules () {
+ git reset --hard &&
+ init_repos &&
+ git submodule add ./full-checkout &&
+ git submodule add ./sparse-checkout &&
+ git submodule add ./sparse-index &&
+
+ git submodule status >actual &&
+ grep full-checkout actual &&
+ grep sparse-checkout actual &&
+ grep sparse-index actual
+}
+
run_on_sparse () {
(
cd sparse-checkout &&
@@ -380,6 +393,15 @@ test_expect_success 'checkout with modified sparse directory' '
test_all_match git checkout base
'
+test_expect_success 'checkout orphan then non-orphan' '
+ init_repos &&
+
+ test_all_match git checkout --orphan test-orphan &&
+ test_all_match git status --porcelain=v2 &&
+ test_all_match git checkout base &&
+ test_all_match git status --porcelain=v2
+'
+
test_expect_success 'add outside sparse cone' '
init_repos &&
@@ -1293,6 +1315,8 @@ test_expect_success 'submodule handling' '
test_all_match git add modules &&
test_all_match git commit -m "add modules directory" &&
+ test_config_global protocol.file.allow always &&
+
run_on_all git submodule add "$(pwd)/initial-repo" modules/sub &&
test_all_match git commit -m "add submodule" &&
@@ -1972,4 +1996,63 @@ test_expect_success 'sparse index is not expanded: rm' '
ensure_not_expanded rm -r deep
'
+test_expect_success 'grep with and --cached' '
+ init_repos &&
+
+ test_all_match git grep --cached a &&
+ test_all_match git grep --cached a -- "folder1/*"
+'
+
+test_expect_success 'grep is not expanded' '
+ init_repos &&
+
+ ensure_not_expanded grep a &&
+ ensure_not_expanded grep a -- deep/* &&
+
+ # All files within the folder1/* pathspec are sparse,
+ # so this command does not find any matches
+ ensure_not_expanded ! grep a -- folder1/* &&
+
+ # test out-of-cone pathspec with or without wildcard
+ ensure_not_expanded grep --cached a -- "folder1/a" &&
+ ensure_not_expanded grep --cached a -- "folder1/*" &&
+
+ # test in-cone pathspec with or without wildcard
+ ensure_not_expanded grep --cached a -- "deep/a" &&
+ ensure_not_expanded grep --cached a -- "deep/*"
+'
+
+# NEEDSWORK: when running `grep` in the superproject with --recurse-submodules,
+# Git expands the index of the submodules unexpectedly. Even though `grep`
+# builtin is marked as "command_requires_full_index = 0", this config is only
+# useful for the superproject. Namely, the submodules have their own configs,
+# which are _not_ populated by the one-time sparse-index feature switch.
+test_expect_failure 'grep within submodules is not expanded' '
+ init_repos_as_submodules &&
+
+ # do not use ensure_not_expanded() here, becasue `grep` should be
+ # run in the superproject, not in "./sparse-index"
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ git grep --cached --recurse-submodules a -- "*/folder1/*" &&
+ test_region ! index ensure_full_index trace2.txt
+'
+
+# NEEDSWORK: this test is not actually testing the code. The design purpose
+# of this test is to verify the grep result when the submodules are using a
+# sparse-index. Namely, we want "folder1/" as a tree (a sparse directory); but
+# because of the index expansion, we are now grepping the "folder1/a" blob.
+# Because of the problem stated above 'grep within submodules is not expanded',
+# we don't have the ideal test environment yet.
+test_expect_success 'grep sparse directory within submodules' '
+ init_repos_as_submodules &&
+
+ cat >expect <<-\EOF &&
+ full-checkout/folder1/a:a
+ sparse-checkout/folder1/a:a
+ sparse-index/folder1/a:a
+ EOF
+ git grep --cached --recurse-submodules a -- "*/folder1/*" >actual &&
+ test_cmp actual expect
+'
+
test_done
diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh
index 335d3f3211a..c69ae41306c 100755
--- a/t/t1304-default-acl.sh
+++ b/t/t1304-default-acl.sh
@@ -18,7 +18,7 @@ test_expect_success 'checking for a working acl setup' '
if setfacl -m d:m:rwx -m u:root:rwx . &&
getfacl . | grep user:root:rwx &&
touch should-have-readable-acl &&
- getfacl should-have-readable-acl | egrep "mask::?rw-"
+ getfacl should-have-readable-acl | grep -E "mask::?rw-"
then
test_set_prereq SETFACL
fi
@@ -34,7 +34,7 @@ check_perms_and_acl () {
getfacl "$1" > actual &&
grep -q "user:root:rwx" actual &&
grep -q "user:${LOGNAME}:rwx" actual &&
- egrep "mask::?r--" actual > /dev/null 2>&1 &&
+ grep -E "mask::?r--" actual > /dev/null 2>&1 &&
grep -q "group::---" actual || false
}
diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index 0c204089b83..d708acdb819 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -175,4 +175,18 @@ test_expect_success 'symbolic-ref allows top-level target for non-HEAD' '
test_cmp_rev top-level HEAD
'
+test_expect_success 'symbolic-ref pointing at another' '
+ git update-ref refs/heads/maint-2.37 HEAD &&
+ git symbolic-ref refs/heads/maint refs/heads/maint-2.37 &&
+ git checkout maint &&
+
+ git symbolic-ref HEAD >actual &&
+ echo refs/heads/maint-2.37 >expect &&
+ test_cmp expect actual &&
+
+ git symbolic-ref --no-recurse HEAD >actual &&
+ echo refs/heads/maint >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 53c2aa10b72..ace4556788d 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -507,6 +507,54 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '
test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out
'
+# An actual bit corruption is more likely than swapped commits, but
+# this provides an easy way to have commits which don't match their purported
+# hashes, but which aren't so broken we can't read them at all.
+test_expect_success 'rev-list --verify-objects notices swapped commits' '
+ git init swapped-commits &&
+ (
+ cd swapped-commits &&
+ test_commit one &&
+ test_commit two &&
+ one_oid=$(git rev-parse HEAD) &&
+ two_oid=$(git rev-parse HEAD^) &&
+ one=.git/objects/$(test_oid_to_path $one_oid) &&
+ two=.git/objects/$(test_oid_to_path $two_oid) &&
+ mv $one tmp &&
+ mv $two $one &&
+ mv tmp $two &&
+ test_must_fail git rev-list --verify-objects HEAD
+ )
+'
+
+test_expect_success 'set up repository with commit-graph' '
+ git init corrupt-graph &&
+ (
+ cd corrupt-graph &&
+ test_commit one &&
+ test_commit two &&
+ git commit-graph write --reachable
+ )
+'
+
+corrupt_graph_obj () {
+ oid=$(git -C corrupt-graph rev-parse "$1") &&
+ obj=corrupt-graph/.git/objects/$(test_oid_to_path $oid) &&
+ test_when_finished 'mv backup $obj' &&
+ mv $obj backup &&
+ echo garbage >$obj
+}
+
+test_expect_success 'rev-list --verify-objects with commit graph (tip)' '
+ corrupt_graph_obj HEAD &&
+ test_must_fail git -C corrupt-graph rev-list --verify-objects HEAD
+'
+
+test_expect_success 'rev-list --verify-objects with commit graph (parent)' '
+ corrupt_graph_obj HEAD^ &&
+ test_must_fail git -C corrupt-graph rev-list --verify-objects HEAD
+'
+
test_expect_success 'force fsck to ignore double author' '
git cat-file commit HEAD >basis &&
sed "s/^author .*/&,&/" <basis | tr , \\n >multiple-authors &&
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 1c2df08333b..81de584ea29 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -4,6 +4,7 @@ test_description='test git rev-parse'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_one () {
@@ -225,7 +226,8 @@ test_expect_success 'showing the superproject correctly' '
test_commit -C super test_commit &&
test_create_repo sub &&
test_commit -C sub test_commit &&
- git -C super submodule add ../sub dir/sub &&
+ git -c protocol.file.allow=always \
+ -C super submodule add ../sub dir/sub &&
echo $(pwd)/super >expect &&
git -C super/dir/sub rev-parse --show-superproject-working-tree >out &&
test_cmp expect out &&
diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh
index 284fe18e726..de1d48f3ba2 100755
--- a/t/t1502-rev-parse-parseopt.sh
+++ b/t/t1502-rev-parse-parseopt.sh
@@ -306,6 +306,13 @@ test_expect_success 'test --parseopt help output: "wrapped" options normal "or:"
test_cmp expect actual
'
+test_expect_success 'test --parseopt invalid opt-spec' '
+ test_write_lines x -- "=, x" >spec &&
+ echo "fatal: missing opt-spec before option flags" >expect &&
+ test_must_fail git rev-parse --parseopt -- >out <spec 2>err &&
+ test_cmp expect err
+'
+
test_expect_success 'test --parseopt help output: multi-line blurb after empty line' '
sed -e "s/^|//" >spec <<-\EOF &&
|cmd [--some-option]
diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
index 64096adac7e..2ef3579fa7c 100755
--- a/t/t1800-hook.sh
+++ b/t/t1800-hook.sh
@@ -95,7 +95,7 @@ test_expect_success 'git hook run -- out-of-repo runs excluded' '
test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
mkdir my-hooks &&
write_script my-hooks/test-hook <<-\EOF &&
- echo Hook ran $1 >>actual
+ echo Hook ran $1
EOF
cat >expect <<-\EOF &&
@@ -157,9 +157,9 @@ test_expect_success 'git hook run a hook with a bad shebang' '
write_script bad-hooks/test-hook "/bad/path/no/spaces" </dev/null &&
# TODO: We should emit the same (or at least a more similar)
- # error on Windows and !Windows. See the OS-specific code in
- # start_command()
- if test_have_prereq !WINDOWS
+ # error on MINGW (essentially Git for Windows) and all other
+ # platforms.. See the OS-specific code in start_command()
+ if test_have_prereq !MINGW
then
cat >expect <<-\EOF
fatal: cannot run bad-hooks/test-hook: ...
diff --git a/t/t2080-parallel-checkout-basics.sh b/t/t2080-parallel-checkout-basics.sh
index 00ce3033d34..5ffe1a41e2c 100755
--- a/t/t2080-parallel-checkout-basics.sh
+++ b/t/t2080-parallel-checkout-basics.sh
@@ -41,6 +41,8 @@ TEST_NO_CREATE_REPO=1
# - m/m (file)
#
test_expect_success 'setup repo for checkout with various types of changes' '
+ test_config_global protocol.file.allow always &&
+
git init sub &&
(
cd sub &&
@@ -140,6 +142,7 @@ do
esac
test_expect_success "$mode checkout on clone" '
+ test_config_global protocol.file.allow always &&
repo=various_${mode}_clone &&
set_checkout_config $workers $threshold &&
test_checkout_workers $expected_workers \
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index f3242fef6b6..d587e0b20db 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -669,6 +669,7 @@ test_expect_success '"add" should not fail because of another bad worktree' '
'
test_expect_success '"add" with uninitialized submodule, with submodule.recurse unset' '
+ test_config_global protocol.file.allow always &&
test_create_repo submodule &&
test_commit -C submodule first &&
test_create_repo project &&
@@ -684,6 +685,7 @@ test_expect_success '"add" with uninitialized submodule, with submodule.recurse
'
test_expect_success '"add" with initialized submodule, with submodule.recurse unset' '
+ test_config_global protocol.file.allow always &&
git -C project-clone submodule update --init &&
git -C project-clone worktree add ../project-4
'
diff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh
index a4e1a178e0a..230a55e99af 100755
--- a/t/t2403-worktree-move.sh
+++ b/t/t2403-worktree-move.sh
@@ -2,6 +2,7 @@
test_description='test git worktree move, remove, lock and unlock'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
@@ -138,7 +139,8 @@ test_expect_success 'move a repo with uninitialized submodule' '
(
cd withsub &&
test_commit initial &&
- git submodule add "$PWD"/.git sub &&
+ git -c protocol.file.allow=always \
+ submodule add "$PWD"/.git sub &&
git commit -m withsub &&
git worktree add second HEAD &&
git worktree move second third
@@ -148,7 +150,7 @@ test_expect_success 'move a repo with uninitialized submodule' '
test_expect_success 'not move a repo with initialized submodule' '
(
cd withsub &&
- git -C third submodule update &&
+ git -c protocol.file.allow=always -C third submodule update &&
test_must_fail git worktree move third forth
)
'
@@ -227,6 +229,7 @@ test_expect_success 'remove cleans up .git/worktrees when empty' '
'
test_expect_success 'remove a repo with uninitialized submodule' '
+ test_config_global protocol.file.allow always &&
(
cd withsub &&
git worktree add to-remove HEAD &&
@@ -235,6 +238,7 @@ test_expect_success 'remove a repo with uninitialized submodule' '
'
test_expect_success 'not remove a repo with initialized submodule' '
+ test_config_global protocol.file.allow always &&
(
cd withsub &&
git worktree add to-remove HEAD &&
diff --git a/t/t2405-worktree-submodule.sh b/t/t2405-worktree-submodule.sh
index b172c26ca43..11018f37c70 100755
--- a/t/t2405-worktree-submodule.sh
+++ b/t/t2405-worktree-submodule.sh
@@ -10,6 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
base_path=$(pwd -P)
test_expect_success 'setup: create origin repos' '
+ git config --global protocol.file.allow always &&
git init origin/sub &&
test_commit -C origin/sub file1 &&
git init origin/main &&
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index f9539968e4c..5d871fde960 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -5,11 +5,6 @@ test_description='wildmatch tests'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
-# Disable expensive chain-lint tests; all of the tests in this script
-# are variants of a few trivial test-tool invocations, and there are a lot of
-# them.
-GIT_TEST_CHAIN_LINT_HARDER_DEFAULT=0
-
should_create_test_file() {
file=$1
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 9723c2827cc..7f605f865b3 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -201,8 +201,8 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
test_expect_success 'git branch -M baz bam should add entries to .git/logs/HEAD' '
msg="Branch: renamed refs/heads/baz to refs/heads/bam" &&
- grep " 0\{40\}.*$msg$" .git/logs/HEAD &&
- grep "^0\{40\}.*$msg$" .git/logs/HEAD
+ grep " $ZERO_OID.*$msg$" .git/logs/HEAD &&
+ grep "^$ZERO_OID.*$msg$" .git/logs/HEAD
'
test_expect_success 'git branch -M should leave orphaned HEAD alone' '
@@ -268,6 +268,17 @@ test_expect_success 'git branch -M topic topic should work when main is checked
git branch -M topic topic
'
+test_expect_success 'git branch -M and -C fail on detached HEAD' '
+ git checkout HEAD^{} &&
+ test_when_finished git checkout - &&
+ echo "fatal: cannot rename the current branch while not on any." >expect &&
+ test_must_fail git branch -M must-fail 2>err &&
+ test_cmp expect err &&
+ echo "fatal: cannot copy the current branch while not on any." >expect &&
+ test_must_fail git branch -C must-fail 2>err &&
+ test_cmp expect err
+'
+
test_expect_success 'git branch -v -d t should work' '
git branch t &&
git rev-parse --verify refs/heads/t &&
@@ -306,6 +317,7 @@ test_expect_success 'deleting checked-out branch from repo that is a submodule'
git init repo1 &&
git init repo1/sub &&
test_commit -C repo1/sub x &&
+ test_config_global protocol.file.allow always &&
git -C repo1 submodule add ./sub &&
git -C repo1 commit -m "adding sub" &&
@@ -1381,6 +1393,9 @@ test_expect_success 'branch --delete --force removes dangling branch' '
'
test_expect_success 'use --edit-description' '
+ EDITOR=: git branch --edit-description &&
+ test_expect_code 1 git config branch.main.description &&
+
write_script editor <<-\EOF &&
echo "New contents" >"$1"
EOF
diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh
index f2b91990077..ea7cfd1951d 100755
--- a/t/t3202-show-branch.sh
+++ b/t/t3202-show-branch.sh
@@ -7,6 +7,28 @@ test_description='test show-branch'
# arbitrary reference time: 2009-08-30 19:20:00
GIT_TEST_DATE_NOW=1251660000; export GIT_TEST_DATE_NOW
+test_expect_success 'error descriptions on empty repository' '
+ current=$(git branch --show-current) &&
+ cat >expect <<-EOF &&
+ error: No commit on branch '\''$current'\'' yet.
+ EOF
+ test_must_fail git branch --edit-description 2>actual &&
+ test_cmp expect actual &&
+ test_must_fail git branch --edit-description $current 2>actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fatal descriptions on empty repository' '
+ current=$(git branch --show-current) &&
+ cat >expect <<-EOF &&
+ fatal: No commit on branch '\''$current'\'' yet.
+ EOF
+ test_must_fail git branch --set-upstream-to=non-existent 2>actual &&
+ test_cmp expect actual &&
+ test_must_fail git branch -c new-branch 2>actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup' '
test_commit initial &&
for i in $(test_seq 1 10)
@@ -175,4 +197,28 @@ done <<\EOF
--reflog --current
EOF
+test_expect_success 'error descriptions on non-existent branch' '
+ cat >expect <<-EOF &&
+ error: No branch named '\''non-existent'\'.'
+ EOF
+ test_must_fail git branch --edit-description non-existent 2>actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fatal descriptions on non-existent branch' '
+ cat >expect <<-EOF &&
+ fatal: branch '\''non-existent'\'' does not exist
+ EOF
+ test_must_fail git branch --set-upstream-to=non-existent non-existent 2>actual &&
+ test_cmp expect actual &&
+
+ cat >expect <<-EOF &&
+ fatal: No branch named '\''non-existent'\''.
+ EOF
+ test_must_fail git branch -c non-existent new-branch 2>actual &&
+ test_cmp expect actual &&
+ test_must_fail git branch -m non-existent new-branch 2>actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh
index 993a6b5eff7..793bf4d269e 100755
--- a/t/t3204-branch-name-interpretation.sh
+++ b/t/t3204-branch-name-interpretation.sh
@@ -133,4 +133,28 @@ test_expect_success 'checkout does not treat remote @{upstream} as a branch' '
expect_branch HEAD one
'
+test_expect_success 'edit-description via @{-1}' '
+ git checkout -b desc-branch &&
+ git checkout -b non-desc-branch &&
+ write_script editor <<-\EOF &&
+ echo "Branch description" >"$1"
+ EOF
+ EDITOR=./editor git branch --edit-description @{-1} &&
+ test_must_fail git config branch.non-desc-branch.description &&
+ git config branch.desc-branch.description >actual &&
+ printf "Branch description\n\n" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'modify branch upstream via "@{-1}" and "@{-1}@{upstream}"' '
+ git checkout -b upstream-branch &&
+ git checkout -b upstream-other -t upstream-branch &&
+ git branch --set-upstream-to upstream-other @{-1} &&
+ git config branch.upstream-branch.merge >actual &&
+ echo "refs/heads/upstream-other" >expect &&
+ test_cmp expect actual &&
+ git branch --unset-upstream @{-1}@{upstream} &&
+ test_must_fail git config branch.upstream-other.merge
+'
+
test_done
diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index d12e4e4cc6c..84dd0cd26d0 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -162,7 +162,7 @@ test_expect_success 'A^! and A^-<n> (unmodified)' '
'
test_expect_success 'A^{/..} is not mistaken for a range' '
- test_must_fail git range-diff topic^.. topic^{/..} 2>error &&
+ test_must_fail git range-diff topic^.. topic^{/..} -- 2>error &&
test_i18ngrep "not a commit range" error
'
@@ -772,6 +772,17 @@ test_expect_success '--left-only/--right-only' '
test_cmp expect actual
'
+test_expect_success 'ranges with pathspecs' '
+ git range-diff topic...mode-only-change -- other-file >actual &&
+ test_line_count = 2 actual &&
+ topic_oid=$(git rev-parse --short topic) &&
+ mode_change_oid=$(git rev-parse --short mode-only-change^) &&
+ file_change_oid=$(git rev-parse --short mode-only-change) &&
+ grep "$mode_change_oid" actual &&
+ ! grep "$file_change_oid" actual &&
+ ! grep "$topic_oid" actual
+'
+
test_expect_success 'submodule changes are shown irrespective of diff.submodule' '
git init sub-repo &&
test_commit -C sub-repo sub-first &&
@@ -782,7 +793,7 @@ test_expect_success 'submodule changes are shown irrespective of diff.submodule'
sub_oid3=$(git -C sub-repo rev-parse HEAD) &&
git checkout -b main-sub topic &&
- git submodule add ./sub-repo sub &&
+ git -c protocol.file.allow=always submodule add ./sub-repo sub &&
git -C sub checkout --detach sub-first &&
git commit -m "add sub" sub &&
sup_oid1=$(git rev-parse --short HEAD) &&
diff --git a/t/t3207-branch-submodule.sh b/t/t3207-branch-submodule.sh
index cfde6b237f5..fe72b247164 100755
--- a/t/t3207-branch-submodule.sh
+++ b/t/t3207-branch-submodule.sh
@@ -28,6 +28,7 @@ test_no_branch () {
}
test_expect_success 'setup superproject and submodule' '
+ git config --global protocol.file.allow always &&
mkdir test_dirs &&
(
cd test_dirs &&
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index d742be88402..3288aaec7dc 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -505,6 +505,11 @@ test_expect_success 'list notes with "git notes"' '
test_cmp expect actual
'
+test_expect_success '"git notes" without subcommand does not take arguments' '
+ test_expect_code 129 git notes HEAD^^ 2>err &&
+ grep "^error: unknown subcommand" err
+'
+
test_expect_success 'list specific note with "git notes list <object>"' '
git rev-parse refs/notes/commits:$commit_3 >expect &&
git notes list HEAD^^ >actual &&
diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh
index 22ffe5bcb99..1ec1fb6715e 100755
--- a/t/t3305-notes-fanout.sh
+++ b/t/t3305-notes-fanout.sh
@@ -9,7 +9,7 @@ path_has_fanout() {
path=$1 &&
fanout=$2 &&
after_last_slash=$(($(test_oid hexsz) - $fanout * 2)) &&
- echo $path | grep -q "^\([0-9a-f]\{2\}/\)\{$fanout\}[0-9a-f]\{$after_last_slash\}$"
+ echo $path | grep -q -E "^([0-9a-f]{2}/){$fanout}[0-9a-f]{$after_last_slash}$"
}
touched_one_note_with_fanout() {
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 688b01e3eb6..462cefd25df 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1244,9 +1244,9 @@ test_expect_success 'short commit ID collide' '
test $colliding_id = "$(git rev-parse HEAD | cut -c 1-4)" &&
grep "^pick $colliding_id " \
.git/rebase-merge/git-rebase-todo.tmp &&
- grep "^pick [0-9a-f]\{$hexsz\}" \
+ grep -E "^pick [0-9a-f]{$hexsz}" \
.git/rebase-merge/git-rebase-todo &&
- grep "^pick [0-9a-f]\{$hexsz\}" \
+ grep -E "^pick [0-9a-f]{$hexsz}" \
.git/rebase-merge/git-rebase-todo.backup &&
git rebase --continue
) &&
@@ -1261,7 +1261,7 @@ test_expect_success 'respect core.abbrev' '
set_cat_todo_editor &&
test_must_fail git rebase -i HEAD~4 >todo-list
) &&
- test 4 = $(grep -c "pick [0-9a-f]\{12,\}" todo-list)
+ test 4 = $(grep -c -E "pick [0-9a-f]{12,}" todo-list)
'
test_expect_success 'todo count' '
@@ -1964,6 +1964,113 @@ test_expect_success 'respect user edits to update-ref steps' '
test_cmp_rev HEAD refs/heads/no-conflict-branch
'
+test_expect_success '--update-refs: all update-ref lines removed' '
+ git checkout -b test-refs-not-removed no-conflict-branch &&
+ git branch -f base HEAD~4 &&
+ git branch -f first HEAD~3 &&
+ git branch -f second HEAD~3 &&
+ git branch -f third HEAD~1 &&
+ git branch -f tip &&
+
+ test_commit test-refs-not-removed &&
+ git commit --amend --fixup first &&
+
+ git rev-parse first second third tip no-conflict-branch >expect-oids &&
+
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i --update-refs base >todo.raw &&
+ sed -e "/^update-ref/d" <todo.raw >todo
+ ) &&
+ (
+ set_replace_editor todo &&
+ git rebase -i --update-refs base
+ ) &&
+
+ # Ensure refs are not deleted and their OIDs have not changed
+ git rev-parse first second third tip no-conflict-branch >actual-oids &&
+ test_cmp expect-oids actual-oids
+'
+
+test_expect_success '--update-refs: all update-ref lines removed, then some re-added' '
+ git checkout -b test-refs-not-removed2 no-conflict-branch &&
+ git branch -f base HEAD~4 &&
+ git branch -f first HEAD~3 &&
+ git branch -f second HEAD~3 &&
+ git branch -f third HEAD~1 &&
+ git branch -f tip &&
+
+ test_commit test-refs-not-removed2 &&
+ git commit --amend --fixup first &&
+
+ git rev-parse first second third >expect-oids &&
+
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i \
+ --autosquash --update-refs \
+ base >todo.raw &&
+ sed -e "/^update-ref/d" <todo.raw >todo
+ ) &&
+
+ # Add a break to the end of the todo so we can edit later
+ echo "break" >>todo &&
+
+ (
+ set_replace_editor todo &&
+ git rebase -i --autosquash --update-refs base &&
+ echo "update-ref refs/heads/tip" >todo &&
+ git rebase --edit-todo &&
+ git rebase --continue
+ ) &&
+
+ # Ensure first/second/third are unchanged, but tip is updated
+ git rev-parse first second third >actual-oids &&
+ test_cmp expect-oids actual-oids &&
+ test_cmp_rev HEAD tip
+'
+
+test_expect_success '--update-refs: --edit-todo with no update-ref lines' '
+ git checkout -b test-refs-not-removed3 no-conflict-branch &&
+ git branch -f base HEAD~4 &&
+ git branch -f first HEAD~3 &&
+ git branch -f second HEAD~3 &&
+ git branch -f third HEAD~1 &&
+ git branch -f tip &&
+
+ test_commit test-refs-not-removed3 &&
+ git commit --amend --fixup first &&
+
+ git rev-parse first second third tip no-conflict-branch >expect-oids &&
+
+ (
+ set_cat_todo_editor &&
+ test_must_fail git rebase -i \
+ --autosquash --update-refs \
+ base >todo.raw &&
+ sed -e "/^update-ref/d" <todo.raw >todo
+ ) &&
+
+ # Add a break to the beginning of the todo so we can resume with no
+ # update-ref lines
+ echo "break" >todo.new &&
+ cat todo >>todo.new &&
+
+ (
+ set_replace_editor todo.new &&
+ git rebase -i --autosquash --update-refs base &&
+
+ # Make no changes when editing so update-refs is still empty
+ cat todo >todo.new &&
+ git rebase --edit-todo &&
+ git rebase --continue
+ ) &&
+
+ # Ensure refs are not deleted and their OIDs have not changed
+ git rev-parse first second third tip no-conflict-branch >actual-oids &&
+ test_cmp expect-oids actual-oids
+'
+
test_expect_success '--update-refs: check failed ref update' '
git checkout -B update-refs-error no-conflict-branch &&
git branch -f base HEAD~4 &&
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index d17b450e811..ceca1600053 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -10,10 +10,16 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
test_expect_success 'setup' '
test_commit O fileO &&
test_commit X fileX &&
+ git branch fast-forward &&
test_commit A fileA &&
test_commit B fileB &&
test_commit Y fileY &&
+ git checkout -b conflicts O &&
+ test_commit P &&
+ test_commit conflict-X fileX &&
+ test_commit Q &&
+
git checkout -b topic O &&
git cherry-pick A B &&
test_commit Z fileZ &&
@@ -79,54 +85,165 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
test_i18ngrep "Invalid whitespace option" err
'
-test_expect_success 'GIT_REFLOG_ACTION' '
- git checkout start &&
- test_commit reflog-onto &&
- git checkout -b reflog-topic start &&
- test_commit reflog-to-rebase &&
+write_reflog_expect () {
+ if test $mode = --apply
+ then
+ sed 's/(continue)/(pick)/'
+ else
+ cat
+ fi >expect
+}
- git rebase reflog-onto &&
- git log -g --format=%gs -3 >actual &&
- cat >expect <<-\EOF &&
- rebase (finish): returning to refs/heads/reflog-topic
- rebase (pick): reflog-to-rebase
- rebase (start): checkout reflog-onto
+test_reflog () {
+ mode=$1
+ reflog_action="$2"
+
+ test_expect_success "rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
+ git checkout conflicts &&
+ test_when_finished "git reset --hard Q" &&
+
+ (
+ if test -n "$reflog_action"
+ then
+ GIT_REFLOG_ACTION="$reflog_action" &&
+ export GIT_REFLOG_ACTION
+ fi &&
+ test_must_fail git rebase $mode main &&
+ echo resolved >fileX &&
+ git add fileX &&
+ git rebase --continue
+ ) &&
+
+ git log -g --format=%gs -5 >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts
+ ${reflog_action:-rebase} (pick): Q
+ ${reflog_action:-rebase} (continue): conflict-X
+ ${reflog_action:-rebase} (pick): P
+ ${reflog_action:-rebase} (start): checkout main
EOF
test_cmp expect actual &&
- git checkout -b reflog-prefix reflog-to-rebase &&
- GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&
- git log -g --format=%gs -3 >actual &&
- cat >expect <<-\EOF &&
- change-the-reflog (finish): returning to refs/heads/reflog-prefix
- change-the-reflog (pick): reflog-to-rebase
- change-the-reflog (start): checkout reflog-onto
+ git log -g --format=%gs -1 conflicts >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main)
+ EOF
+ test_cmp expect actual &&
+
+ # check there is only one new entry in the branch reflog
+ test_cmp_rev conflicts@{1} Q
+ '
+
+ test_expect_success "rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
+ git checkout fast-forward &&
+ test_when_finished "git reset --hard X" &&
+
+ (
+ if test -n "$reflog_action"
+ then
+ GIT_REFLOG_ACTION="$reflog_action" &&
+ export GIT_REFLOG_ACTION
+ fi &&
+ git rebase $mode main
+ ) &&
+
+ git log -g --format=%gs -2 >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward
+ ${reflog_action:-rebase} (start): checkout main
+ EOF
+ test_cmp expect actual &&
+
+ git log -g --format=%gs -1 fast-forward >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main)
+ EOF
+ test_cmp expect actual &&
+
+ # check there is only one new entry in the branch reflog
+ test_cmp_rev fast-forward@{1} X
+ '
+
+ test_expect_success "rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
+ git checkout conflicts &&
+ test_when_finished "git reset --hard Q" &&
+
+ (
+ if test -n "$reflog_action"
+ then
+ GIT_REFLOG_ACTION="$reflog_action" &&
+ export GIT_REFLOG_ACTION
+ fi &&
+ test_must_fail git rebase $mode main &&
+ git rebase --skip
+ ) &&
+
+ git log -g --format=%gs -4 >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts
+ ${reflog_action:-rebase} (pick): Q
+ ${reflog_action:-rebase} (pick): P
+ ${reflog_action:-rebase} (start): checkout main
EOF
test_cmp expect actual
-'
+ '
-test_expect_success 'rebase --apply reflog' '
- git checkout -b reflog-apply start &&
- old_head_reflog="$(git log -g --format=%gs -1 HEAD)" &&
+ test_expect_success "rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
+ git checkout conflicts &&
+ test_when_finished "git reset --hard Q" &&
- git rebase --apply Y &&
+ git log -g -1 conflicts >branch-expect &&
+ (
+ if test -n "$reflog_action"
+ then
+ GIT_REFLOG_ACTION="$reflog_action" &&
+ export GIT_REFLOG_ACTION
+ fi &&
+ test_must_fail git rebase $mode main &&
+ git rebase --abort
+ ) &&
- git log -g --format=%gs -4 HEAD >actual &&
- cat >expect <<-EOF &&
- rebase finished: returning to refs/heads/reflog-apply
- rebase: Z
- rebase: checkout Y
- $old_head_reflog
+ git log -g --format=%gs -3 >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (abort): returning to refs/heads/conflicts
+ ${reflog_action:-rebase} (pick): P
+ ${reflog_action:-rebase} (start): checkout main
EOF
test_cmp expect actual &&
- git log -g --format=%gs -2 reflog-apply >actual &&
- cat >expect <<-EOF &&
- rebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)
- branch: Created from start
+ # check branch reflog is unchanged
+ git log -g -1 conflicts >branch-actual &&
+ test_cmp branch-expect branch-actual
+ '
+
+ test_expect_success "rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" '
+ git checkout Q &&
+ test_when_finished "git reset --hard Q" &&
+
+ (
+ if test -n "$reflog_action"
+ then
+ GIT_REFLOG_ACTION="$reflog_action" &&
+ export GIT_REFLOG_ACTION
+ fi &&
+ test_must_fail git rebase $mode main &&
+ git rebase --abort
+ ) &&
+
+ git log -g --format=%gs -3 >actual &&
+ write_reflog_expect <<-EOF &&
+ ${reflog_action:-rebase} (abort): returning to $(git rev-parse Q)
+ ${reflog_action:-rebase} (pick): P
+ ${reflog_action:-rebase} (start): checkout main
EOF
test_cmp expect actual
-'
+ '
+}
+
+test_reflog --merge
+test_reflog --merge my-reflog-action
+test_reflog --apply
+test_reflog --apply my-reflog-action
test_expect_success 'rebase -i onto unrelated history' '
git init unrelated &&
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 78c27496d6a..a364530d762 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -232,6 +232,19 @@ test_expect_success 'auto squash that matches longer sha1' '
test_line_count = 1 actual
'
+test_expect_success 'auto squash of fixup commit that matches branch name which points back to fixup commit' '
+ git reset --hard base &&
+ git commit --allow-empty -m "fixup! self-cycle" &&
+ git branch self-cycle &&
+ GIT_SEQUENCE_EDITOR="cat >tmp" git rebase --autosquash -i HEAD^^ &&
+ sed -ne "/^[^#]/{s/[0-9a-f]\{7,\}/HASH/g;p;}" tmp >actual &&
+ cat <<-EOF >expect &&
+ pick HASH second commit
+ pick HASH fixup! self-cycle # empty
+ EOF
+ test_cmp expect actual
+'
+
test_auto_commit_flags () {
git reset --hard base &&
echo 1 >file1 &&
diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh
index 3e04802cb00..ea501f2b42b 100755
--- a/t/t3416-rebase-onto-threedots.sh
+++ b/t/t3416-rebase-onto-threedots.sh
@@ -79,8 +79,10 @@ test_expect_success 'rebase -i --onto main...topic' '
git reset --hard &&
git checkout topic &&
git reset --hard G &&
- set_fake_editor &&
- EXPECT_COUNT=1 git rebase -i --onto main...topic F &&
+ (
+ set_fake_editor &&
+ EXPECT_COUNT=1 git rebase -i --onto main...topic F
+ ) &&
git rev-parse HEAD^1 >actual &&
git rev-parse C^0 >expect &&
test_cmp expect actual
@@ -90,20 +92,22 @@ test_expect_success 'rebase -i --onto main...' '
git reset --hard &&
git checkout topic &&
git reset --hard G &&
- set_fake_editor &&
- EXPECT_COUNT=1 git rebase -i --onto main... F &&
+ (
+ set_fake_editor &&
+ EXPECT_COUNT=1 git rebase -i --onto main... F
+ ) &&
git rev-parse HEAD^1 >actual &&
git rev-parse C^0 >expect &&
test_cmp expect actual
'
-test_expect_success 'rebase -i --onto main...side' '
+test_expect_success 'rebase --onto main...side requires a single merge-base' '
git reset --hard &&
git checkout side &&
git reset --hard K &&
- set_fake_editor &&
- test_must_fail git rebase -i --onto main...side J
+ test_must_fail git rebase -i --onto main...side J 2>err &&
+ grep "need exactly one merge base" err
'
test_expect_success 'rebase --keep-base --onto incompatible' '
@@ -156,8 +160,10 @@ test_expect_success 'rebase -i --keep-base main from topic' '
git checkout topic &&
git reset --hard G &&
- set_fake_editor &&
- EXPECT_COUNT=2 git rebase -i --keep-base main &&
+ (
+ set_fake_editor &&
+ EXPECT_COUNT=2 git rebase -i --keep-base main
+ ) &&
git rev-parse C >base.expect &&
git merge-base main HEAD >base.actual &&
test_cmp base.expect base.actual &&
@@ -171,8 +177,10 @@ test_expect_success 'rebase -i --keep-base main topic from main' '
git checkout main &&
git branch -f topic G &&
- set_fake_editor &&
- EXPECT_COUNT=2 git rebase -i --keep-base main topic &&
+ (
+ set_fake_editor &&
+ EXPECT_COUNT=2 git rebase -i --keep-base main topic
+ ) &&
git rev-parse C >base.expect &&
git merge-base main HEAD >base.actual &&
test_cmp base.expect base.actual &&
@@ -182,13 +190,39 @@ test_expect_success 'rebase -i --keep-base main topic from main' '
test_cmp expect actual
'
-test_expect_success 'rebase -i --keep-base main from side' '
+test_expect_success 'rebase --keep-base requires a single merge base' '
git reset --hard &&
git checkout side &&
git reset --hard K &&
- set_fake_editor &&
- test_must_fail git rebase -i --keep-base main
+ test_must_fail git rebase -i --keep-base main 2>err &&
+ grep "need exactly one merge base with branch" err
+'
+
+test_expect_success 'rebase --keep-base keeps cherry picks' '
+ git checkout -f -B main E &&
+ git cherry-pick F &&
+ (
+ set_fake_editor &&
+ EXPECT_COUNT=2 git rebase -i --keep-base HEAD G
+ ) &&
+ test_cmp_rev HEAD G
+'
+
+test_expect_success 'rebase --keep-base --no-reapply-cherry-picks' '
+ git checkout -f -B main E &&
+ git cherry-pick F &&
+ (
+ set_fake_editor &&
+ EXPECT_COUNT=1 git rebase -i --keep-base \
+ --no-reapply-cherry-picks HEAD G
+ ) &&
+ test_cmp_rev HEAD^ C
+'
+
+# This must be the last test in this file
+test_expect_success '$EDITOR and friends are unchanged' '
+ test_editor_unchanged
'
test_done
diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh
index 295040f2fe3..7181f176b81 100755
--- a/t/t3419-rebase-patch-id.sh
+++ b/t/t3419-rebase-patch-id.sh
@@ -43,15 +43,26 @@ test_expect_success 'setup: 500 lines' '
git add newfile &&
git commit -q -m "add small file" &&
- git cherry-pick main >/dev/null 2>&1
-'
+ git cherry-pick main >/dev/null 2>&1 &&
+
+ git branch -f squashed main &&
+ git checkout -q -f squashed &&
+ git reset -q --soft HEAD~2 &&
+ git commit -q -m squashed &&
+
+ git branch -f mode main &&
+ git checkout -q -f mode &&
+ test_chmod +x file &&
+ git commit -q -a --amend &&
-test_expect_success 'setup attributes' '
- echo "file binary" >.gitattributes
+ git branch -f modeother other &&
+ git checkout -q -f modeother &&
+ test_chmod +x file &&
+ git commit -q -a --amend
'
test_expect_success 'detect upstream patch' '
- git checkout -q main &&
+ git checkout -q main^{} &&
scramble file &&
git add file &&
git commit -q -m "change big file again" &&
@@ -61,14 +72,46 @@ test_expect_success 'detect upstream patch' '
test_must_be_empty revs
'
+test_expect_success 'detect upstream patch binary' '
+ echo "file binary" >.gitattributes &&
+ git checkout -q other^{} &&
+ git rebase main &&
+ git rev-list main...HEAD~ >revs &&
+ test_must_be_empty revs &&
+ test_when_finished "rm .gitattributes"
+'
+
+test_expect_success 'detect upstream patch modechange' '
+ git checkout -q modeother^{} &&
+ git rebase mode &&
+ git rev-list mode...HEAD~ >revs &&
+ test_must_be_empty revs
+'
+
test_expect_success 'do not drop patch' '
- git branch -f squashed main &&
- git checkout -q -f squashed &&
- git reset -q --soft HEAD~2 &&
- git commit -q -m squashed &&
git checkout -q other^{} &&
test_must_fail git rebase squashed &&
- git rebase --quit
+ test_when_finished "git rebase --abort"
+'
+
+test_expect_success 'do not drop patch binary' '
+ echo "file binary" >.gitattributes &&
+ git checkout -q other^{} &&
+ test_must_fail git rebase squashed &&
+ test_when_finished "git rebase --abort" &&
+ test_when_finished "rm .gitattributes"
+'
+
+test_expect_success 'do not drop patch modechange' '
+ git checkout -q modeother^{} &&
+ git rebase other &&
+ cat >expected <<-\EOF &&
+ diff --git a/file b/file
+ old mode 100644
+ new mode 100755
+ EOF
+ git diff HEAD~ >modediff &&
+ test_cmp expected modediff
'
test_done
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index 43fcb68f27e..693934ee8be 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -310,7 +310,7 @@ test_expect_success 'autostash is saved on editor failure with conflict' '
test_expect_success 'autostash with dirty submodules' '
test_when_finished "git reset --hard && git checkout main" &&
git checkout -b with-submodule &&
- git submodule add ./ sub &&
+ git -c protocol.file.allow=always submodule add ./ sub &&
test_tick &&
git commit -m add-submodule &&
echo changed >sub/file0 &&
diff --git a/t/t3426-rebase-submodule.sh b/t/t3426-rebase-submodule.sh
index 7a9f1127a4b..ba069dccbdf 100755
--- a/t/t3426-rebase-submodule.sh
+++ b/t/t3426-rebase-submodule.sh
@@ -48,7 +48,8 @@ test_expect_success 'rebase interactive ignores modified submodules' '
git init sub &&
git -C sub commit --allow-empty -m "Initial commit" &&
git init super &&
- git -C super submodule add ../sub &&
+ git -c protocol.file.allow=always \
+ -C super submodule add ../sub &&
git -C super config submodule.sub.ignore dirty &&
>super/foo &&
git -C super add foo &&
diff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh
index 1d0b15380ed..70e81363569 100755
--- a/t/t3431-rebase-fork-point.sh
+++ b/t/t3431-rebase-fork-point.sh
@@ -50,7 +50,7 @@ test_rebase () {
test_rebase 'G F E D B A'
test_rebase 'G F D B A' --onto D
-test_rebase 'G F B A' --keep-base
+test_rebase 'G F C B A' --keep-base
test_rebase 'G F C E D B A' --no-fork-point
test_rebase 'G F C D B A' --no-fork-point --onto D
test_rebase 'G F C B A' --no-fork-point --keep-base
diff --git a/t/t3435-rebase-gpg-sign.sh b/t/t3435-rebase-gpg-sign.sh
index 5f8ba2c7399..6aa2aeb628d 100755
--- a/t/t3435-rebase-gpg-sign.sh
+++ b/t/t3435-rebase-gpg-sign.sh
@@ -64,14 +64,6 @@ test_rebase_gpg_sign ! true -i --no-gpg-sign
test_rebase_gpg_sign ! true -i --gpg-sign --no-gpg-sign
test_rebase_gpg_sign false -i --no-gpg-sign --gpg-sign
-test_expect_failure 'rebase -p --no-gpg-sign override commit.gpgsign' '
- test_when_finished "git clean -f" &&
- git reset --hard merged &&
- git config commit.gpgsign true &&
- git rebase -p --no-gpg-sign --onto=one fork-point main &&
- test_must_fail git verify-commit HEAD
-'
-
test_expect_success 'rebase -r, merge strategy, --gpg-sign will sign commit' '
git reset --hard merged &&
test_unconfig commit.gpgsign &&
diff --git a/t/t3438-rebase-broken-files.sh b/t/t3438-rebase-broken-files.sh
new file mode 100755
index 00000000000..b92a3ce46b8
--- /dev/null
+++ b/t/t3438-rebase-broken-files.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+test_description='rebase behavior when on-disk files are broken'
+. ./test-lib.sh
+
+test_expect_success 'set up conflicting branches' '
+ test_commit base file &&
+ git checkout -b branch1 &&
+ test_commit one file &&
+ git checkout -b branch2 HEAD^ &&
+ test_commit two file
+'
+
+create_conflict () {
+ test_when_finished "git rebase --abort" &&
+ git checkout -B tmp branch2 &&
+ test_must_fail git rebase branch1
+}
+
+check_resolve_fails () {
+ echo resolved >file &&
+ git add file &&
+ test_must_fail git rebase --continue
+}
+
+for item in NAME EMAIL DATE
+do
+ test_expect_success "detect missing GIT_AUTHOR_$item" '
+ create_conflict &&
+
+ grep -v $item .git/rebase-merge/author-script >tmp &&
+ mv tmp .git/rebase-merge/author-script &&
+
+ check_resolve_fails
+ '
+done
+
+for item in NAME EMAIL DATE
+do
+ test_expect_success "detect duplicate GIT_AUTHOR_$item" '
+ create_conflict &&
+
+ grep -i $item .git/rebase-merge/author-script >tmp &&
+ cat tmp >>.git/rebase-merge/author-script &&
+
+ check_resolve_fails
+ '
+done
+
+test_expect_success 'unknown key in author-script' '
+ create_conflict &&
+
+ echo "GIT_AUTHOR_BOGUS=${SQ}whatever${SQ}" \
+ >>.git/rebase-merge/author-script &&
+
+ check_resolve_fails
+'
+
+test_done
diff --git a/t/t3512-cherry-pick-submodule.sh b/t/t3512-cherry-pick-submodule.sh
index c657840db33..f22d1ddead1 100755
--- a/t/t3512-cherry-pick-submodule.sh
+++ b/t/t3512-cherry-pick-submodule.sh
@@ -16,6 +16,8 @@ fi
test_submodule_switch "cherry-pick"
test_expect_success 'unrelated submodule/file conflict is ignored' '
+ test_config_global protocol.file.allow always &&
+
test_create_repo sub &&
touch sub/file &&
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index e74a318ac33..0e8afe49ed1 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -333,7 +333,7 @@ test_expect_success 'rm removes empty submodules from work tree' '
test_expect_success 'rm removes removed submodule from index and .gitmodules' '
git reset --hard &&
- git submodule update &&
+ git -c protocol.file.allow=always submodule update &&
rm -rf submod &&
git rm submod &&
git status -s -uno --ignore-submodules=none >actual &&
@@ -639,6 +639,7 @@ cat >expect.deepmodified <<EOF
EOF
test_expect_success 'setup subsubmodule' '
+ test_config_global protocol.file.allow always &&
git reset --hard &&
git submodule update &&
(
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 8689b48589c..51afbd7b24a 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -291,7 +291,7 @@ test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" '
git reset --hard &&
touch fo\[ou\]bar foobar &&
git add '\''fo\[ou\]bar'\'' &&
- git ls-files fo\[ou\]bar | fgrep fo\[ou\]bar &&
+ git ls-files fo\[ou\]bar | grep -F fo\[ou\]bar &&
! ( git ls-files foobar | grep foobar )
'
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 3b7df9bed5a..5841f280fb2 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -7,9 +7,9 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
-if ! test_have_prereq PERL
+if test_have_prereq !ADD_I_USE_BUILTIN,!PERL
then
- skip_all='skipping add -i tests, perl not available'
+ skip_all='skipping add -i (scripted) tests, perl not available'
test_done
fi
@@ -761,9 +761,20 @@ test_expect_success 'detect bogus diffFilter output' '
git reset --hard &&
echo content >test &&
- test_config interactive.diffFilter "sed 1d" &&
+ test_config interactive.diffFilter "sed 6d" &&
printf y >y &&
- force_color test_must_fail git add -p <y
+ force_color test_must_fail git add -p <y >output 2>&1 &&
+ grep "mismatched output" output
+'
+
+test_expect_success 'handle iffy colored hunk headers' '
+ git reset --hard &&
+
+ echo content >test &&
+ printf n >n &&
+ force_color git -c interactive.diffFilter="sed s/.*@@.*/XX/" \
+ add -p >output 2>&1 <n &&
+ grep "^XX$" output
'
test_expect_success 'handle very large filtered diff' '
@@ -944,6 +955,18 @@ test_expect_success 'status ignores dirty submodules (except HEAD)' '
! grep dirty-otherwise output
'
+test_expect_success 'handle submodules' '
+ echo 123 >>for-submodules/dirty-otherwise/initial.t &&
+
+ force_color git -C for-submodules add -p dirty-otherwise >output 2>&1 &&
+ grep "No changes" output &&
+
+ force_color git -C for-submodules add -p dirty-head >output 2>&1 <y &&
+ git -C for-submodules ls-files --stage dirty-head >actual &&
+ rev="$(git -C for-submodules/dirty-head rev-parse HEAD)" &&
+ grep "$rev" actual
+'
+
test_expect_success 'set up pathological context' '
git reset --hard &&
test_write_lines a a a a a a a a a a a >a &&
diff --git a/t/t3702-add-edit.sh b/t/t3702-add-edit.sh
index a1801a8cbd4..82bfb2fd2ac 100755
--- a/t/t3702-add-edit.sh
+++ b/t/t3702-add-edit.sh
@@ -100,7 +100,7 @@ EOF
echo "#!$SHELL_PATH" >fake-editor.sh
cat >> fake-editor.sh <<\EOF
-egrep -v '^index' "$1" >orig-patch &&
+grep -E -v '^index' "$1" >orig-patch &&
mv -f patch "$1"
EOF
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 2a4c3fd61c0..376cc8f4ab8 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -25,7 +25,7 @@ test_expect_success 'usage on main command -h emits a summary of subcommands' '
grep -F "or: git stash show" usage
'
-test_expect_failure 'usage for subcommands should emit subcommand usage' '
+test_expect_success 'usage for subcommands should emit subcommand usage' '
test_expect_code 129 git stash push -h >usage &&
grep -F "usage: git stash [push" usage
'
diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh
index a52e53dd2da..0f7348ec21b 100755
--- a/t/t3906-stash-submodule.sh
+++ b/t/t3906-stash-submodule.sh
@@ -36,7 +36,7 @@ setup_basic () {
git init main &&
(
cd main &&
- git submodule add ../sub &&
+ git -c protocol.file.allow=always submodule add ../sub &&
test_commit main_file
)
}
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index c509143c814..c64d9d2f405 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -113,20 +113,20 @@ test_expect_success 'diff --no-index with binary creation' '
'
cat >expect <<EOF
- binfile | Bin 0 -> 1026 bytes
- textfile | 10000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ binfilë | Bin 0 -> 1026 bytes
+ tëxtfilë | 10000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
test_expect_success 'diff --stat with binary files and big change count' '
- printf "\01\00%1024d" 1 >binfile &&
- git add binfile &&
+ printf "\01\00%1024d" 1 >binfilë &&
+ git add binfilë &&
i=0 &&
while test $i -lt 10000; do
echo $i &&
i=$(($i + 1)) || return 1
- done >textfile &&
- git add textfile &&
- git diff --cached --stat binfile textfile >output &&
+ done >tëxtfilë &&
+ git add tëxtfilë &&
+ git -c core.quotepath=false diff --cached --stat binfilë tëxtfilë >output &&
grep " | " output >actual &&
test_cmp expect actual
'
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index fbec8ad2ef7..de1da4673da 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -1400,6 +1400,43 @@ test_expect_success '--from omits redundant in-body header' '
test_cmp expect patch.head
'
+test_expect_success 'with --force-in-body-from, redundant in-body from is kept' '
+ git format-patch --force-in-body-from \
+ -1 --stdout --from="A U Thor <author@example.com>" >patch &&
+ cat >expect <<-\EOF &&
+ From: A U Thor <author@example.com>
+
+ From: A U Thor <author@example.com>
+
+ EOF
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
+ test_cmp expect patch.head
+'
+
+test_expect_success 'format.forceInBodyFrom, equivalent to --force-in-body-from' '
+ git -c format.forceInBodyFrom=yes format-patch \
+ -1 --stdout --from="A U Thor <author@example.com>" >patch &&
+ cat >expect <<-\EOF &&
+ From: A U Thor <author@example.com>
+
+ From: A U Thor <author@example.com>
+
+ EOF
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
+ test_cmp expect patch.head
+'
+
+test_expect_success 'format.forceInBodyFrom, equivalent to --force-in-body-from' '
+ git -c format.forceInBodyFrom=yes format-patch --no-force-in-body-from \
+ -1 --stdout --from="A U Thor <author@example.com>" >patch &&
+ cat >expect <<-\EOF &&
+ From: A U Thor <author@example.com>
+
+ EOF
+ sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
+ test_cmp expect patch.head
+'
+
test_expect_success 'in-body headers trigger content encoding' '
test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
test_when_finished "git reset --hard HEAD^" &&
@@ -1420,7 +1457,7 @@ append_signoff()
C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
sed -n -e "1,/^---$/p" append_signoff.patch |
- egrep -n "^Subject|Sign|^$"
+ grep -E -n "^Subject|Sign|^$"
}
test_expect_success 'signoff: commit with no body' '
@@ -2237,10 +2274,10 @@ test_expect_success 'format-patch --base with --attach' '
test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
test_when_finished "rm -fr patches" &&
git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
- ! egrep "^--+mimemime" patches/0000*.patch &&
- egrep "^--+mimemime$" patches/0001*.patch >output &&
+ ! grep -E "^--+mimemime" patches/0000*.patch &&
+ grep -E "^--+mimemime$" patches/0001*.patch >output &&
test_line_count = 2 output &&
- egrep "^--+mimemime--$" patches/0001*.patch >output &&
+ grep -E "^--+mimemime--$" patches/0001*.patch >output &&
test_line_count = 1 output
'
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index 9a292bac70c..2ce26e585c9 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -80,11 +80,21 @@ test_expect_success 'check combined output (1)' '
verify_helper sidewithone
'
+test_expect_success 'check combined output (1) with git diff <rev>^!' '
+ git diff sidewithone^! -- >sidewithone &&
+ verify_helper sidewithone
+'
+
test_expect_success 'check combined output (2)' '
git show sidesansone -- >sidesansone &&
verify_helper sidesansone
'
+test_expect_success 'check combined output (2) with git diff <rev>^!' '
+ git diff sidesansone^! -- >sidesansone &&
+ verify_helper sidesansone
+'
+
test_expect_success 'diagnose truncated file' '
>file &&
git add file &&
diff --git a/t/t4059-diff-submodule-not-initialized.sh b/t/t4059-diff-submodule-not-initialized.sh
index 49bca7b48d9..d489230df89 100755
--- a/t/t4059-diff-submodule-not-initialized.sh
+++ b/t/t4059-diff-submodule-not-initialized.sh
@@ -49,7 +49,7 @@ test_expect_success 'setup - submodules' '
'
test_expect_success 'setup - git submodule add' '
- git submodule add ./sm2 sm1 &&
+ git -c protocol.file.allow=always submodule add ./sm2 sm1 &&
commit_file sm1 .gitmodules &&
git diff-tree -p --no-commit-id --submodule=log HEAD -- sm1 >actual &&
cat >expected <<-EOF &&
diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh
index d86e38abd88..97c6424cd51 100755
--- a/t/t4060-diff-submodule-option-diff-format.sh
+++ b/t/t4060-diff-submodule-option-diff-format.sh
@@ -840,7 +840,7 @@ rm sm2
mv sm2-bak sm2
test_expect_success 'setup nested submodule' '
- git -C sm2 submodule add ../sm2 nested &&
+ git -c protocol.file.allow=always -C sm2 submodule add ../sm2 nested &&
git -C sm2 commit -a -m "nested sub" &&
head10=$(git -C sm2 rev-parse --short --verify HEAD)
'
diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh
index 804f2a82e83..28f42a4046e 100755
--- a/t/t4067-diff-partial-clone.sh
+++ b/t/t4067-diff-partial-clone.sh
@@ -77,6 +77,7 @@ test_expect_success 'diff skips same-OID blobs' '
test_expect_success 'when fetching missing objects, diff skips GITLINKs' '
test_when_finished "rm -rf sub server client trace" &&
+ test_config_global protocol.file.allow always &&
test_create_repo sub &&
test_commit -C sub first &&
diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh
index 9e7cac68b1c..07323ebafe0 100755
--- a/t/t4069-remerge-diff.sh
+++ b/t/t4069-remerge-diff.sh
@@ -2,7 +2,6 @@
test_description='remerge-diff handling'
-TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# This test is ort-specific
@@ -57,6 +56,11 @@ test_expect_success 'remerge-diff on a clean merge' '
test_cmp expect actual
'
+test_expect_success 'remerge-diff on a clean merge with a filter' '
+ git show --oneline --remerge-diff --diff-filter=U bc_resolution >actual &&
+ test_must_be_empty actual
+'
+
test_expect_success 'remerge-diff with both a resolved conflict and an unrelated change' '
git log -1 --oneline ab_resolution >tmp &&
cat <<-EOF >>tmp &&
@@ -90,6 +94,22 @@ test_expect_success 'remerge-diff with both a resolved conflict and an unrelated
test_cmp expect actual
'
+test_expect_success 'pickaxe still includes additional headers for relevant changes' '
+ # reuses "expect" from the previous testcase
+
+ git log --oneline --remerge-diff -Sacht ab_resolution >tmp &&
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'can filter out additional headers with pickaxe' '
+ git show --remerge-diff --submodule=log --find-object=HEAD ab_resolution >actual &&
+ test_must_be_empty actual &&
+
+ git show --remerge-diff -S"not present" --all >actual &&
+ test_must_be_empty actual
+'
+
test_expect_success 'setup non-content conflicts' '
git switch --orphan base &&
@@ -185,6 +205,14 @@ test_expect_success 'remerge-diff w/ diff-filter=U: all conflict headers, no dif
test_cmp expect actual
'
+test_expect_success 'submodule formatting ignores additional headers' '
+ # Reuses "expect" from last testcase
+
+ git show --oneline --remerge-diff --diff-filter=U --submodule=log >tmp &&
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'remerge-diff w/ diff-filter=R: relevant file + conflict header' '
git log -1 --oneline resolution >tmp &&
cat <<-EOF >>tmp &&
diff --git a/t/t4141-apply-too-large.sh b/t/t4141-apply-too-large.sh
new file mode 100755
index 00000000000..58742d4fc5d
--- /dev/null
+++ b/t/t4141-apply-too-large.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+test_description='git apply with too-large patch'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success EXPENSIVE 'git apply rejects patches that are too large' '
+ sz=$((1024 * 1024 * 1023)) &&
+ {
+ cat <<-\EOF &&
+ diff --git a/file b/file
+ new file mode 100644
+ --- /dev/null
+ +++ b/file
+ @@ -0,0 +1 @@
+ EOF
+ test-tool genzeros
+ } | test_copy_bytes $sz | test_must_fail git apply 2>err &&
+ grep "git apply: failed to read" err
+'
+
+test_done
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index 3095b1b2ffe..8e4effebdb7 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -83,6 +83,13 @@ test_expect_success 'pretty format' '
test_cmp expect log.predictable
'
+test_expect_success 'pretty format (with --date)' '
+ sed "s/SUBJECT/2005-04-07 OBJECT_NAME/" expect.template >expect &&
+ git shortlog --format="%ad %H" --date=short HEAD >log &&
+ fuzz log >log.predictable &&
+ test_cmp expect log.predictable
+'
+
test_expect_success '--abbrev' '
sed s/SUBJECT/OBJID/ expect.template >expect &&
git shortlog --format="%h" --abbrev=35 HEAD >log &&
@@ -237,6 +244,26 @@ test_expect_success 'shortlog --group=trailer:signed-off-by' '
test_cmp expect actual
'
+test_expect_success 'shortlog --group=format' '
+ git shortlog -s --date="format:%Y" --group="format:%cN (%cd)" \
+ HEAD >actual &&
+ cat >expect <<-\EOF &&
+ 4 C O Mitter (2005)
+ 1 Sin Nombre (2005)
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'shortlog --group=<format> DWIM' '
+ git shortlog -s --date="format:%Y" --group="%cN (%cd)" HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'shortlog bogus --group' '
+ test_must_fail git shortlog --group=bogus HEAD 2>err &&
+ grep "unknown group type" err
+'
+
test_expect_success 'trailer idents are split' '
cat >expect <<-\EOF &&
2 C O Mitter
@@ -319,6 +346,18 @@ test_expect_success 'shortlog can match multiple groups' '
test_cmp expect actual
'
+test_expect_success 'shortlog can match multiple format groups' '
+ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" \
+ git commit --allow-empty -m "identical names" &&
+ test_tick &&
+ cat >expect <<-\EOF &&
+ 2 A U Thor
+ 1 C O Mitter
+ EOF
+ git shortlog -ns --group="%cn" --group="%an" -2 HEAD >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'set up option selection tests' '
git commit --allow-empty -F - <<-\EOF
subject
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index cc15cb4ff62..2ce2b41174d 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -249,6 +249,15 @@ test_expect_success 'log --grep' '
test_cmp expect actual
'
+for noop_opt in --invert-grep --all-match
+do
+ test_expect_success "log $noop_opt without --grep is a NOOP" '
+ git log >expect &&
+ git log $noop_opt >actual &&
+ test_cmp expect actual
+ '
+done
+
cat > expect << EOF
second
initial
diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh
index a730c0db985..a7fa94ce0a2 100755
--- a/t/t4204-patch-id.sh
+++ b/t/t4204-patch-id.sh
@@ -8,13 +8,13 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
test_expect_success 'setup' '
- as="a a a a a a a a" && # eight a
- test_write_lines $as >foo &&
- test_write_lines $as >bar &&
+ str="ab cd ef gh ij kl mn op" &&
+ test_write_lines $str >foo &&
+ test_write_lines $str >bar &&
git add foo bar &&
git commit -a -m initial &&
- test_write_lines $as b >foo &&
- test_write_lines $as b >bar &&
+ test_write_lines $str b >foo &&
+ test_write_lines $str b >bar &&
git commit -a -m first &&
git checkout -b same main &&
git commit --amend -m same-msg &&
@@ -22,8 +22,23 @@ test_expect_success 'setup' '
echo c >foo &&
echo c >bar &&
git commit --amend -a -m notsame-msg &&
+ git checkout -b with_space main~ &&
+ cat >foo <<-\EOF &&
+ a b
+ c d
+ e f
+ g h
+ i j
+ k l
+ m n
+ op
+ EOF
+ cp foo bar &&
+ git add foo bar &&
+ git commit --amend -m "with spaces" &&
test_write_lines bar foo >bar-then-foo &&
test_write_lines foo bar >foo-then-bar
+
'
test_expect_success 'patch-id output is well-formed' '
@@ -42,7 +57,7 @@ calc_patch_id () {
}
get_top_diff () {
- git log -p -1 "$@" -O bar-then-foo --
+ git log -p -1 "$@" -O bar-then-foo --full-index --
}
get_patch_id () {
@@ -61,6 +76,33 @@ test_expect_success 'patch-id detects inequality' '
get_patch_id notsame &&
! test_cmp patch-id_main patch-id_notsame
'
+test_expect_success 'patch-id detects equality binary' '
+ cat >.gitattributes <<-\EOF &&
+ foo binary
+ bar binary
+ EOF
+ get_patch_id main &&
+ get_patch_id same &&
+ git log -p -1 --binary main >top-diff.output &&
+ calc_patch_id <top-diff.output main_binpatch &&
+ git log -p -1 --binary same >top-diff.output &&
+ calc_patch_id <top-diff.output same_binpatch &&
+ test_cmp patch-id_main patch-id_main_binpatch &&
+ test_cmp patch-id_same patch-id_same_binpatch &&
+ test_cmp patch-id_main patch-id_same &&
+ test_when_finished "rm .gitattributes"
+'
+
+test_expect_success 'patch-id detects inequality binary' '
+ cat >.gitattributes <<-\EOF &&
+ foo binary
+ bar binary
+ EOF
+ get_patch_id main &&
+ get_patch_id notsame &&
+ ! test_cmp patch-id_main patch-id_notsame &&
+ test_when_finished "rm .gitattributes"
+'
test_expect_success 'patch-id supports git-format-patch output' '
get_patch_id main &&
@@ -101,9 +143,21 @@ test_patch_id_file_order () {
git format-patch -1 --stdout -O foo-then-bar >format-patch.output &&
calc_patch_id <format-patch.output "ordered-$name" "$@" &&
cmp_patch_id $relevant "$name" "ordered-$name"
+}
+test_patch_id_whitespace () {
+ relevant="$1"
+ shift
+ name="ws-${1}-$relevant"
+ shift
+ get_top_diff "main~" >top-diff.output &&
+ calc_patch_id <top-diff.output "$name" "$@" &&
+ get_top_diff "with_space" >top-diff.output &&
+ calc_patch_id <top-diff.output "ws-$name" "$@" &&
+ cmp_patch_id $relevant "$name" "ws-$name"
}
+
# combined test for options: add more tests here to make them
# run with all options
test_patch_id () {
@@ -119,6 +173,14 @@ test_expect_success 'file order is relevant with --unstable' '
test_patch_id_file_order relevant --unstable --unstable
'
+test_expect_success 'whitespace is relevant with --verbatim' '
+ test_patch_id_whitespace relevant --verbatim --verbatim
+'
+
+test_expect_success 'whitespace is irrelevant without --verbatim' '
+ test_patch_id_whitespace irrelevant --stable --stable
+'
+
#Now test various option combinations.
test_expect_success 'default is unstable' '
test_patch_id relevant default
@@ -134,6 +196,17 @@ test_expect_success 'patchid.stable = false is unstable' '
test_patch_id relevant patchid.stable=false
'
+test_expect_success 'patchid.verbatim = true is correct and stable' '
+ test_config patchid.verbatim true &&
+ test_patch_id_whitespace relevant patchid.verbatim=true &&
+ test_patch_id irrelevant patchid.verbatim=true
+'
+
+test_expect_success 'patchid.verbatim = false is unstable' '
+ test_config patchid.verbatim false &&
+ test_patch_id relevant patchid.verbatim=false
+'
+
test_expect_success '--unstable overrides patchid.stable = true' '
test_config patchid.stable true &&
test_patch_id relevant patchid.stable=true--unstable --unstable
@@ -144,6 +217,11 @@ test_expect_success '--stable overrides patchid.stable = false' '
test_patch_id irrelevant patchid.stable=false--stable --stable
'
+test_expect_success '--verbatim overrides patchid.stable = false' '
+ test_config patchid.stable false &&
+ test_patch_id_whitespace relevant stable=false--verbatim --verbatim
+'
+
test_expect_success 'patch-id supports git-format-patch MIME output' '
get_patch_id main &&
git checkout same &&
@@ -198,7 +276,10 @@ test_expect_success 'patch-id handles no-nl-at-eof markers' '
EOF
calc_patch_id nonl <nonl &&
calc_patch_id withnl <withnl &&
- test_cmp patch-id_nonl patch-id_withnl
+ test_cmp patch-id_nonl patch-id_withnl &&
+ calc_patch_id nonl-inc-ws --verbatim <nonl &&
+ calc_patch_id withnl-inc-ws --verbatim <withnl &&
+ ! test_cmp patch-id_nonl-inc-ws patch-id_withnl-inc-ws
'
test_expect_success 'patch-id handles diffs with one line of before/after' '
diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh
index 7f0c1dcc0f0..2e8f5ad7b82 100755
--- a/t/t4208-log-magic-pathspec.sh
+++ b/t/t4208-log-magic-pathspec.sh
@@ -124,6 +124,7 @@ test_expect_success 'command line pathspec parsing for "git log"' '
test_expect_success 'tree_entry_interesting does not match past submodule boundaries' '
test_when_finished "rm -rf repo submodule" &&
+ test_config_global protocol.file.allow always &&
git init submodule &&
test_commit -C submodule initial &&
git init repo &&
diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh
index a243e3c5176..cac85591b52 100755
--- a/t/t4301-merge-tree-write-tree.sh
+++ b/t/t4301-merge-tree-write-tree.sh
@@ -2,7 +2,6 @@
test_description='git merge-tree --write-tree'
-TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# This test is ort-specific
@@ -138,6 +137,579 @@ test_expect_success 'test conflict notices and such' '
test_cmp expect actual
'
+# directory rename + content conflict
+# Commit O: foo, olddir/{a,b,c}
+# Commit A: modify foo, newdir/{a,b,c}
+# Commit B: modify foo differently & rename foo -> olddir/bar
+# Expected: CONFLICT(content) for for newdir/bar (not olddir/bar or foo)
+
+test_expect_success 'directory rename + content conflict' '
+ # Setup
+ 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 || exit 1; done &&
+ git add foo olddir &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ test_write_lines 1 2 3 4 5 6 >foo &&
+ git add foo &&
+ git mv olddir newdir &&
+ git commit -m "Modify foo, rename olddir to newdir" &&
+
+ git checkout B &&
+ test_write_lines 1 2 3 4 5 six >foo &&
+ git add foo &&
+ git mv foo olddir/bar &&
+ git commit -m "Modify foo & rename foo -> olddir/bar"
+ ) &&
+ # Testing
+ (
+ cd dir-rename-and-content &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+ anonymize_hash out >actual &&
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 1Qnewdir/bar
+ 100644 HASH 2Qnewdir/bar
+ 100644 HASH 3Qnewdir/bar
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q2Qnewdir/barQolddir/barQCONFLICT (directory rename suggested)QCONFLICT (file location): foo renamed to olddir/bar in B^0, inside a directory that was renamed in A^0, suggesting it should perhaps be moved to newdir/bar.
+ Q1Qnewdir/barQAuto-mergingQAuto-merging newdir/bar
+ Q1Qnewdir/barQCONFLICT (contents)QCONFLICT (content): Merge conflict in newdir/bar
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# rename/delete + modify/delete handling
+# Commit O: foo
+# Commit A: modify foo + rename to bar
+# Commit B: delete foo
+# Expected: CONFLICT(rename/delete) + CONFLICT(modify/delete)
+
+test_expect_success 'rename/delete handling' '
+ # Setup
+ git init rename-delete &&
+ (
+ cd rename-delete &&
+ test_write_lines 1 2 3 4 5 >foo &&
+ git add foo &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ test_write_lines 1 2 3 4 5 6 >foo &&
+ git add foo &&
+ git mv foo bar &&
+ git commit -m "Modify foo, rename to bar" &&
+
+ git checkout B &&
+ git rm foo &&
+ git commit -m "remove foo"
+ ) &&
+ # Testing
+ (
+ cd rename-delete &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+ anonymize_hash out >actual &&
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 1Qbar
+ 100644 HASH 2Qbar
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q2QbarQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to bar in A^0, but deleted in B^0.
+ Q1QbarQCONFLICT (modify/delete)QCONFLICT (modify/delete): bar deleted in B^0 and modified in A^0. Version A^0 of bar left in tree.
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# rename/add handling
+# Commit O: foo
+# Commit A: modify foo, add different bar
+# Commit B: modify & rename foo->bar
+# Expected: CONFLICT(add/add) [via rename collide] for bar
+
+test_expect_success 'rename/add handling' '
+ # Setup
+ git init rename-add &&
+ (
+ cd rename-add &&
+ test_write_lines original 1 2 3 4 5 >foo &&
+ git add foo &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ test_write_lines 1 2 3 4 5 >foo &&
+ echo "different file" >bar &&
+ git add foo bar &&
+ git commit -m "Modify foo, add bar" &&
+
+ git checkout B &&
+ test_write_lines original 1 2 3 4 5 6 >foo &&
+ git add foo &&
+ git mv foo bar &&
+ git commit -m "rename foo to bar"
+ ) &&
+ # Testing
+ (
+ cd rename-add &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+
+ #
+ # First, check that the bar that appears at stage 3 does not
+ # correspond to an individual blob anywhere in history
+ #
+ hash=$(cat out | tr "\0" "\n" | head -n 3 | grep 3.bar | cut -f 2 -d " ") &&
+ git rev-list --objects --all >all_blobs &&
+ ! grep $hash all_blobs &&
+
+ #
+ # Second, check anonymized hash output against expectation
+ #
+ anonymize_hash out >actual &&
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 2Qbar
+ 100644 HASH 3Qbar
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q1QbarQAuto-mergingQAuto-merging bar
+ Q1QbarQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in bar
+ Q1QfooQAuto-mergingQAuto-merging foo
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# rename/add, where add is a mode conflict
+# Commit O: foo
+# Commit A: modify foo, add symlink bar
+# Commit B: modify & rename foo->bar
+# Expected: CONFLICT(distinct modes) for bar
+
+test_expect_success SYMLINKS 'rename/add, where add is a mode conflict' '
+ # Setup
+ git init rename-add-symlink &&
+ (
+ cd rename-add-symlink &&
+ test_write_lines original 1 2 3 4 5 >foo &&
+ git add foo &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ test_write_lines 1 2 3 4 5 >foo &&
+ ln -s foo bar &&
+ git add foo bar &&
+ git commit -m "Modify foo, add symlink bar" &&
+
+ git checkout B &&
+ test_write_lines original 1 2 3 4 5 6 >foo &&
+ git add foo &&
+ git mv foo bar &&
+ git commit -m "rename foo to bar"
+ ) &&
+ # Testing
+ (
+ cd rename-add-symlink &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+
+ #
+ # First, check that the bar that appears at stage 3 does not
+ # correspond to an individual blob anywhere in history
+ #
+ hash=$(cat out | tr "\0" "\n" | head -n 3 | grep 3.bar | cut -f 2 -d " ") &&
+ git rev-list --objects --all >all_blobs &&
+ ! grep $hash all_blobs &&
+
+ #
+ # Second, check anonymized hash output against expectation
+ #
+ anonymize_hash out >actual &&
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 120000 HASH 2Qbar
+ 100644 HASH 3Qbar~B^0
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q2QbarQbar~B^0QCONFLICT (distinct modes)QCONFLICT (distinct types): bar had different types on each side; renamed one of them so each can be recorded somewhere.
+ Q1QfooQAuto-mergingQAuto-merging foo
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# rename/rename(1to2) + content conflict handling
+# Commit O: foo
+# Commit A: modify foo & rename to bar
+# Commit B: modify foo & rename to baz
+# Expected: CONFLICT(rename/rename)
+
+test_expect_success 'rename/rename + content conflict' '
+ # Setup
+ git init rr-plus-content &&
+ (
+ cd rr-plus-content &&
+ test_write_lines 1 2 3 4 5 >foo &&
+ git add foo &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ test_write_lines 1 2 3 4 5 six >foo &&
+ git add foo &&
+ git mv foo bar &&
+ git commit -m "Modify foo + rename to bar" &&
+
+ git checkout B &&
+ test_write_lines 1 2 3 4 5 6 >foo &&
+ git add foo &&
+ git mv foo baz &&
+ git commit -m "Modify foo + rename to baz"
+ ) &&
+ # Testing
+ (
+ cd rr-plus-content &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+ anonymize_hash out >actual &&
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 2Qbar
+ 100644 HASH 3Qbaz
+ 100644 HASH 1Qfoo
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q1QfooQAuto-mergingQAuto-merging foo
+ Q3QfooQbarQbazQCONFLICT (rename/rename)QCONFLICT (rename/rename): foo renamed to bar in A^0 and to baz in B^0.
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# rename/add/delete
+# Commit O: foo
+# Commit A: rm foo, add different bar
+# Commit B: rename foo->bar
+# Expected: CONFLICT (rename/delete), CONFLICT(add/add) [via rename collide]
+# for bar
+
+test_expect_success 'rename/add/delete conflict' '
+ # Setup
+ git init rad &&
+ (
+ cd rad &&
+ echo "original file" >foo &&
+ git add foo &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git rm foo &&
+ echo "different file" >bar &&
+ git add bar &&
+ git commit -m "Remove foo, add bar" &&
+
+ git checkout B &&
+ git mv foo bar &&
+ git commit -m "rename foo to bar"
+ ) &&
+ # Testing
+ (
+ cd rad &&
+
+ test_expect_code 1 \
+ git merge-tree -z B^0 A^0 >out &&
+ echo >>out &&
+ anonymize_hash out >actual &&
+
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 2Qbar
+ 100644 HASH 3Qbar
+
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ 2QbarQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to bar in B^0, but deleted in A^0.
+ Q1QbarQAuto-mergingQAuto-merging bar
+ Q1QbarQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in bar
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# rename/rename(2to1)/delete/delete
+# Commit O: foo, bar
+# Commit A: rename foo->baz, rm bar
+# Commit B: rename bar->baz, rm foo
+# Expected: 2x CONFLICT (rename/delete), CONFLICT (add/add) via colliding
+# renames for baz
+
+test_expect_success 'rename/rename(2to1)/delete/delete conflict' '
+ # Setup
+ git init rrdd &&
+ (
+ cd rrdd &&
+ echo foo >foo &&
+ echo bar >bar &&
+ git add foo bar &&
+ git commit -m O &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv foo baz &&
+ git rm bar &&
+ git commit -m "Rename foo, remove bar" &&
+
+ git checkout B &&
+ git mv bar baz &&
+ git rm foo &&
+ git commit -m "Rename bar, remove foo"
+ ) &&
+ # Testing
+ (
+ cd rrdd &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+ anonymize_hash out >actual &&
+
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 2Qbaz
+ 100644 HASH 3Qbaz
+
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ 2QbazQbarQCONFLICT (rename/delete)QCONFLICT (rename/delete): bar renamed to baz in B^0, but deleted in A^0.
+ Q2QbazQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to baz in A^0, but deleted in B^0.
+ Q1QbazQAuto-mergingQAuto-merging baz
+ Q1QbazQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in baz
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# mod6: chains of rename/rename(1to2) + add/add via colliding renames
+# Commit O: one, three, five
+# Commit A: one->two, three->four, five->six
+# Commit B: one->six, three->two, five->four
+# Expected: three CONFLICT(rename/rename) messages + three CONFLICT(add/add)
+# messages; each path in two of the multi-way merged contents
+# found in two, four, six
+
+test_expect_success 'mod6: chains of rename/rename(1to2) and add/add via colliding renames' '
+ # Setup
+ git init mod6 &&
+ (
+ cd mod6 &&
+ test_seq 11 19 >one &&
+ test_seq 31 39 >three &&
+ test_seq 51 59 >five &&
+ git add . &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ test_seq 10 19 >one &&
+ echo 40 >>three &&
+ git add one three &&
+ git mv one two &&
+ git mv three four &&
+ git mv five six &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ echo 20 >>one &&
+ echo forty >>three &&
+ echo 60 >>five &&
+ git add one three five &&
+ git mv one six &&
+ git mv three two &&
+ git mv five four &&
+ test_tick &&
+ git commit -m "B"
+ ) &&
+ # Testing
+ (
+ cd mod6 &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+
+ #
+ # First, check that some of the hashes that appear as stage
+ # conflict entries do not appear as individual blobs anywhere
+ # in history.
+ #
+ hash1=$(cat out | tr "\0" "\n" | head | grep 2.four | cut -f 2 -d " ") &&
+ hash2=$(cat out | tr "\0" "\n" | head | grep 3.two | cut -f 2 -d " ") &&
+ git rev-list --objects --all >all_blobs &&
+ ! grep $hash1 all_blobs &&
+ ! grep $hash2 all_blobs &&
+
+ #
+ # Now compare anonymized hash output with expectation
+ #
+ anonymize_hash out >actual &&
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 1Qfive
+ 100644 HASH 2Qfour
+ 100644 HASH 3Qfour
+ 100644 HASH 1Qone
+ 100644 HASH 2Qsix
+ 100644 HASH 3Qsix
+ 100644 HASH 1Qthree
+ 100644 HASH 2Qtwo
+ 100644 HASH 3Qtwo
+
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ 3QfiveQsixQfourQCONFLICT (rename/rename)QCONFLICT (rename/rename): five renamed to six in A^0 and to four in B^0.
+ Q1QfourQAuto-mergingQAuto-merging four
+ Q1QfourQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in four
+ Q1QoneQAuto-mergingQAuto-merging one
+ Q3QoneQtwoQsixQCONFLICT (rename/rename)QCONFLICT (rename/rename): one renamed to two in A^0 and to six in B^0.
+ Q1QsixQAuto-mergingQAuto-merging six
+ Q1QsixQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in six
+ Q1QthreeQAuto-mergingQAuto-merging three
+ Q3QthreeQfourQtwoQCONFLICT (rename/rename)QCONFLICT (rename/rename): three renamed to four in A^0 and to two in B^0.
+ Q1QtwoQAuto-mergingQAuto-merging two
+ Q1QtwoQCONFLICT (contents)QCONFLICT (add/add): Merge conflict in two
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
+# directory rename + rename/delete + modify/delete + directory/file conflict
+# Commit O: foo, olddir/{a,b,c}
+# Commit A: delete foo, rename olddir/ -> newdir/, add newdir/bar/file
+# Commit B: modify foo & rename foo -> olddir/bar
+# Expected: CONFLICT(content) for for newdir/bar (not olddir/bar or foo)
+
+test_expect_success 'directory rename + rename/delete + modify/delete + directory/file conflict' '
+ # Setup
+ git init 4-stacked-conflict &&
+ (
+ cd 4-stacked-conflict &&
+ test_write_lines 1 2 3 4 5 >foo &&
+ mkdir olddir &&
+ for i in a b c; do echo $i >olddir/$i || exit 1; done &&
+ git add foo olddir &&
+ git commit -m "original" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git rm foo &&
+ git mv olddir newdir &&
+ mkdir newdir/bar &&
+ >newdir/bar/file &&
+ git add newdir/bar/file &&
+ git commit -m "rm foo, olddir/ -> newdir/, + newdir/bar/file" &&
+
+ git checkout B &&
+ test_write_lines 1 2 3 4 5 6 >foo &&
+ git add foo &&
+ git mv foo olddir/bar &&
+ git commit -m "Modify foo & rename foo -> olddir/bar"
+ ) &&
+ # Testing
+ (
+ cd 4-stacked-conflict &&
+
+ test_expect_code 1 \
+ git merge-tree -z A^0 B^0 >out &&
+ echo >>out &&
+ anonymize_hash out >actual &&
+
+ q_to_tab <<-\EOF | lf_to_nul >expect &&
+ HASH
+ 100644 HASH 1Qnewdir/bar~B^0
+ 100644 HASH 3Qnewdir/bar~B^0
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q2Qnewdir/barQolddir/barQCONFLICT (directory rename suggested)QCONFLICT (file location): foo renamed to olddir/bar in B^0, inside a directory that was renamed in A^0, suggesting it should perhaps be moved to newdir/bar.
+ Q2Qnewdir/barQfooQCONFLICT (rename/delete)QCONFLICT (rename/delete): foo renamed to newdir/bar in B^0, but deleted in A^0.
+ Q2Qnewdir/bar~B^0Qnewdir/barQCONFLICT (file/directory)QCONFLICT (file/directory): directory in the way of newdir/bar from B^0; moving it to newdir/bar~B^0 instead.
+ Q1Qnewdir/bar~B^0QCONFLICT (modify/delete)QCONFLICT (modify/delete): newdir/bar~B^0 deleted in A^0 and modified in B^0. Version B^0 of newdir/bar~B^0 left in tree.
+ Q
+ EOF
+ test_cmp expect actual
+ )
+'
+
for opt in $(git merge-tree --git-completion-helper-all)
do
if test $opt = "--trivial-merge" || test $opt = "--write-tree"
@@ -188,8 +760,8 @@ test_expect_success 'NUL terminated conflicted file "lines"' '
git commit -m "Renamed numbers" &&
test_expect_code 1 git merge-tree --write-tree -z tweak1 side2 >out &&
+ echo >>out &&
anonymize_hash out >actual &&
- printf "\\n" >>actual &&
# Expected results:
# "greeting" should merge with conflicts
@@ -238,4 +810,54 @@ test_expect_success 'can override merge of unrelated histories' '
test_cmp expect actual
'
+test_expect_success SANITY 'merge-ort fails gracefully in a read-only repository' '
+ git init --bare read-only &&
+ git push read-only side1 side2 side3 &&
+ test_when_finished "chmod -R u+w read-only" &&
+ chmod -R a-w read-only &&
+ test_must_fail git -C read-only merge-tree side1 side3 &&
+ test_must_fail git -C read-only merge-tree side1 side2
+'
+
+test_expect_success '--stdin with both a successful and a conflicted merge' '
+ printf "side1 side3\nside1 side2" | git merge-tree --stdin >actual &&
+
+ git checkout side1^0 &&
+ git merge side3 &&
+
+ printf "1\0" >expect &&
+ git rev-parse HEAD^{tree} | lf_to_nul >>expect &&
+ printf "\0" >>expect &&
+
+ git checkout side1^0 &&
+ test_must_fail git merge side2 &&
+ sed s/HEAD/side1/ greeting >tmp &&
+ mv tmp greeting &&
+ git add -u &&
+ git mv whatever~HEAD whatever~side1 &&
+
+ printf "0\0" >>expect &&
+ git write-tree | lf_to_nul >>expect &&
+
+ cat <<-EOF | q_to_tab | lf_to_nul >>expect &&
+ 100644 $(git rev-parse side1~1:greeting) 1Qgreeting
+ 100644 $(git rev-parse side1:greeting) 2Qgreeting
+ 100644 $(git rev-parse side2:greeting) 3Qgreeting
+ 100644 $(git rev-parse side1~1:whatever) 1Qwhatever~side1
+ 100644 $(git rev-parse side1:whatever) 2Qwhatever~side1
+ EOF
+
+ q_to_nul <<-EOF >>expect &&
+ Q1QgreetingQAuto-mergingQAuto-merging greeting
+ Q1QgreetingQCONFLICT (contents)QCONFLICT (content): Merge conflict in greeting
+ Q1QnumbersQAuto-mergingQAuto-merging numbers
+ Q2Qwhatever~side1QwhateverQCONFLICT (file/directory)QCONFLICT (file/directory): directory in the way of whatever from side1; moving it to whatever~side1 instead.
+ Q1Qwhatever~side1QCONFLICT (modify/delete)QCONFLICT (modify/delete): whatever~side1 deleted in side2 and modified in side1. Version side1 of whatever~side1 left in tree.
+ EOF
+
+ printf "\0\0" >>expect &&
+
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index eaa0b22ece4..d4730481384 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -342,6 +342,13 @@ test_expect_success 'only enabled filters are available remotely' '
test_cmp_bin remote.bar config.bar
'
+test_expect_success 'invalid filter is reported only once' '
+ test_must_fail git -c tar.invalid.command= archive --format=invalid \
+ HEAD >out 2>err &&
+ test_must_be_empty out &&
+ test_line_count = 1 err
+'
+
test_expect_success 'git archive --format=tgz' '
git archive --format=tgz HEAD >j.tgz
'
diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
index cebad1048cf..db11cababd3 100755
--- a/t/t5100-mailinfo.sh
+++ b/t/t5100-mailinfo.sh
@@ -201,13 +201,13 @@ test_expect_success 'mailinfo -b double [PATCH]' '
test z"$subj" = z"Subject: message"
'
-test_expect_failure 'mailinfo -b trailing [PATCH]' '
+test_expect_success 'mailinfo -b trailing [PATCH]' '
subj="$(echo "Subject: [other] [PATCH] message" |
git mailinfo -b /dev/null /dev/null)" &&
test z"$subj" = z"Subject: [other] message"
'
-test_expect_failure 'mailinfo -b separated double [PATCH]' '
+test_expect_success 'mailinfo -b separated double [PATCH]' '
subj="$(echo "Subject: [PATCH] [other] [PATCH] message" |
git mailinfo -b /dev/null /dev/null)" &&
test z"$subj" = z"Subject: [other] message"
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index f775fc1ce69..6d693eef82f 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -26,22 +26,415 @@ has_any () {
grep -Ff "$1" "$2"
}
-setup_bitmap_history
-
-test_expect_success 'setup writing bitmaps during repack' '
- git config repack.writeBitmaps true
-'
-
-test_expect_success 'full repack creates bitmaps' '
- GIT_TRACE2_EVENT="$(pwd)/trace" \
+test_bitmap_cases () {
+ writeLookupTable=false
+ for i in "$@"
+ do
+ case "$i" in
+ "pack.writeBitmapLookupTable") writeLookupTable=true;;
+ esac
+ done
+
+ test_expect_success 'setup test repository' '
+ rm -fr * .git &&
+ git init &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"'
+ '
+ setup_bitmap_history
+
+ test_expect_success 'setup writing bitmaps during repack' '
+ git config repack.writeBitmaps true
+ '
+
+ test_expect_success 'full repack creates bitmaps' '
+ GIT_TRACE2_EVENT="$(pwd)/trace" \
+ git repack -ad &&
+ ls .git/objects/pack/ | grep bitmap >output &&
+ test_line_count = 1 output &&
+ grep "\"key\":\"num_selected_commits\",\"value\":\"106\"" trace &&
+ grep "\"key\":\"num_maximal_commits\",\"value\":\"107\"" trace
+ '
+
+ basic_bitmap_tests
+
+ test_expect_success 'pack-objects respects --local (non-local loose)' '
+ git init --bare alt.git &&
+ echo $(pwd)/alt.git/objects >.git/objects/info/alternates &&
+ echo content1 >file1 &&
+ # non-local loose object which is not present in bitmapped pack
+ altblob=$(GIT_DIR=alt.git git hash-object -w file1) &&
+ # non-local loose object which is also present in bitmapped pack
+ git cat-file blob $blob | GIT_DIR=alt.git git hash-object -w --stdin &&
+ git add file1 &&
+ test_tick &&
+ git commit -m commit_file1 &&
+ echo HEAD | git pack-objects --local --stdout --revs >1.pack &&
+ git index-pack 1.pack &&
+ list_packed_objects 1.idx >1.objects &&
+ printf "%s\n" "$altblob" "$blob" >nonlocal-loose &&
+ ! has_any nonlocal-loose 1.objects
+ '
+
+ test_expect_success 'pack-objects respects --honor-pack-keep (local non-bitmapped pack)' '
+ echo content2 >file2 &&
+ blob2=$(git hash-object -w file2) &&
+ git add file2 &&
+ test_tick &&
+ git commit -m commit_file2 &&
+ printf "%s\n" "$blob2" "$bitmaptip" >keepobjects &&
+ pack2=$(git pack-objects pack2 <keepobjects) &&
+ mv pack2-$pack2.* .git/objects/pack/ &&
+ >.git/objects/pack/pack2-$pack2.keep &&
+ rm $(objpath $blob2) &&
+ echo HEAD | git pack-objects --honor-pack-keep --stdout --revs >2a.pack &&
+ git index-pack 2a.pack &&
+ list_packed_objects 2a.idx >2a.objects &&
+ ! has_any keepobjects 2a.objects
+ '
+
+ test_expect_success 'pack-objects respects --local (non-local pack)' '
+ mv .git/objects/pack/pack2-$pack2.* alt.git/objects/pack/ &&
+ echo HEAD | git pack-objects --local --stdout --revs >2b.pack &&
+ git index-pack 2b.pack &&
+ list_packed_objects 2b.idx >2b.objects &&
+ ! has_any keepobjects 2b.objects
+ '
+
+ test_expect_success 'pack-objects respects --honor-pack-keep (local bitmapped pack)' '
+ ls .git/objects/pack/ | grep bitmap >output &&
+ test_line_count = 1 output &&
+ packbitmap=$(basename $(cat output) .bitmap) &&
+ list_packed_objects .git/objects/pack/$packbitmap.idx >packbitmap.objects &&
+ test_when_finished "rm -f .git/objects/pack/$packbitmap.keep" &&
+ >.git/objects/pack/$packbitmap.keep &&
+ echo HEAD | git pack-objects --honor-pack-keep --stdout --revs >3a.pack &&
+ git index-pack 3a.pack &&
+ list_packed_objects 3a.idx >3a.objects &&
+ ! has_any packbitmap.objects 3a.objects
+ '
+
+ test_expect_success 'pack-objects respects --local (non-local bitmapped pack)' '
+ mv .git/objects/pack/$packbitmap.* alt.git/objects/pack/ &&
+ rm -f .git/objects/pack/multi-pack-index &&
+ test_when_finished "mv alt.git/objects/pack/$packbitmap.* .git/objects/pack/" &&
+ echo HEAD | git pack-objects --local --stdout --revs >3b.pack &&
+ git index-pack 3b.pack &&
+ list_packed_objects 3b.idx >3b.objects &&
+ ! has_any packbitmap.objects 3b.objects
+ '
+
+ test_expect_success 'pack-objects to file can use bitmap' '
+ # make sure we still have 1 bitmap index from previous tests
+ ls .git/objects/pack/ | grep bitmap >output &&
+ test_line_count = 1 output &&
+ # verify equivalent packs are generated with/without using bitmap index
+ packasha1=$(git pack-objects --no-use-bitmap-index --all packa </dev/null) &&
+ packbsha1=$(git pack-objects --use-bitmap-index --all packb </dev/null) &&
+ list_packed_objects packa-$packasha1.idx >packa.objects &&
+ list_packed_objects packb-$packbsha1.idx >packb.objects &&
+ test_cmp packa.objects packb.objects
+ '
+
+ test_expect_success 'full repack, reusing previous bitmaps' '
git repack -ad &&
- ls .git/objects/pack/ | grep bitmap >output &&
- test_line_count = 1 output &&
- grep "\"key\":\"num_selected_commits\",\"value\":\"106\"" trace &&
- grep "\"key\":\"num_maximal_commits\",\"value\":\"107\"" trace
-'
+ ls .git/objects/pack/ | grep bitmap >output &&
+ test_line_count = 1 output
+ '
+
+ test_expect_success 'fetch (full bitmap)' '
+ git --git-dir=clone.git fetch origin second:second &&
+ git rev-parse HEAD >expect &&
+ git --git-dir=clone.git rev-parse HEAD >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success 'create objects for missing-HAVE tests' '
+ blob=$(echo "missing have" | git hash-object -w --stdin) &&
+ tree=$(printf "100644 blob $blob\tfile\n" | git mktree) &&
+ parent=$(echo parent | git commit-tree $tree) &&
+ commit=$(echo commit | git commit-tree $tree -p $parent) &&
+ cat >revs <<-EOF
+ HEAD
+ ^HEAD^
+ ^$commit
+ EOF
+ '
+
+ test_expect_success 'pack-objects respects --incremental' '
+ cat >revs2 <<-EOF &&
+ HEAD
+ $commit
+ EOF
+ git pack-objects --incremental --stdout --revs <revs2 >4.pack &&
+ git index-pack 4.pack &&
+ list_packed_objects 4.idx >4.objects &&
+ test_line_count = 4 4.objects &&
+ git rev-list --objects $commit >revlist &&
+ cut -d" " -f1 revlist |sort >objects &&
+ test_cmp 4.objects objects
+ '
+
+ test_expect_success 'pack with missing blob' '
+ rm $(objpath $blob) &&
+ git pack-objects --stdout --revs <revs >/dev/null
+ '
+
+ test_expect_success 'pack with missing tree' '
+ rm $(objpath $tree) &&
+ git pack-objects --stdout --revs <revs >/dev/null
+ '
+
+ test_expect_success 'pack with missing parent' '
+ rm $(objpath $parent) &&
+ git pack-objects --stdout --revs <revs >/dev/null
+ '
+
+ test_expect_success JGIT,SHA1 'we can read jgit bitmaps' '
+ git clone --bare . compat-jgit.git &&
+ (
+ cd compat-jgit.git &&
+ rm -f objects/pack/*.bitmap &&
+ jgit gc &&
+ git rev-list --test-bitmap HEAD
+ )
+ '
+
+ test_expect_success JGIT,SHA1 'jgit can read our bitmaps' '
+ git clone --bare . compat-us.git &&
+ (
+ cd compat-us.git &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+ git repack -adb &&
+ # jgit gc will barf if it does not like our bitmaps
+ jgit gc
+ )
+ '
+
+ test_expect_success 'splitting packs does not generate bogus bitmaps' '
+ test-tool genrandom foo $((1024 * 1024)) >rand &&
+ git add rand &&
+ git commit -m "commit with big file" &&
+ git -c pack.packSizeLimit=500k repack -adb &&
+ git init --bare no-bitmaps.git &&
+ git -C no-bitmaps.git fetch .. HEAD
+ '
+
+ test_expect_success 'set up reusable pack' '
+ rm -f .git/objects/pack/*.keep &&
+ git repack -adb &&
+ reusable_pack () {
+ git for-each-ref --format="%(objectname)" |
+ git pack-objects --delta-base-offset --revs --stdout "$@"
+ }
+ '
+
+ test_expect_success 'pack reuse respects --honor-pack-keep' '
+ test_when_finished "rm -f .git/objects/pack/*.keep" &&
+ for i in .git/objects/pack/*.pack
+ do
+ >${i%.pack}.keep || return 1
+ done &&
+ reusable_pack --honor-pack-keep >empty.pack &&
+ git index-pack empty.pack &&
+ git show-index <empty.idx >actual &&
+ test_must_be_empty actual
+ '
+
+ test_expect_success 'pack reuse respects --local' '
+ mv .git/objects/pack/* alt.git/objects/pack/ &&
+ test_when_finished "mv alt.git/objects/pack/* .git/objects/pack/" &&
+ reusable_pack --local >empty.pack &&
+ git index-pack empty.pack &&
+ git show-index <empty.idx >actual &&
+ test_must_be_empty actual
+ '
+
+ test_expect_success 'pack reuse respects --incremental' '
+ reusable_pack --incremental >empty.pack &&
+ git index-pack empty.pack &&
+ git show-index <empty.idx >actual &&
+ test_must_be_empty actual
+ '
+
+ test_expect_success 'truncated bitmap fails gracefully (ewah)' '
+ test_config pack.writebitmaphashcache false &&
+ test_config pack.writebitmaplookuptable false &&
+ git repack -ad &&
+ git rev-list --use-bitmap-index --count --all >expect &&
+ bitmap=$(ls .git/objects/pack/*.bitmap) &&
+ test_when_finished "rm -f $bitmap" &&
+ test_copy_bytes 256 <$bitmap >$bitmap.tmp &&
+ mv -f $bitmap.tmp $bitmap &&
+ git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
+ test_cmp expect actual &&
+ test_i18ngrep corrupt.ewah.bitmap stderr
+ '
+
+ test_expect_success 'truncated bitmap fails gracefully (cache)' '
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+ git repack -ad &&
+ git rev-list --use-bitmap-index --count --all >expect &&
+ bitmap=$(ls .git/objects/pack/*.bitmap) &&
+ test_when_finished "rm -f $bitmap" &&
+ test_copy_bytes 512 <$bitmap >$bitmap.tmp &&
+ mv -f $bitmap.tmp $bitmap &&
+ git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
+ test_cmp expect actual &&
+ test_i18ngrep corrupted.bitmap.index stderr
+ '
+
+ # Create a state of history with these properties:
+ #
+ # - refs that allow a client to fetch some new history, while sharing some old
+ # history with the server; we use branches delta-reuse-old and
+ # delta-reuse-new here
+ #
+ # - the new history contains an object that is stored on the server as a delta
+ # against a base that is in the old history
+ #
+ # - the base object is not immediately reachable from the tip of the old
+ # history; finding it would involve digging down through history we know the
+ # other side has
+ #
+ # This should result in a state where fetching from old->new would not
+ # traditionally reuse the on-disk delta (because we'd have to dig to realize
+ # that the client has it), but we will do so if bitmaps can tell us cheaply
+ # that the other side has it.
+ test_expect_success 'set up thin delta-reuse parent' '
+ # This first commit contains the buried base object.
+ test-tool genrandom delta 16384 >file &&
+ git add file &&
+ git commit -m "delta base" &&
+ base=$(git rev-parse --verify HEAD:file) &&
+
+ # These intermediate commits bury the base back in history.
+ # This becomes the "old" state.
+ for i in 1 2 3 4 5
+ do
+ echo $i >file &&
+ git commit -am "intermediate $i" || return 1
+ done &&
+ git branch delta-reuse-old &&
+
+ # And now our new history has a delta against the buried base. Note
+ # that this must be smaller than the original file, since pack-objects
+ # prefers to create deltas from smaller objects to larger.
+ test-tool genrandom delta 16300 >file &&
+ git commit -am "delta result" &&
+ delta=$(git rev-parse --verify HEAD:file) &&
+ git branch delta-reuse-new &&
+
+ # Repack with bitmaps and double check that we have the expected delta
+ # relationship.
+ git repack -adb &&
+ have_delta $delta $base
+ '
+
+ # Now we can sanity-check the non-bitmap behavior (that the server is not able
+ # to reuse the delta). This isn't strictly something we care about, so this
+ # test could be scrapped in the future. But it makes sure that the next test is
+ # actually triggering the feature we want.
+ #
+ # Note that our tools for working with on-the-wire "thin" packs are limited. So
+ # we actually perform the fetch, retain the resulting pack, and inspect the
+ # result.
+ test_expect_success 'fetch without bitmaps ignores delta against old base' '
+ test_config pack.usebitmaps false &&
+ test_when_finished "rm -rf client.git" &&
+ git init --bare client.git &&
+ (
+ cd client.git &&
+ git config transfer.unpackLimit 1 &&
+ git fetch .. delta-reuse-old:delta-reuse-old &&
+ git fetch .. delta-reuse-new:delta-reuse-new &&
+ have_delta $delta $ZERO_OID
+ )
+ '
+
+ # And do the same for the bitmap case, where we do expect to find the delta.
+ test_expect_success 'fetch with bitmaps can reuse old base' '
+ test_config pack.usebitmaps true &&
+ test_when_finished "rm -rf client.git" &&
+ git init --bare client.git &&
+ (
+ cd client.git &&
+ git config transfer.unpackLimit 1 &&
+ git fetch .. delta-reuse-old:delta-reuse-old &&
+ git fetch .. delta-reuse-new:delta-reuse-new &&
+ have_delta $delta $base
+ )
+ '
+
+ test_expect_success 'pack.preferBitmapTips' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+
+ # create enough commits that not all are receive bitmap
+ # coverage even if they are all at the tip of some reference.
+ test_commit_bulk --message="%s" 103 &&
+
+ git rev-list HEAD >commits.raw &&
+ sort <commits.raw >commits &&
+
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
+
+ git repack -adb &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+
+ # remember which commits did not receive bitmaps
+ comm -13 bitmaps commits >before &&
+ test_file_not_empty before &&
+
+ # mark the commits which did not receive bitmaps as preferred,
+ # and generate the bitmap again
+ perl -pe "s{^}{create refs/tags/include/$. }" <before |
+ git update-ref --stdin &&
+ git -c pack.preferBitmapTips=refs/tags/include repack -adb &&
+
+ # finally, check that the commit(s) without bitmap coverage
+ # are not the same ones as before
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >after &&
+
+ ! test_cmp before after
+ )
+ '
+
+ test_expect_success 'complains about multiple pack bitmaps' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+
+ test_commit base &&
+
+ git repack -adb &&
+ bitmap="$(ls .git/objects/pack/pack-*.bitmap)" &&
+ mv "$bitmap" "$bitmap.bak" &&
+
+ test_commit other &&
+ git repack -ab &&
+
+ mv "$bitmap.bak" "$bitmap" &&
+
+ find .git/objects/pack -type f -name "*.pack" >packs &&
+ find .git/objects/pack -type f -name "*.bitmap" >bitmaps &&
+ test_line_count = 2 packs &&
+ test_line_count = 2 bitmaps &&
+
+ git rev-list --use-bitmap-index HEAD 2>err &&
+ grep "ignoring extra bitmap file" err
+ )
+ '
+}
-basic_bitmap_tests
+test_bitmap_cases
test_expect_success 'incremental repack fails when bitmaps are requested' '
test_commit more-1 &&
@@ -54,219 +447,17 @@ test_expect_success 'incremental repack can disable bitmaps' '
git repack -d --no-write-bitmap-index
'
-test_expect_success 'pack-objects respects --local (non-local loose)' '
- git init --bare alt.git &&
- echo $(pwd)/alt.git/objects >.git/objects/info/alternates &&
- echo content1 >file1 &&
- # non-local loose object which is not present in bitmapped pack
- altblob=$(GIT_DIR=alt.git git hash-object -w file1) &&
- # non-local loose object which is also present in bitmapped pack
- git cat-file blob $blob | GIT_DIR=alt.git git hash-object -w --stdin &&
- git add file1 &&
- test_tick &&
- git commit -m commit_file1 &&
- echo HEAD | git pack-objects --local --stdout --revs >1.pack &&
- git index-pack 1.pack &&
- list_packed_objects 1.idx >1.objects &&
- printf "%s\n" "$altblob" "$blob" >nonlocal-loose &&
- ! has_any nonlocal-loose 1.objects
-'
-
-test_expect_success 'pack-objects respects --honor-pack-keep (local non-bitmapped pack)' '
- echo content2 >file2 &&
- blob2=$(git hash-object -w file2) &&
- git add file2 &&
- test_tick &&
- git commit -m commit_file2 &&
- printf "%s\n" "$blob2" "$bitmaptip" >keepobjects &&
- pack2=$(git pack-objects pack2 <keepobjects) &&
- mv pack2-$pack2.* .git/objects/pack/ &&
- >.git/objects/pack/pack2-$pack2.keep &&
- rm $(objpath $blob2) &&
- echo HEAD | git pack-objects --honor-pack-keep --stdout --revs >2a.pack &&
- git index-pack 2a.pack &&
- list_packed_objects 2a.idx >2a.objects &&
- ! has_any keepobjects 2a.objects
-'
-
-test_expect_success 'pack-objects respects --local (non-local pack)' '
- mv .git/objects/pack/pack2-$pack2.* alt.git/objects/pack/ &&
- echo HEAD | git pack-objects --local --stdout --revs >2b.pack &&
- git index-pack 2b.pack &&
- list_packed_objects 2b.idx >2b.objects &&
- ! has_any keepobjects 2b.objects
-'
-
-test_expect_success 'pack-objects respects --honor-pack-keep (local bitmapped pack)' '
- ls .git/objects/pack/ | grep bitmap >output &&
- test_line_count = 1 output &&
- packbitmap=$(basename $(cat output) .bitmap) &&
- list_packed_objects .git/objects/pack/$packbitmap.idx >packbitmap.objects &&
- test_when_finished "rm -f .git/objects/pack/$packbitmap.keep" &&
- >.git/objects/pack/$packbitmap.keep &&
- echo HEAD | git pack-objects --honor-pack-keep --stdout --revs >3a.pack &&
- git index-pack 3a.pack &&
- list_packed_objects 3a.idx >3a.objects &&
- ! has_any packbitmap.objects 3a.objects
-'
-
-test_expect_success 'pack-objects respects --local (non-local bitmapped pack)' '
- mv .git/objects/pack/$packbitmap.* alt.git/objects/pack/ &&
- rm -f .git/objects/pack/multi-pack-index &&
- test_when_finished "mv alt.git/objects/pack/$packbitmap.* .git/objects/pack/" &&
- echo HEAD | git pack-objects --local --stdout --revs >3b.pack &&
- git index-pack 3b.pack &&
- list_packed_objects 3b.idx >3b.objects &&
- ! has_any packbitmap.objects 3b.objects
-'
-
-test_expect_success 'pack-objects to file can use bitmap' '
- # make sure we still have 1 bitmap index from previous tests
- ls .git/objects/pack/ | grep bitmap >output &&
- test_line_count = 1 output &&
- # verify equivalent packs are generated with/without using bitmap index
- packasha1=$(git pack-objects --no-use-bitmap-index --all packa </dev/null) &&
- packbsha1=$(git pack-objects --use-bitmap-index --all packb </dev/null) &&
- list_packed_objects packa-$packasha1.idx >packa.objects &&
- list_packed_objects packb-$packbsha1.idx >packb.objects &&
- test_cmp packa.objects packb.objects
-'
-
-test_expect_success 'full repack, reusing previous bitmaps' '
- git repack -ad &&
- ls .git/objects/pack/ | grep bitmap >output &&
- test_line_count = 1 output
-'
-
-test_expect_success 'fetch (full bitmap)' '
- git --git-dir=clone.git fetch origin second:second &&
- git rev-parse HEAD >expect &&
- git --git-dir=clone.git rev-parse HEAD >actual &&
- test_cmp expect actual
-'
-
-test_expect_success 'create objects for missing-HAVE tests' '
- blob=$(echo "missing have" | git hash-object -w --stdin) &&
- tree=$(printf "100644 blob $blob\tfile\n" | git mktree) &&
- parent=$(echo parent | git commit-tree $tree) &&
- commit=$(echo commit | git commit-tree $tree -p $parent) &&
- cat >revs <<-EOF
- HEAD
- ^HEAD^
- ^$commit
- EOF
-'
-
-test_expect_success 'pack-objects respects --incremental' '
- cat >revs2 <<-EOF &&
- HEAD
- $commit
- EOF
- git pack-objects --incremental --stdout --revs <revs2 >4.pack &&
- git index-pack 4.pack &&
- list_packed_objects 4.idx >4.objects &&
- test_line_count = 4 4.objects &&
- git rev-list --objects $commit >revlist &&
- cut -d" " -f1 revlist |sort >objects &&
- test_cmp 4.objects objects
-'
-
-test_expect_success 'pack with missing blob' '
- rm $(objpath $blob) &&
- git pack-objects --stdout --revs <revs >/dev/null
-'
-
-test_expect_success 'pack with missing tree' '
- rm $(objpath $tree) &&
- git pack-objects --stdout --revs <revs >/dev/null
-'
-
-test_expect_success 'pack with missing parent' '
- rm $(objpath $parent) &&
- git pack-objects --stdout --revs <revs >/dev/null
-'
-
-test_expect_success JGIT,SHA1 'we can read jgit bitmaps' '
- git clone --bare . compat-jgit.git &&
- (
- cd compat-jgit.git &&
- rm -f objects/pack/*.bitmap &&
- jgit gc &&
- git rev-list --test-bitmap HEAD
- )
-'
-
-test_expect_success JGIT,SHA1 'jgit can read our bitmaps' '
- git clone --bare . compat-us.git &&
- (
- cd compat-us.git &&
- git repack -adb &&
- # jgit gc will barf if it does not like our bitmaps
- jgit gc
- )
-'
-
-test_expect_success 'splitting packs does not generate bogus bitmaps' '
- test-tool genrandom foo $((1024 * 1024)) >rand &&
- git add rand &&
- git commit -m "commit with big file" &&
- git -c pack.packSizeLimit=500k repack -adb &&
- git init --bare no-bitmaps.git &&
- git -C no-bitmaps.git fetch .. HEAD
-'
-
-test_expect_success 'set up reusable pack' '
- rm -f .git/objects/pack/*.keep &&
- git repack -adb &&
- reusable_pack () {
- git for-each-ref --format="%(objectname)" |
- git pack-objects --delta-base-offset --revs --stdout "$@"
- }
-'
-
-test_expect_success 'pack reuse respects --honor-pack-keep' '
- test_when_finished "rm -f .git/objects/pack/*.keep" &&
- for i in .git/objects/pack/*.pack
- do
- >${i%.pack}.keep || return 1
- done &&
- reusable_pack --honor-pack-keep >empty.pack &&
- git index-pack empty.pack &&
- git show-index <empty.idx >actual &&
- test_must_be_empty actual
-'
-
-test_expect_success 'pack reuse respects --local' '
- mv .git/objects/pack/* alt.git/objects/pack/ &&
- test_when_finished "mv alt.git/objects/pack/* .git/objects/pack/" &&
- reusable_pack --local >empty.pack &&
- git index-pack empty.pack &&
- git show-index <empty.idx >actual &&
- test_must_be_empty actual
-'
+test_bitmap_cases "pack.writeBitmapLookupTable"
-test_expect_success 'pack reuse respects --incremental' '
- reusable_pack --incremental >empty.pack &&
- git index-pack empty.pack &&
- git show-index <empty.idx >actual &&
- test_must_be_empty actual
+test_expect_success 'verify writing bitmap lookup table when enabled' '
+ GIT_TRACE2_EVENT="$(pwd)/trace2" \
+ git repack -ad &&
+ grep "\"label\":\"writing_lookup_table\"" trace2
'
-test_expect_success 'truncated bitmap fails gracefully (ewah)' '
+test_expect_success 'truncated bitmap fails gracefully (lookup table)' '
test_config pack.writebitmaphashcache false &&
- git repack -ad &&
- git rev-list --use-bitmap-index --count --all >expect &&
- bitmap=$(ls .git/objects/pack/*.bitmap) &&
- test_when_finished "rm -f $bitmap" &&
- test_copy_bytes 256 <$bitmap >$bitmap.tmp &&
- mv -f $bitmap.tmp $bitmap &&
- git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
- test_cmp expect actual &&
- test_i18ngrep corrupt.ewah.bitmap stderr
-'
-
-test_expect_success 'truncated bitmap fails gracefully (cache)' '
- git repack -ad &&
+ git repack -adb &&
git rev-list --use-bitmap-index --count --all >expect &&
bitmap=$(ls .git/objects/pack/*.bitmap) &&
test_when_finished "rm -f $bitmap" &&
@@ -277,152 +468,4 @@ test_expect_success 'truncated bitmap fails gracefully (cache)' '
test_i18ngrep corrupted.bitmap.index stderr
'
-# Create a state of history with these properties:
-#
-# - refs that allow a client to fetch some new history, while sharing some old
-# history with the server; we use branches delta-reuse-old and
-# delta-reuse-new here
-#
-# - the new history contains an object that is stored on the server as a delta
-# against a base that is in the old history
-#
-# - the base object is not immediately reachable from the tip of the old
-# history; finding it would involve digging down through history we know the
-# other side has
-#
-# This should result in a state where fetching from old->new would not
-# traditionally reuse the on-disk delta (because we'd have to dig to realize
-# that the client has it), but we will do so if bitmaps can tell us cheaply
-# that the other side has it.
-test_expect_success 'set up thin delta-reuse parent' '
- # This first commit contains the buried base object.
- test-tool genrandom delta 16384 >file &&
- git add file &&
- git commit -m "delta base" &&
- base=$(git rev-parse --verify HEAD:file) &&
-
- # These intermediate commits bury the base back in history.
- # This becomes the "old" state.
- for i in 1 2 3 4 5
- do
- echo $i >file &&
- git commit -am "intermediate $i" || return 1
- done &&
- git branch delta-reuse-old &&
-
- # And now our new history has a delta against the buried base. Note
- # that this must be smaller than the original file, since pack-objects
- # prefers to create deltas from smaller objects to larger.
- test-tool genrandom delta 16300 >file &&
- git commit -am "delta result" &&
- delta=$(git rev-parse --verify HEAD:file) &&
- git branch delta-reuse-new &&
-
- # Repack with bitmaps and double check that we have the expected delta
- # relationship.
- git repack -adb &&
- have_delta $delta $base
-'
-
-# Now we can sanity-check the non-bitmap behavior (that the server is not able
-# to reuse the delta). This isn't strictly something we care about, so this
-# test could be scrapped in the future. But it makes sure that the next test is
-# actually triggering the feature we want.
-#
-# Note that our tools for working with on-the-wire "thin" packs are limited. So
-# we actually perform the fetch, retain the resulting pack, and inspect the
-# result.
-test_expect_success 'fetch without bitmaps ignores delta against old base' '
- test_config pack.usebitmaps false &&
- test_when_finished "rm -rf client.git" &&
- git init --bare client.git &&
- (
- cd client.git &&
- git config transfer.unpackLimit 1 &&
- git fetch .. delta-reuse-old:delta-reuse-old &&
- git fetch .. delta-reuse-new:delta-reuse-new &&
- have_delta $delta $ZERO_OID
- )
-'
-
-# And do the same for the bitmap case, where we do expect to find the delta.
-test_expect_success 'fetch with bitmaps can reuse old base' '
- test_config pack.usebitmaps true &&
- test_when_finished "rm -rf client.git" &&
- git init --bare client.git &&
- (
- cd client.git &&
- git config transfer.unpackLimit 1 &&
- git fetch .. delta-reuse-old:delta-reuse-old &&
- git fetch .. delta-reuse-new:delta-reuse-new &&
- have_delta $delta $base
- )
-'
-
-test_expect_success 'pack.preferBitmapTips' '
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
-
- # create enough commits that not all are receive bitmap
- # coverage even if they are all at the tip of some reference.
- test_commit_bulk --message="%s" 103 &&
-
- git rev-list HEAD >commits.raw &&
- sort <commits.raw >commits &&
-
- git log --format="create refs/tags/%s %H" HEAD >refs &&
- git update-ref --stdin <refs &&
-
- git repack -adb &&
- test-tool bitmap list-commits | sort >bitmaps &&
-
- # remember which commits did not receive bitmaps
- comm -13 bitmaps commits >before &&
- test_file_not_empty before &&
-
- # mark the commits which did not receive bitmaps as preferred,
- # and generate the bitmap again
- perl -pe "s{^}{create refs/tags/include/$. }" <before |
- git update-ref --stdin &&
- git -c pack.preferBitmapTips=refs/tags/include repack -adb &&
-
- # finally, check that the commit(s) without bitmap coverage
- # are not the same ones as before
- test-tool bitmap list-commits | sort >bitmaps &&
- comm -13 bitmaps commits >after &&
-
- ! test_cmp before after
- )
-'
-
-test_expect_success 'complains about multiple pack bitmaps' '
- rm -fr repo &&
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
-
- test_commit base &&
-
- git repack -adb &&
- bitmap="$(ls .git/objects/pack/pack-*.bitmap)" &&
- mv "$bitmap" "$bitmap.bak" &&
-
- test_commit other &&
- git repack -ab &&
-
- mv "$bitmap.bak" "$bitmap" &&
-
- find .git/objects/pack -type f -name "*.pack" >packs &&
- find .git/objects/pack -type f -name "*.bitmap" >bitmaps &&
- test_line_count = 2 packs &&
- test_line_count = 2 bitmaps &&
-
- git rev-list --use-bitmap-index HEAD 2>err &&
- grep "ignoring extra bitmap file" err
- )
-'
-
test_done
diff --git a/t/t5311-pack-bitmaps-shallow.sh b/t/t5311-pack-bitmaps-shallow.sh
index 872a95df338..9dae60f73e3 100755
--- a/t/t5311-pack-bitmaps-shallow.sh
+++ b/t/t5311-pack-bitmaps-shallow.sh
@@ -17,23 +17,40 @@ test_description='check bitmap operation with shallow repositories'
# the tree for A. But in a shallow one, we've grafted away
# A, and fetching A to B requires that the other side send
# us the tree for file=1.
-test_expect_success 'setup shallow repo' '
- echo 1 >file &&
- git add file &&
- git commit -m orig &&
- echo 2 >file &&
- git commit -a -m update &&
- git clone --no-local --bare --depth=1 . shallow.git &&
- echo 1 >file &&
- git commit -a -m repeat
-'
-
-test_expect_success 'turn on bitmaps in the parent' '
- git repack -adb
-'
-
-test_expect_success 'shallow fetch from bitmapped repo' '
- (cd shallow.git && git fetch)
-'
+test_shallow_bitmaps () {
+ writeLookupTable=false
+
+ for i in "$@"
+ do
+ case $i in
+ "pack.writeBitmapLookupTable") writeLookupTable=true;;
+ esac
+ done
+
+ test_expect_success 'setup shallow repo' '
+ rm -rf * .git &&
+ git init &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+ echo 1 >file &&
+ git add file &&
+ git commit -m orig &&
+ echo 2 >file &&
+ git commit -a -m update &&
+ git clone --no-local --bare --depth=1 . shallow.git &&
+ echo 1 >file &&
+ git commit -a -m repeat
+ '
+
+ test_expect_success 'turn on bitmaps in the parent' '
+ git repack -adb
+ '
+
+ test_expect_success 'shallow fetch from bitmapped repo' '
+ (cd shallow.git && git fetch)
+ '
+}
+
+test_shallow_bitmaps
+test_shallow_bitmaps "pack.writeBitmapLookupTable"
test_done
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index 1b0cd82359d..049c5fc8ead 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -12,12 +12,12 @@ test_expect_success 'usage' '
test_expect_success 'usage shown without sub-command' '
test_expect_code 129 git commit-graph 2>err &&
- ! grep error: err
+ grep usage: err
'
test_expect_success 'usage shown with an error on unknown sub-command' '
cat >expect <<-\EOF &&
- error: unrecognized subcommand: unknown
+ error: unknown subcommand: `unknown'\''
EOF
test_expect_code 129 git commit-graph unknown 2>stderr &&
grep error stderr >actual &&
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index afbe93f162e..b5f9b109222 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -784,6 +784,70 @@ test_expect_success 'repack creates a new pack' '
)
'
+test_expect_success 'repack (all) ignores cruft pack' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ test_commit base &&
+ test_commit --no-tag unreachable &&
+
+ git reset --hard base &&
+ git reflog expire --all --expire=all &&
+ git repack --cruft -d &&
+
+ git multi-pack-index write &&
+
+ find $objdir/pack | sort >before &&
+ git multi-pack-index repack --batch-size=0 &&
+ find $objdir/pack | sort >after &&
+
+ test_cmp before after
+ )
+'
+
+test_expect_success 'repack (--batch-size) ignores cruft pack' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ test_commit_bulk 5 &&
+ test_commit --no-tag unreachable &&
+
+ git reset --hard HEAD^ &&
+ git reflog expire --all --expire=all &&
+ git repack --cruft -d &&
+
+ test_commit four &&
+
+ find $objdir/pack -type f -name "*.pack" | sort >before &&
+ git repack -d &&
+ find $objdir/pack -type f -name "*.pack" | sort >after &&
+
+ pack="$(comm -13 before after)" &&
+ test_file_size "$pack" >sz &&
+ # Set --batch-size to twice the size of the pack created
+ # in the previous step, since this is enough to
+ # accommodate it and the cruft pack.
+ #
+ # This means that the MIDX machinery *could* combine the
+ # new and cruft packs together.
+ #
+ # We ensure that it does not below.
+ batch="$((($(cat sz) * 2)))" &&
+
+ git multi-pack-index write &&
+
+ find $objdir/pack | sort >before &&
+ git multi-pack-index repack --batch-size=$batch &&
+ find $objdir/pack | sort >after &&
+
+ test_cmp before after
+ )
+'
+
test_expect_success 'expire removes repacked packs' '
(
cd dup &&
@@ -847,6 +911,36 @@ test_expect_success 'expire respects .keep files' '
)
'
+test_expect_success 'expiring unreferenced cruft pack retains pack' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ test_commit base &&
+ test_commit --no-tag unreachable &&
+ unreachable=$(git rev-parse HEAD) &&
+
+ git reset --hard base &&
+ git reflog expire --all --expire=all &&
+ git repack --cruft -d &&
+ mtimes="$(ls $objdir/pack/pack-*.mtimes)" &&
+
+ echo "base..$unreachable" >in &&
+ pack="$(git pack-objects --revs --delta-base-offset \
+ $objdir/pack/pack <in)" &&
+
+ # Preferring the contents of "$pack" will leave the
+ # cruft pack unreferenced (ie., none of the objects
+ # contained in the cruft pack will have their MIDX copy
+ # selected from the cruft pack).
+ git multi-pack-index write --preferred-pack="pack-$pack.pack" &&
+ git multi-pack-index expire &&
+
+ test_path_is_file "$mtimes"
+ )
+'
+
test_expect_success 'repack --batch-size=0 repacks everything' '
cp -r dup dup2 &&
(
diff --git a/t/t5320-delta-islands.sh b/t/t5320-delta-islands.sh
index 124d47603df..406363381f1 100755
--- a/t/t5320-delta-islands.sh
+++ b/t/t5320-delta-islands.sh
@@ -134,7 +134,7 @@ test_expect_success 'island core places core objects first' '
repack -adfi &&
git verify-pack -v .git/objects/pack/*.pack |
cut -d" " -f1 |
- egrep "$root|$two" >actual &&
+ grep -E "$root|$two" >actual &&
test_cmp expect actual
'
diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
index 4fe57414c13..0882cbb6e4a 100755
--- a/t/t5326-multi-pack-bitmaps.sh
+++ b/t/t5326-multi-pack-bitmaps.sh
@@ -15,17 +15,24 @@ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
sane_unset GIT_TEST_MIDX_WRITE_REV
sane_unset GIT_TEST_MIDX_READ_RIDX
-midx_bitmap_core
-
bitmap_reuse_tests() {
from=$1
to=$2
+ writeLookupTable=false
+
+ for i in $3-${$#}
+ do
+ case $i in
+ "pack.writeBitmapLookupTable") writeLookupTable=true;;
+ esac
+ done
test_expect_success "setup pack reuse tests ($from -> $to)" '
rm -fr repo &&
git init repo &&
(
cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
test_commit_bulk 16 &&
git tag old-tip &&
@@ -43,6 +50,7 @@ bitmap_reuse_tests() {
test_expect_success "build bitmap from existing ($from -> $to)" '
(
cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
test_commit_bulk --id=further 16 &&
git tag new-tip &&
@@ -59,6 +67,7 @@ bitmap_reuse_tests() {
test_expect_success "verify resulting bitmaps ($from -> $to)" '
(
cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
git for-each-ref &&
git rev-list --test-bitmap refs/tags/old-tip &&
git rev-list --test-bitmap refs/tags/new-tip
@@ -66,244 +75,362 @@ bitmap_reuse_tests() {
'
}
-bitmap_reuse_tests 'pack' 'MIDX'
-bitmap_reuse_tests 'MIDX' 'pack'
-bitmap_reuse_tests 'MIDX' 'MIDX'
+test_midx_bitmap_cases () {
+ writeLookupTable=false
+ writeBitmapLookupTable=
+
+ for i in "$@"
+ do
+ case $i in
+ "pack.writeBitmapLookupTable")
+ writeLookupTable=true
+ writeBitmapLookupTable="$i"
+ ;;
+ esac
+ done
+
+ test_expect_success 'setup test_repository' '
+ rm -rf * .git &&
+ git init &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"'
+ '
-test_expect_success 'missing object closure fails gracefully' '
- rm -fr repo &&
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
+ midx_bitmap_core
- test_commit loose &&
- test_commit packed &&
+ bitmap_reuse_tests 'pack' 'MIDX' "$writeBitmapLookupTable"
+ bitmap_reuse_tests 'MIDX' 'pack' "$writeBitmapLookupTable"
+ bitmap_reuse_tests 'MIDX' 'MIDX' "$writeBitmapLookupTable"
- # Do not pass "--revs"; we want a pack without the "loose"
- # commit.
- git pack-objects $objdir/pack/pack <<-EOF &&
- $(git rev-parse packed)
- EOF
+ test_expect_success 'missing object closure fails gracefully' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
- test_must_fail git multi-pack-index write --bitmap 2>err &&
- grep "doesn.t have full closure" err &&
- test_path_is_missing $midx
- )
-'
+ test_commit loose &&
+ test_commit packed &&
-midx_bitmap_partial_tests
+ # Do not pass "--revs"; we want a pack without the "loose"
+ # commit.
+ git pack-objects $objdir/pack/pack <<-EOF &&
+ $(git rev-parse packed)
+ EOF
-test_expect_success 'removing a MIDX clears stale bitmaps' '
- rm -fr repo &&
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
- test_commit base &&
- git repack &&
- git multi-pack-index write --bitmap &&
+ test_must_fail git multi-pack-index write --bitmap 2>err &&
+ grep "doesn.t have full closure" err &&
+ test_path_is_missing $midx
+ )
+ '
- # Write a MIDX and bitmap; remove the MIDX but leave the bitmap.
- stale_bitmap=$midx-$(midx_checksum $objdir).bitmap &&
- rm $midx &&
+ midx_bitmap_partial_tests
- # Then write a new MIDX.
- test_commit new &&
- git repack &&
- git multi-pack-index write --bitmap &&
+ test_expect_success 'removing a MIDX clears stale bitmaps' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+ test_commit base &&
+ git repack &&
+ git multi-pack-index write --bitmap &&
+
+ # Write a MIDX and bitmap; remove the MIDX but leave the bitmap.
+ stale_bitmap=$midx-$(midx_checksum $objdir).bitmap &&
+ rm $midx &&
+
+ # Then write a new MIDX.
+ test_commit new &&
+ git repack &&
+ git multi-pack-index write --bitmap &&
+
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_missing $stale_bitmap
+ )
+ '
- test_path_is_file $midx &&
- test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
- test_path_is_missing $stale_bitmap
- )
-'
+ test_expect_success 'pack.preferBitmapTips' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
-test_expect_success 'pack.preferBitmapTips' '
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
+ test_commit_bulk --message="%s" 103 &&
- test_commit_bulk --message="%s" 103 &&
+ git log --format="%H" >commits.raw &&
+ sort <commits.raw >commits &&
- git log --format="%H" >commits.raw &&
- sort <commits.raw >commits &&
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
- git log --format="create refs/tags/%s %H" HEAD >refs &&
- git update-ref --stdin <refs &&
+ git multi-pack-index write --bitmap &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
- git multi-pack-index write --bitmap &&
- test_path_is_file $midx &&
- test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >before &&
+ test_line_count = 1 before &&
- test-tool bitmap list-commits | sort >bitmaps &&
- comm -13 bitmaps commits >before &&
- test_line_count = 1 before &&
+ perl -ne "printf(\"create refs/tags/include/%d \", $.); print" \
+ <before | git update-ref --stdin &&
- perl -ne "printf(\"create refs/tags/include/%d \", $.); print" \
- <before | git update-ref --stdin &&
+ rm -fr $midx-$(midx_checksum $objdir).bitmap &&
+ rm -fr $midx &&
- rm -fr $midx-$(midx_checksum $objdir).bitmap &&
- rm -fr $midx &&
+ git -c pack.preferBitmapTips=refs/tags/include \
+ multi-pack-index write --bitmap &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >after &&
- git -c pack.preferBitmapTips=refs/tags/include \
- multi-pack-index write --bitmap &&
- test-tool bitmap list-commits | sort >bitmaps &&
- comm -13 bitmaps commits >after &&
+ ! test_cmp before after
+ )
+ '
- ! test_cmp before after
- )
-'
+ test_expect_success 'writing a bitmap with --refs-snapshot' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
-test_expect_success 'writing a bitmap with --refs-snapshot' '
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
+ test_commit one &&
+ test_commit two &&
- test_commit one &&
- test_commit two &&
+ git rev-parse one >snapshot &&
- git rev-parse one >snapshot &&
+ git repack -ad &&
- git repack -ad &&
+ # First, write a MIDX which see both refs/tags/one and
+ # refs/tags/two (causing both of those commits to receive
+ # bitmaps).
+ git multi-pack-index write --bitmap &&
- # First, write a MIDX which see both refs/tags/one and
- # refs/tags/two (causing both of those commits to receive
- # bitmaps).
- git multi-pack-index write --bitmap &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
- test_path_is_file $midx &&
- test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ grep "$(git rev-parse one)" bitmaps &&
+ grep "$(git rev-parse two)" bitmaps &&
- test-tool bitmap list-commits | sort >bitmaps &&
- grep "$(git rev-parse one)" bitmaps &&
- grep "$(git rev-parse two)" bitmaps &&
+ rm -fr $midx-$(midx_checksum $objdir).bitmap &&
+ rm -fr $midx &&
- rm -fr $midx-$(midx_checksum $objdir).bitmap &&
- rm -fr $midx &&
+ # Then again, but with a refs snapshot which only sees
+ # refs/tags/one.
+ git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
- # Then again, but with a refs snapshot which only sees
- # refs/tags/one.
- git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
- test_path_is_file $midx &&
- test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ grep "$(git rev-parse one)" bitmaps &&
+ ! grep "$(git rev-parse two)" bitmaps
+ )
+ '
- test-tool bitmap list-commits | sort >bitmaps &&
- grep "$(git rev-parse one)" bitmaps &&
- ! grep "$(git rev-parse two)" bitmaps
- )
-'
+ test_expect_success 'write a bitmap with --refs-snapshot (preferred tips)' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
-test_expect_success 'write a bitmap with --refs-snapshot (preferred tips)' '
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
+ test_commit_bulk --message="%s" 103 &&
- test_commit_bulk --message="%s" 103 &&
+ git log --format="%H" >commits.raw &&
+ sort <commits.raw >commits &&
- git log --format="%H" >commits.raw &&
- sort <commits.raw >commits &&
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
- git log --format="create refs/tags/%s %H" HEAD >refs &&
- git update-ref --stdin <refs &&
+ git multi-pack-index write --bitmap &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
- git multi-pack-index write --bitmap &&
- test_path_is_file $midx &&
- test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >before &&
+ test_line_count = 1 before &&
- test-tool bitmap list-commits | sort >bitmaps &&
- comm -13 bitmaps commits >before &&
- test_line_count = 1 before &&
+ (
+ grep -vf before commits.raw &&
+ # mark missing commits as preferred
+ sed "s/^/+/" before
+ ) >snapshot &&
+ rm -fr $midx-$(midx_checksum $objdir).bitmap &&
+ rm -fr $midx &&
+
+ git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >after &&
+
+ ! test_cmp before after
+ )
+ '
+
+ test_expect_success 'hash-cache values are propagated from pack bitmaps' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
(
- grep -vf before commits.raw &&
- # mark missing commits as preferred
- sed "s/^/+/" before
- ) >snapshot &&
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
- rm -fr $midx-$(midx_checksum $objdir).bitmap &&
- rm -fr $midx &&
+ test_commit base &&
+ test_commit base2 &&
+ git repack -adb &&
- git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
- test-tool bitmap list-commits | sort >bitmaps &&
- comm -13 bitmaps commits >after &&
+ test-tool bitmap dump-hashes >pack.raw &&
+ test_file_not_empty pack.raw &&
+ sort pack.raw >pack.hashes &&
- ! test_cmp before after
- )
-'
+ test_commit new &&
+ git repack &&
+ git multi-pack-index write --bitmap &&
-test_expect_success 'hash-cache values are propagated from pack bitmaps' '
- rm -fr repo &&
- git init repo &&
- test_when_finished "rm -fr repo" &&
- (
- cd repo &&
+ test-tool bitmap dump-hashes >midx.raw &&
+ sort midx.raw >midx.hashes &&
- test_commit base &&
- test_commit base2 &&
- git repack -adb &&
+ # ensure that every namehash in the pack bitmap can be found in
+ # the midx bitmap (i.e., that there are no oid-namehash pairs
+ # unique to the pack bitmap).
+ comm -23 pack.hashes midx.hashes >dropped.hashes &&
+ test_must_be_empty dropped.hashes
+ )
+ '
- test-tool bitmap dump-hashes >pack.raw &&
- test_file_not_empty pack.raw &&
- sort pack.raw >pack.hashes &&
+ test_expect_success 'no .bitmap is written without any objects' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
- test_commit new &&
- git repack &&
- git multi-pack-index write --bitmap &&
+ empty="$(git pack-objects $objdir/pack/pack </dev/null)" &&
+ cat >packs <<-EOF &&
+ pack-$empty.idx
+ EOF
- test-tool bitmap dump-hashes >midx.raw &&
- sort midx.raw >midx.hashes &&
+ git multi-pack-index write --bitmap --stdin-packs \
+ <packs 2>err &&
- # ensure that every namehash in the pack bitmap can be found in
- # the midx bitmap (i.e., that there are no oid-namehash pairs
- # unique to the pack bitmap).
- comm -23 pack.hashes midx.hashes >dropped.hashes &&
- test_must_be_empty dropped.hashes
- )
-'
+ grep "bitmap without any objects" err &&
+
+ test_path_is_file $midx &&
+ test_path_is_missing $midx-$(midx_checksum $objdir).bitmap
+ )
+ '
+
+ test_expect_success 'graceful fallback when missing reverse index' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
+
+ test_commit base &&
+
+ # write a pack and MIDX bitmap containing base
+ git repack -adb &&
+ git multi-pack-index write --bitmap &&
+
+ GIT_TEST_MIDX_READ_RIDX=0 \
+ git rev-list --use-bitmap-index HEAD 2>err &&
+ ! grep "ignoring extra bitmap file" err
+ )
+ '
+}
+
+test_midx_bitmap_cases
-test_expect_success 'no .bitmap is written without any objects' '
+test_midx_bitmap_cases "pack.writeBitmapLookupTable"
+
+test_expect_success 'multi-pack-index write writes lookup table if enabled' '
rm -fr repo &&
git init repo &&
test_when_finished "rm -fr repo" &&
(
cd repo &&
+ test_commit base &&
+ git config pack.writeBitmapLookupTable true &&
+ git repack -ad &&
+ GIT_TRACE2_EVENT="$(pwd)/trace" \
+ git multi-pack-index write --bitmap &&
+ grep "\"label\":\"writing_lookup_table\"" trace
+ )
+'
+
+test_expect_success 'preferred pack change with existing MIDX bitmap' '
+ git init preferred-pack-with-existing &&
+ (
+ cd preferred-pack-with-existing &&
+
+ test_commit base &&
+ test_commit other &&
+
+ git rev-list --objects --no-object-names base >p1.objects &&
+ git rev-list --objects --no-object-names other >p2.objects &&
- empty="$(git pack-objects $objdir/pack/pack </dev/null)" &&
- cat >packs <<-EOF &&
- pack-$empty.idx
- EOF
+ p1="$(git pack-objects "$objdir/pack/pack" \
+ --delta-base-offset <p1.objects)" &&
+ p2="$(git pack-objects "$objdir/pack/pack" \
+ --delta-base-offset <p2.objects)" &&
- git multi-pack-index write --bitmap --stdin-packs \
- <packs 2>err &&
+ # Generate a MIDX containing the first two packs,
+ # marking p1 as preferred, and ensure that it can be
+ # successfully cloned.
+ git multi-pack-index write --bitmap \
+ --preferred-pack="pack-$p1.pack" &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ git clone --no-local . clone1 &&
- grep "bitmap without any objects" err &&
+ # Then generate a new pack which sorts ahead of any
+ # existing pack (by tweaking the pack prefix).
+ test_commit foo &&
+ git pack-objects --all --unpacked $objdir/pack/pack0 &&
+ # Generate a new MIDX which changes the preferred pack
+ # to a pack contained in the existing MIDX.
+ git multi-pack-index write --bitmap \
+ --preferred-pack="pack-$p2.pack" &&
test_path_is_file $midx &&
- test_path_is_missing $midx-$(midx_checksum $objdir).bitmap
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+
+ # When the above circumstances are met, the preferred
+ # pack should change appropriately and clones should
+ # (still) succeed.
+ git clone --no-local . clone2
)
'
-test_expect_success 'graceful fallback when missing reverse index' '
+test_expect_success 'tagged commits are selected for bitmapping' '
rm -fr repo &&
git init repo &&
test_when_finished "rm -fr repo" &&
(
cd repo &&
- test_commit base &&
+ test_commit --annotate base &&
+ git repack -d &&
+
+ # Remove refs/heads/main which points at the commit directly,
+ # leaving only a reference to the annotated tag.
+ git branch -M main &&
+ git checkout base &&
+ git branch -d main &&
- # write a pack and MIDX bitmap containing base
- git repack -adb &&
git multi-pack-index write --bitmap &&
- GIT_TEST_MIDX_READ_RIDX=0 \
- git rev-list --use-bitmap-index HEAD 2>err &&
- ! grep "ignoring extra bitmap file" err
+ git rev-parse HEAD >want &&
+ test-tool bitmap list-commits >actual &&
+ grep $(cat want) actual
)
'
diff --git a/t/t5327-multi-pack-bitmaps-rev.sh b/t/t5327-multi-pack-bitmaps-rev.sh
index d30ba632c87..e65e311cd73 100755
--- a/t/t5327-multi-pack-bitmaps-rev.sh
+++ b/t/t5327-multi-pack-bitmaps-rev.sh
@@ -17,7 +17,27 @@ GIT_TEST_MIDX_READ_RIDX=0
export GIT_TEST_MIDX_WRITE_REV
export GIT_TEST_MIDX_READ_RIDX
-midx_bitmap_core rev
-midx_bitmap_partial_tests rev
+test_midx_bitmap_rev () {
+ writeLookupTable=false
+
+ for i in "$@"
+ do
+ case $i in
+ "pack.writeBitmapLookupTable") writeLookupTable=true;;
+ esac
+ done
+
+ test_expect_success 'setup bitmap config' '
+ rm -rf * .git &&
+ git init &&
+ git config pack.writeBitmapLookupTable '"$writeLookupTable"'
+ '
+
+ midx_bitmap_core rev
+ midx_bitmap_partial_tests rev
+}
+
+test_midx_bitmap_rev
+test_midx_bitmap_rev "pack.writeBitmapLookupTable"
test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 6c7370f87f5..43b7bcd7159 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -241,6 +241,26 @@ test_expect_success 'add invalid foreign_vcs remote' '
test_cmp expect actual
'
+test_expect_success 'without subcommand' '
+ echo origin >expect &&
+ git -C test remote >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'without subcommand accepts -v' '
+ cat >expect <<-EOF &&
+ origin $(pwd)/one (fetch)
+ origin $(pwd)/one (push)
+ EOF
+ git -C test remote -v >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'without subcommand does not take arguments' '
+ test_expect_code 129 git -C test remote origin 2>err &&
+ grep "^error: unknown subcommand:" err
+'
+
cat >test/expect <<EOF
* remote origin
Fetch URL: $(pwd)/one
@@ -882,6 +902,17 @@ test_expect_success 'rename a remote renames repo remote.pushDefault but keeps g
)
'
+test_expect_success 'rename handles remote without fetch refspec' '
+ git clone --bare one no-refspec.git &&
+ # confirm assumption that bare clone does not create refspec
+ test_expect_code 5 \
+ git -C no-refspec.git config --unset-all remote.origin.fetch &&
+ git -C no-refspec.git config remote.origin.url >expect &&
+ git -C no-refspec.git remote rename origin foo &&
+ git -C no-refspec.git config remote.foo.url >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'rename does not update a non-default fetch refspec' '
git clone one four.one &&
(
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index b45879a760b..c0b745e33b8 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -790,6 +790,7 @@ test_expect_success 'fetch.writeCommitGraph' '
'
test_expect_success 'fetch.writeCommitGraph with submodules' '
+ test_config_global protocol.file.allow always &&
git clone dups super &&
(
cd super &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 3211002d466..4f2bfaf0051 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -222,6 +222,7 @@ test_expect_success 'push with negotiation proceeds anyway even if negotiation f
test_expect_success 'push with negotiation does not attempt to fetch submodules' '
mk_empty submodule_upstream &&
test_commit -C submodule_upstream submodule_commit &&
+ test_config_global protocol.file.allow always &&
git submodule add ./submodule_upstream submodule &&
mk_empty testrepo &&
git push testrepo $the_first_commit:refs/remotes/origin/first_commit &&
@@ -1852,37 +1853,6 @@ test_expect_success 'refuse to push a hidden ref, and make sure do not pollute t
test_dir_is_empty testrepo/.git/objects/pack
'
-test_expect_success LIBCURL 'fetch warns or fails when using username:password' '
- message="URL '\''https://username:<redacted>@localhost/'\'' uses plaintext credentials" &&
- test_must_fail git -c transfer.credentialsInUrl=allow fetch https://username:password@localhost 2>err &&
- ! grep "$message" err &&
-
- test_must_fail git -c transfer.credentialsInUrl=warn fetch https://username:password@localhost 2>err &&
- grep "warning: $message" err >warnings &&
- test_line_count = 3 warnings &&
-
- test_must_fail git -c transfer.credentialsInUrl=die fetch https://username:password@localhost 2>err &&
- grep "fatal: $message" err >warnings &&
- test_line_count = 1 warnings &&
-
- test_must_fail git -c transfer.credentialsInUrl=die fetch https://username:@localhost 2>err &&
- grep "fatal: $message" err >warnings &&
- test_line_count = 1 warnings
-'
-
-
-test_expect_success LIBCURL 'push warns or fails when using username:password' '
- message="URL '\''https://username:<redacted>@localhost/'\'' uses plaintext credentials" &&
- test_must_fail git -c transfer.credentialsInUrl=allow push https://username:password@localhost 2>err &&
- ! grep "$message" err &&
-
- test_must_fail git -c transfer.credentialsInUrl=warn push https://username:password@localhost 2>err &&
- grep "warning: $message" err >warnings &&
- test_must_fail git -c transfer.credentialsInUrl=die push https://username:password@localhost 2>err &&
- grep "fatal: $message" err >warnings &&
- test_line_count = 1 warnings
-'
-
test_expect_success 'push with config push.useBitmaps' '
mk_test testrepo heads/main &&
git checkout main &&
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 081808009b2..0b72112fb10 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -218,6 +218,23 @@ test_expect_success 'fail if upstream branch does not exist' '
test_cmp expect file
'
+test_expect_success 'fetch upstream branch even if refspec excludes it' '
+ # the branch names are not important here except that
+ # the first one must not be a prefix of the second,
+ # since otherwise the ref-prefix protocol extension
+ # would match both
+ git branch in-refspec HEAD^ &&
+ git branch not-in-refspec HEAD &&
+ git init -b in-refspec downstream &&
+ git -C downstream remote add -t in-refspec origin "file://$(pwd)/.git" &&
+ git -C downstream config branch.in-refspec.remote origin &&
+ git -C downstream config branch.in-refspec.merge refs/heads/not-in-refspec &&
+ git -C downstream pull &&
+ git rev-parse --verify not-in-refspec >expect &&
+ git -C downstream rev-parse --verify HEAD >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'fail if the index has unresolved entries' '
git checkout -b third second^ &&
test_when_finished "git checkout -f copy && git branch -D third" &&
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index a301b56db89..b9546ef8e5e 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -127,6 +127,7 @@ verify_fetch_result () {
}
test_expect_success setup '
+ git config --global protocol.file.allow always &&
mkdir deepsubmodule &&
(
cd deepsubmodule &&
@@ -177,6 +178,7 @@ test_expect_success "submodule.recurse option triggers recursive fetch" '
'
test_expect_success "fetch --recurse-submodules -j2 has the same output behaviour" '
+ test_when_finished "rm -f trace.out" &&
add_submodule_commits &&
(
cd downstream &&
@@ -704,17 +706,30 @@ test_expect_success "'fetch.recurseSubmodules=on-demand' works also without .git
test_expect_success 'fetching submodules respects parallel settings' '
git config fetch.recurseSubmodules true &&
+ test_when_finished "rm -f downstream/trace.out" &&
(
cd downstream &&
GIT_TRACE=$(pwd)/trace.out git fetch &&
grep "1 tasks" trace.out &&
+ >trace.out &&
+
GIT_TRACE=$(pwd)/trace.out git fetch --jobs 7 &&
grep "7 tasks" trace.out &&
+ >trace.out &&
+
git config submodule.fetchJobs 8 &&
GIT_TRACE=$(pwd)/trace.out git fetch &&
grep "8 tasks" trace.out &&
+ >trace.out &&
+
GIT_TRACE=$(pwd)/trace.out git fetch --jobs 9 &&
- grep "9 tasks" trace.out
+ grep "9 tasks" trace.out &&
+ >trace.out &&
+
+ GIT_TRACE=$(pwd)/trace.out git -c submodule.fetchJobs=0 fetch &&
+ grep "preparing to run up to [0-9]* tasks" trace.out &&
+ ! grep "up to 0 tasks" trace.out &&
+ >trace.out
)
'
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 10e9a7ff264..37f7547a4ca 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -162,6 +162,8 @@ test_expect_success 'fetch --update-shallow' '
'
test_expect_success 'fetch --update-shallow into a repo with submodules' '
+ test_config_global protocol.file.allow always &&
+
git init a-submodule &&
test_commit -C a-submodule foo &&
@@ -175,7 +177,8 @@ test_expect_success 'fetch --update-shallow into a repo with submodules' '
test_expect_success 'fetch --update-shallow a commit that is also a shallow point into a repo with submodules' '
test_when_finished "rm -rf repo-with-sub" &&
git init repo-with-sub &&
- git -C repo-with-sub submodule add ../a-submodule a-submodule &&
+ git -c protocol.file.allow=always -C repo-with-sub \
+ submodule add ../a-submodule a-submodule &&
git -C repo-with-sub commit -m "added submodule" &&
SHALLOW=$(cat shallow/.git/shallow) &&
diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh
index 214228349ad..a158e7d2c01 100755
--- a/t/t5545-push-options.sh
+++ b/t/t5545-push-options.sh
@@ -119,6 +119,7 @@ test_expect_success 'push options and submodules' '
test_commit -C parent one &&
git -C parent push --mirror up &&
+ test_config_global protocol.file.allow always &&
git -C parent submodule add ../upstream workbench &&
git -C parent/workbench remote add up ../../upstream &&
git -C parent commit -m "add submodule" &&
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index d7cf85ffead..8f182a3cbfe 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -234,7 +234,7 @@ test_expect_success 'http-fetch --packfile' '
--index-pack-arg=--keep \
"$HTTPD_URL"/dumb/repo_pack.git/$p >out &&
- grep "^keep.[0-9a-f]\{16,\}$" out &&
+ grep -E "^keep.[0-9a-f]{16,}$" out &&
cut -c6- out >packhash &&
# Ensure that the expected files are generated
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index 6a38294a476..64c6c9f59ef 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -580,4 +580,81 @@ test_expect_success 'passing hostname resolution information works' '
git -c "http.curloptResolve=$BOGUS_HOST:$LIB_HTTPD_PORT:127.0.0.1" ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null
'
+# here user%40host is the URL-encoded version of user@host,
+# which is our intentionally-odd username to catch parsing errors
+url_user=$HTTPD_URL_USER/auth/smart/repo.git
+url_userpass=$HTTPD_URL_USER_PASS/auth/smart/repo.git
+url_userblank=$HTTPD_PROTO://user%40host:@$HTTPD_DEST/auth/smart/repo.git
+message="URL .*:<redacted>@.* uses plaintext credentials"
+
+test_expect_success 'clone warns or fails when using username:password' '
+ test_when_finished "rm -rf attempt*" &&
+
+ git -c transfer.credentialsInUrl=allow \
+ clone $url_userpass attempt1 2>err &&
+ ! grep "$message" err &&
+
+ git -c transfer.credentialsInUrl=warn \
+ clone $url_userpass attempt2 2>err &&
+ grep "warning: $message" err >warnings &&
+ test_line_count -ge 1 warnings &&
+
+ test_must_fail git -c transfer.credentialsInUrl=die \
+ clone $url_userpass attempt3 2>err &&
+ grep "fatal: $message" err >warnings &&
+ test_line_count -ge 1 warnings &&
+
+ test_must_fail git -c transfer.credentialsInUrl=die \
+ clone $url_userblank attempt4 2>err &&
+ grep "fatal: $message" err >warnings &&
+ test_line_count -ge 1 warnings
+'
+
+test_expect_success 'clone does not detect username:password when it is https://username@domain:port/' '
+ test_when_finished "rm -rf attempt1" &&
+
+ # we are relying on lib-httpd for url construction, so document our
+ # assumptions
+ case "$HTTPD_URL_USER" in
+ *:[0-9]*) : ok ;;
+ *) BUG "httpd url does not have port: $HTTPD_URL_USER"
+ esac &&
+
+ git -c transfer.credentialsInUrl=warn clone $url_user attempt1 2>err &&
+ ! grep "uses plaintext credentials" err
+'
+
+test_expect_success 'fetch warns or fails when using username:password' '
+ git -c transfer.credentialsInUrl=allow fetch $url_userpass 2>err &&
+ ! grep "$message" err &&
+
+ git -c transfer.credentialsInUrl=warn fetch $url_userpass 2>err &&
+ grep "warning: $message" err >warnings &&
+ test_line_count -ge 1 warnings &&
+
+ test_must_fail git -c transfer.credentialsInUrl=die \
+ fetch $url_userpass 2>err &&
+ grep "fatal: $message" err >warnings &&
+ test_line_count -ge 1 warnings &&
+
+ test_must_fail git -c transfer.credentialsInUrl=die \
+ fetch $url_userblank 2>err &&
+ grep "fatal: $message" err >warnings &&
+ test_line_count -ge 1 warnings
+'
+
+
+test_expect_success 'push warns or fails when using username:password' '
+ git -c transfer.credentialsInUrl=allow push $url_userpass 2>err &&
+ ! grep "$message" err &&
+
+ git -c transfer.credentialsInUrl=warn push $url_userpass 2>err &&
+ grep "warning: $message" err >warnings &&
+
+ test_must_fail git -c transfer.credentialsInUrl=die \
+ push $url_userpass 2>err &&
+ grep "fatal: $message" err >warnings &&
+ test_line_count -ge 1 warnings
+'
+
test_done
diff --git a/t/t5557-http-get.sh b/t/t5557-http-get.sh
new file mode 100755
index 00000000000..76a4bbd16af
--- /dev/null
+++ b/t/t5557-http-get.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+test_description='test downloading a file by URL'
+
+TEST_PASSES_SANITIZE_LEAK=true
+
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'get by URL: 404' '
+ test_when_finished "rm -f file.temp" &&
+ url="$HTTPD_URL/none.txt" &&
+ cat >input <<-EOF &&
+ capabilities
+ get $url file1
+ EOF
+
+ test_must_fail git remote-http $url <input 2>err &&
+ test_path_is_missing file1 &&
+ grep "failed to download file at URL" err
+'
+
+test_expect_success 'get by URL: 200' '
+ echo data >"$HTTPD_DOCUMENT_ROOT_PATH/exists.txt" &&
+
+ url="$HTTPD_URL/exists.txt" &&
+ cat >input <<-EOF &&
+ capabilities
+ get $url file2
+
+ EOF
+
+ git remote-http $url <input &&
+ test_cmp "$HTTPD_DOCUMENT_ROOT_PATH/exists.txt" file2
+'
+
+test_done
diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh
new file mode 100755
index 00000000000..9155f31fa2c
--- /dev/null
+++ b/t/t5558-clone-bundle-uri.sh
@@ -0,0 +1,356 @@
+#!/bin/sh
+
+test_description='test fetching bundles with --bundle-uri'
+
+. ./test-lib.sh
+
+test_expect_success 'fail to clone from non-existent file' '
+ test_when_finished rm -rf test &&
+ git clone --bundle-uri="$(pwd)/does-not-exist" . test 2>err &&
+ grep "failed to download bundle from URI" err
+'
+
+test_expect_success 'fail to clone from non-bundle file' '
+ test_when_finished rm -rf test &&
+ echo bogus >bogus &&
+ git clone --bundle-uri="$(pwd)/bogus" . test 2>err &&
+ grep "is not a bundle" err
+'
+
+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
+'
+
+test_expect_success 'clone with path bundle' '
+ git clone --bundle-uri="clone-from/B.bundle" \
+ clone-from clone-path &&
+ git -C clone-path rev-parse refs/bundles/topic >actual &&
+ git -C clone-from rev-parse topic >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'clone with file:// bundle' '
+ git clone --bundle-uri="file://$(pwd)/clone-from/B.bundle" \
+ clone-from clone-file &&
+ git -C clone-file rev-parse refs/bundles/topic >actual &&
+ git -C clone-from rev-parse topic >expect &&
+ test_cmp expect actual
+'
+
+# To get interesting tests for bundle lists, we need to construct a
+# somewhat-interesting commit history.
+#
+# ---------------- bundle-4
+#
+# 4
+# / \
+# ----|---|------- bundle-3
+# | |
+# | 3
+# | |
+# ----|---|------- bundle-2
+# | |
+# 2 |
+# | |
+# ----|---|------- bundle-1
+# \ /
+# 1
+# |
+# (previous commits)
+test_expect_success 'construct incremental bundle list' '
+ (
+ cd clone-from &&
+ git checkout -b base &&
+ test_commit 1 &&
+ git checkout -b left &&
+ test_commit 2 &&
+ git checkout -b right base &&
+ test_commit 3 &&
+ git checkout -b merge left &&
+ git merge right -m "4" &&
+
+ git bundle create bundle-1.bundle base &&
+ git bundle create bundle-2.bundle base..left &&
+ git bundle create bundle-3.bundle base..right &&
+ git bundle create bundle-4.bundle merge --not left right
+ )
+'
+
+test_expect_success 'clone bundle list (file, no heuristic)' '
+ 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
+
+ [bundle "bundle-3"]
+ uri = file://$(pwd)/clone-from/bundle-3.bundle
+
+ [bundle "bundle-4"]
+ uri = file://$(pwd)/clone-from/bundle-4.bundle
+ EOF
+
+ git clone --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from clone-list-file 2>err &&
+ ! grep "Repository lacks these prerequisite commits" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-list-file cat-file --batch-check <oids &&
+
+ git -C clone-list-file for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ refs/bundles/merge
+ refs/bundles/right
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'clone bundle list (file, all mode, some failures)' '
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-0"]
+ uri = file://$(pwd)/clone-from/bundle-0.bundle
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+
+ # No bundle-3 means bundle-4 will not apply.
+
+ [bundle "bundle-4"]
+ uri = file://$(pwd)/clone-from/bundle-4.bundle
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-5"]
+ uri = file://$(pwd)/clone-from/bundle-5.bundle
+ EOF
+
+ GIT_TRACE2_PERF=1 \
+ git clone --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from clone-all-some 2>err &&
+ ! grep "Repository lacks these prerequisite commits" err &&
+ ! grep "fatal" err &&
+ grep "warning: failed to download bundle from URI" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-all-some cat-file --batch-check <oids &&
+
+ git -C clone-all-some 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
+'
+
+test_expect_success 'clone bundle list (file, all mode, all failures)' '
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-0"]
+ uri = file://$(pwd)/clone-from/bundle-0.bundle
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-5"]
+ uri = file://$(pwd)/clone-from/bundle-5.bundle
+ EOF
+
+ git clone --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from clone-all-fail 2>err &&
+ ! grep "Repository lacks these prerequisite commits" err &&
+ ! grep "fatal" err &&
+ grep "warning: failed to download bundle from URI" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-all-fail cat-file --batch-check <oids &&
+
+ git -C clone-all-fail for-each-ref --format="%(refname)" >refs &&
+ ! grep "refs/bundles/" refs
+'
+
+test_expect_success 'clone bundle list (file, any mode)' '
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = any
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-0"]
+ uri = file://$(pwd)/clone-from/bundle-0.bundle
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-5"]
+ uri = file://$(pwd)/clone-from/bundle-5.bundle
+ EOF
+
+ git clone --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from clone-any-file 2>err &&
+ ! grep "Repository lacks these prerequisite commits" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-any-file cat-file --batch-check <oids &&
+
+ git -C clone-any-file for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'clone bundle list (file, any mode, all failures)' '
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = any
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-0"]
+ uri = $HTTPD_URL/bundle-0.bundle
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-5"]
+ uri = $HTTPD_URL/bundle-5.bundle
+ EOF
+
+ git clone --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from clone-any-fail 2>err &&
+ ! grep "fatal" err &&
+ grep "warning: failed to download bundle from URI" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-any-fail cat-file --batch-check <oids &&
+
+ git -C clone-any-fail for-each-ref --format="%(refname)" >refs &&
+ ! grep "refs/bundles/" refs
+'
+
+#########################################################################
+# HTTP tests begin here
+
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'fail to fetch from non-existent HTTP URL' '
+ test_when_finished rm -rf test &&
+ git clone --bundle-uri="$HTTPD_URL/does-not-exist" . test 2>err &&
+ grep "failed to download bundle from URI" err
+'
+
+test_expect_success 'fail to fetch from non-bundle HTTP URL' '
+ test_when_finished rm -rf test &&
+ echo bogus >"$HTTPD_DOCUMENT_ROOT_PATH/bogus" &&
+ git clone --bundle-uri="$HTTPD_URL/bogus" . test 2>err &&
+ grep "is not a bundle" err
+'
+
+test_expect_success 'clone HTTP bundle' '
+ cp clone-from/B.bundle "$HTTPD_DOCUMENT_ROOT_PATH/B.bundle" &&
+
+ git clone --no-local --mirror clone-from \
+ "$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" &&
+
+ git clone --bundle-uri="$HTTPD_URL/B.bundle" \
+ "$HTTPD_URL/smart/fetch.git" clone-http &&
+ git -C clone-http rev-parse refs/bundles/topic >actual &&
+ git -C clone-from rev-parse topic >expect &&
+ test_cmp expect actual &&
+
+ test_config -C clone-http log.excludedecoration refs/bundle/
+'
+
+test_expect_success 'clone bundle list (HTTP, no heuristic)' '
+ cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
+ cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+
+ [bundle "bundle-1"]
+ uri = $HTTPD_URL/bundle-1.bundle
+
+ [bundle "bundle-2"]
+ uri = $HTTPD_URL/bundle-2.bundle
+
+ [bundle "bundle-3"]
+ uri = $HTTPD_URL/bundle-3.bundle
+
+ [bundle "bundle-4"]
+ uri = $HTTPD_URL/bundle-4.bundle
+ EOF
+
+ git clone --bundle-uri="$HTTPD_URL/bundle-list" \
+ clone-from clone-list-http 2>err &&
+ ! grep "Repository lacks these prerequisite commits" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-list-http cat-file --batch-check <oids
+'
+
+test_expect_success 'clone bundle list (HTTP, any mode)' '
+ cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
+ cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
+ [bundle]
+ version = 1
+ mode = any
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-0"]
+ uri = $HTTPD_URL/bundle-0.bundle
+
+ [bundle "bundle-1"]
+ uri = $HTTPD_URL/bundle-1.bundle
+
+ # Does not exist. Should be skipped.
+ [bundle "bundle-5"]
+ uri = $HTTPD_URL/bundle-5.bundle
+ EOF
+
+ git clone --bundle-uri="$HTTPD_URL/bundle-list" \
+ clone-from clone-any-http 2>err &&
+ ! grep "fatal" err &&
+ grep "warning: failed to download bundle from URI" err &&
+
+ git -C clone-from for-each-ref --format="%(objectname)" >oids &&
+ git -C clone-any-http cat-file --batch-check <oids &&
+
+ git -C clone-list-file for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ refs/bundles/merge
+ refs/bundles/right
+ EOF
+ test_cmp expect actual
+'
+
+# Do not add tests here unless they use the HTTP server, as they will
+# not run unless the HTTP dependencies exist.
+
+test_done
diff --git a/t/t5572-pull-submodule.sh b/t/t5572-pull-submodule.sh
index a35396fadf5..09097eff3f4 100755
--- a/t/t5572-pull-submodule.sh
+++ b/t/t5572-pull-submodule.sh
@@ -52,6 +52,10 @@ then
fi
test_submodule_switch_func "git_pull_noff"
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'pull --recurse-submodule setup' '
test_create_repo child &&
test_commit -C child bar &&
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 2e57de9c12a..b2524a24c29 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -71,29 +71,6 @@ test_expect_success 'clone respects GIT_WORK_TREE' '
'
-test_expect_success LIBCURL 'clone warns or fails when using username:password' '
- message="URL '\''https://username:<redacted>@localhost/'\'' uses plaintext credentials" &&
- test_must_fail git -c transfer.credentialsInUrl=allow clone https://username:password@localhost attempt1 2>err &&
- ! grep "$message" err &&
-
- test_must_fail git -c transfer.credentialsInUrl=warn clone https://username:password@localhost attempt2 2>err &&
- grep "warning: $message" err >warnings &&
- test_line_count = 2 warnings &&
-
- test_must_fail git -c transfer.credentialsInUrl=die clone https://username:password@localhost attempt3 2>err &&
- grep "fatal: $message" err >warnings &&
- test_line_count = 1 warnings &&
-
- test_must_fail git -c transfer.credentialsInUrl=die clone https://username:@localhost attempt3 2>err &&
- grep "fatal: $message" err >warnings &&
- test_line_count = 1 warnings
-'
-
-test_expect_success LIBCURL 'clone does not detect username:password when it is https://username@domain:port/' '
- test_must_fail git -c transfer.credentialsInUrl=warn clone https://username@localhost:8080 attempt3 2>err &&
- ! grep "uses plaintext credentials" err
-'
-
test_expect_success 'clone from hooks' '
test_create_repo r0 &&
@@ -767,6 +744,7 @@ test_expect_success 'batch missing blob request does not inadvertently try to fe
echo aa >server/a &&
echo bb >server/b &&
# Also add a gitlink pointing to an arbitrary repository
+ test_config_global protocol.file.allow always &&
git -C server submodule add "$(pwd)/repo_for_submodule" c &&
git -C server add a b c &&
git -C server commit -m x &&
diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh
index 24340e6d56e..2734e37e880 100755
--- a/t/t5604-clone-reference.sh
+++ b/t/t5604-clone-reference.sh
@@ -303,8 +303,6 @@ test_expect_success SYMLINKS 'setup repo with manually symlinked or unknown file
ln -s ../an-object $obj &&
cd ../ &&
- find . -type f | sort >../../../T.objects-files.raw &&
- find . -type l | sort >../../../T.objects-symlinks.raw &&
echo unknown_content >unknown_file
) &&
git -C T fsck &&
@@ -313,19 +311,27 @@ test_expect_success SYMLINKS 'setup repo with manually symlinked or unknown file
test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at objects/' '
- for option in --local --no-hardlinks --shared --dissociate
+ # None of these options work when cloning locally, since T has
+ # symlinks in its `$GIT_DIR/objects` directory
+ for option in --local --no-hardlinks --dissociate
do
- git clone $option T T$option || return 1 &&
- git -C T$option fsck || return 1 &&
- git -C T$option rev-list --all --objects >T$option.objects &&
- test_cmp T.objects T$option.objects &&
- (
- cd T$option/.git/objects &&
- find . -type f | sort >../../../T$option.objects-files.raw &&
- find . -type l | sort >../../../T$option.objects-symlinks.raw
- )
+ test_must_fail git clone $option T T$option 2>err || return 1 &&
+ test_i18ngrep "symlink.*exists" err || return 1
done &&
+ # But `--shared` clones should still work, even when specifying
+ # a local path *and* that repository has symlinks present in its
+ # `$GIT_DIR/objects` directory.
+ git clone --shared T T--shared &&
+ git -C T--shared fsck &&
+ git -C T--shared rev-list --all --objects >T--shared.objects &&
+ test_cmp T.objects T--shared.objects &&
+ (
+ cd T--shared/.git/objects &&
+ find . -type f | sort >../../../T--shared.objects-files.raw &&
+ find . -type l | sort >../../../T--shared.objects-symlinks.raw
+ ) &&
+
for raw in $(ls T*.raw)
do
sed -e "s!/../!/Y/!; s![0-9a-f]\{38,\}!Z!" -e "/commit-graph/d" \
@@ -333,26 +339,6 @@ test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at obje
sort $raw.de-sha-1 >$raw.de-sha || return 1
done &&
- cat >expected-files <<-EOF &&
- ./Y/Z
- ./Y/Z
- ./Y/Z
- ./a-loose-dir/Z
- ./an-object
- ./info/packs
- ./pack/pack-Z.idx
- ./pack/pack-Z.pack
- ./packs/pack-Z.idx
- ./packs/pack-Z.pack
- ./unknown_file
- EOF
-
- for option in --local --no-hardlinks --dissociate
- do
- test_cmp expected-files T$option.objects-files.raw.de-sha || return 1 &&
- test_must_be_empty T$option.objects-symlinks.raw.de-sha || return 1
- done &&
-
echo ./info/alternates >expected-files &&
test_cmp expected-files T--shared.objects-files.raw &&
test_must_be_empty T--shared.objects-symlinks.raw
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 8f676d6b0c0..cf221e92c4d 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -42,11 +42,12 @@ test_expect_success 'rejects invalid -o/--origin' '
'
-test_expect_success 'disallows --bare with --origin' '
+test_expect_success 'clone --bare -o' '
- test_must_fail git clone -o foo --bare parent clone-bare-o 2>err &&
- test_debug "cat err" &&
- test_i18ngrep -e "options .--bare. and .--origin foo. cannot be used together" err
+ git clone -o foo --bare parent clone-bare-o &&
+ (cd parent && pwd) >expect &&
+ git -C clone-bare-o config remote.foo.url >actual &&
+ test_cmp expect actual
'
@@ -58,6 +59,14 @@ test_expect_success 'disallows --bare with --separate-git-dir' '
'
+test_expect_success 'disallows --bundle-uri with shallow options' '
+ for option in --depth=1 --shallow-since=01-01-2000 --shallow-exclude=HEAD
+ do
+ test_must_fail git clone --bundle-uri=bundle $option from to 2>err &&
+ grep "bundle-uri is incompatible" err || return 1
+ done
+'
+
test_expect_success 'reject cloning shallow repository' '
test_when_finished "rm -rf repo" &&
test_must_fail git clone --reject-shallow shallow-repo out 2>err &&
diff --git a/t/t5614-clone-submodules-shallow.sh b/t/t5614-clone-submodules-shallow.sh
index 5504b519c79..0c85ef834ab 100755
--- a/t/t5614-clone-submodules-shallow.sh
+++ b/t/t5614-clone-submodules-shallow.sh
@@ -24,6 +24,7 @@ test_expect_success 'setup' '
test_expect_success 'nonshallow clone implies nonshallow submodule' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git clone --recurse-submodules "file://$pwd/." super_clone &&
git -C super_clone log --oneline >lines &&
test_line_count = 3 lines &&
@@ -33,6 +34,7 @@ test_expect_success 'nonshallow clone implies nonshallow submodule' '
test_expect_success 'shallow clone with shallow submodule' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git clone --recurse-submodules --depth 2 --shallow-submodules "file://$pwd/." super_clone &&
git -C super_clone log --oneline >lines &&
test_line_count = 2 lines &&
@@ -42,6 +44,7 @@ test_expect_success 'shallow clone with shallow submodule' '
test_expect_success 'shallow clone does not imply shallow submodule' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone &&
git -C super_clone log --oneline >lines &&
test_line_count = 2 lines &&
@@ -51,6 +54,7 @@ test_expect_success 'shallow clone does not imply shallow submodule' '
test_expect_success 'shallow clone with non shallow submodule' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone &&
git -C super_clone log --oneline >lines &&
test_line_count = 2 lines &&
@@ -60,6 +64,7 @@ test_expect_success 'shallow clone with non shallow submodule' '
test_expect_success 'non shallow clone with shallow submodule' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone &&
git -C super_clone log --oneline >lines &&
test_line_count = 3 lines &&
@@ -69,6 +74,7 @@ test_expect_success 'non shallow clone with shallow submodule' '
test_expect_success 'clone follows shallow recommendation' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git config -f .gitmodules submodule.sub.shallow true &&
git add .gitmodules &&
git commit -m "recommend shallow for sub" &&
@@ -87,6 +93,7 @@ test_expect_success 'clone follows shallow recommendation' '
test_expect_success 'get unshallow recommended shallow submodule' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git clone --no-local "file://$pwd/." super_clone &&
(
cd super_clone &&
@@ -103,6 +110,7 @@ test_expect_success 'get unshallow recommended shallow submodule' '
test_expect_success 'clone follows non shallow recommendation' '
test_when_finished "rm -rf super_clone" &&
+ test_config_global protocol.file.allow always &&
git config -f .gitmodules submodule.sub.shallow false &&
git add .gitmodules &&
git commit -m "recommend non shallow for sub" &&
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 9aeacc2f6a5..037941b95d2 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -260,6 +260,8 @@ test_expect_success 'partial clone with transfer.fsckobjects=1 works with submod
test_config -C src_with_sub uploadpack.allowfilter 1 &&
test_config -C src_with_sub uploadpack.allowanysha1inwant 1 &&
+ test_config_global protocol.file.allow always &&
+
git -C src_with_sub submodule add "file://$(pwd)/submodule" mysub &&
git -C src_with_sub commit -m "commit with submodule" &&
diff --git a/t/t5617-clone-submodules-remote.sh b/t/t5617-clone-submodules-remote.sh
index ca8f80083a2..68843382493 100755
--- a/t/t5617-clone-submodules-remote.sh
+++ b/t/t5617-clone-submodules-remote.sh
@@ -10,6 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
pwd=$(pwd)
test_expect_success 'setup' '
+ git config --global protocol.file.allow always &&
git checkout -b main &&
test_commit commit1 &&
mkdir sub &&
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 5d42a355a8b..b33cd4afca3 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -1001,7 +1001,7 @@ test_expect_success 'part of packfile response provided as URI' '
do
git verify-pack --object-format=$(test_oid algo) --verbose $idx >out &&
{
- grep "^[0-9a-f]\{16,\} " out || :
+ grep -E "^[0-9a-f]{16,} " out || :
} >out.objectlist &&
if test_line_count = 1 out.objectlist
then
diff --git a/t/t5750-bundle-uri-parse.sh b/t/t5750-bundle-uri-parse.sh
new file mode 100755
index 00000000000..c2fe3f9c5a5
--- /dev/null
+++ b/t/t5750-bundle-uri-parse.sh
@@ -0,0 +1,171 @@
+#!/bin/sh
+
+test_description="Test bundle-uri bundle_uri_parse_line()"
+
+TEST_NO_CREATE_REPO=1
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success 'bundle_uri_parse_line() just URIs' '
+ cat >in <<-\EOF &&
+ bundle.one.uri=http://example.com/bundle.bdl
+ bundle.two.uri=https://example.com/bundle.bdl
+ bundle.three.uri=file:///usr/share/git/bundle.bdl
+ EOF
+
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'bundle_uri_parse_line() parsing edge cases: empty key or value' '
+ cat >in <<-\EOF &&
+ =bogus-value
+ bogus-key=
+ EOF
+
+ cat >err.expect <<-EOF &&
+ error: bundle-uri: line has empty key or value
+ error: bad line: '\''=bogus-value'\''
+ error: bundle-uri: line has empty key or value
+ error: bad line: '\''bogus-key='\''
+ EOF
+
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_cmp err.expect err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'bundle_uri_parse_line() parsing edge cases: empty lines' '
+ cat >in <<-\EOF &&
+ bundle.one.uri=http://example.com/bundle.bdl
+
+ bundle.two.uri=https://example.com/bundle.bdl
+
+ bundle.three.uri=file:///usr/share/git/bundle.bdl
+ EOF
+
+ cat >err.expect <<-\EOF &&
+ error: bundle-uri: got an empty line
+ error: bad line: '\'''\''
+ error: bundle-uri: got an empty line
+ error: bad line: '\'''\''
+ EOF
+
+ # We fail, but try to continue parsing regardless
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_cmp err.expect err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'bundle_uri_parse_line() parsing edge cases: duplicate lines' '
+ cat >in <<-\EOF &&
+ bundle.one.uri=http://example.com/bundle.bdl
+ bundle.two.uri=https://example.com/bundle.bdl
+ bundle.one.uri=https://example.com/bundle-2.bdl
+ bundle.three.uri=file:///usr/share/git/bundle.bdl
+ EOF
+
+ cat >err.expect <<-\EOF &&
+ error: bad line: '\''bundle.one.uri=https://example.com/bundle-2.bdl'\''
+ EOF
+
+ # We fail, but try to continue parsing regardless
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_cmp err.expect err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'parse config format: just URIs' '
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test-tool bundle-uri parse-config expect >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'parse config format edge cases: empty key or value' '
+ cat >in1 <<-\EOF &&
+ = bogus-value
+ EOF
+
+ cat >err1 <<-EOF &&
+ error: bad config line 1 in file in1
+ EOF
+
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-config in1 >actual 2>err &&
+ test_cmp err1 err &&
+ test_cmp_config_output expect actual &&
+
+ cat >in2 <<-\EOF &&
+ bogus-key =
+ EOF
+
+ cat >err2 <<-EOF &&
+ error: bad config line 1 in file in2
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-config in2 >actual 2>err &&
+ test_cmp err2 err &&
+ test_cmp_config_output expect actual
+'
+
+test_done
diff --git a/t/t6008-rev-list-submodule.sh b/t/t6008-rev-list-submodule.sh
index 3153a0d8910..2cdef6fdf98 100755
--- a/t/t6008-rev-list-submodule.sh
+++ b/t/t6008-rev-list-submodule.sh
@@ -8,6 +8,7 @@ test_description='git rev-list involving submodules that this repo has'
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' '
@@ -26,7 +27,7 @@ test_expect_success 'setup' '
: > super-file &&
git add super-file &&
- git submodule add "$(pwd)" sub &&
+ git -c protocol.file.allow=always submodule add "$(pwd)" sub &&
git symbolic-ref HEAD refs/heads/super &&
test_tick &&
git commit -m super-initial &&
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 83931d482fb..6dbbe62eb22 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -266,6 +266,16 @@ test_expect_success '"git bisect run" simple case' '
git bisect reset
'
+# We want to make sure no arguments has been eaten
+test_expect_success '"git bisect run" simple case' '
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run printf "%s %s\n" reset --bisect-skip >my_bisect_log.txt &&
+ grep -e "reset --bisect-skip" my_bisect_log.txt &&
+ git bisect reset
+'
+
# We want to automatically find the commit that
# added "Ciao" into hello.
test_expect_success '"git bisect run" with more complex "git bisect start"' '
diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh
index 9fdafeb1e90..cada952f9ae 100755
--- a/t/t6132-pathspec-exclude.sh
+++ b/t/t6132-pathspec-exclude.sh
@@ -293,7 +293,11 @@ test_expect_success 'add with all negative' '
test_cmp expect actual
'
-test_expect_success 'add -p with all negative' '
+test_lazy_prereq ADD_I_USE_BUILTIN_OR_PERL '
+ test_have_prereq ADD_I_USE_BUILTIN || test_have_prereq PERL
+'
+
+test_expect_success ADD_I_USE_BUILTIN_OR_PERL 'add -p with all negative' '
H=$(git rev-parse HEAD) &&
git reset --hard $H &&
git clean -f &&
diff --git a/t/t6134-pathspec-in-submodule.sh b/t/t6134-pathspec-in-submodule.sh
index 0f1cb49cedc..3214d9db97d 100755
--- a/t/t6134-pathspec-in-submodule.sh
+++ b/t/t6134-pathspec-in-submodule.sh
@@ -2,6 +2,7 @@
test_description='test case exclude pathspec'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup a submodule' '
@@ -9,7 +10,7 @@ test_expect_success 'setup a submodule' '
: >pretzel/a &&
git -C pretzel add a &&
git -C pretzel commit -m "add a file" -- a &&
- git submodule add ./pretzel sub &&
+ git -c protocol.file.allow=always submodule add ./pretzel sub &&
git commit -a -m "add submodule" &&
git submodule deinit --all
'
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index dcaab7265f5..fa38b874416 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -1406,4 +1406,44 @@ test_expect_success 'for-each-ref reports broken tags' '
refs/tags/broken-tag-*
'
+test_expect_success 'set up tag with signature and no blank lines' '
+ git tag -F - fake-sig-no-blanks <<-\EOF
+ this is the subject
+ -----BEGIN PGP SIGNATURE-----
+ not a real signature, but we just care about the
+ subject/body parsing. It is important here that
+ there are no blank lines in the signature.
+ -----END PGP SIGNATURE-----
+ EOF
+'
+
+test_atom refs/tags/fake-sig-no-blanks contents:subject 'this is the subject'
+test_atom refs/tags/fake-sig-no-blanks contents:body ''
+test_atom refs/tags/fake-sig-no-blanks contents:signature "$sig"
+
+test_expect_success 'set up tag with CRLF signature' '
+ append_cr <<-\EOF |
+ this is the subject
+ -----BEGIN PGP SIGNATURE-----
+
+ not a real signature, but we just care about
+ the subject/body parsing. It is important here
+ that there is a blank line separating this
+ from the signature header.
+ -----END PGP SIGNATURE-----
+ EOF
+ git tag -F - --cleanup=verbatim fake-sig-crlf
+'
+
+test_atom refs/tags/fake-sig-crlf contents:subject 'this is the subject'
+test_atom refs/tags/fake-sig-crlf contents:body ''
+
+# CRLF is retained in the signature, so we have to pass our expected value
+# through append_cr. But test_atom requires a shell string, which means command
+# substitution, and the shell will strip trailing newlines from the output of
+# the substitution. Hack around it by adding and then removing a dummy line.
+sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)"
+sig_crlf=${sig_crlf%dummy}
+test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf"
+
test_done
diff --git a/t/t6400-merge-df.sh b/t/t6400-merge-df.sh
index 57a67cf3627..3de4ef6bd9e 100755
--- a/t/t6400-merge-df.sh
+++ b/t/t6400-merge-df.sh
@@ -126,7 +126,7 @@ test_expect_success 'Simple merge in repo with interesting pathnames' '
# foo/bar-2/baz
# The fact that foo/bar-2 appears between foo/bar and foo/bar/baz
# can trip up some codepaths, and is the point of this test.
- test_create_repo name-ordering &&
+ git init name-ordering &&
(
cd name-ordering &&
diff --git a/t/t6406-merge-attr.sh b/t/t6406-merge-attr.sh
index 99abefd44b9..8650a88c40a 100755
--- a/t/t6406-merge-attr.sh
+++ b/t/t6406-merge-attr.sh
@@ -162,8 +162,8 @@ test_expect_success 'custom merge backend' '
'
test_expect_success 'up-to-date merge without common ancestor' '
- test_create_repo repo1 &&
- test_create_repo repo2 &&
+ git init repo1 &&
+ git init repo2 &&
test_tick &&
(
cd repo1 &&
diff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh
index 690c8482b13..17b54d625d0 100755
--- a/t/t6416-recursive-corner-cases.sh
+++ b/t/t6416-recursive-corner-cases.sh
@@ -19,7 +19,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
#
test_expect_success 'setup basic criss-cross + rename with no modifications' '
- test_create_repo basic-rename &&
+ git init basic-rename &&
(
cd basic-rename &&
@@ -85,7 +85,7 @@ test_expect_success 'merge simple rename+criss-cross with no modifications' '
#
test_expect_success 'setup criss-cross + rename merges with basic modification' '
- test_create_repo rename-modify &&
+ git init rename-modify &&
(
cd rename-modify &&
@@ -160,7 +160,7 @@ test_expect_success 'merge criss-cross + rename merges with basic modification'
#
test_expect_success 'setup differently handled merges of rename/add conflict' '
- test_create_repo rename-add &&
+ git init rename-add &&
(
cd rename-add &&
@@ -324,7 +324,7 @@ test_expect_success 'git detects differently handled merges conflict, swapped' '
# Merging commits D & E should result in modify/delete conflict.
test_expect_success 'setup criss-cross + modify/delete resolved differently' '
- test_create_repo modify-delete &&
+ git init modify-delete &&
(
cd modify-delete &&
@@ -499,7 +499,7 @@ test_expect_success 'git detects conflict merging criss-cross+modify/delete, rev
#
test_expect_success 'setup differently handled merges of directory/file conflict' '
- test_create_repo directory-file &&
+ git init directory-file &&
(
cd directory-file &&
@@ -867,7 +867,7 @@ test_expect_failure 'merge of D2 & E4 merges a2s & reports conflict for a/file'
# but that may cancel out at the final merge stage".
test_expect_success 'setup rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
- test_create_repo rename-squared-squared &&
+ git init rename-squared-squared &&
(
cd rename-squared-squared &&
@@ -944,7 +944,7 @@ test_expect_success 'handle rename/rename(1to2)/modify followed by what looks li
# content merge handled.
test_expect_success 'setup criss-cross + rename/rename/add-source + modify/modify' '
- test_create_repo rename-rename-add-source &&
+ git init rename-rename-add-source &&
(
cd rename-rename-add-source &&
@@ -1032,7 +1032,7 @@ test_expect_failure 'detect rename/rename/add-source for virtual merge-base' '
# base of B & C needs to not delete B:c for that to work, though...
test_expect_success 'setup criss-cross+rename/rename/add-dest + simple modify' '
- test_create_repo rename-rename-add-dest &&
+ git init rename-rename-add-dest &&
(
cd rename-rename-add-dest &&
@@ -1111,7 +1111,7 @@ test_expect_success 'virtual merge base handles rename/rename(1to2)/add-dest' '
# git detect it?
test_expect_success 'setup symlink modify/modify' '
- test_create_repo symlink-modify-modify &&
+ git init symlink-modify-modify &&
(
cd symlink-modify-modify &&
@@ -1178,7 +1178,7 @@ test_expect_merge_algorithm failure success 'check symlink modify/modify' '
# git detect it?
test_expect_success 'setup symlink add/add' '
- test_create_repo symlink-add-add &&
+ git init symlink-add-add &&
(
cd symlink-add-add &&
@@ -1244,11 +1244,11 @@ test_expect_merge_algorithm failure success 'check symlink add/add' '
# git detect it?
test_expect_success 'setup submodule modify/modify' '
- test_create_repo submodule-modify-modify &&
+ git init submodule-modify-modify &&
(
cd submodule-modify-modify &&
- test_create_repo submod &&
+ git init submod &&
(
cd submod &&
touch file-A &&
@@ -1332,11 +1332,11 @@ test_expect_merge_algorithm failure success 'check submodule modify/modify' '
# git detect it?
test_expect_success 'setup submodule add/add' '
- test_create_repo submodule-add-add &&
+ git init submodule-add-add &&
(
cd submodule-add-add &&
- test_create_repo submod &&
+ git init submod &&
(
cd submod &&
touch file-A &&
@@ -1419,11 +1419,11 @@ test_expect_merge_algorithm failure success 'check submodule add/add' '
# This is an obvious add/add conflict for 'path'. Can git detect it?
test_expect_success 'setup conflicting entry types (submodule vs symlink)' '
- test_create_repo submodule-symlink-add-add &&
+ git init submodule-symlink-add-add &&
(
cd submodule-symlink-add-add &&
- test_create_repo path &&
+ git init path &&
(
cd path &&
touch file-B &&
@@ -1494,7 +1494,7 @@ test_expect_merge_algorithm failure success 'check conflicting entry types (subm
# This is an obvious add/add mode conflict. Can git detect it?
test_expect_success 'setup conflicting modes for regular file' '
- test_create_repo regular-file-mode-conflict &&
+ git init regular-file-mode-conflict &&
(
cd regular-file-mode-conflict &&
@@ -1571,7 +1571,7 @@ test_expect_failure 'check conflicting modes for regular file' '
# to ensure that we handle it as well as practical.
test_expect_success 'setup nested conflicts' '
- test_create_repo nested_conflicts &&
+ git init nested_conflicts &&
(
cd nested_conflicts &&
@@ -1757,7 +1757,7 @@ test_expect_success 'check nested conflicts' '
# have three levels of conflict markers. Can we distinguish all three?
test_expect_success 'setup virtual merge base with nested conflicts' '
- test_create_repo virtual_merge_base_has_nested_conflicts &&
+ git init virtual_merge_base_has_nested_conflicts &&
(
cd virtual_merge_base_has_nested_conflicts &&
diff --git a/t/t6421-merge-partial-clone.sh b/t/t6421-merge-partial-clone.sh
index 36bcd7c3280..5413e5dd9d6 100755
--- a/t/t6421-merge-partial-clone.sh
+++ b/t/t6421-merge-partial-clone.sh
@@ -31,7 +31,7 @@ test_description="limiting blob downloads when merging with partial clones"
test_setup_repo () {
test -d server && return
- test_create_repo server &&
+ git init server &&
(
cd server &&
diff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh
index 9b65768aed6..346253c7c88 100755
--- a/t/t6422-merge-rename-corner-cases.sh
+++ b/t/t6422-merge-rename-corner-cases.sh
@@ -11,7 +11,7 @@ TEST_PASSES_SANITIZE_LEAK=true
. "$TEST_DIRECTORY"/lib-merge.sh
test_setup_rename_delete_untracked () {
- test_create_repo rename-delete-untracked &&
+ git init rename-delete-untracked &&
(
cd rename-delete-untracked &&
@@ -56,7 +56,7 @@ test_expect_success "Does git preserve Gollum's precious artifact?" '
# We should be able to merge B & C cleanly
test_setup_rename_modify_add_source () {
- test_create_repo rename-modify-add-source &&
+ git init rename-modify-add-source &&
(
cd rename-modify-add-source &&
@@ -96,7 +96,7 @@ test_expect_failure 'rename/modify/add-source conflict resolvable' '
'
test_setup_break_detection_1 () {
- test_create_repo break-detection-1 &&
+ git init break-detection-1 &&
(
cd break-detection-1 &&
@@ -144,7 +144,7 @@ test_expect_failure 'conflict caused if rename not detected' '
'
test_setup_break_detection_2 () {
- test_create_repo break-detection-2 &&
+ git init break-detection-2 &&
(
cd break-detection-2 &&
@@ -192,7 +192,7 @@ test_expect_failure 'missed conflict if rename not detected' '
# Commit C: rename a->b, add unrelated a
test_setup_break_detection_3 () {
- test_create_repo break-detection-3 &&
+ git init break-detection-3 &&
(
cd break-detection-3 &&
@@ -268,7 +268,7 @@ test_expect_failure 'detect rename/add-source and preserve all data, merge other
'
test_setup_rename_directory () {
- test_create_repo rename-directory-$1 &&
+ git init rename-directory-$1 &&
(
cd rename-directory-$1 &&
@@ -386,7 +386,7 @@ test_expect_success 'rename/directory conflict + content merge conflict' '
'
test_setup_rename_directory_2 () {
- test_create_repo rename-directory-2 &&
+ git init rename-directory-2 &&
(
cd rename-directory-2 &&
@@ -445,7 +445,7 @@ test_expect_success 'disappearing dir in rename/directory conflict handled' '
# Commit B: modify a, add different b
test_setup_rename_with_content_merge_and_add () {
- test_create_repo rename-with-content-merge-and-add-$1 &&
+ git init rename-with-content-merge-and-add-$1 &&
(
cd rename-with-content-merge-and-add-$1 &&
@@ -570,7 +570,7 @@ test_expect_success 'handle rename-with-content-merge vs. add, merge other way'
# * Nothing else should be present. Is anything?
test_setup_rename_rename_2to1 () {
- test_create_repo rename-rename-2to1 &&
+ git init rename-rename-2to1 &&
(
cd rename-rename-2to1 &&
@@ -642,7 +642,7 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
# Commit B: rename a->b
# Commit C: rename a->c
test_setup_rename_rename_1to2 () {
- test_create_repo rename-rename-1to2 &&
+ git init rename-rename-1to2 &&
(
cd rename-rename-1to2 &&
@@ -700,7 +700,7 @@ test_expect_success 'merge has correct working tree contents' '
# Merging of B & C should NOT be clean; there's a rename/rename conflict
test_setup_rename_rename_1to2_add_source_1 () {
- test_create_repo rename-rename-1to2-add-source-1 &&
+ git init rename-rename-1to2-add-source-1 &&
(
cd rename-rename-1to2-add-source-1 &&
@@ -748,7 +748,7 @@ test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge'
'
test_setup_rename_rename_1to2_add_source_2 () {
- test_create_repo rename-rename-1to2-add-source-2 &&
+ git init rename-rename-1to2-add-source-2 &&
(
cd rename-rename-1to2-add-source-2 &&
@@ -794,7 +794,7 @@ test_expect_failure 'rename/rename/add-source still tracks new a file' '
'
test_setup_rename_rename_1to2_add_dest () {
- test_create_repo rename-rename-1to2-add-dest &&
+ git init rename-rename-1to2-add-dest &&
(
cd rename-rename-1to2-add-dest &&
@@ -874,7 +874,7 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
# Expected: CONFLICT (rename/add/delete), two-way merged bar
test_setup_rad () {
- test_create_repo rad &&
+ git init rad &&
(
cd rad &&
echo "original file" >foo &&
@@ -946,7 +946,7 @@ test_expect_merge_algorithm failure success 'rad-check: rename/add/delete confli
# Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
test_setup_rrdd () {
- test_create_repo rrdd &&
+ git init rrdd &&
(
cd rrdd &&
echo foo >foo &&
@@ -1022,7 +1022,7 @@ test_expect_merge_algorithm failure success 'rrdd-check: rename/rename(2to1)/del
# multi-way merged contents found in two, four, six
test_setup_mod6 () {
- test_create_repo mod6 &&
+ git init mod6 &&
(
cd mod6 &&
test_seq 11 19 >one &&
@@ -1160,7 +1160,7 @@ test_conflicts_with_adds_and_renames() {
# tree
test_setup_collision_conflict () {
#test_expect_success "setup simple $sideL/$sideR conflict" '
- test_create_repo simple_${sideL}_${sideR} &&
+ git init simple_${sideL}_${sideR} &&
(
cd simple_${sideL}_${sideR} &&
@@ -1308,7 +1308,7 @@ test_conflicts_with_adds_and_renames add add
# So, we have four different conflicting files that all end up at path
# 'three'.
test_setup_nested_conflicts_from_rename_rename () {
- test_create_repo nested_conflicts_from_rename_rename &&
+ git init nested_conflicts_from_rename_rename &&
(
cd nested_conflicts_from_rename_rename &&
@@ -1417,7 +1417,7 @@ test_expect_success 'check nested conflicts from rename/rename(2to1)' '
# Expected: CONFLICT(rename/rename) message, three unstaged entries in the
# index, and contents of orig-[AB] at path orig-[AB]
test_setup_rename_rename_1_to_2_binary () {
- test_create_repo rename_rename_1_to_2_binary &&
+ git init rename_rename_1_to_2_binary &&
(
cd rename_rename_1_to_2_binary &&
diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh
index 99baf77cbfd..944de75b805 100755
--- a/t/t6423-merge-rename-directories.sh
+++ b/t/t6423-merge-rename-directories.sh
@@ -40,7 +40,7 @@ test_description="recursive merge with directory renames"
# Expected: y/{b,c,d,e/f}
test_setup_1a () {
- test_create_repo 1a &&
+ git init 1a &&
(
cd 1a &&
@@ -106,7 +106,7 @@ test_expect_success '1a: Simple directory rename detection' '
# Expected: y/{b,c,d,e}
test_setup_1b () {
- test_create_repo 1b &&
+ git init 1b &&
(
cd 1b &&
@@ -169,7 +169,7 @@ test_expect_success '1b: Merge a directory with another' '
# Expected: y/{b,c,d} (because x/d -> z/d -> y/d)
test_setup_1c () {
- test_create_repo 1c &&
+ git init 1c &&
(
cd 1c &&
@@ -232,7 +232,7 @@ test_expect_success '1c: Transitive renaming' '
# y/wham_1 & z/wham_2 should too...giving us a conflict.
test_setup_1d () {
- test_create_repo 1d &&
+ git init 1d &&
(
cd 1d &&
@@ -328,7 +328,7 @@ test_expect_success '1d: Directory renames cause a rename/rename(2to1) conflict'
# Expected: y/{newb,newc,d}
test_setup_1e () {
- test_create_repo 1e &&
+ git init 1e &&
(
cd 1e &&
@@ -387,7 +387,7 @@ test_expect_success '1e: Renamed directory, with all files being renamed too' '
# Expected: y/{b,c}, x/{d,e,f,g}
test_setup_1f () {
- test_create_repo 1f &&
+ git init 1f &&
(
cd 1f &&
@@ -476,7 +476,7 @@ test_expect_success '1f: Split a directory into two other directories' '
# Commit B: z/{b,c,d}
# Expected: y/b, w/c, z/d, with warning about z/ -> (y/ vs. w/) conflict
test_setup_2a () {
- test_create_repo 2a &&
+ git init 2a &&
(
cd 2a &&
@@ -538,7 +538,7 @@ test_expect_success '2a: Directory split into two on one side, with equal number
# Commit B: z/{b,c}, x/d
# Expected: y/b, w/c, x/d; No warning about z/ -> (y/ vs. w/) conflict
test_setup_2b () {
- test_create_repo 2b &&
+ git init 2b &&
(
cd 2b &&
@@ -620,7 +620,7 @@ test_expect_success '2b: Directory split into two on one side, with equal number
# Commit B: y/{b,c}, x/d
# Expected: y/{b,c}, x/d
test_setup_3a () {
- test_create_repo 3a &&
+ git init 3a &&
(
cd 3a &&
@@ -684,7 +684,7 @@ test_expect_success '3a: Avoid implicit rename if involved as source on other si
# end up with CONFLICT:(z/d -> y/d vs. x/d vs. w/d), i.e. a
# rename/rename/rename(1to3) conflict, which is just weird.
test_setup_3b () {
- test_create_repo 3b &&
+ git init 3b &&
(
cd 3b &&
@@ -807,7 +807,7 @@ test_expect_success '3b: Avoid implicit rename if involved as source on current
# NOTE: Even though most files from z moved to y, we don't want f to follow.
test_setup_4a () {
- test_create_repo 4a &&
+ git init 4a &&
(
cd 4a &&
@@ -896,7 +896,7 @@ test_expect_success '4a: Directory split, with original directory still present'
# index.
test_setup_5a () {
- test_create_repo 5a &&
+ git init 5a &&
(
cd 5a &&
@@ -971,7 +971,7 @@ test_expect_success '5a: Merge directories, other side adds files to original an
# back to git behavior without the directory rename detection.
test_setup_5b () {
- test_create_repo 5b &&
+ git init 5b &&
(
cd 5b &&
@@ -1048,7 +1048,7 @@ test_expect_success '5b: Rename/delete in order to get add/add/add conflict' '
# though, because it doesn't have anything in the way.
test_setup_5c () {
- test_create_repo 5c &&
+ git init 5c &&
(
cd 5c &&
@@ -1138,7 +1138,7 @@ test_expect_success '5c: Transitive rename would cause rename/rename/rename/add/
# directory rename detection for z/f -> y/f.
test_setup_5d () {
- test_create_repo 5d &&
+ git init 5d &&
(
cd 5d &&
@@ -1239,7 +1239,7 @@ test_expect_success '5d: Directory/file/file conflict due to directory rename' '
# it is also involved in a rename/delete conflict.
test_setup_6a () {
- test_create_repo 6a &&
+ git init 6a &&
(
cd 6a &&
@@ -1337,7 +1337,7 @@ test_expect_success '6a: Tricky rename/delete' '
# the behavior on testcases 6b2 and 8e, and introduced this 6b1 testcase.
test_setup_6b1 () {
- test_create_repo 6b1 &&
+ git init 6b1 &&
(
cd 6b1 &&
@@ -1415,7 +1415,7 @@ test_expect_merge_algorithm failure success '6b1: Same renames done on both side
# the z/ -> y/ rename.
test_setup_6b2 () {
- test_create_repo 6b2 &&
+ git init 6b2 &&
(
cd 6b2 &&
@@ -1479,7 +1479,7 @@ test_expect_merge_algorithm failure success '6b2: Same rename done on both sides
# "accidentally detect a rename" and give us y/{b,c,d}.
test_setup_6c () {
- test_create_repo 6c &&
+ git init 6c &&
(
cd 6c &&
@@ -1542,7 +1542,7 @@ test_expect_success '6c: Rename only done on same side' '
# doesn't "accidentally detect a rename" and give us y/{b,c,d}.
test_setup_6d () {
- test_create_repo 6d &&
+ git init 6d &&
(
cd 6d &&
@@ -1605,7 +1605,7 @@ test_expect_success '6d: We do not always want transitive renaming' '
# add/add conflict on y/d_1 vs y/d_2.
test_setup_6e () {
- test_create_repo 6e &&
+ git init 6e &&
(
cd 6e &&
@@ -1700,7 +1700,7 @@ test_expect_success '6e: Add/add from one side' '
# NOTE: There's a rename of z/ here, y/ has more renames, so z/d -> y/d.
test_setup_7a () {
- test_create_repo 7a &&
+ git init 7a &&
(
cd 7a &&
@@ -1772,7 +1772,7 @@ test_expect_success '7a: rename-dir vs. rename-dir (NOT split evenly) PLUS add-o
# Expected: y/{b,c}, CONFLICT(rename/rename(2to1): x/d_1, w/d_2 -> y_d)
test_setup_7b () {
- test_create_repo 7b &&
+ git init 7b &&
(
cd 7b &&
@@ -1861,7 +1861,7 @@ test_expect_success '7b: rename/rename(2to1), but only due to transitive rename'
# nor CONFLiCT x/d -> w/d vs. y/d vs. z/d)
test_setup_7c () {
- test_create_repo 7c &&
+ git init 7c &&
(
cd 7c &&
@@ -1926,7 +1926,7 @@ test_expect_success '7c: rename/rename(1to...2or3); transitive rename may add co
# NOTE: z->y so NOT CONFLICT(delete x/d vs rename to z/d)
test_setup_7d () {
- test_create_repo 7d &&
+ git init 7d &&
(
cd 7d &&
@@ -2027,7 +2027,7 @@ test_expect_success '7d: transitive rename involved in rename/delete; how is it
# how it's resolved.
test_setup_7e () {
- test_create_repo 7e &&
+ git init 7e &&
(
cd 7e &&
@@ -2137,7 +2137,7 @@ test_expect_success '7e: transitive rename in rename/delete AND dirs in the way'
# we potentially could.
test_setup_8a () {
- test_create_repo 8a &&
+ git init 8a &&
(
cd 8a &&
@@ -2216,7 +2216,7 @@ test_expect_success '8a: Dual-directory rename, one into the others way' '
# e_1 and e_2.
test_setup_8b () {
- test_create_repo 8b &&
+ git init 8b &&
(
cd 8b &&
@@ -2290,7 +2290,7 @@ test_expect_success '8b: Dual-directory rename, one into the others way, with co
# notes in 8d.
test_setup_8c () {
- test_create_repo 8c &&
+ git init 8c &&
(
cd 8c &&
@@ -2370,7 +2370,7 @@ test_expect_success '8c: modify/delete or rename+modify/delete' '
# differently.
test_setup_8d () {
- test_create_repo 8d &&
+ git init 8d &&
(
cd 8d &&
@@ -2453,7 +2453,7 @@ test_expect_success '8d: rename/delete...or not?' '
# the behavior, and predict it without computing as many details.
test_setup_8e () {
- test_create_repo 8e &&
+ git init 8e &&
(
cd 8e &&
@@ -2537,7 +2537,7 @@ test_expect_success '8e: Both sides rename, one side adds to original directory'
# of that could take the new file in commit B at z/i to x/w/i or x/i.
test_setup_9a () {
- test_create_repo 9a &&
+ git init 9a &&
(
cd 9a &&
@@ -2609,7 +2609,7 @@ test_expect_success '9a: Inner renamed directory within outer renamed directory'
# Expected: y/{b,c,d_merged}
test_setup_9b () {
- test_create_repo 9b &&
+ git init 9b &&
(
cd 9b &&
@@ -2697,7 +2697,7 @@ test_expect_success '9b: Transitive rename with content merge' '
# history for any implicit directory renames.
test_setup_9c () {
- test_create_repo 9c &&
+ git init 9c &&
(
cd 9c &&
@@ -2786,7 +2786,7 @@ test_expect_success '9c: Doubly transitive rename?' '
# testcases and simplifies things for the user.
test_setup_9d () {
- test_create_repo 9d &&
+ git init 9d &&
(
cd 9d &&
@@ -2861,7 +2861,7 @@ test_expect_success '9d: N-way transitive rename?' '
# dir1/yo, dir2/yo, dir3/yo, dirN/yo
test_setup_9e () {
- test_create_repo 9e &&
+ git init 9e &&
(
cd 9e &&
@@ -2954,7 +2954,7 @@ test_expect_success '9e: N-to-1 whammo' '
# Expected: priority/{a,b}/$more_files, priority/c
test_setup_9f () {
- test_create_repo 9f &&
+ git init 9f &&
(
cd 9f &&
@@ -3027,7 +3027,7 @@ test_expect_success '9f: Renamed directory that only contained immediate subdirs
# viewpoint...
test_setup_9g () {
- test_create_repo 9g &&
+ git init 9g &&
(
cd 9g &&
@@ -3096,7 +3096,7 @@ test_expect_failure '9g: Renamed directory that only contained immediate subdirs
# NOTE: If we applied the z/ -> y/ rename to z/d, then we'd end up with
# a rename/rename(1to2) conflict (z/d -> y/d vs. x/d)
test_setup_9h () {
- test_create_repo 9h &&
+ git init 9h &&
(
cd 9h &&
@@ -3177,7 +3177,7 @@ test_expect_success '9h: Avoid dir rename on merely modified path' '
# ERROR_MSG(untracked working tree files would be overwritten by merge)
test_setup_10a () {
- test_create_repo 10a &&
+ git init 10a &&
(
cd 10a &&
@@ -3243,7 +3243,7 @@ test_expect_success '10a: Overwrite untracked with normal rename/delete' '
# ERROR_MSG(refusing to lose untracked file at 'y/d')
test_setup_10b () {
- test_create_repo 10b &&
+ git init 10b &&
(
cd 10b &&
@@ -3334,7 +3334,7 @@ test_expect_success '10b: Overwrite untracked with dir rename + delete' '
# ERROR_MSG(Refusing to lose untracked file at y/c)
test_setup_10c () {
- test_create_repo 10c_$1 &&
+ git init 10c_$1 &&
(
cd 10c_$1 &&
@@ -3472,7 +3472,7 @@ test_expect_success '10c2: Overwrite untracked with dir rename/rename(1to2), oth
# ERROR_MSG(Refusing to lose untracked file at y/wham)
test_setup_10d () {
- test_create_repo 10d &&
+ git init 10d &&
(
cd 10d &&
@@ -3568,7 +3568,7 @@ test_expect_success '10d: Delete untracked with dir rename/rename(2to1)' '
# Expected: y/{a,b,c} + untracked z/c
test_setup_10e () {
- test_create_repo 10e &&
+ git init 10e &&
(
cd 10e &&
@@ -3650,7 +3650,7 @@ test_expect_merge_algorithm failure success '10e: Does git complain about untrac
# z/c with uncommitted mods on top of A:z/c_v1
test_setup_11a () {
- test_create_repo 11a &&
+ git init 11a &&
(
cd 11a &&
@@ -3728,7 +3728,7 @@ test_expect_success '11a: Avoid losing dirty contents with simple rename' '
test_setup_11b () {
- test_create_repo 11b &&
+ git init 11b &&
(
cd 11b &&
@@ -3810,7 +3810,7 @@ test_expect_success '11b: Avoid losing dirty file involved in directory rename'
# y/c left untouched (still has uncommitted mods)
test_setup_11c () {
- test_create_repo 11c &&
+ git init 11c &&
(
cd 11c &&
@@ -3883,7 +3883,7 @@ test_expect_success '11c: Avoid losing not-uptodate with rename + D/F conflict'
# y/{a,c~HEAD,c/d}, x/b, now-untracked z/c_v1 with uncommitted mods
test_setup_11d () {
- test_create_repo 11d &&
+ git init 11d &&
(
cd 11d &&
@@ -3968,7 +3968,7 @@ test_expect_success '11d: Avoid losing not-uptodate with rename + D/F conflict'
# y/c has dirty file from before merge
test_setup_11e () {
- test_create_repo 11e &&
+ git init 11e &&
(
cd 11e &&
@@ -4060,7 +4060,7 @@ test_expect_success '11e: Avoid deleting not-uptodate with dir rename/rename(1to
# ERROR_MSG(Refusing to lose dirty file at y/wham)
test_setup_11f () {
- test_create_repo 11f &&
+ git init 11f &&
(
cd 11f &&
@@ -4155,7 +4155,7 @@ test_expect_success '11f: Avoid deleting not-uptodate with dir rename/rename(2to
# Expected: node1/{leaf1,leaf2,leaf5,node2/{leaf3,leaf4,leaf6}}
test_setup_12a () {
- test_create_repo 12a &&
+ git init 12a &&
(
cd 12a &&
@@ -4238,7 +4238,7 @@ test_expect_success '12a: Moving one directory hierarchy into another' '
# node2/node1/{leaf1, leaf2}
test_setup_12b1 () {
- test_create_repo 12b1 &&
+ git init 12b1 &&
(
cd 12b1 &&
@@ -4327,7 +4327,7 @@ test_expect_merge_algorithm failure success '12b1: Moving two directory hierarch
# even simple rules give weird results when given weird inputs.
test_setup_12b2 () {
- test_create_repo 12b2 &&
+ git init 12b2 &&
(
cd 12b2 &&
@@ -4402,7 +4402,7 @@ test_expect_success '12b2: Moving two directory hierarchies into each other' '
# each side of the merge.
test_setup_12c1 () {
- test_create_repo 12c1 &&
+ git init 12c1 &&
(
cd 12c1 &&
@@ -4492,7 +4492,7 @@ test_expect_merge_algorithm failure success '12c1: Moving one directory hierarch
# on each side of the merge.
test_setup_12c2 () {
- test_create_repo 12c2 &&
+ git init 12c2 &&
(
cd 12c2 &&
@@ -4584,7 +4584,7 @@ test_expect_success '12c2: Moving one directory hierarchy into another w/ conten
# Expected: subdir/foo, bar
test_setup_12d () {
- test_create_repo 12d &&
+ git init 12d &&
(
cd 12d &&
@@ -4642,7 +4642,7 @@ test_expect_success '12d: Rename/merge subdir into the root, variant 1' '
# Expected: foo, bar
test_setup_12e () {
- test_create_repo 12e &&
+ git init 12e &&
(
cd 12e &&
@@ -4743,7 +4743,7 @@ test_expect_success '12e: Rename/merge subdir into the root, variant 2' '
# pick and re-applying them in the subsequent one.
test_setup_12f () {
- test_create_repo 12f &&
+ git init 12f &&
(
cd 12f &&
@@ -4902,7 +4902,7 @@ test_expect_merge_algorithm failure success '12f: Trivial directory resolve, cac
# Expected: newfile_{merged}, newdir/{a_B,b_B,c_A}
test_setup_12g () {
- test_create_repo 12g &&
+ git init 12g &&
(
cd 12g &&
@@ -4973,7 +4973,7 @@ test_expect_success '12g: Testcase with two kinds of "relevant" renames' '
# Expected: newdir/{alpha_2, b}
test_setup_12h () {
- test_create_repo 12h &&
+ git init 12h &&
(
cd 12h &&
@@ -5032,7 +5032,7 @@ test_expect_failure '12h: renaming a file within a renamed directory' '
# source/bar vs. source/subdir/bar
test_setup_12i () {
- test_create_repo 12i &&
+ git init 12i &&
(
cd 12i &&
@@ -5090,7 +5090,7 @@ test_expect_success '12i: Directory rename causes rename-to-self' '
# Expected: {foo, bar, baz_2}, with conflicts on bar vs. subdir/bar
test_setup_12j () {
- test_create_repo 12j &&
+ git init 12j &&
(
cd 12j &&
@@ -5148,7 +5148,7 @@ test_expect_success '12j: Directory rename to root causes rename-to-self' '
# Expected: dirA/{foo, bar, baz_2}, with conflicts on dirA/bar vs. dirB/bar
test_setup_12k () {
- test_create_repo 12k &&
+ git init 12k &&
(
cd 12k &&
@@ -5218,7 +5218,7 @@ test_expect_success '12k: Directory rename with sibling causes rename-to-self' '
# is needed for there to be a sub1/ -> sub3/ rename.
test_setup_12l () {
- test_create_repo 12l_$1 &&
+ git init 12l_$1 &&
(
cd 12l_$1 &&
@@ -5304,6 +5304,62 @@ test_expect_merge_algorithm failure success '12l (A into B): Rename into each ot
)
'
+# Testcase 12m, Directory rename, plus change of parent dir to symlink
+# Commit O: dir/subdir/file
+# Commit A: renamed-dir/subdir/file
+# Commit B: dir/subdir
+# In words:
+# A: dir/subdir/ -> renamed-dir/subdir
+# B: delete dir/subdir/file, add dir/subdir as symlink
+#
+# Expected: CONFLICT (rename/delete): renamed-dir/subdir/file,
+# CONFLICT (file location): renamed-dir/subdir vs. dir/subdir
+# CONFLICT (directory/file): renamed-dir/subdir symlink has
+# renamed-dir/subdir in the way
+
+test_setup_12m () {
+ git init 12m &&
+ (
+ cd 12m &&
+
+ mkdir -p dir/subdir &&
+ echo 1 >dir/subdir/file &&
+ git add . &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git switch A &&
+ git mv dir/ renamed-dir/ &&
+ git add . &&
+ git commit -m "A" &&
+
+ git switch B &&
+ git rm dir/subdir/file &&
+ mkdir dir &&
+ ln -s /dev/null dir/subdir &&
+ git add . &&
+ git commit -m "B"
+ )
+}
+
+test_expect_merge_algorithm failure success '12m: Change parent of renamed-dir to symlink on other side' '
+ test_setup_12m &&
+ (
+ cd 12m &&
+
+ git checkout -q A^0 &&
+
+ test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 &&
+
+ test_stdout_line_count = 3 git ls-files -s &&
+ test_stdout_line_count = 2 ls -1 renamed-dir &&
+ test_path_is_missing dir
+ )
+'
+
###########################################################################
# SECTION 13: Checking informational and conflict messages
#
@@ -5322,7 +5378,7 @@ test_expect_merge_algorithm failure success '12l (A into B): Rename into each ot
# Expected: y/{b,c,d,e/f}, with notices/conflicts for both y/d and y/e/f
test_setup_13a () {
- test_create_repo 13a_$1 &&
+ git init 13a_$1 &&
(
cd 13a_$1 &&
@@ -5409,7 +5465,7 @@ test_expect_success '13a(info): messages for newly added files' '
# one about content, and one about file location
test_setup_13b () {
- test_create_repo 13b_$1 &&
+ git init 13b_$1 &&
(
cd 13b_$1 &&
@@ -5496,7 +5552,7 @@ test_expect_success '13b(info): messages for transitive rename with conflicted c
# shown in testcase 13d.
test_setup_13c () {
- test_create_repo 13c_$1 &&
+ git init 13c_$1 &&
(
cd 13c_$1 &&
@@ -5584,7 +5640,7 @@ test_expect_success '13c(info): messages for rename/rename(1to1) via transitive
# No conflict in where a/y ends up, so put it in d/y.
test_setup_13d () {
- test_create_repo 13d_$1 &&
+ git init 13d_$1 &&
(
cd 13d_$1 &&
@@ -5710,7 +5766,7 @@ test_expect_success '13d(info): messages for rename/rename(1to1) via dual transi
# least avoids hitting a BUG().
#
test_setup_13e () {
- test_create_repo 13e &&
+ git init 13e &&
(
cd 13e &&
diff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh
index 7b5f1c1dcd1..2bb8e7f09bb 100755
--- a/t/t6426-merge-skip-unneeded-updates.sh
+++ b/t/t6426-merge-skip-unneeded-updates.sh
@@ -38,7 +38,7 @@ test_description="merge cases"
# Expected: b_2
test_setup_1a () {
- test_create_repo 1a_$1 &&
+ git init 1a_$1 &&
(
cd 1a_$1 &&
@@ -136,7 +136,7 @@ test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '
# Expected: c_2
test_setup_2a () {
- test_create_repo 2a_$1 &&
+ git init 2a_$1 &&
(
cd 2a_$1 &&
@@ -229,7 +229,7 @@ test_expect_success '2a-R: Modify/rename, merge into rename side' '
# Expected: c_2
test_setup_2b () {
- test_create_repo 2b_$1 &&
+ git init 2b_$1 &&
(
cd 2b_$1 &&
@@ -336,7 +336,7 @@ test_expect_success '2b-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
# not make that particular mistake.
test_setup_2c () {
- test_create_repo 2c &&
+ git init 2c &&
(
cd 2c &&
@@ -437,7 +437,7 @@ test_expect_success '2c: Modify b & add c VS rename b->c' '
# Expected: bar/{bq_2, whatever}
test_setup_3a () {
- test_create_repo 3a_$1 &&
+ git init 3a_$1 &&
(
cd 3a_$1 &&
@@ -537,7 +537,7 @@ test_expect_success '3a-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
# Expected: bar/{bq_2, whatever}
test_setup_3b () {
- test_create_repo 3b_$1 &&
+ git init 3b_$1 &&
(
cd 3b_$1 &&
@@ -642,7 +642,7 @@ test_expect_success '3b-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
# Expected: b_2 for merge, b_4 in working copy
test_setup_4a () {
- test_create_repo 4a &&
+ git init 4a &&
(
cd 4a &&
@@ -714,7 +714,7 @@ test_expect_merge_algorithm failure success '4a: Change on A, change on B subset
# Expected: c_2
test_setup_4b () {
- test_create_repo 4b &&
+ git init 4b &&
(
cd 4b &&
diff --git a/t/t6427-diff3-conflict-markers.sh b/t/t6427-diff3-conflict-markers.sh
index a9ee4cb207a..dd5fe6a4021 100755
--- a/t/t6427-diff3-conflict-markers.sh
+++ b/t/t6427-diff3-conflict-markers.sh
@@ -19,7 +19,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
#
test_expect_success 'setup no merge base' '
- test_create_repo no_merge_base &&
+ git init no_merge_base &&
(
cd no_merge_base &&
@@ -55,7 +55,7 @@ test_expect_success 'check no merge base' '
#
test_expect_success 'setup unique merge base' '
- test_create_repo unique_merge_base &&
+ git init unique_merge_base &&
(
cd unique_merge_base &&
@@ -116,7 +116,7 @@ test_expect_success 'check unique merge base' '
#
test_expect_success 'setup multiple merge bases' '
- test_create_repo multiple_merge_bases &&
+ git init multiple_merge_bases &&
(
cd multiple_merge_bases &&
@@ -190,7 +190,7 @@ test_expect_success 'check multiple merge bases' '
'
test_expect_success 'rebase --merge describes parent of commit being picked' '
- test_create_repo rebase &&
+ git init rebase &&
(
cd rebase &&
test_commit base file &&
@@ -212,7 +212,7 @@ test_expect_success 'rebase --apply describes fake ancestor base' '
'
test_setup_zdiff3 () {
- test_create_repo zdiff3 &&
+ git init zdiff3 &&
(
cd zdiff3 &&
diff --git a/t/t6428-merge-conflicts-sparse.sh b/t/t6428-merge-conflicts-sparse.sh
index 064be1b629e..9919c3fa7cd 100755
--- a/t/t6428-merge-conflicts-sparse.sh
+++ b/t/t6428-merge-conflicts-sparse.sh
@@ -29,7 +29,7 @@ test_description="merge cases"
# Testcase basic, conflicting changes in 'numerals'
test_setup_numerals () {
- test_create_repo numerals_$1 &&
+ git init numerals_$1 &&
(
cd numerals_$1 &&
diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh
index 650b3cd14ff..d02fa16614e 100755
--- a/t/t6429-merge-sequence-rename-caching.sh
+++ b/t/t6429-merge-sequence-rename-caching.sh
@@ -35,7 +35,7 @@ test_description="remember regular & dir renames in sequence of merges"
# preventing us from finding new renames.
#
test_expect_success 'caching renames does not preclude finding new ones' '
- test_create_repo caching-renames-and-new-renames &&
+ git init caching-renames-and-new-renames &&
(
cd caching-renames-and-new-renames &&
@@ -106,7 +106,7 @@ test_expect_success 'caching renames does not preclude finding new ones' '
# should be able to only run rename detection on the upstream side one
# time.)
test_expect_success 'cherry-pick both a commit and its immediate revert' '
- test_create_repo pick-commit-and-its-immediate-revert &&
+ git init pick-commit-and-its-immediate-revert &&
(
cd pick-commit-and-its-immediate-revert &&
@@ -162,7 +162,7 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' '
# could cause a spurious rename/add conflict.
#
test_expect_success 'rename same file identically, then reintroduce it' '
- test_create_repo rename-rename-1to1-then-add-old-filename &&
+ git init rename-rename-1to1-then-add-old-filename &&
(
cd rename-rename-1to1-then-add-old-filename &&
@@ -229,7 +229,7 @@ test_expect_success 'rename same file identically, then reintroduce it' '
# cached, the directory rename could put newfile in the wrong directory.
#
test_expect_success 'rename same file identically, then add file to old dir' '
- test_create_repo rename-rename-1to1-then-add-file-to-old-dir &&
+ git init rename-rename-1to1-then-add-file-to-old-dir &&
(
cd rename-rename-1to1-then-add-file-to-old-dir &&
@@ -311,7 +311,7 @@ test_expect_success 'rename same file identically, then add file to old dir' '
# should avoid the need to re-detect upstream renames.)
#
test_expect_success 'cached dir rename does not prevent noticing later conflict' '
- test_create_repo dir-rename-cache-not-occluding-later-conflict &&
+ git init dir-rename-cache-not-occluding-later-conflict &&
(
cd dir-rename-cache-not-occluding-later-conflict &&
@@ -365,7 +365,7 @@ test_expect_success 'cached dir rename does not prevent noticing later conflict'
# Helper for the next two tests
test_setup_upstream_rename () {
- test_create_repo $1 &&
+ git init $1 &&
(
cd $1 &&
@@ -537,7 +537,7 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir
# Helper for the next two tests
test_setup_topic_rename () {
- test_create_repo $1 &&
+ git init $1 &&
(
cd $1 &&
diff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh
index d5f3e0fed65..c9a86f2e947 100755
--- a/t/t6437-submodule-merge.sh
+++ b/t/t6437-submodule-merge.sh
@@ -336,7 +336,7 @@ test_expect_success 'recursive merge with submodule' '
# Expected: path/ is submodule and file contents for B's path are somewhere
test_expect_success 'setup file/submodule conflict' '
- test_create_repo file-submodule &&
+ git init file-submodule &&
(
cd file-submodule &&
@@ -351,7 +351,7 @@ test_expect_success 'setup file/submodule conflict' '
git commit -m B &&
git checkout A &&
- test_create_repo path &&
+ git init path &&
test_commit -C path world &&
git submodule add ./path &&
git commit -m A
@@ -411,7 +411,7 @@ test_expect_success 'file/submodule conflict; merge --abort works afterward' '
# under the submodule to be treated as untracked or in the way.
test_expect_success 'setup directory/submodule conflict' '
- test_create_repo directory-submodule &&
+ git init directory-submodule &&
(
cd directory-submodule &&
@@ -434,7 +434,7 @@ test_expect_success 'setup directory/submodule conflict' '
git commit -m B2 &&
git checkout A &&
- test_create_repo path &&
+ git init path &&
test_commit -C path hello world &&
git submodule add ./path &&
git commit -m A
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index cd6c53360d2..d9acb639512 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -202,6 +202,102 @@ test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "e
grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out
'
+prepare_cruft_history () {
+ test_commit base &&
+
+ test_commit --no-tag foo &&
+ test_commit --no-tag bar &&
+ git reset HEAD^^
+}
+
+assert_cruft_packs () {
+ find .git/objects/pack -name "*.mtimes" >mtimes &&
+ sed -e 's/\.mtimes$/\.pack/g' mtimes >packs &&
+
+ test_file_not_empty packs &&
+ while read pack
+ do
+ test_path_is_file "$pack" || return 1
+ done <packs
+}
+
+assert_no_cruft_packs () {
+ find .git/objects/pack -name "*.mtimes" >mtimes &&
+ test_must_be_empty mtimes
+}
+
+test_expect_success 'gc --cruft generates a cruft pack' '
+ test_when_finished "rm -fr crufts" &&
+ git init crufts &&
+ (
+ cd crufts &&
+
+ prepare_cruft_history &&
+ git gc --cruft &&
+ assert_cruft_packs
+ )
+'
+
+test_expect_success 'gc.cruftPacks=true generates a cruft pack' '
+ test_when_finished "rm -fr crufts" &&
+ git init crufts &&
+ (
+ cd crufts &&
+
+ prepare_cruft_history &&
+ git -c gc.cruftPacks=true gc &&
+ assert_cruft_packs
+ )
+'
+
+test_expect_success 'feature.experimental=true generates a cruft pack' '
+ git init crufts &&
+ test_when_finished "rm -fr crufts" &&
+ (
+ cd crufts &&
+
+ prepare_cruft_history &&
+ git -c feature.experimental=true gc &&
+ assert_cruft_packs
+ )
+'
+
+test_expect_success 'feature.experimental=false allows explicit cruft packs' '
+ git init crufts &&
+ test_when_finished "rm -fr crufts" &&
+ (
+ cd crufts &&
+
+ prepare_cruft_history &&
+ git -c gc.cruftPacks=true -c feature.experimental=false gc &&
+ assert_cruft_packs
+ )
+'
+
+test_expect_success 'feature.experimental=true can be overridden' '
+ git init crufts &&
+ test_when_finished "rm -fr crufts" &&
+ (
+ cd crufts &&
+
+ prepare_cruft_history &&
+ git -c feature.expiremental=true -c gc.cruftPacks=false gc &&
+ assert_no_cruft_packs
+ )
+'
+
+test_expect_success 'feature.experimental=false avoids cruft packs by default' '
+ git init crufts &&
+ test_when_finished "rm -fr crufts" &&
+ (
+ cd crufts &&
+
+ prepare_cruft_history &&
+ git -c feature.experimental=false gc &&
+ assert_no_cruft_packs
+ )
+'
+
run_and_wait_for_auto_gc () {
# We read stdout from gc for the side effect of waiting until the
# background gc process exits, closing its fd 9. Furthermore, the
diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh
index a402908142d..d72cef88264 100755
--- a/t/t7001-mv.sh
+++ b/t/t7001-mv.sh
@@ -60,8 +60,8 @@ test_expect_success 'checking the commit' '
test_expect_success 'mv --dry-run does not move file' '
git mv -n path0/COPYING MOVED &&
- test -f path0/COPYING &&
- test ! -f MOVED
+ test_path_is_file path0/COPYING &&
+ test_path_is_missing MOVED
'
test_expect_success 'checking -k on non-existing file' '
@@ -71,25 +71,25 @@ test_expect_success 'checking -k on non-existing file' '
test_expect_success 'checking -k on untracked file' '
>untracked1 &&
git mv -k untracked1 path0 &&
- test -f untracked1 &&
- test ! -f path0/untracked1
+ test_path_is_file untracked1 &&
+ test_path_is_missing path0/untracked1
'
test_expect_success 'checking -k on multiple untracked files' '
>untracked2 &&
git mv -k untracked1 untracked2 path0 &&
- test -f untracked1 &&
- test -f untracked2 &&
- test ! -f path0/untracked1 &&
- test ! -f path0/untracked2
+ test_path_is_file untracked1 &&
+ test_path_is_file untracked2 &&
+ test_path_is_missing path0/untracked1 &&
+ test_path_is_missing path0/untracked2
'
test_expect_success 'checking -f on untracked file with existing target' '
>path0/untracked1 &&
test_must_fail git mv -f untracked1 path0 &&
- test ! -f .git/index.lock &&
- test -f untracked1 &&
- test -f path0/untracked1
+ test_path_is_missing .git/index.lock &&
+ test_path_is_file untracked1 &&
+ test_path_is_file path0/untracked1
'
# clean up the mess in case bad things happen
@@ -215,8 +215,8 @@ test_expect_success 'absolute pathname' '
git add sub/file &&
git mv sub "$(pwd)/in" &&
- ! test -d sub &&
- test -d in &&
+ test_path_is_missing sub &&
+ test_path_is_dir in &&
git ls-files --error-unmatch in/file
)
'
@@ -234,8 +234,8 @@ test_expect_success 'absolute pathname outside should fail' '
git add sub/file &&
test_must_fail git mv sub "$out/out" &&
- test -d sub &&
- ! test -d ../in &&
+ test_path_is_dir sub &&
+ test_path_is_missing ../in &&
git ls-files --error-unmatch sub/file
)
'
@@ -295,8 +295,8 @@ test_expect_success 'git mv should overwrite symlink to a file' '
git add moved &&
test_must_fail git mv moved symlink &&
git mv -f moved symlink &&
- ! test -e moved &&
- test -f symlink &&
+ test_path_is_missing moved &&
+ test_path_is_file symlink &&
test "$(cat symlink)" = 1 &&
git update-index --refresh &&
git diff-files --quiet
@@ -312,18 +312,19 @@ test_expect_success 'git mv should overwrite file with a symlink' '
git add moved &&
test_must_fail git mv symlink moved &&
git mv -f symlink moved &&
- ! test -e symlink &&
+ test_path_is_missing symlink &&
git update-index --refresh &&
git diff-files --quiet
'
test_expect_success SYMLINKS 'check moved symlink' '
- test -h moved
+ test_path_is_symlink moved
'
rm -f moved symlink
test_expect_success 'setup submodule' '
+ test_config_global protocol.file.allow always &&
git commit -m initial &&
git reset --hard &&
git submodule add ./. sub &&
@@ -351,7 +352,7 @@ test_expect_success 'git mv moves a submodule with a .git directory and no .gitm
) &&
mkdir mod &&
git mv sub mod/sub &&
- ! test -e sub &&
+ test_path_is_missing sub &&
test "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" &&
git -C mod/sub status &&
git update-index --refresh &&
@@ -371,7 +372,7 @@ test_expect_success 'git mv moves a submodule with a .git directory and .gitmodu
) &&
mkdir mod &&
git mv sub mod/sub &&
- ! test -e sub &&
+ test_path_is_missing sub &&
test "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" &&
git -C mod/sub status &&
echo mod/sub >expected &&
@@ -388,7 +389,7 @@ test_expect_success 'git mv moves a submodule with gitfile' '
entry="$(git ls-files --stage sub | cut -f 1)" &&
mkdir mod &&
git -C mod mv ../sub/ . &&
- ! test -e sub &&
+ test_path_is_missing sub &&
test "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" &&
git -C mod/sub status &&
echo mod/sub >expected &&
@@ -407,7 +408,7 @@ test_expect_success 'mv does not complain when no .gitmodules file is found' '
mkdir mod &&
git mv sub mod/sub 2>actual.err &&
test_must_be_empty actual.err &&
- ! test -e sub &&
+ test_path_is_missing sub &&
test "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" &&
git -C mod/sub status &&
git update-index --refresh &&
@@ -422,13 +423,13 @@ test_expect_success 'mv will error out on a modified .gitmodules file unless sta
entry="$(git ls-files --stage sub | cut -f 1)" &&
mkdir mod &&
test_must_fail git mv sub mod/sub 2>actual.err &&
- test -s actual.err &&
- test -e sub &&
+ test_file_not_empty actual.err &&
+ test_path_exists sub &&
git diff-files --quiet -- sub &&
git add .gitmodules &&
git mv sub mod/sub 2>actual.err &&
test_must_be_empty actual.err &&
- ! test -e sub &&
+ test_path_is_missing sub &&
test "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" &&
git -C mod/sub status &&
git update-index --refresh &&
@@ -446,7 +447,7 @@ test_expect_success 'mv issues a warning when section is not found in .gitmodule
mkdir mod &&
git mv sub mod/sub 2>actual.err &&
test_cmp expect.err actual.err &&
- ! test -e sub &&
+ test_path_is_missing sub &&
test "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" &&
git -C mod/sub status &&
git update-index --refresh &&
@@ -459,7 +460,7 @@ test_expect_success 'mv --dry-run does not touch the submodule or .gitmodules' '
git submodule update &&
mkdir mod &&
git mv -n sub mod/sub 2>actual.err &&
- test -f sub/.git &&
+ test_path_is_file sub/.git &&
git diff-index --exit-code HEAD &&
git update-index --refresh &&
git diff-files --quiet -- sub .gitmodules
@@ -473,10 +474,10 @@ test_expect_success 'checking out a commit before submodule moved needs manual u
git status -s sub2 >actual &&
echo "?? sub2/" >expected &&
test_cmp expected actual &&
- ! test -f sub/.git &&
- test -f sub2/.git &&
+ test_path_is_missing sub/.git &&
+ test_path_is_file sub2/.git &&
git submodule update &&
- test -f sub/.git &&
+ test_path_is_file sub/.git &&
rm -rf sub2 &&
git diff-index --exit-code HEAD &&
git update-index --refresh &&
@@ -509,6 +510,7 @@ test_expect_success 'moving a submodule in nested directories' '
'
test_expect_success 'moving nested submodules' '
+ test_config_global protocol.file.allow always &&
git commit -am "cleanup commit" &&
mkdir sub_nested_nested &&
(
diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh
index 71fe29690fd..26582ae4e5f 100755
--- a/t/t7002-mv-sparse-checkout.sh
+++ b/t/t7002-mv-sparse-checkout.sh
@@ -28,12 +28,25 @@ test_expect_success 'setup' "
updated in the index:
EOF
- cat >sparse_hint <<-EOF
+ cat >sparse_hint <<-EOF &&
hint: If you intend to update such entries, try one of the following:
hint: * Use the --sparse option.
hint: * Disable or modify the sparsity rules.
hint: Disable this message with \"git config advice.updateSparsePath false\"
EOF
+
+ cat >dirty_error_header <<-EOF &&
+ The following paths have been moved outside the
+ sparse-checkout definition but are not sparse due to local
+ modifications.
+ EOF
+
+ cat >dirty_hint <<-EOF
+ hint: To correct the sparsity of these paths, do the following:
+ hint: * Use \"git add --sparse <paths>\" to update the index
+ hint: * Use \"git sparse-checkout reapply\" to apply the sparsity rules
+ hint: Disable this message with \"git config advice.updateSparsePath false\"
+ EOF
"
test_expect_success 'mv refuses to move sparse-to-sparse' '
@@ -290,4 +303,215 @@ test_expect_success 'move sparse file to existing destination with --force and -
test_cmp expect sub/file1
'
+test_expect_success 'move clean path from in-cone to out-of-cone' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ setup_sparse_checkout &&
+
+ test_must_fail git mv sub/d folder1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/d" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse sub/d folder1 2>stderr &&
+ test_must_be_empty stderr &&
+
+ test_path_is_missing sub/d &&
+ test_path_is_missing folder1/d &&
+ git ls-files -t >actual &&
+ ! grep "^H sub/d\$" actual &&
+ grep "S folder1/d" actual
+'
+
+test_expect_success 'move clean path from in-cone to out-of-cone overwrite' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ setup_sparse_checkout &&
+ echo "sub/file1 overwrite" >sub/file1 &&
+ git add sub/file1 &&
+
+ test_must_fail git mv sub/file1 folder1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/file1" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ test_must_fail git mv --sparse sub/file1 folder1 2>stderr &&
+ echo "fatal: destination exists in the index, source=sub/file1, destination=folder1/file1" \
+ >expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse -f sub/file1 folder1 2>stderr &&
+ test_must_be_empty stderr &&
+
+ test_path_is_missing sub/file1 &&
+ test_path_is_missing folder1/file1 &&
+ git ls-files -t >actual &&
+ ! grep "H sub/file1" actual &&
+ grep "S folder1/file1" actual &&
+
+ # compare file content before move and after move
+ echo "sub/file1 overwrite" >expect &&
+ git ls-files -s -- folder1/file1 | awk "{print \$2}" >oid &&
+ git cat-file blob $(cat oid) >actual &&
+ test_cmp expect actual
+'
+
+# This test is testing the same behavior as the
+# "move clean path from in-cone to out-of-cone overwrite" above.
+# The only difference is the <destination> changes from "folder1" to "folder1/file1"
+test_expect_success 'move clean path from in-cone to out-of-cone file overwrite' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ setup_sparse_checkout &&
+ echo "sub/file1 overwrite" >sub/file1 &&
+ git add sub/file1 &&
+
+ test_must_fail git mv sub/file1 folder1/file1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/file1" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ test_must_fail git mv --sparse sub/file1 folder1/file1 2>stderr &&
+ echo "fatal: destination exists in the index, source=sub/file1, destination=folder1/file1" \
+ >expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse -f sub/file1 folder1/file1 2>stderr &&
+ test_must_be_empty stderr &&
+
+ test_path_is_missing sub/file1 &&
+ test_path_is_missing folder1/file1 &&
+ git ls-files -t >actual &&
+ ! grep "H sub/file1" actual &&
+ grep "S folder1/file1" actual &&
+
+ # compare file content before move and after move
+ echo "sub/file1 overwrite" >expect &&
+ git ls-files -s -- folder1/file1 | awk "{print \$2}" >oid &&
+ git cat-file blob $(cat oid) >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'move directory with one of the files overwrite' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ mkdir -p folder1/dir &&
+ touch folder1/dir/file1 &&
+ git add folder1 &&
+ git sparse-checkout set --cone sub &&
+
+ echo test >sub/dir/file1 &&
+ git add sub/dir/file1 &&
+
+ test_must_fail git mv sub/dir folder1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/dir/e" >>expect &&
+ echo "folder1/dir/file1" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ test_must_fail git mv --sparse sub/dir folder1 2>stderr &&
+ echo "fatal: destination exists in the index, source=sub/dir/file1, destination=folder1/dir/file1" \
+ >expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse -f sub/dir folder1 2>stderr &&
+ test_must_be_empty stderr &&
+
+ test_path_is_missing sub/dir/file1 &&
+ test_path_is_missing sub/dir/e &&
+ test_path_is_missing folder1/file1 &&
+ git ls-files -t >actual &&
+ ! grep "H sub/dir/file1" actual &&
+ ! grep "H sub/dir/e" actual &&
+ grep "S folder1/dir/file1" actual &&
+
+ # compare file content before move and after move
+ echo test >expect &&
+ git ls-files -s -- folder1/dir/file1 | awk "{print \$2}" >oid &&
+ git cat-file blob $(cat oid) >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'move dirty path from in-cone to out-of-cone' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ setup_sparse_checkout &&
+ echo "modified" >>sub/d &&
+
+ test_must_fail git mv sub/d folder1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/d" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse sub/d folder1 2>stderr &&
+ cat dirty_error_header >expect &&
+ echo "folder1/d" >>expect &&
+ cat dirty_hint >>expect &&
+ test_cmp expect stderr &&
+
+ test_path_is_missing sub/d &&
+ test_path_is_file folder1/d &&
+ git ls-files -t >actual &&
+ ! grep "^H sub/d\$" actual &&
+ grep "H folder1/d" actual
+'
+
+test_expect_success 'move dir from in-cone to out-of-cone' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ setup_sparse_checkout &&
+ mkdir sub/dir/deep &&
+
+ test_must_fail git mv sub/dir folder1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/dir/e" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse sub/dir folder1 2>stderr &&
+ test_must_be_empty stderr &&
+
+ test_path_is_missing sub/dir &&
+ test_path_is_missing folder1 &&
+ git ls-files -t >actual &&
+ ! grep "H sub/dir/e" actual &&
+ grep "S folder1/dir/e" actual
+'
+
+test_expect_success 'move partially-dirty dir from in-cone to out-of-cone' '
+ test_when_finished "cleanup_sparse_checkout" &&
+ setup_sparse_checkout &&
+ mkdir sub/dir/deep &&
+ touch sub/dir/e2 sub/dir/e3 &&
+ git add sub/dir/e2 sub/dir/e3 &&
+ echo "modified" >>sub/dir/e2 &&
+ echo "modified" >>sub/dir/e3 &&
+
+ test_must_fail git mv sub/dir folder1 2>stderr &&
+ cat sparse_error_header >expect &&
+ echo "folder1/dir/e" >>expect &&
+ echo "folder1/dir/e2" >>expect &&
+ echo "folder1/dir/e3" >>expect &&
+ cat sparse_hint >>expect &&
+ test_cmp expect stderr &&
+
+ git mv --sparse sub/dir folder1 2>stderr &&
+ cat dirty_error_header >expect &&
+ echo "folder1/dir/e2" >>expect &&
+ echo "folder1/dir/e3" >>expect &&
+ cat dirty_hint >>expect &&
+ test_cmp expect stderr &&
+
+ test_path_is_missing sub/dir &&
+ test_path_is_missing folder1/dir/e &&
+ test_path_is_file folder1/dir/e2 &&
+ test_path_is_file folder1/dir/e3 &&
+ git ls-files -t >actual &&
+ ! grep "H sub/dir/e" actual &&
+ ! grep "H sub/dir/e2" actual &&
+ ! grep "H sub/dir/e3" actual &&
+ grep "S folder1/dir/e" actual &&
+ grep "H folder1/dir/e2" actual &&
+ grep "H folder1/dir/e3" actual
+'
+
test_done
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index e18a2189523..f6aebe92ff9 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -49,7 +49,7 @@ test_expect_success 'result is really identical' '
test_expect_success 'rewrite bare repository identically' '
(git config core.bare true && cd .git &&
git filter-branch branch > filter-output 2>&1 &&
- ! fgrep fatal filter-output)
+ ! grep fatal filter-output)
'
git config core.bare false
test_expect_success 'result is really identical' '
@@ -506,7 +506,7 @@ test_expect_success 'rewrite repository including refs that point at non-commit
git tag -a -m "tag to a tree" treetag $new_tree &&
git reset --hard HEAD &&
git filter-branch -f -- --all >filter-output 2>&1 &&
- ! fgrep fatal filter-output
+ ! grep fatal filter-output
'
test_expect_success 'filter-branch handles ref deletion' '
diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh
index 20a0d2afc2a..11884d2fc36 100755
--- a/t/t7064-wtstatus-pv2.sh
+++ b/t/t7064-wtstatus-pv2.sh
@@ -473,6 +473,7 @@ test_expect_success 'create and add submodule, submodule appears clean (A. S...)
git checkout initial-branch &&
git clone . sub_repo &&
git clone . super_repo &&
+ test_config_global protocol.file.allow always &&
( cd super_repo &&
git submodule add ../sub_repo sub1 &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 0399701e627..c975eb54d23 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -480,6 +480,7 @@ test_expect_success 'should not clean submodules' '
git init &&
test_commit msg hello.world
) &&
+ test_config_global protocol.file.allow always &&
git submodule add ./repo/.git sub1 &&
git commit -m "sub1" &&
git branch before_sub2 &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index e7cec2e457a..eae6a46ef3d 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -14,6 +14,36 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
+test_expect_success 'setup - enable local submodules' '
+ git config --global protocol.file.allow always
+'
+
+test_expect_success 'submodule usage: -h' '
+ git submodule -h >out 2>err &&
+ grep "^usage: git submodule" out &&
+ test_must_be_empty err
+'
+
+test_expect_success 'submodule usage: --recursive' '
+ test_expect_code 1 git submodule --recursive >out 2>err &&
+ grep "^usage: git submodule" err &&
+ test_must_be_empty out
+'
+
+test_expect_success 'submodule usage: status --' '
+ test_expect_code 1 git submodule -- &&
+ test_expect_code 1 git submodule --end-of-options
+'
+
+for opt in '--quiet' '--cached'
+do
+ test_expect_success "submodule usage: status $opt" '
+ git submodule $opt &&
+ git submodule status $opt &&
+ git submodule $opt status
+ '
+done
+
test_expect_success 'submodule deinit works on empty repository' '
git submodule deinit --all
'
@@ -152,6 +182,11 @@ test_expect_success 'submodule add' '
test_must_be_empty untracked
'
+test_expect_success !WINDOWS 'submodule add (absolute path)' '
+ test_when_finished "git reset --hard" &&
+ git submodule add "$submodurl" "$submodurl/add-abs"
+'
+
test_expect_success 'setup parent and one repository' '
test_create_repo parent &&
test_commit -C parent one
@@ -544,6 +579,16 @@ test_expect_success 'status should be "modified" after submodule commit' '
grep "^+$rev2" list
'
+test_expect_success '"submodule --cached" command forms should be identical' '
+ git submodule status --cached >expect &&
+
+ git submodule --cached >actual &&
+ test_cmp expect actual &&
+
+ git submodule --cached status >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'the --cached sha1 should be rev1' '
git submodule --cached status >list &&
grep "^+$rev1" list
@@ -1224,31 +1269,6 @@ test_expect_success 'submodule add clone shallow submodule' '
)
'
-test_expect_success 'submodule helper list is not confused by common prefixes' '
- mkdir -p dir1/b &&
- (
- cd dir1/b &&
- git init &&
- echo hi >testfile2 &&
- git add . &&
- git commit -m "test1"
- ) &&
- mkdir -p dir2/b &&
- (
- cd dir2/b &&
- git init &&
- echo hello >testfile1 &&
- git add . &&
- git commit -m "test2"
- ) &&
- git submodule add /dir1/b dir1/b &&
- git submodule add /dir2/b dir2/b &&
- git commit -m "first submodule commit" &&
- git submodule--helper list dir1/b | cut -f 2 >actual &&
- echo "dir1/b" >expect &&
- test_cmp expect actual
-'
-
test_expect_success 'setup superproject with submodules' '
git init sub1 &&
test_commit -C sub1 test &&
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index 9c3cc4cf404..542b3331a78 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -17,6 +17,7 @@ This test script tries to verify the sanity of summary subcommand of git submodu
# various reasons, one of them being that there are lots of commands taking place
# outside of 'test_expect_success' block, which is no longer in good-style.
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
add_file () {
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index 7d2ac3322b5..ea92ef52a5e 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -14,6 +14,8 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
test_expect_success setup '
+ git config --global protocol.file.allow always &&
+
echo file >file &&
git add file &&
test_tick &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 6cc07460dd2..f094e3d7f36 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -25,6 +25,7 @@ compare_head()
test_expect_success 'setup a submodule tree' '
+ git config --global protocol.file.allow always &&
echo file > file &&
git add file &&
test_tick &&
@@ -769,7 +770,7 @@ test_expect_success 'submodule update continues after recursive checkout error'
echo "" > file
)
) &&
- test_must_fail git submodule update --recursive &&
+ test_expect_code 1 git submodule update --recursive &&
(cd submodule2 &&
git rev-parse --verify HEAD >../actual
) &&
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index e2f110b7863..8d7b234beb8 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -16,6 +16,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
test_expect_success 'setup a submodule tree' '
+ git config --global protocol.file.allow always &&
echo file > file &&
git add file &&
test_tick &&
@@ -153,6 +154,11 @@ test_expect_success 'use "submodule foreach" to checkout 2nd level submodule' '
)
'
+test_expect_success 'usage: foreach -- --not-an-option' '
+ test_expect_code 1 git submodule foreach -- --not-an-option &&
+ test_expect_code 1 git -C clone2 submodule foreach -- --not-an-option
+'
+
test_expect_success 'use "foreach --recursive" to checkout all submodules' '
(
cd clone2 &&
diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh
index c3a45455106..d6040e0a337 100755
--- a/t/t7408-submodule-reference.sh
+++ b/t/t7408-submodule-reference.sh
@@ -17,6 +17,10 @@ test_alternate_is_used () {
test_cmp expect actual
}
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'preparing first repository' '
test_create_repo A &&
(
diff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh
index e17ac81a893..374ed481e9c 100755
--- a/t/t7409-submodule-detached-work-tree.sh
+++ b/t/t7409-submodule-detached-work-tree.sh
@@ -15,6 +15,10 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'submodule on detached working tree' '
git init --bare remote &&
test_create_repo bundle1 &&
diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
index ad28e938805..c0167944abd 100755
--- a/t/t7411-submodule-config.sh
+++ b/t/t7411-submodule-config.sh
@@ -12,6 +12,9 @@ from the database and from the worktree works.
TEST_NO_CREATE_REPO=1
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
test_expect_success 'submodule config cache setup' '
mkdir submodule &&
(cd submodule &&
@@ -134,44 +137,44 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
)
'
-test_expect_success 'reading submodules config from the working tree with "submodule--helper config"' '
+test_expect_success 'reading submodules config from the working tree' '
(cd super &&
echo "../submodule" >expect &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
-test_expect_success 'unsetting submodules config from the working tree with "submodule--helper config --unset"' '
+test_expect_success 'unsetting submodules config from the working tree' '
(cd super &&
- git submodule--helper config --unset submodule.submodule.url &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-unset submodule.submodule.url &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_must_be_empty actual
)
'
-test_expect_success 'writing submodules config with "submodule--helper config"' '
+test_expect_success 'writing submodules config' '
(cd super &&
echo "new_url" >expect &&
- git submodule--helper config submodule.submodule.url "new_url" &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-set submodule.submodule.url "new_url" &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
-test_expect_success 'overwriting unstaged submodules config with "submodule--helper config"' '
+test_expect_success 'overwriting unstaged submodules config' '
test_when_finished "git -C super checkout .gitmodules" &&
(cd super &&
echo "newer_url" >expect &&
- git submodule--helper config submodule.submodule.url "newer_url" &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-set submodule.submodule.url "newer_url" &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
test_expect_success 'writeable .gitmodules when it is in the working tree' '
- git -C super submodule--helper config --check-writeable
+ test-tool -C super submodule config-writeable
'
test_expect_success 'writeable .gitmodules when it is nowhere in the repository' '
@@ -180,7 +183,7 @@ test_expect_success 'writeable .gitmodules when it is nowhere in the repository'
(cd super &&
git rm .gitmodules &&
git commit -m "remove .gitmodules from the current branch" &&
- git submodule--helper config --check-writeable
+ test-tool submodule config-writeable
)
'
@@ -188,7 +191,7 @@ test_expect_success 'non-writeable .gitmodules when it is in the index but not i
test_when_finished "git -C super checkout .gitmodules" &&
(cd super &&
rm -f .gitmodules &&
- test_must_fail git submodule--helper config --check-writeable
+ test_must_fail test-tool submodule config-writeable
)
'
@@ -197,7 +200,7 @@ test_expect_success 'non-writeable .gitmodules when it is in the current branch
test_when_finished "git -C super reset --hard $ORIG" &&
(cd super &&
git rm .gitmodules &&
- test_must_fail git submodule--helper config --check-writeable
+ test_must_fail test-tool submodule config-writeable
)
'
@@ -205,11 +208,11 @@ test_expect_success 'reading submodules config from the index when .gitmodules i
ORIG=$(git -C super rev-parse HEAD) &&
test_when_finished "git -C super reset --hard $ORIG" &&
(cd super &&
- git submodule--helper config submodule.submodule.url "staged_url" &&
+ test-tool submodule config-set submodule.submodule.url "staged_url" &&
git add .gitmodules &&
rm -f .gitmodules &&
echo "staged_url" >expect &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
@@ -220,7 +223,7 @@ test_expect_success 'reading submodules config from the current branch when .git
(cd super &&
git rm .gitmodules &&
echo "../submodule" >expect &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index 1cfa150768d..2859695c6d2 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -6,6 +6,7 @@ This test verifies that `git submodue absorbgitdirs` moves a submodules git
directory into the superproject.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup a real submodule' '
diff --git a/t/t7413-submodule-is-active.sh b/t/t7413-submodule-is-active.sh
index c8e7e983317..7cdc2637649 100755
--- a/t/t7413-submodule-is-active.sh
+++ b/t/t7413-submodule-is-active.sh
@@ -1,14 +1,19 @@
#!/bin/sh
-test_description='Test submodule--helper is-active
+test_description='Test with test-tool submodule is-active
-This test verifies that `git submodue--helper is-active` correctly identifies
+This test verifies that `test-tool submodule is-active` correctly identifies
submodules which are "active" and interesting to the user.
+
+This is a unit test of the submodule.c is_submodule_active() function,
+which is also indirectly tested elsewhere.
'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '
+ git config --global protocol.file.allow always &&
git init sub &&
test_commit -C sub initial &&
git init super &&
@@ -25,13 +30,13 @@ test_expect_success 'setup' '
'
test_expect_success 'is-active works with urls' '
- git -C super submodule--helper is-active sub1 &&
- git -C super submodule--helper is-active sub2 &&
+ test-tool -C super submodule is-active sub1 &&
+ test-tool -C super submodule is-active sub2 &&
git -C super config --unset submodule.sub1.URL &&
- test_must_fail git -C super submodule--helper is-active sub1 &&
+ test_must_fail test-tool -C super submodule is-active sub1 &&
git -C super config submodule.sub1.URL ../sub &&
- git -C super submodule--helper is-active sub1
+ test-tool -C super submodule is-active sub1
'
test_expect_success 'is-active works with submodule.<name>.active config' '
@@ -39,11 +44,11 @@ test_expect_success 'is-active works with submodule.<name>.active config' '
test_when_finished "git -C super config submodule.sub1.URL ../sub" &&
git -C super config --bool submodule.sub1.active "false" &&
- test_must_fail git -C super submodule--helper is-active sub1 &&
+ test_must_fail test-tool -C super submodule is-active sub1 &&
git -C super config --bool submodule.sub1.active "true" &&
git -C super config --unset submodule.sub1.URL &&
- git -C super submodule--helper is-active sub1
+ test-tool -C super submodule is-active sub1
'
test_expect_success 'is-active works with basic submodule.active config' '
@@ -53,17 +58,17 @@ test_expect_success 'is-active works with basic submodule.active config' '
git -C super config --add submodule.active "." &&
git -C super config --unset submodule.sub1.URL &&
- git -C super submodule--helper is-active sub1 &&
- git -C super submodule--helper is-active sub2
+ test-tool -C super submodule is-active sub1 &&
+ test-tool -C super submodule is-active sub2
'
test_expect_success 'is-active correctly works with paths that are not submodules' '
test_when_finished "git -C super config --unset-all submodule.active" &&
- test_must_fail git -C super submodule--helper is-active not-a-submodule &&
+ test_must_fail test-tool -C super submodule is-active not-a-submodule &&
git -C super config --add submodule.active "." &&
- test_must_fail git -C super submodule--helper is-active not-a-submodule
+ test_must_fail test-tool -C super submodule is-active not-a-submodule
'
test_expect_success 'is-active works with exclusions in submodule.active config' '
@@ -72,8 +77,8 @@ test_expect_success 'is-active works with exclusions in submodule.active config'
git -C super config --add submodule.active "." &&
git -C super config --add submodule.active ":(exclude)sub1" &&
- test_must_fail git -C super submodule--helper is-active sub1 &&
- git -C super submodule--helper is-active sub2
+ test_must_fail test-tool -C super submodule is-active sub1 &&
+ test-tool -C super submodule is-active sub2
'
test_expect_success 'is-active with submodule.active and submodule.<name>.active' '
@@ -85,8 +90,8 @@ test_expect_success 'is-active with submodule.active and submodule.<name>.active
git -C super config --bool submodule.sub1.active "false" &&
git -C super config --bool submodule.sub2.active "true" &&
- test_must_fail git -C super submodule--helper is-active sub1 &&
- git -C super submodule--helper is-active sub2
+ test_must_fail test-tool -C super submodule is-active sub1 &&
+ test-tool -C super submodule is-active sub2
'
test_expect_success 'is-active, submodule.active and submodule add' '
diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
index f2e7df59cf2..101afff30f6 100755
--- a/t/t7414-submodule-mistakes.sh
+++ b/t/t7414-submodule-mistakes.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='handling of common mistakes people may make with submodules'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'create embedded repository' '
@@ -30,7 +32,8 @@ test_expect_success 'no warning when updating entry' '
test_expect_success 'submodule add does not warn' '
test_when_finished "git rm -rf submodule .gitmodules" &&
- git submodule add ./embed submodule 2>stderr &&
+ git -c protocol.file.allow=always \
+ submodule add ./embed submodule 2>stderr &&
test_i18ngrep ! warning stderr
'
diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh
index d21dc8b009f..3ebd9859814 100755
--- a/t/t7416-submodule-dash-url.sh
+++ b/t/t7416-submodule-dash-url.sh
@@ -3,6 +3,10 @@
test_description='check handling of disallowed .gitmodule urls'
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'create submodule with protected dash in url' '
git init upstream &&
git -C upstream commit --allow-empty -m base &&
diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh
index f0f6b9fa9e9..2f4b25dfd7e 100755
--- a/t/t7417-submodule-path-url.sh
+++ b/t/t7417-submodule-path-url.sh
@@ -6,6 +6,10 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'create submodule with dash in path' '
git init upstream &&
git -C upstream commit --allow-empty -m base &&
diff --git a/t/t7418-submodule-sparse-gitmodules.sh b/t/t7418-submodule-sparse-gitmodules.sh
index 57d7ab3eced..dde11ecce80 100755
--- a/t/t7418-submodule-sparse-gitmodules.sh
+++ b/t/t7418-submodule-sparse-gitmodules.sh
@@ -17,6 +17,10 @@ export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'sparse checkout setup which hides .gitmodules' '
git init upstream &&
git init submodule &&
@@ -46,12 +50,12 @@ test_expect_success 'sparse checkout setup which hides .gitmodules' '
test_expect_success 'reading gitmodules config file when it is not checked out' '
echo "../submodule" >expect &&
- git -C super submodule--helper config submodule.submodule.url >actual &&
+ test-tool -C super submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
'
test_expect_success 'not writing gitmodules config file when it is not checked out' '
- test_must_fail git -C super submodule--helper config submodule.submodule.url newurl &&
+ test_must_fail test-tool -C super submodule config-set submodule.submodule.url newurl &&
test_path_is_missing super/.gitmodules
'
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
index 3b925c302fc..232065504cb 100755
--- a/t/t7419-submodule-set-branch.sh
+++ b/t/t7419-submodule-set-branch.sh
@@ -9,9 +9,14 @@ This test verifies that the set-branch subcommand of git-submodule is working
as expected.
'
+TEST_PASSES_SANITIZE_LEAK=true
TEST_NO_CREATE_REPO=1
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'submodule config cache setup' '
mkdir submodule &&
(cd submodule &&
diff --git a/t/t7420-submodule-set-url.sh b/t/t7420-submodule-set-url.sh
index ef0cb6e8e18..d6bf62b3ac6 100755
--- a/t/t7420-submodule-set-url.sh
+++ b/t/t7420-submodule-set-url.sh
@@ -12,6 +12,10 @@ as expected.
TEST_NO_CREATE_REPO=1
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'submodule config cache setup' '
mkdir submodule &&
(
diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh
index b070f13714a..ce64d8b1372 100755
--- a/t/t7421-submodule-summary-add.sh
+++ b/t/t7421-submodule-summary-add.sh
@@ -12,6 +12,10 @@ while making sure to add submodules using `git submodule add` instead of
. ./test-lib.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'summary test environment setup' '
git init sm &&
test_commit -C sm "add file" file file-content file-tag &&
diff --git a/t/t7422-submodule-output.sh b/t/t7422-submodule-output.sh
new file mode 100755
index 00000000000..ab946ec9405
--- /dev/null
+++ b/t/t7422-submodule-output.sh
@@ -0,0 +1,170 @@
+#!/bin/sh
+
+test_description='submodule --cached, --quiet etc. output'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-t3100.sh
+
+setup_sub () {
+ local d="$1" &&
+ shift &&
+ git $@ clone . "$d" &&
+ git $@ submodule add ./"$d"
+}
+
+normalize_status () {
+ sed -e 's/-g[0-9a-f]*/-gHASH/'
+}
+
+test_expect_success 'setup' '
+ test_commit A &&
+ test_commit B &&
+ setup_sub S &&
+ setup_sub S.D &&
+ setup_sub S.C &&
+ setup_sub S.C.D &&
+ setup_sub X &&
+ git add S* &&
+ test_commit C &&
+
+ # recursive in X/
+ git -C X pull &&
+ GIT_ALLOW_PROTOCOL=file git -C X submodule update --init &&
+
+ # dirty
+ for d in S.D X/S.D
+ do
+ echo dirty >"$d"/A.t || return 1
+ done &&
+
+ # commit (for --cached)
+ for d in S.C* X/S.C*
+ do
+ git -C "$d" reset --hard A || return 1
+ done &&
+
+ # dirty
+ for d in S*.D X/S*.D
+ do
+ echo dirty >"$d/C2.t" || return 1
+ done &&
+
+ for ref in A B C
+ do
+ # Not different with SHA-1 and SHA-256, just (ab)using
+ # test_oid_cache as a variable bag to avoid using
+ # $(git rev-parse ...).
+ oid=$(git rev-parse $ref) &&
+ test_oid_cache <<-EOF || return 1
+ $ref sha1:$oid
+ $ref sha256:$oid
+ EOF
+ done
+'
+
+for opts in "" "status"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid A) S.C (A)
+ >+$(test_oid A) S.C.D (A)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid C) X (C)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+for opts in \
+ "status --recursive"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid A) S.C (A)
+ >+$(test_oid A) S.C.D (A)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid C) X (C)
+ > $(test_oid B) X/S (B)
+ >+$(test_oid A) X/S.C (A)
+ >+$(test_oid A) X/S.C.D (A)
+ > $(test_oid B) X/S.D (B)
+ > $(test_oid B) X/X (B)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+for opts in \
+ "--quiet" \
+ "--quiet status" \
+ "status --quiet"
+do
+ test_expect_success "git submodule $opts" '
+ git submodule $opts >out &&
+ test_must_be_empty out
+ '
+done
+
+for opts in \
+ "--cached" \
+ "--cached status" \
+ "status --cached"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid B) S.C (B)
+ >+$(test_oid B) S.C.D (B)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid B) X (B)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+for opts in \
+ "--cached --quiet" \
+ "--cached --quiet status" \
+ "--cached status --quiet" \
+ "--quiet status --cached" \
+ "status --cached --quiet"
+do
+ test_expect_success "git submodule $opts" '
+ git submodule $opts >out &&
+ test_must_be_empty out
+ '
+done
+
+for opts in \
+ "status --cached --recursive" \
+ "--cached status --recursive"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid B) S.C (B)
+ >+$(test_oid B) S.C.D (B)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid B) X (B)
+ > $(test_oid B) X/S (B)
+ >+$(test_oid B) X/S.C (B)
+ >+$(test_oid B) X/S.C.D (B)
+ > $(test_oid B) X/S.D (B)
+ > $(test_oid B) X/X (B)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+test_done
diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh
index 41706c1c9ff..ba1f569bcbb 100755
--- a/t/t7450-bad-git-dotfiles.sh
+++ b/t/t7450-bad-git-dotfiles.sh
@@ -15,13 +15,17 @@ Such as:
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-pack.sh
+test_expect_success 'setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'check names' '
cat >expect <<-\EOF &&
valid
valid/with/paths
EOF
- git submodule--helper check-name >actual <<-\EOF &&
+ test-tool submodule check-name >actual <<-\EOF &&
valid
valid/with/paths
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
index 3fcb44767f5..d050091345b 100755
--- a/t/t7506-status-submodule.sh
+++ b/t/t7506-status-submodule.sh
@@ -2,6 +2,7 @@
test_description='git status for submodule'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_create_repo_with_commit () {
@@ -251,6 +252,7 @@ test_expect_success 'status with merge conflict in .gitmodules' '
test_create_repo_with_commit sub1 &&
test_tick &&
test_create_repo_with_commit sub2 &&
+ test_config_global protocol.file.allow always &&
(
cd super &&
prev=$(git rev-parse HEAD) &&
@@ -326,6 +328,7 @@ test_expect_success 'diff --submodule with merge conflict in .gitmodules' '
# sub2 will have an untracked file
# sub3 will have an untracked repository
test_expect_success 'setup superproject with untracked file in nested submodule' '
+ test_config_global protocol.file.allow always &&
(
cd super &&
git clean -dfx &&
diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh
index ed2653d46fe..916470c48bd 100755
--- a/t/t7507-commit-verbose.sh
+++ b/t/t7507-commit-verbose.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='verbose commit template'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
write_script "check-for-diff" <<\EOF &&
@@ -74,6 +76,7 @@ test_expect_success 'diff in message is retained with -v' '
test_expect_success 'submodule log is stripped out too with -v' '
git config diff.submodule log &&
+ test_config_global protocol.file.allow always &&
git submodule add ./. sub &&
git commit -m "sub added" &&
(
diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh
index 56c0dfffea6..4abc74db2bb 100755
--- a/t/t7527-builtin-fsmonitor.sh
+++ b/t/t7527-builtin-fsmonitor.sh
@@ -813,6 +813,10 @@ my_match_and_clean () {
git -C super/dir_1/dir_2/sub clean -d -f
}
+test_expect_success 'submodule setup' '
+ git config --global protocol.file.allow always
+'
+
test_expect_success 'submodule always visited' '
test_when_finished "git -C super fsmonitor--daemon stop; \
rm -rf super; \
@@ -939,9 +943,9 @@ test_expect_success CASE_INSENSITIVE_FS 'case insensitive+preserving' '
# directories and files that we touched. We may or may not get a
# trailing slash on modified directories.
#
- egrep "^event: abc/?$" ./insensitive.trace &&
- egrep "^event: abc/def/?$" ./insensitive.trace &&
- egrep "^event: abc/def/xyz$" ./insensitive.trace
+ grep -E "^event: abc/?$" ./insensitive.trace &&
+ grep -E "^event: abc/def/?$" ./insensitive.trace &&
+ grep -E "^event: abc/def/xyz$" ./insensitive.trace
'
# The variable "unicode_debug" is defined in the following library
@@ -983,20 +987,20 @@ test_expect_success !UNICODE_COMPOSITION_SENSITIVE 'Unicode nfc/nfd' '
then
# We should have seen NFC event from OS.
# We should not have synthesized an NFD event.
- egrep "^event: nfc/c_${utf8_nfc}/?$" ./unicode.trace &&
- egrep -v "^event: nfc/c_${utf8_nfd}/?$" ./unicode.trace
+ grep -E "^event: nfc/c_${utf8_nfc}/?$" ./unicode.trace &&
+ grep -E -v "^event: nfc/c_${utf8_nfd}/?$" ./unicode.trace
else
# We should have seen NFD event from OS.
# We should have synthesized an NFC event.
- egrep "^event: nfc/c_${utf8_nfd}/?$" ./unicode.trace &&
- egrep "^event: nfc/c_${utf8_nfc}/?$" ./unicode.trace
+ grep -E "^event: nfc/c_${utf8_nfd}/?$" ./unicode.trace &&
+ grep -E "^event: nfc/c_${utf8_nfc}/?$" ./unicode.trace
fi &&
# We assume UNICODE_NFD_PRESERVED.
# We should have seen explicit NFD from OS.
# We should have synthesized an NFC event.
- egrep "^event: nfd/d_${utf8_nfd}/?$" ./unicode.trace &&
- egrep "^event: nfd/d_${utf8_nfc}/?$" ./unicode.trace
+ grep -E "^event: nfd/d_${utf8_nfd}/?$" ./unicode.trace &&
+ grep -E "^event: nfd/d_${utf8_nfc}/?$" ./unicode.trace
'
test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index f0f6fda150b..7c3f6ed9943 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -255,6 +255,15 @@ test_expect_success 'merge --squash c3 with c7' '
test_cmp expect actual
'
+test_expect_success 'merge --squash --autostash conflict does not attempt to apply autostash' '
+ git reset --hard c3 &&
+ >unrelated &&
+ git add unrelated &&
+ test_must_fail git merge --squash c7 --autostash >out 2>err &&
+ ! grep "Applying autostash resulted in conflicts." err &&
+ grep "When finished, apply stashed changes with \`git stash pop\`" out
+'
+
test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
git config commit.cleanup scissors &&
git reset --hard c3 &&
diff --git a/t/t7609-mergetool--lib.sh b/t/t7609-mergetool--lib.sh
index 8b1c3bd39f2..2090d12a489 100755
--- a/t/t7609-mergetool--lib.sh
+++ b/t/t7609-mergetool--lib.sh
@@ -8,7 +8,7 @@ TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'mergetool --tool=vimdiff creates the expected layout' '
- . "$GIT_BUILD_DIR"/mergetools/vimdiff &&
+ . "$GIT_SOURCE_DIR"/mergetools/vimdiff &&
run_unit_tests
'
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index ca45c4cd2c1..c630e0d52da 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -426,12 +426,73 @@ test_expect_success '--write-midx -b packs non-kept objects' '
)
'
+test_expect_success '--write-midx removes stale pack-based bitmaps' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ test_commit base &&
+ GIT_TEST_MULTI_PACK_INDEX=0 git repack -Ab &&
+
+ pack_bitmap=$(ls $objdir/pack/pack-*.bitmap) &&
+ test_path_is_file "$pack_bitmap" &&
+
+ test_commit tip &&
+ GIT_TEST_MULTI_PACK_INDEX=0 git repack -bm &&
+
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_missing $pack_bitmap
+ )
+'
+
+test_expect_success '--write-midx with --pack-kept-objects' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ test_commit one &&
+ test_commit two &&
+
+ one="$(echo "one" | git pack-objects --revs $objdir/pack/pack)" &&
+ two="$(echo "one..two" | git pack-objects --revs $objdir/pack/pack)" &&
+
+ keep="$objdir/pack/pack-$one.keep" &&
+ touch "$keep" &&
+
+ git repack --write-midx --write-bitmap-index --geometric=2 -d \
+ --pack-kept-objects &&
+
+ test_path_is_file $keep &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap
+ )
+'
+
test_expect_success TTY '--quiet disables progress' '
test_terminal env GIT_PROGRESS_DELAY=0 \
git -C midx repack -ad --quiet --write-midx 2>stderr &&
test_must_be_empty stderr
'
+test_expect_success 'clean up .tmp-* packs on error' '
+ test_must_fail ok=sigpipe git \
+ -c repack.cruftwindow=bogus \
+ repack -ad --cruft &&
+ find $objdir/pack -name '.tmp-*' >tmpfiles &&
+ test_must_be_empty tmpfiles
+'
+
+test_expect_success 'repack -ad cleans up old .tmp-* packs' '
+ git rev-parse HEAD >input &&
+ git pack-objects $objdir/pack/.tmp-1234 <input &&
+ git repack -ad &&
+ find $objdir/pack -name '.tmp-*' >tmpfiles &&
+ test_must_be_empty tmpfiles
+'
+
test_expect_success 'setup for update-server-info' '
git init update-server-info &&
test_commit -C update-server-info message
@@ -482,4 +543,125 @@ test_expect_success '-n overrides repack.updateServerInfo=true' '
test_server_info_missing
'
+test_expect_success '--expire-to stores pruned objects (now)' '
+ git init expire-to-now &&
+ (
+ cd expire-to-now &&
+
+ git branch -M main &&
+
+ test_commit base &&
+
+ git checkout -b cruft &&
+ test_commit --no-tag cruft &&
+
+ git rev-list --objects --no-object-names main..cruft >moved.raw &&
+ sort moved.raw >moved.want &&
+
+ git rev-list --all --objects --no-object-names >expect.raw &&
+ sort expect.raw >expect &&
+
+ git checkout main &&
+ git branch -D cruft &&
+ git reflog expire --all --expire=all &&
+
+ git init --bare expired.git &&
+ git repack -d \
+ --cruft --cruft-expiration="now" \
+ --expire-to="expired.git/objects/pack/pack" &&
+
+ expired="$(ls expired.git/objects/pack/pack-*.idx)" &&
+ test_path_is_file "${expired%.idx}.mtimes" &&
+
+ # Since the `--cruft-expiration` is "now", the effective
+ # behavior is to move _all_ unreachable objects out to
+ # the location in `--expire-to`.
+ git show-index <$expired >expired.raw &&
+ cut -d" " -f2 expired.raw | sort >expired.objects &&
+ git rev-list --all --objects --no-object-names \
+ >remaining.objects &&
+
+ # ...in other words, the combined contents of this
+ # repository and expired.git should be the same as the
+ # set of objects we started with.
+ cat expired.objects remaining.objects | sort >actual &&
+ test_cmp expect actual &&
+
+ # The "moved" objects (i.e., those in expired.git)
+ # should be the same as the cruft objects which were
+ # expired in the previous step.
+ test_cmp moved.want expired.objects
+ )
+'
+
+test_expect_success '--expire-to stores pruned objects (5.minutes.ago)' '
+ git init expire-to-5.minutes.ago &&
+ (
+ cd expire-to-5.minutes.ago &&
+
+ git branch -M main &&
+
+ test_commit base &&
+
+ # Create two classes of unreachable objects, one which
+ # is older than 5 minutes (stale), and another which is
+ # newer (recent).
+ for kind in stale recent
+ do
+ git checkout -b $kind main &&
+ test_commit --no-tag $kind || return 1
+ done &&
+
+ git rev-list --objects --no-object-names main..stale >in &&
+ stale="$(git pack-objects $objdir/pack/pack <in)" &&
+ mtime="$(test-tool chmtime --get =-600 $objdir/pack/pack-$stale.pack)" &&
+
+ # expect holds the set of objects we expect to find in
+ # this repository after repacking
+ git rev-list --objects --no-object-names recent >expect.raw &&
+ sort expect.raw >expect &&
+
+ # moved.want holds the set of objects we expect to find
+ # in expired.git
+ git rev-list --objects --no-object-names main..stale >out &&
+ sort out >moved.want &&
+
+ git checkout main &&
+ git branch -D stale recent &&
+ git reflog expire --all --expire=all &&
+ git prune-packed &&
+
+ git init --bare expired.git &&
+ git repack -d \
+ --cruft --cruft-expiration=5.minutes.ago \
+ --expire-to="expired.git/objects/pack/pack" &&
+
+ # Some of the remaining objects in this repository are
+ # unreachable, so use `cat-file --batch-all-objects`
+ # instead of `rev-list` to get their names
+ git cat-file --batch-all-objects --batch-check="%(objectname)" \
+ >remaining.objects &&
+ sort remaining.objects >actual &&
+ test_cmp expect actual &&
+
+ (
+ cd expired.git &&
+
+ expired="$(ls objects/pack/pack-*.mtimes)" &&
+ test-tool pack-mtimes $(basename $expired) >out &&
+ cut -d" " -f1 out | sort >../moved.got &&
+
+ # Ensure that there are as many objects with the
+ # expected mtime as were moved to expired.git.
+ #
+ # In other words, ensure that the recorded
+ # mtimes of any moved objects was written
+ # correctly.
+ grep " $mtime$" out >matching &&
+ test_line_count = $(wc -l <../moved.want) matching
+ ) &&
+ test_cmp moved.want moved.got
+ )
+'
+
test_done
diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh
index 937f89ee8c8..b7ac4f598a8 100755
--- a/t/t7701-repack-unpack-unreachable.sh
+++ b/t/t7701-repack-unpack-unreachable.sh
@@ -35,7 +35,7 @@ test_expect_success '-A with -d option leaves unreachable objects unpacked' '
git repack -A -d -l &&
# verify objects are packed in repository
test 3 = $(git verify-pack -v -- .git/objects/pack/*.idx |
- egrep "^($fsha1|$csha1|$tsha1) " |
+ grep -E "^($fsha1|$csha1|$tsha1) " |
sort | uniq | wc -l) &&
git show $fsha1 &&
git show $csha1 &&
@@ -49,7 +49,7 @@ test_expect_success '-A with -d option leaves unreachable objects unpacked' '
git repack -A -d -l &&
# verify objects are retained unpacked
test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
- egrep "^($fsha1|$csha1|$tsha1) " |
+ grep -E "^($fsha1|$csha1|$tsha1) " |
sort | uniq | wc -l) &&
git show $fsha1 &&
git show $csha1 &&
diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh
index da87f8b2d88..8821fbd2dd5 100755
--- a/t/t7703-repack-geometric.sh
+++ b/t/t7703-repack-geometric.sh
@@ -176,8 +176,12 @@ test_expect_success '--geometric ignores kept packs' '
# be repacked, too.
git repack --geometric 2 -d --pack-kept-objects &&
+ # After repacking, two packs remain: one new one (containing the
+ # objects in both the .keep and non-kept pack), and the .keep
+ # pack (since `--pack-kept-objects -d` does not actually delete
+ # the kept pack).
find $objdir/pack -name "*.pack" >after &&
- test_line_count = 1 after
+ test_line_count = 2 after
)
'
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 096456292c0..24297e26ca0 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -636,6 +636,7 @@ test_expect_success 'difftool --no-symlinks detects conflict ' '
test_expect_success 'difftool properly honors gitlink and core.worktree' '
test_when_finished rm -rf submod/ule &&
+ test_config_global protocol.file.allow always &&
git submodule add ./. submod/ule &&
test_config -C submod/ule diff.tool checktrees &&
test_config -C submod/ule difftool.checktrees.cmd '\''
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 0f937990a06..8eded6ab274 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -18,6 +18,9 @@ test_invalid_grep_expression() {
'
}
+LC_ALL=en_US.UTF-8 test-tool regex '^.$' '¿' &&
+ test_set_prereq MB_REGEX
+
cat >hello.c <<EOF
#include <assert.h>
#include <stdio.h>
@@ -88,6 +91,10 @@ test_expect_success setup '
echo unusual >"\"unusual\" pathname" &&
echo unusual >"t/nested \"unusual\" pathname"
fi &&
+ if test_have_prereq MB_REGEX
+ then
+ echo "¿" >reverse-question-mark
+ fi &&
git add . &&
test_tick &&
git commit -m initial
@@ -569,6 +576,14 @@ do
'
done
+test_expect_success MB_REGEX 'grep exactly one char in single-char multibyte file' '
+ LC_ALL=en_US.UTF-8 git grep "^.$" reverse-question-mark
+'
+
+test_expect_success MB_REGEX 'grep two chars in single-char multibyte file' '
+ LC_ALL=en_US.UTF-8 test_expect_code 1 git grep ".." reverse-question-mark
+'
+
cat >expected <<EOF
file
EOF
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index 3ad80526c4c..8143817b19e 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -197,6 +197,7 @@ test_expect_success !MINGW 'grep recurse submodule colon in name' '
git -C "su:b" commit -m "add fi:le" &&
test_tick &&
+ test_config_global protocol.file.allow always &&
git -C parent submodule add "../su:b" "su:b" &&
git -C parent commit -m "add submodule" &&
test_tick &&
@@ -231,6 +232,7 @@ test_expect_success 'grep history with moved submoules' '
git -C sub commit -m "add file" &&
test_tick &&
+ test_config_global protocol.file.allow always &&
git -C parent submodule add ../sub dir/sub &&
git -C parent commit -m "add submodule" &&
test_tick &&
@@ -275,6 +277,7 @@ test_expect_success 'grep using relative path' '
mkdir parent/src &&
echo "(1|2)d(3|4)" >parent/src/file2 &&
git -C parent add src/file2 &&
+ test_config_global protocol.file.allow always &&
git -C parent submodule add ../sub &&
git -C parent commit -m "add files and submodule" &&
test_tick &&
@@ -317,6 +320,7 @@ test_expect_success 'grep from a subdir' '
mkdir parent/src &&
echo "(1|2)d(3|4)" >parent/src/file &&
git -C parent add src/file &&
+ test_config_global protocol.file.allow always &&
git -C parent submodule add ../sub src/sub &&
git -C parent submodule add ../sub sub &&
git -C parent commit -m "add files and submodules" &&
@@ -550,6 +554,7 @@ test_expect_failure 'grep saves textconv cache in the appropriate repository' '
test_expect_success 'grep partially-cloned submodule' '
# Set up clean superproject and submodule for partial cloning.
+ test_config_global protocol.file.allow always &&
git init super &&
git init super/sub &&
(
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index 62ed694a404..091da683a8a 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -32,11 +32,13 @@ test_systemd_analyze_verify () {
}
test_expect_success 'help text' '
- test_expect_code 129 git maintenance -h 2>err &&
- test_i18ngrep "usage: git maintenance <subcommand>" err &&
- test_expect_code 128 git maintenance barf 2>err &&
- test_i18ngrep "invalid subcommand: barf" err &&
+ test_expect_code 129 git maintenance -h >actual &&
+ test_i18ngrep "usage: git maintenance <subcommand>" actual &&
+ test_expect_code 129 git maintenance barf 2>err &&
+ test_i18ngrep "unknown subcommand: \`barf'\''" err &&
+ test_i18ngrep "usage: git maintenance" err &&
test_expect_code 129 git maintenance 2>err &&
+ test_i18ngrep "error: need a subcommand" err &&
test_i18ngrep "usage: git maintenance" err
'
@@ -478,6 +480,11 @@ test_expect_success 'maintenance.strategy inheritance' '
test_expect_success 'register and unregister' '
test_when_finished git config --global --unset-all maintenance.repo &&
+
+ test_must_fail git maintenance unregister 2>err &&
+ grep "is not registered" err &&
+ git maintenance unregister --force &&
+
git config --global --add maintenance.repo /existing1 &&
git config --global --add maintenance.repo /existing2 &&
git config --global --get-all maintenance.repo >before &&
@@ -491,7 +498,26 @@ test_expect_success 'register and unregister' '
git maintenance unregister &&
git config --global --get-all maintenance.repo >actual &&
- test_cmp before actual
+ test_cmp before actual &&
+
+ git config --file ./other --add maintenance.repo /existing1 &&
+ git config --file ./other --add maintenance.repo /existing2 &&
+ git config --file ./other --get-all maintenance.repo >before &&
+
+ git maintenance register --config-file ./other &&
+ test_cmp_config false maintenance.auto &&
+ git config --file ./other --get-all maintenance.repo >between &&
+ cp before expect &&
+ pwd >>expect &&
+ test_cmp expect between &&
+
+ git maintenance unregister --config-file ./other &&
+ git config --file ./other --get-all maintenance.repo >actual &&
+ test_cmp before actual &&
+
+ test_must_fail git maintenance unregister 2>err &&
+ grep "is not registered" err &&
+ git maintenance unregister --force
'
test_expect_success !MINGW 'register and unregister with regex metacharacters' '
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 01c74b8b075..1130ef21b34 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -1519,7 +1519,7 @@ test_expect_success $PREREQ 'asks about and fixes 8bit encodings' '
grep "do not declare a Content-Transfer-Encoding" stdout &&
grep email-using-8bit stdout &&
grep "Which 8bit encoding" stdout &&
- egrep "Content|MIME" msgtxt1 >actual &&
+ grep -E "Content|MIME" msgtxt1 >actual &&
test_cmp content-type-decl actual
'
@@ -1530,7 +1530,7 @@ test_expect_success $PREREQ 'sendemail.8bitEncoding works' '
git send-email --from=author@example.com --to=nobody@example.com \
--smtp-server="$(pwd)/fake.sendmail" \
email-using-8bit >stdout &&
- egrep "Content|MIME" msgtxt1 >actual &&
+ grep -E "Content|MIME" msgtxt1 >actual &&
test_cmp content-type-decl actual
'
@@ -1545,7 +1545,7 @@ test_expect_success $PREREQ 'sendemail.8bitEncoding in .git/config overrides --g
git send-email --from=author@example.com --to=nobody@example.com \
--smtp-server="$(pwd)/fake.sendmail" \
email-using-8bit >stdout &&
- egrep "Content|MIME" msgtxt1 >actual &&
+ grep -E "Content|MIME" msgtxt1 >actual &&
test_cmp content-type-decl actual
'
@@ -1557,7 +1557,7 @@ test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' '
--smtp-server="$(pwd)/fake.sendmail" \
--8bit-encoding=UTF-8 \
email-using-8bit >stdout &&
- egrep "Content|MIME" msgtxt1 >actual &&
+ grep -E "Content|MIME" msgtxt1 >actual &&
test_cmp content-type-decl actual
'
diff --git a/t/t9133-git-svn-nested-git-repo.sh b/t/t9133-git-svn-nested-git-repo.sh
index f894860867a..d8d536269cf 100755
--- a/t/t9133-git-svn-nested-git-repo.sh
+++ b/t/t9133-git-svn-nested-git-repo.sh
@@ -35,7 +35,7 @@ test_expect_success 'SVN-side change outside of .git' '
echo b >> a &&
svn_cmd commit -m "SVN-side change outside of .git" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change outside of .git"
+ svn_cmd log -v | grep -F "SVN-side change outside of .git"
)
'
@@ -59,7 +59,7 @@ test_expect_success 'SVN-side change inside of .git' '
svn_cmd add --force .git &&
svn_cmd commit -m "SVN-side change inside of .git" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change inside of .git"
+ svn_cmd log -v | grep -F "SVN-side change inside of .git"
)
'
@@ -82,7 +82,7 @@ test_expect_success 'SVN-side change in and out of .git' '
git commit -m "add a inside an SVN repo" &&
svn_cmd commit -m "SVN-side change in and out of .git" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change in and out of .git"
+ svn_cmd log -v | grep -F "SVN-side change in and out of .git"
)
'
diff --git a/t/t9134-git-svn-ignore-paths.sh b/t/t9134-git-svn-ignore-paths.sh
index 4a77eb9f60d..31884002263 100755
--- a/t/t9134-git-svn-ignore-paths.sh
+++ b/t/t9134-git-svn-ignore-paths.sh
@@ -43,7 +43,7 @@ test_expect_success 'init+fetch an SVN repository with ignored www directory' '
test_expect_success 'verify ignore-paths config saved by clone' '
(
cd g &&
- git config --get svn-remote.svn.ignore-paths | fgrep "www"
+ git config --get svn-remote.svn.ignore-paths | grep www
)
'
@@ -53,7 +53,7 @@ test_expect_success 'SVN-side change outside of www' '
echo b >> qqq/test_qqq.txt &&
svn_cmd commit -m "SVN-side change outside of www" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change outside of www"
+ svn_cmd log -v | grep "SVN-side change outside of www"
)
'
@@ -85,7 +85,7 @@ test_expect_success 'SVN-side change inside of ignored www' '
echo zaq >> www/test_www.txt &&
svn_cmd commit -m "SVN-side change inside of www/test_www.txt" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change inside of www/test_www.txt"
+ svn_cmd log -v | grep -F "SVN-side change inside of www/test_www.txt"
)
'
@@ -118,7 +118,7 @@ test_expect_success 'SVN-side change in and out of ignored www' '
echo ygg >> qqq/test_qqq.txt &&
svn_cmd commit -m "SVN-side change in and out of ignored www" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change in and out of ignored www"
+ svn_cmd log -v | grep "SVN-side change in and out of ignored www"
)
'
diff --git a/t/t9140-git-svn-reset.sh b/t/t9140-git-svn-reset.sh
index e8559046296..a420b2a87af 100755
--- a/t/t9140-git-svn-reset.sh
+++ b/t/t9140-git-svn-reset.sh
@@ -43,7 +43,7 @@ test_expect_success 'fetch fails on modified hidden file' '
git svn find-rev refs/remotes/git-svn > ../expect &&
test_must_fail git svn fetch 2> ../errors &&
git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
- fgrep "not found in commit" errors &&
+ grep "not found in commit" errors &&
test_cmp expect expect2
'
@@ -59,7 +59,7 @@ test_expect_success 'refetch succeeds not ignoring any files' '
( cd g &&
git svn fetch &&
git svn rebase &&
- fgrep "mod hidden" hid/hid.txt
+ grep "mod hidden" hid/hid.txt
)
'
diff --git a/t/t9147-git-svn-include-paths.sh b/t/t9147-git-svn-include-paths.sh
index 257fc8f2f8d..63fa0b6732e 100755
--- a/t/t9147-git-svn-include-paths.sh
+++ b/t/t9147-git-svn-include-paths.sh
@@ -45,7 +45,7 @@ test_expect_success 'init+fetch an SVN repository with included qqq directory' '
test_expect_success 'verify include-paths config saved by clone' '
(
cd g &&
- git config --get svn-remote.svn.include-paths | fgrep "qqq"
+ git config --get svn-remote.svn.include-paths | grep qqq
)
'
@@ -55,7 +55,7 @@ test_expect_success 'SVN-side change outside of www' '
echo b >> qqq/test_qqq.txt &&
svn_cmd commit -m "SVN-side change outside of www" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change outside of www"
+ svn_cmd log -v | grep "SVN-side change outside of www"
)
'
@@ -87,7 +87,7 @@ test_expect_success 'SVN-side change inside of ignored www' '
echo zaq >> www/test_www.txt &&
svn_cmd commit -m "SVN-side change inside of www/test_www.txt" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change inside of www/test_www.txt"
+ svn_cmd log -v | grep "SVN-side change inside of www/test_www.txt"
)
'
@@ -120,7 +120,7 @@ test_expect_success 'SVN-side change in and out of included qqq' '
echo ygg >> qqq/test_qqq.txt &&
svn_cmd commit -m "SVN-side change in and out of ignored www" &&
svn_cmd up &&
- svn_cmd log -v | fgrep "SVN-side change in and out of ignored www"
+ svn_cmd log -v | grep "SVN-side change in and out of ignored www"
)
'
diff --git a/contrib/scalar/t/t9099-scalar.sh b/t/t9210-scalar.sh
index dfb949f52ee..c7f8a379108 100755
--- a/contrib/scalar/t/t9099-scalar.sh
+++ b/t/t9210-scalar.sh
@@ -2,15 +2,9 @@
test_description='test the `scalar` command'
-TEST_DIRECTORY=$PWD/../../../t
-export TEST_DIRECTORY
+. ./test-lib.sh
-# Make it work with --no-bin-wrappers
-PATH=$PWD/..:$PATH
-
-. ../../../t/test-lib.sh
-
-GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab ../cron.txt,launchctl:true,schtasks:true"
+GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
export GIT_TEST_MAINT_SCHEDULER
test_expect_success 'scalar shows a usage' '
@@ -122,7 +116,10 @@ test_expect_success 'scalar unregister' '
test_must_fail git config --get --global --fixed-value \
maintenance.repo "$(pwd)/vanish/src" &&
scalar list >scalar.repos &&
- ! grep -F "$(pwd)/vanish/src" scalar.repos
+ ! grep -F "$(pwd)/vanish/src" scalar.repos &&
+
+ # scalar unregister should be idempotent
+ scalar unregister vanish
'
test_expect_success 'set up repository to clone' '
@@ -169,6 +166,17 @@ test_expect_success 'scalar reconfigure' '
test true = "$(git -C one/src config core.preloadIndex)"
'
+test_expect_success '`reconfigure -a` removes stale config entries' '
+ git init stale/src &&
+ scalar register stale &&
+ scalar list >scalar.repos &&
+ grep stale scalar.repos &&
+ rm -rf stale &&
+ scalar reconfigure -a &&
+ scalar list >scalar.repos &&
+ ! grep stale scalar.repos
+'
+
test_expect_success 'scalar delete without enlistment shows a usage' '
test_expect_code 129 scalar delete
'
diff --git a/t/t9211-scalar-clone.sh b/t/t9211-scalar-clone.sh
new file mode 100755
index 00000000000..dd33d87e9be
--- /dev/null
+++ b/t/t9211-scalar-clone.sh
@@ -0,0 +1,151 @@
+#!/bin/sh
+
+test_description='test the `scalar clone` subcommand'
+
+. ./test-lib.sh
+
+GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
+export GIT_TEST_MAINT_SCHEDULER
+
+test_expect_success 'set up repository to clone' '
+ rm -rf .git &&
+ git init to-clone &&
+ (
+ cd to-clone &&
+ git branch -m base &&
+
+ test_commit first &&
+ test_commit second &&
+ test_commit third &&
+
+ git switch -c parallel first &&
+ mkdir -p 1/2 &&
+ test_commit 1/2/3 &&
+
+ git switch base &&
+
+ # By default, permit
+ git config uploadpack.allowfilter true &&
+ git config uploadpack.allowanysha1inwant true
+ )
+'
+
+cleanup_clone () {
+ rm -rf "$1"
+}
+
+test_expect_success 'creates content in enlistment root' '
+ enlistment=cloned &&
+
+ scalar clone "file://$(pwd)/to-clone" $enlistment &&
+ ls -A $enlistment >enlistment-root &&
+ test_line_count = 1 enlistment-root &&
+ test_path_is_dir $enlistment/src &&
+ test_path_is_dir $enlistment/src/.git &&
+
+ cleanup_clone $enlistment
+'
+
+test_expect_success 'with spaces' '
+ enlistment="cloned with space" &&
+
+ scalar clone "file://$(pwd)/to-clone" "$enlistment" &&
+ test_path_is_dir "$enlistment" &&
+ test_path_is_dir "$enlistment/src" &&
+ test_path_is_dir "$enlistment/src/.git" &&
+
+ cleanup_clone "$enlistment"
+'
+
+test_expect_success 'partial clone if supported by server' '
+ enlistment=partial-clone &&
+
+ scalar clone "file://$(pwd)/to-clone" $enlistment &&
+
+ (
+ cd $enlistment/src &&
+
+ # Two promisor packs: one for refs, the other for blobs
+ ls .git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 2 promisorlist
+ ) &&
+
+ cleanup_clone $enlistment
+'
+
+test_expect_success 'fall back on full clone if partial unsupported' '
+ enlistment=no-partial-support &&
+
+ test_config -C to-clone uploadpack.allowfilter false &&
+ test_config -C to-clone uploadpack.allowanysha1inwant false &&
+
+ scalar clone "file://$(pwd)/to-clone" $enlistment 2>err &&
+ grep "filtering not recognized by server, ignoring" err &&
+
+ (
+ cd $enlistment/src &&
+
+ # Still get a refs promisor file, but none for blobs
+ ls .git/objects/pack/pack-*.promisor >promisorlist &&
+ test_line_count = 1 promisorlist
+ ) &&
+
+ cleanup_clone $enlistment
+'
+
+test_expect_success 'initializes sparse-checkout by default' '
+ enlistment=sparse &&
+
+ scalar clone "file://$(pwd)/to-clone" $enlistment &&
+ (
+ cd $enlistment/src &&
+ test_cmp_config true core.sparseCheckout &&
+ test_cmp_config true core.sparseCheckoutCone
+ ) &&
+
+ cleanup_clone $enlistment
+'
+
+test_expect_success '--full-clone does not create sparse-checkout' '
+ enlistment=full-clone &&
+
+ scalar clone --full-clone "file://$(pwd)/to-clone" $enlistment &&
+ (
+ cd $enlistment/src &&
+ test_cmp_config "" --default "" core.sparseCheckout &&
+ test_cmp_config "" --default "" core.sparseCheckoutCone
+ ) &&
+
+ cleanup_clone $enlistment
+'
+
+test_expect_success '--single-branch clones HEAD only' '
+ enlistment=single-branch &&
+
+ scalar clone --single-branch "file://$(pwd)/to-clone" $enlistment &&
+ (
+ cd $enlistment/src &&
+ git for-each-ref refs/remotes/origin >out &&
+ test_line_count = 1 out &&
+ grep "refs/remotes/origin/base" out
+ ) &&
+
+ cleanup_clone $enlistment
+'
+
+test_expect_success '--no-single-branch clones all branches' '
+ enlistment=no-single-branch &&
+
+ scalar clone --no-single-branch "file://$(pwd)/to-clone" $enlistment &&
+ (
+ cd $enlistment/src &&
+ git for-each-ref refs/remotes/origin >out &&
+ test_line_count = 2 out &&
+ grep "refs/remotes/origin/base" out &&
+ grep "refs/remotes/origin/parallel" out
+ ) &&
+
+ cleanup_clone $enlistment
+'
+
+test_done
diff --git a/t/t9304-fast-import-marks.sh b/t/t9304-fast-import-marks.sh
index bed01c99ea7..a98ef032d94 100755
--- a/t/t9304-fast-import-marks.sh
+++ b/t/t9304-fast-import-marks.sh
@@ -25,6 +25,7 @@ test_expect_success 'import with large marks file' '
'
test_expect_success 'setup dump with submodule' '
+ test_config_global protocol.file.allow always &&
git submodule add "$PWD" sub &&
git commit -m "add submodule" &&
git fast-export HEAD >dump
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index fc99703fc51..ff21a12ee6e 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -268,6 +268,7 @@ test_expect_success 'signed-tags=warn-strip' '
test_expect_success 'setup submodule' '
+ test_config_global protocol.file.allow always &&
git checkout -f main &&
mkdir sub &&
(
@@ -293,6 +294,7 @@ test_expect_success 'setup submodule' '
test_expect_success 'submodule fast-export | fast-import' '
+ test_config_global protocol.file.allow always &&
SUBENT1=$(git ls-tree main^ sub) &&
SUBENT2=$(git ls-tree main sub) &&
rm -rf new &&
diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh
index 4aa5d90d328..b105d6d9d57 100755
--- a/t/t9700-perl-git.sh
+++ b/t/t9700-perl-git.sh
@@ -45,6 +45,10 @@ test_expect_success \
git config --add test.pathmulti bar
'
+test_expect_success 'set up bare repository' '
+ git init --bare bare.git
+'
+
test_expect_success 'use t9700/test.pl to test Git.pm' '
"$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl 2>stderr &&
test_must_be_empty stderr
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index e046f7db762..6d753708d2a 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -30,6 +30,18 @@ BEGIN { use_ok('Git') }
# set up
our $abs_repo_dir = cwd();
ok(our $r = Git->repository(Directory => "."), "open repository");
+{
+ local $ENV{GIT_TEST_ASSUME_DIFFERENT_OWNER} = 1;
+ my $failed;
+
+ $failed = eval { Git->repository(Directory => $abs_repo_dir) };
+ ok(!$failed, "reject unsafe non-bare repository");
+ like($@, qr/not a git repository/i, "unsafe error message");
+
+ $failed = eval { Git->repository(Directory => "$abs_repo_dir/bare.git") };
+ ok(!$failed, "reject unsafe bare repository");
+ like($@, qr/not a git repository/i, "unsafe error message");
+}
# config
is($r->config("test.string"), "value", "config scalar: string");
diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh
index 468767cbf4b..2a9838f37fe 100755
--- a/t/t9814-git-p4-rename.sh
+++ b/t/t9814-git-p4-rename.sh
@@ -216,7 +216,7 @@ test_expect_success 'detect copies' '
# variable exists, which allows admins to disable the "p4 move" command.
test_lazy_prereq P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW '
p4 configure show run.move.allow >out &&
- egrep ^run.move.allow: out
+ grep -E ^run.move.allow: out
'
# If move can be disabled, turn it off and test p4 move handling
diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh
index 9779dc0d11f..0ca9937de6c 100755
--- a/t/t9815-git-p4-submit-fail.sh
+++ b/t/t9815-git-p4-submit-fail.sh
@@ -417,8 +417,8 @@ test_expect_success 'cleanup chmod after submit cancel' '
! p4 fstat -T action text &&
test_path_is_file text+x &&
! p4 fstat -T action text+x &&
- ls -l text | egrep ^-r-- &&
- ls -l text+x | egrep ^-r-x
+ ls -l text | grep -E ^-r-- &&
+ ls -l text+x | grep -E ^-r-x
)
'
diff --git a/t/t9850-shell.sh b/t/t9850-shell.sh
new file mode 100755
index 00000000000..cfc71c3bd43
--- /dev/null
+++ b/t/t9850-shell.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+test_description='git shell tests'
+. ./test-lib.sh
+
+test_expect_success 'shell allows upload-pack' '
+ printf 0000 >input &&
+ git upload-pack . <input >expect &&
+ git shell -c "git-upload-pack $SQ.$SQ" <input >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'shell forbids other commands' '
+ test_must_fail git shell -c "git config foo.bar baz"
+'
+
+test_expect_success 'shell forbids interactive use by default' '
+ test_must_fail git shell
+'
+
+test_expect_success 'shell allows interactive command' '
+ mkdir git-shell-commands &&
+ write_script git-shell-commands/ping <<-\EOF &&
+ echo pong
+ EOF
+ echo pong >expect &&
+ echo ping | git shell >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'shell complains of overlong commands' '
+ perl -e "print \"a\" x 2**12 for (0..2**19)" |
+ test_must_fail git shell 2>err &&
+ grep "too long" err
+'
+
+test_done
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 43de868b800..1bd4cae92fe 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -33,7 +33,7 @@ complete ()
GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr rebase ls-files'
GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout rebase'
-. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
+. "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash"
# We don't need this function to actually join words or do anything special.
# Also, it's cleaner to avoid touching bash's internal completion variables.
@@ -2567,7 +2567,7 @@ test_expect_success 'sourcing the completion script clears cached commands' '
(
__git_compute_all_commands &&
verbose test -n "$__git_all_commands" &&
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ . "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash" &&
verbose test -z "$__git_all_commands"
)
'
@@ -2576,7 +2576,7 @@ test_expect_success 'sourcing the completion script clears cached merge strategi
(
__git_compute_merge_strategies &&
verbose test -n "$__git_merge_strategies" &&
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ . "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash" &&
verbose test -z "$__git_merge_strategies"
)
'
@@ -2587,7 +2587,7 @@ test_expect_success 'sourcing the completion script clears cached --options' '
verbose test -n "$__gitcomp_builtin_checkout" &&
__gitcomp_builtin notes_edit &&
verbose test -n "$__gitcomp_builtin_notes_edit" &&
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ . "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash" &&
verbose test -z "$__gitcomp_builtin_checkout" &&
verbose test -z "$__gitcomp_builtin_notes_edit"
)
@@ -2599,7 +2599,7 @@ test_expect_success 'option aliases are not shown by default' '
test_expect_success 'option aliases are shown with GIT_COMPLETION_SHOW_ALL' '
(
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ . "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash" &&
GIT_COMPLETION_SHOW_ALL=1 && export GIT_COMPLETION_SHOW_ALL &&
test_completion "git clone --recurs" <<-\EOF
--recurse-submodules Z
@@ -2610,7 +2610,7 @@ test_expect_success 'option aliases are shown with GIT_COMPLETION_SHOW_ALL' '
test_expect_success 'plumbing commands are excluded without GIT_COMPLETION_SHOW_ALL_COMMANDS' '
(
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ . "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash" &&
sane_unset GIT_TESTING_PORCELAIN_COMMAND_LIST &&
# Just mainporcelain, not plumbing commands
@@ -2622,7 +2622,7 @@ test_expect_success 'plumbing commands are excluded without GIT_COMPLETION_SHOW_
test_expect_success 'all commands are shown with GIT_COMPLETION_SHOW_ALL_COMMANDS (also main non-builtin)' '
(
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ . "$GIT_SOURCE_DIR/contrib/completion/git-completion.bash" &&
GIT_COMPLETION_SHOW_ALL_COMMANDS=1 &&
export GIT_COMPLETION_SHOW_ALL_COMMANDS &&
sane_unset GIT_TESTING_PORCELAIN_COMMAND_LIST &&
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index d459fae6551..06f0abfc294 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -10,7 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./lib-bash.sh
-. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
+. "$GIT_SOURCE_DIR/contrib/completion/git-prompt.sh"
actual="$TRASH_DIRECTORY/actual"
c_red='\\[\\e[31m\\]'
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index c6479f24eb5..796093a7b32 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -273,13 +273,13 @@ debug () {
# <file>, <contents>, and <tag> all default to <message>.
test_commit () {
- notick= &&
- echo=echo &&
- append= &&
- author= &&
- signoff= &&
- indir= &&
- tag=light &&
+ local notick= &&
+ local echo=echo &&
+ local append= &&
+ local author= &&
+ local signoff= &&
+ local indir= &&
+ local tag=light &&
while test $# != 0
do
case "$1" in
@@ -322,7 +322,7 @@ test_commit () {
shift
done &&
indir=${indir:+"$indir"/} &&
- file=${2:-"$1.t"} &&
+ local file=${2:-"$1.t"} &&
if test -n "$append"
then
$echo "${3-$1}" >>"$indir$file"
@@ -897,7 +897,7 @@ test_path_is_symlink () {
test_dir_is_empty () {
test "$#" -ne 1 && BUG "1 param"
test_path_is_dir "$1" &&
- if test -n "$(ls -a1 "$1" | egrep -v '^\.\.?$')"
+ if test -n "$(ls -a1 "$1" | grep -E -v '^\.\.?$')"
then
echo "Directory '$1' is not empty, it contains:"
ls -la "$1"
@@ -921,10 +921,6 @@ test_path_is_missing () {
then
echo "Path exists:"
ls -ld "$1"
- if test $# -ge 1
- then
- echo "$*"
- fi
false
fi
}
@@ -1868,3 +1864,14 @@ test_is_magic_mtime () {
rm -f .git/test-mtime-actual
return $ret
}
+
+# Given two filenames, parse both using 'git config --list --file'
+# and compare the sorted output of those commands. Useful when
+# wanting to ignore whitespace differences and sorting concerns.
+test_cmp_config_output () {
+ git config --list --file="$1" >config-expect &&
+ git config --list --file="$2" >config-actual &&
+ sort config-expect >sorted-expect &&
+ sort config-actual >sorted-actual &&
+ test_cmp sorted-expect sorted-actual
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 377cc1c1203..ce319c9963e 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -48,6 +48,28 @@ then
exit 1
fi
+# For CMake the top-level source directory is different from our build
+# directory. With the top-level Makefile they're the same.
+GIT_SOURCE_DIR="$GIT_BUILD_DIR"
+
+GIT_AUTO_CONTRIB_BUILDSYSTEMS_OUT=
+if test -n "$GIT_TEST_BUILD_DIR"
+then
+ GIT_BUILD_DIR="$GIT_TEST_BUILD_DIR"
+elif ! test -x "$GIT_BUILD_DIR/git" &&
+ test -x "$GIT_BUILD_DIR/contrib/buildsystems/out/git"
+then
+ GIT_BUILD_DIR="$GIT_SOURCE_DIR/contrib/buildsystems/out"
+ GIT_AUTO_CONTRIB_BUILDSYSTEMS_OUT=t
+
+ # On Windows, we must convert Windows paths lest they contain a colon
+ case "$(uname -s)" in
+ *MINGW*)
+ GIT_BUILD_DIR="$(cygpath -au "$GIT_BUILD_DIR")"
+ ;;
+ esac
+fi
+
# Prepend a string to a VAR using an arbitrary ":" delimiter, not
# adding the delimiter if VAR or VALUE is empty. I.e. a generalized:
#
@@ -563,9 +585,11 @@ case $GIT_TEST_FSYNC in
esac
# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing
-# the test with valgrind and have not compiled with SANITIZE=address.
+# the test with valgrind and have not compiled with conflict SANITIZE
+# options.
if test -n "$valgrind" ||
test -n "$SANITIZE_ADDRESS" ||
+ test -n "$SANITIZE_LEAK" ||
test -n "$TEST_NO_MALLOC_CHECK"
then
setup_malloc_check () {
@@ -1091,11 +1115,7 @@ test_run_ () {
trace=
# 117 is magic because it is unlikely to match the exit
# code of other programs
- if test "OK-117" != "$(test_eval_ "(exit 117) && $1${LF}${LF}echo OK-\$?" 3>&1)" ||
- {
- test "${GIT_TEST_CHAIN_LINT_HARDER:-${GIT_TEST_CHAIN_LINT_HARDER_DEFAULT:-1}}" != 0 &&
- $(printf '%s\n' "$1" | sed -f "$GIT_BUILD_DIR/t/chainlint.sed" | grep -q '?![A-Z][A-Z]*?!')
- }
+ if test "OK-117" != "$(test_eval_ "(exit 117) && $1${LF}${LF}echo OK-\$?" 3>&1)"
then
BUG "broken &&-chain or run-away HERE-DOC: $1"
fi
@@ -1439,7 +1459,7 @@ then
make_valgrind_symlink $file
done
# special-case the mergetools loadables
- make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
+ make_symlink "$GIT_SOURCE_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
OLDIFS=$IFS
IFS=:
for path in $PATH
@@ -1492,6 +1512,8 @@ GIT_CONFIG_NOSYSTEM=1
GIT_ATTR_NOSYSTEM=1
GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.."
export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM GIT_CEILING_DIRECTORIES
+MERGE_TOOLS_DIR="$GIT_SOURCE_DIR/mergetools"
+export MERGE_TOOLS_DIR
if test -z "$GIT_TEST_CMP"
then
@@ -1591,6 +1613,12 @@ then
BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_SANITIZE_LEAK_LOG=true"
fi
+if test "${GIT_TEST_CHAIN_LINT:-1}" != 0
+then
+ "$PERL_PATH" "$TEST_DIRECTORY/chainlint.pl" "$0" ||
+ BUG "lint error (see '?!...!? annotations above)"
+fi
+
# Last-minute variable setup
USER_HOME="$HOME"
HOME="$TRASH_DIRECTORY"
@@ -1614,6 +1642,13 @@ remove_trash_directory "$TRASH_DIRECTORY" || {
BAIL_OUT 'cannot prepare test area'
}
+# Emitting this now because earlier we didn't have "say", but not in
+# anything using lib-subtest.sh
+if test -n "$GIT_AUTO_CONTRIB_BUILDSYSTEMS_OUT" && test -t 1
+then
+ say "setup: had no ../git, but found & used cmake built git in ../contrib/buildsystems/out/git"
+fi
+
remove_trash=t
if test -z "$TEST_NO_CREATE_REPO"
then
diff --git a/tempfile.c b/tempfile.c
index 2024c82691f..e27048f970b 100644
--- a/tempfile.c
+++ b/tempfile.c
@@ -14,16 +14,14 @@
*
* The possible states of a `tempfile` object are as follows:
*
- * - Uninitialized. In this state the object's `on_list` field must be
- * zero but the rest of its contents need not be initialized. As
- * soon as the object is used in any way, it is irrevocably
- * registered in `tempfile_list`, and `on_list` is set.
+ * - Inactive/unallocated. The only way to get a tempfile is via a creation
+ * function like create_tempfile(). Once allocated, the tempfile is on the
+ * global tempfile_list and considered active.
*
* - Active, file open (after `create_tempfile()` or
* `reopen_tempfile()`). In this state:
*
* - the temporary file exists
- * - `active` is set
* - `filename` holds the filename of the temporary file
* - `fd` holds a file descriptor open for writing to it
* - `fp` holds a pointer to an open `FILE` object if and only if
@@ -35,14 +33,8 @@
* `fd` is -1, and `fp` is `NULL`.
*
* - Inactive (after `delete_tempfile()`, `rename_tempfile()`, or a
- * failed attempt to create a temporary file). In this state:
- *
- * - `active` is unset
- * - `filename` is empty (usually, though there are transitory
- * states in which this condition doesn't hold). Client code should
- * *not* rely on the filename being empty in this state.
- * - `fd` is -1 and `fp` is `NULL`
- * - the object is removed from `tempfile_list` (but could be used again)
+ * failed attempt to create a temporary file). The struct is removed from
+ * the global tempfile_list and deallocated.
*
* A temporary file is owned by the process that created it. The
* `tempfile` has an `owner` field that records the owner's PID. This
@@ -59,14 +51,11 @@ static VOLATILE_LIST_HEAD(tempfile_list);
static void remove_template_directory(struct tempfile *tempfile,
int in_signal_handler)
{
- if (tempfile->directorylen > 0 &&
- tempfile->directorylen < tempfile->filename.len &&
- tempfile->filename.buf[tempfile->directorylen] == '/') {
- strbuf_setlen(&tempfile->filename, tempfile->directorylen);
+ if (tempfile->directory) {
if (in_signal_handler)
- rmdir(tempfile->filename.buf);
+ rmdir(tempfile->directory);
else
- rmdir_or_warn(tempfile->filename.buf);
+ rmdir_or_warn(tempfile->directory);
}
}
@@ -89,8 +78,6 @@ static void remove_tempfiles(int in_signal_handler)
else
unlink_or_warn(p->filename.buf);
remove_template_directory(p, in_signal_handler);
-
- p->active = 0;
}
}
@@ -111,11 +98,10 @@ static struct tempfile *new_tempfile(void)
struct tempfile *tempfile = xmalloc(sizeof(*tempfile));
tempfile->fd = -1;
tempfile->fp = NULL;
- tempfile->active = 0;
tempfile->owner = 0;
INIT_LIST_HEAD(&tempfile->list);
strbuf_init(&tempfile->filename, 0);
- tempfile->directorylen = 0;
+ tempfile->directory = NULL;
return tempfile;
}
@@ -123,9 +109,6 @@ static void activate_tempfile(struct tempfile *tempfile)
{
static int initialized;
- if (is_tempfile_active(tempfile))
- BUG("activate_tempfile called for active object");
-
if (!initialized) {
sigchain_push_common(remove_tempfiles_on_signal);
atexit(remove_tempfiles_on_exit);
@@ -134,14 +117,13 @@ static void activate_tempfile(struct tempfile *tempfile)
volatile_list_add(&tempfile->list, &tempfile_list);
tempfile->owner = getpid();
- tempfile->active = 1;
}
static void deactivate_tempfile(struct tempfile *tempfile)
{
- tempfile->active = 0;
- strbuf_release(&tempfile->filename);
volatile_list_del(&tempfile->list);
+ strbuf_release(&tempfile->filename);
+ free(tempfile->directory);
free(tempfile);
}
@@ -254,7 +236,7 @@ struct tempfile *mks_tempfile_dt(const char *directory_template,
tempfile = new_tempfile();
strbuf_swap(&tempfile->filename, &sb);
- tempfile->directorylen = directorylen;
+ tempfile->directory = xmemdupz(tempfile->filename.buf, directorylen);
tempfile->fd = fd;
activate_tempfile(tempfile);
return tempfile;
diff --git a/tempfile.h b/tempfile.h
index d7804a214ab..d0413af733c 100644
--- a/tempfile.h
+++ b/tempfile.h
@@ -77,12 +77,11 @@
struct tempfile {
volatile struct volatile_list_head list;
- volatile sig_atomic_t active;
volatile int fd;
FILE *volatile fp;
volatile pid_t owner;
struct strbuf filename;
- size_t directorylen;
+ char *directory;
};
/*
@@ -221,7 +220,7 @@ FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode);
static inline int is_tempfile_active(struct tempfile *tempfile)
{
- return tempfile && tempfile->active;
+ return !!tempfile;
}
/*
diff --git a/tmp-objdir.c b/tmp-objdir.c
index adf6033549e..2a2012eb6d0 100644
--- a/tmp-objdir.c
+++ b/tmp-objdir.c
@@ -18,7 +18,7 @@ struct tmp_objdir {
/*
* Allow only one tmp_objdir at a time in a running process, which simplifies
- * our signal/atexit cleanup routines. It's doubtful callers will ever need
+ * our atexit cleanup routines. It's doubtful callers will ever need
* more than one, and we can expand later if so. You can have many such
* tmp_objdirs simultaneously in many processes, of course.
*/
@@ -31,7 +31,7 @@ static void tmp_objdir_free(struct tmp_objdir *t)
free(t);
}
-static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal)
+int tmp_objdir_destroy(struct tmp_objdir *t)
{
int err;
@@ -41,44 +41,21 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal)
if (t == the_tmp_objdir)
the_tmp_objdir = NULL;
- if (!on_signal && t->prev_odb)
+ if (t->prev_odb)
restore_primary_odb(t->prev_odb, t->path.buf);
- /*
- * This may use malloc via strbuf_grow(), but we should
- * have pre-grown t->path sufficiently so that this
- * doesn't happen in practice.
- */
err = remove_dir_recursively(&t->path, 0);
- /*
- * When we are cleaning up due to a signal, we won't bother
- * freeing memory; it may cause a deadlock if the signal
- * arrived while libc's allocator lock is held.
- */
- if (!on_signal)
- tmp_objdir_free(t);
+ tmp_objdir_free(t);
return err;
}
-int tmp_objdir_destroy(struct tmp_objdir *t)
-{
- return tmp_objdir_destroy_1(t, 0);
-}
-
static void remove_tmp_objdir(void)
{
tmp_objdir_destroy(the_tmp_objdir);
}
-static void remove_tmp_objdir_on_signal(int signo)
-{
- tmp_objdir_destroy_1(the_tmp_objdir, 1);
- sigchain_pop(signo);
- raise(signo);
-}
-
void tmp_objdir_discard_objects(struct tmp_objdir *t)
{
remove_dir_recursively(&t->path, REMOVE_DIR_KEEP_TOPLEVEL);
@@ -152,14 +129,6 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix)
*/
strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", get_object_directory(), prefix);
- /*
- * Grow the strbuf beyond any filename we expect to be placed in it.
- * If tmp_objdir_destroy() is called by a signal handler, then
- * we should be able to use the strbuf to remove files without
- * having to call malloc.
- */
- strbuf_grow(&t->path, 1024);
-
if (!mkdtemp(t->path.buf)) {
/* free, not destroy, as we never touched the filesystem */
tmp_objdir_free(t);
@@ -169,7 +138,6 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix)
the_tmp_objdir = t;
if (!installed_handlers) {
atexit(remove_tmp_objdir);
- sigchain_push_common(remove_tmp_objdir_on_signal);
installed_handlers++;
}
diff --git a/tmp-objdir.h b/tmp-objdir.h
index 76efc7edee5..237d96b6605 100644
--- a/tmp-objdir.h
+++ b/tmp-objdir.h
@@ -10,9 +10,11 @@
*
* Example:
*
+ * struct child_process child = CHILD_PROCESS_INIT;
* struct tmp_objdir *t = tmp_objdir_create("incoming");
- * if (!run_command_v_opt_cd_env(cmd, 0, NULL, tmp_objdir_env(t)) &&
- * !tmp_objdir_migrate(t))
+ * strvec_push(&child.args, cmd);
+ * strvec_pushv(&child.env, tmp_objdir_env(t));
+ * if (!run_command(&child)) && !tmp_objdir_migrate(t))
* printf("success!\n");
* else
* die("failed...tmp_objdir will clean up for us");
diff --git a/trace2.c b/trace2.c
index 0c0a11e07d5..279bddf53b4 100644
--- a/trace2.c
+++ b/trace2.c
@@ -8,11 +8,13 @@
#include "version.h"
#include "trace2/tr2_cfg.h"
#include "trace2/tr2_cmd_name.h"
+#include "trace2/tr2_ctr.h"
#include "trace2/tr2_dst.h"
#include "trace2/tr2_sid.h"
#include "trace2/tr2_sysenv.h"
#include "trace2/tr2_tgt.h"
#include "trace2/tr2_tls.h"
+#include "trace2/tr2_tmr.h"
static int trace2_enabled;
@@ -52,7 +54,7 @@ static struct tr2_tgt *tr2_tgt_builtins[] =
* Force (rather than lazily) initialize any of the requested
* builtin TRACE2 targets at startup (and before we've seen an
* actual TRACE2 event call) so we can see if we need to setup
- * the TR2 and TLS machinery.
+ * private data structures and thread-local storage.
*
* Return the number of builtin targets enabled.
*/
@@ -83,6 +85,39 @@ static void tr2_tgt_disable_builtins(void)
tgt_j->pfn_term();
}
+/*
+ * The signature of this function must match the pfn_timer
+ * method in the targets. (Think of this is an apply operation
+ * across the set of active targets.)
+ */
+static void tr2_tgt_emit_a_timer(const struct tr2_timer_metadata *meta,
+ const struct tr2_timer *timer,
+ int is_final_data)
+{
+ struct tr2_tgt *tgt_j;
+ int j;
+
+ for_each_wanted_builtin (j, tgt_j)
+ if (tgt_j->pfn_timer)
+ tgt_j->pfn_timer(meta, timer, is_final_data);
+}
+
+/*
+ * The signature of this function must match the pfn_counter
+ * method in the targets.
+ */
+static void tr2_tgt_emit_a_counter(const struct tr2_counter_metadata *meta,
+ const struct tr2_counter *counter,
+ int is_final_data)
+{
+ struct tr2_tgt *tgt_j;
+ int j;
+
+ for_each_wanted_builtin (j, tgt_j)
+ if (tgt_j->pfn_counter)
+ tgt_j->pfn_counter(meta, counter, is_final_data);
+}
+
static int tr2main_exit_code;
/*
@@ -110,6 +145,32 @@ static void tr2main_atexit_handler(void)
*/
tr2tls_pop_unwind_self();
+ /*
+ * Some timers want per-thread details. If the main thread
+ * used one of those timers, emit the details now (before
+ * we emit the aggregate timer values).
+ *
+ * Likewise for counters.
+ */
+ tr2_emit_per_thread_timers(tr2_tgt_emit_a_timer);
+ tr2_emit_per_thread_counters(tr2_tgt_emit_a_counter);
+
+ /*
+ * Add stopwatch timer and counter data for the main thread to
+ * the final totals. And then emit the final values.
+ *
+ * Technically, we shouldn't need to hold the lock to update
+ * and output the final_timer_block and final_counter_block
+ * (since all other threads should be dead by now), but it
+ * doesn't hurt anything.
+ */
+ tr2tls_lock();
+ tr2_update_final_timers();
+ tr2_update_final_counters();
+ tr2_emit_final_timers(tr2_tgt_emit_a_timer);
+ tr2_emit_final_counters(tr2_tgt_emit_a_counter);
+ tr2tls_unlock();
+
for_each_wanted_builtin (j, tgt_j)
if (tgt_j->pfn_atexit)
tgt_j->pfn_atexit(us_elapsed_absolute,
@@ -466,7 +527,7 @@ void trace2_exec_result_fl(const char *file, int line, int exec_id, int code)
file, line, us_elapsed_absolute, exec_id, code);
}
-void trace2_thread_start_fl(const char *file, int line, const char *thread_name)
+void trace2_thread_start_fl(const char *file, int line, const char *thread_base_name)
{
struct tr2_tgt *tgt_j;
int j;
@@ -488,14 +549,14 @@ void trace2_thread_start_fl(const char *file, int line, const char *thread_name)
*/
trace2_region_enter_printf_fl(file, line, NULL, NULL, NULL,
"thread-proc on main: %s",
- thread_name);
+ thread_base_name);
return;
}
us_now = getnanotime() / 1000;
us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
- tr2tls_create_self(thread_name, us_now);
+ tr2tls_create_self(thread_base_name, us_now);
for_each_wanted_builtin (j, tgt_j)
if (tgt_j->pfn_thread_start_fl)
@@ -541,6 +602,25 @@ void trace2_thread_exit_fl(const char *file, int line)
tr2tls_pop_unwind_self();
us_elapsed_thread = tr2tls_region_elasped_self(us_now);
+ /*
+ * Some timers want per-thread details. If this thread used
+ * one of those timers, emit the details now.
+ *
+ * Likewise for counters.
+ */
+ tr2_emit_per_thread_timers(tr2_tgt_emit_a_timer);
+ tr2_emit_per_thread_counters(tr2_tgt_emit_a_counter);
+
+ /*
+ * Add stopwatch timer and counter data from the current
+ * (non-main) thread to the final totals. (We'll accumulate
+ * data for the main thread later during "atexit".)
+ */
+ tr2tls_lock();
+ tr2_update_final_timers();
+ tr2_update_final_counters();
+ tr2tls_unlock();
+
for_each_wanted_builtin (j, tgt_j)
if (tgt_j->pfn_thread_exit_fl)
tgt_j->pfn_thread_exit_fl(file, line,
@@ -795,6 +875,39 @@ void trace2_printf_fl(const char *file, int line, const char *fmt, ...)
va_end(ap);
}
+void trace2_timer_start(enum trace2_timer_id tid)
+{
+ if (!trace2_enabled)
+ return;
+
+ if (tid < 0 || tid >= TRACE2_NUMBER_OF_TIMERS)
+ BUG("trace2_timer_start: invalid timer id: %d", tid);
+
+ tr2_start_timer(tid);
+}
+
+void trace2_timer_stop(enum trace2_timer_id tid)
+{
+ if (!trace2_enabled)
+ return;
+
+ if (tid < 0 || tid >= TRACE2_NUMBER_OF_TIMERS)
+ BUG("trace2_timer_stop: invalid timer id: %d", tid);
+
+ tr2_stop_timer(tid);
+}
+
+void trace2_counter_add(enum trace2_counter_id cid, uint64_t value)
+{
+ if (!trace2_enabled)
+ return;
+
+ if (cid < 0 || cid >= TRACE2_NUMBER_OF_COUNTERS)
+ BUG("trace2_counter_add: invalid counter id: %d", cid);
+
+ tr2_counter_increment(cid, value);
+}
+
const char *trace2_session_id(void)
{
return tr2_sid_get();
diff --git a/trace2.h b/trace2.h
index 88d906ea830..4ced30c0db3 100644
--- a/trace2.h
+++ b/trace2.h
@@ -51,6 +51,8 @@ struct json_writer;
* [] trace2_region* -- emit region nesting messages.
* [] trace2_data* -- emit region/thread/repo data messages.
* [] trace2_printf* -- legacy trace[1] messages.
+ * [] trace2_timer* -- stopwatch timers (messages are deferred).
+ * [] trace2_counter* -- global counters (messages are deferred).
*/
/*
@@ -73,8 +75,7 @@ void trace2_initialize_clock(void);
/*
* Initialize TRACE2 tracing facility if any of the builtin TRACE2
* targets are enabled in the system config or the environment.
- * This includes setting up the Trace2 thread local storage (TLS).
- * Emits a 'version' message containing the version of git
+ * This emits a 'version' message containing the version of git
* and the Trace2 protocol.
*
* This function should be called from `main()` as early as possible in
@@ -302,21 +303,23 @@ void trace2_exec_result_fl(const char *file, int line, int exec_id, int code);
/*
* Emit a 'thread_start' event. This must be called from inside the
- * thread-proc to set up the trace2 TLS data for the thread.
+ * thread-proc to allow the thread to create its own thread-local
+ * storage.
*
- * Thread names should be descriptive, like "preload_index".
- * Thread names will be decorated with an instance number automatically.
+ * The thread base name should be descriptive, like "preload_index" or
+ * taken from the thread-proc function. A unique thread name will be
+ * created from the given base name and the thread id automatically.
*/
void trace2_thread_start_fl(const char *file, int line,
- const char *thread_name);
+ const char *thread_base_name);
-#define trace2_thread_start(thread_name) \
- trace2_thread_start_fl(__FILE__, __LINE__, (thread_name))
+#define trace2_thread_start(thread_base_name) \
+ trace2_thread_start_fl(__FILE__, __LINE__, (thread_base_name))
/*
* Emit a 'thread_exit' event. This must be called from inside the
- * thread-proc to report thread-specific data and cleanup TLS data
- * for the thread.
+ * thread-proc so that the thread can access and clean up its
+ * thread-local storage.
*/
void trace2_thread_exit_fl(const char *file, int line);
@@ -485,6 +488,84 @@ void trace2_printf_fl(const char *file, int line, const char *fmt, ...);
#define trace2_printf(...) trace2_printf_fl(__FILE__, __LINE__, __VA_ARGS__)
/*
+ * Define the set of stopwatch timers.
+ *
+ * We can add more at any time, but they must be defined at compile
+ * time (to avoid the need to dynamically allocate and synchronize
+ * them between different threads).
+ *
+ * These must start at 0 and be contiguous (because we use them
+ * elsewhere as array indexes).
+ *
+ * Any values added to this enum must also be added to the
+ * `tr2_timer_metadata[]` in `trace2/tr2_tmr.c`.
+ */
+enum trace2_timer_id {
+ /*
+ * Define two timers for testing. See `t/helper/test-trace2.c`.
+ * These can be used for ad hoc testing, but should not be used
+ * for permanent analysis code.
+ */
+ TRACE2_TIMER_ID_TEST1 = 0, /* emits summary event only */
+ TRACE2_TIMER_ID_TEST2, /* emits summary and thread events */
+
+ /* Add additional timer definitions before here. */
+ TRACE2_NUMBER_OF_TIMERS
+};
+
+/*
+ * Start/Stop the indicated stopwatch timer in the current thread.
+ *
+ * The time spent by the current thread between the _start and _stop
+ * calls will be added to the thread's partial sum for this timer.
+ *
+ * Timer events are emitted at thread and program exit.
+ *
+ * Note: Since the stopwatch API routines do not generate individual
+ * events, they do not take (file, line) arguments. Similarly, the
+ * category and timer name values are defined at compile-time in the
+ * timer definitions array, so they are not needed here in the API.
+ */
+void trace2_timer_start(enum trace2_timer_id tid);
+void trace2_timer_stop(enum trace2_timer_id tid);
+
+/*
+ * Define the set of global counters.
+ *
+ * We can add more at any time, but they must be defined at compile
+ * time (to avoid the need to dynamically allocate and synchronize
+ * them between different threads).
+ *
+ * These must start at 0 and be contiguous (because we use them
+ * elsewhere as array indexes).
+ *
+ * Any values added to this enum be also be added to the
+ * `tr2_counter_metadata[]` in `trace2/tr2_tr2_ctr.c`.
+ */
+enum trace2_counter_id {
+ /*
+ * Define two counters for testing. See `t/helper/test-trace2.c`.
+ * These can be used for ad hoc testing, but should not be used
+ * for permanent analysis code.
+ */
+ TRACE2_COUNTER_ID_TEST1 = 0, /* emits summary event only */
+ TRACE2_COUNTER_ID_TEST2, /* emits summary and thread events */
+
+ /* Add additional counter definitions before here. */
+ TRACE2_NUMBER_OF_COUNTERS
+};
+
+/*
+ * Increase the named global counter by value.
+ *
+ * Note that this adds `value` to the current thread's partial sum for
+ * this counter (without locking) and that the complete sum is not
+ * available until all threads have exited, so it does not return the
+ * new value of the counter.
+ */
+void trace2_counter_add(enum trace2_counter_id cid, uint64_t value);
+
+/*
* Optional platform-specific code to dump information about the
* current and any parent process(es). This is intended to allow
* post-processors to know who spawned this git instance and anything
diff --git a/trace2/tr2_ctr.c b/trace2/tr2_ctr.c
new file mode 100644
index 00000000000..483ca7c308f
--- /dev/null
+++ b/trace2/tr2_ctr.c
@@ -0,0 +1,101 @@
+#include "cache.h"
+#include "thread-utils.h"
+#include "trace2/tr2_tgt.h"
+#include "trace2/tr2_tls.h"
+#include "trace2/tr2_ctr.h"
+
+/*
+ * A global counter block to aggregrate values from the partial sums
+ * from each thread.
+ */
+static struct tr2_counter_block final_counter_block; /* access under tr2tls_mutex */
+
+/*
+ * Define metadata for each global counter.
+ *
+ * This array must match the "enum trace2_counter_id" and the values
+ * in "struct tr2_counter_block.counter[*]".
+ */
+static struct tr2_counter_metadata tr2_counter_metadata[TRACE2_NUMBER_OF_COUNTERS] = {
+ [TRACE2_COUNTER_ID_TEST1] = {
+ .category = "test",
+ .name = "test1",
+ .want_per_thread_events = 0,
+ },
+ [TRACE2_COUNTER_ID_TEST2] = {
+ .category = "test",
+ .name = "test2",
+ .want_per_thread_events = 1,
+ },
+
+ /* Add additional metadata before here. */
+};
+
+void tr2_counter_increment(enum trace2_counter_id cid, uint64_t value)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ struct tr2_counter *c = &ctx->counter_block.counter[cid];
+
+ c->value += value;
+
+ ctx->used_any_counter = 1;
+ if (tr2_counter_metadata[cid].want_per_thread_events)
+ ctx->used_any_per_thread_counter = 1;
+}
+
+void tr2_update_final_counters(void)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ enum trace2_counter_id cid;
+
+ if (!ctx->used_any_counter)
+ return;
+
+ /*
+ * Access `final_counter_block` requires holding `tr2tls_mutex`.
+ * We assume that our caller is holding the lock.
+ */
+
+ for (cid = 0; cid < TRACE2_NUMBER_OF_COUNTERS; cid++) {
+ struct tr2_counter *c_final = &final_counter_block.counter[cid];
+ const struct tr2_counter *c = &ctx->counter_block.counter[cid];
+
+ c_final->value += c->value;
+ }
+}
+
+void tr2_emit_per_thread_counters(tr2_tgt_evt_counter_t *fn_apply)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ enum trace2_counter_id cid;
+
+ if (!ctx->used_any_per_thread_counter)
+ return;
+
+ /*
+ * For each counter, if the counter wants per-thread events
+ * and this thread used it (the value is non-zero), emit it.
+ */
+ for (cid = 0; cid < TRACE2_NUMBER_OF_COUNTERS; cid++)
+ if (tr2_counter_metadata[cid].want_per_thread_events &&
+ ctx->counter_block.counter[cid].value)
+ fn_apply(&tr2_counter_metadata[cid],
+ &ctx->counter_block.counter[cid],
+ 0);
+}
+
+void tr2_emit_final_counters(tr2_tgt_evt_counter_t *fn_apply)
+{
+ enum trace2_counter_id cid;
+
+ /*
+ * Access `final_counter_block` requires holding `tr2tls_mutex`.
+ * We assume that our caller is holding the lock.
+ */
+
+ for (cid = 0; cid < TRACE2_NUMBER_OF_COUNTERS; cid++)
+ if (final_counter_block.counter[cid].value)
+ fn_apply(&tr2_counter_metadata[cid],
+ &final_counter_block.counter[cid],
+ 1);
+}
diff --git a/trace2/tr2_ctr.h b/trace2/tr2_ctr.h
new file mode 100644
index 00000000000..a2267ee9901
--- /dev/null
+++ b/trace2/tr2_ctr.h
@@ -0,0 +1,104 @@
+#ifndef TR2_CTR_H
+#define TR2_CTR_H
+
+#include "trace2.h"
+#include "trace2/tr2_tgt.h"
+
+/*
+ * Define a mechanism to allow global "counters".
+ *
+ * Counters can be used count interesting activity that does not fit
+ * the "region and data" model, such as code called from many
+ * different regions and/or where you want to count a number of items,
+ * but don't have control of when the last item will be processed,
+ * such as counter the number of calls to `lstat()`.
+ *
+ * Counters differ from Trace2 "data" events. Data events are emitted
+ * immediately and are appropriate for documenting loop counters at
+ * the end of a region, for example. Counter values are accumulated
+ * during the program and final counter values are emitted at program
+ * exit.
+ *
+ * To make this model efficient, we define a compile-time fixed set of
+ * counters and counter ids using a fixed size "counter block" array
+ * in thread-local storage. This gives us constant time, lock-free
+ * access to each counter within each thread. This lets us avoid the
+ * complexities of dynamically allocating a counter and sharing that
+ * definition with other threads.
+ *
+ * Each thread uses the counter block in its thread-local storage to
+ * increment partial sums for each counter (without locking). When a
+ * thread exits, those partial sums are (under lock) added to the
+ * global final sum.
+ *
+ * Partial sums for each counter are optionally emitted when a thread
+ * exits.
+ *
+ * Final sums for each counter are emitted between the "exit" and
+ * "atexit" events.
+ *
+ * A parallel "counter metadata" table contains the "category" and
+ * "name" fields for each counter. This eliminates the need to
+ * include those args in the various counter APIs.
+ */
+
+/*
+ * The definition of an individual counter as used by an individual
+ * thread (and later in aggregation).
+ */
+struct tr2_counter {
+ uint64_t value;
+};
+
+/*
+ * Metadata for a counter.
+ */
+struct tr2_counter_metadata {
+ const char *category;
+ const char *name;
+
+ /*
+ * True if we should emit per-thread events for this counter
+ * when individual threads exit.
+ */
+ unsigned int want_per_thread_events:1;
+};
+
+/*
+ * A compile-time fixed block of counters to insert into thread-local
+ * storage. This wrapper is used to avoid quirks of C and the usual
+ * need to pass an array size argument.
+ */
+struct tr2_counter_block {
+ struct tr2_counter counter[TRACE2_NUMBER_OF_COUNTERS];
+};
+
+/*
+ * Private routines used by trace2.c to increment a counter for the
+ * current thread.
+ */
+void tr2_counter_increment(enum trace2_counter_id cid, uint64_t value);
+
+/*
+ * Add the current thread's counter data to the global totals.
+ * This is called during thread-exit.
+ *
+ * Caller must be holding the tr2tls_mutex.
+ */
+void tr2_update_final_counters(void);
+
+/*
+ * Emit per-thread counter data for the current thread.
+ * This is called during thread-exit.
+ */
+void tr2_emit_per_thread_counters(tr2_tgt_evt_counter_t *fn_apply);
+
+/*
+ * Emit global counter values.
+ * This is called during atexit handling.
+ *
+ * Caller must be holding the tr2tls_mutex.
+ */
+void tr2_emit_final_counters(tr2_tgt_evt_counter_t *fn_apply);
+
+#endif /* TR2_CTR_H */
diff --git a/trace2/tr2_tgt.h b/trace2/tr2_tgt.h
index 65f94e15748..bf8745c4f05 100644
--- a/trace2/tr2_tgt.h
+++ b/trace2/tr2_tgt.h
@@ -4,6 +4,12 @@
struct child_process;
struct repository;
struct json_writer;
+struct tr2_timer_metadata;
+struct tr2_timer;
+struct tr2_counter_metadata;
+struct tr2_counter;
+
+#define NS_TO_SEC(ns) ((double)(ns) / 1.0e9)
/*
* Function prototypes for a TRACE2 "target" vtable.
@@ -96,6 +102,14 @@ typedef void(tr2_tgt_evt_printf_va_fl_t)(const char *file, int line,
uint64_t us_elapsed_absolute,
const char *fmt, va_list ap);
+typedef void(tr2_tgt_evt_timer_t)(const struct tr2_timer_metadata *meta,
+ const struct tr2_timer *timer,
+ int is_final_data);
+
+typedef void(tr2_tgt_evt_counter_t)(const struct tr2_counter_metadata *meta,
+ const struct tr2_counter *counter,
+ int is_final_data);
+
/*
* "vtable" for a TRACE2 target. Use NULL if a target does not want
* to emit that message.
@@ -132,6 +146,8 @@ struct tr2_tgt {
tr2_tgt_evt_data_fl_t *pfn_data_fl;
tr2_tgt_evt_data_json_fl_t *pfn_data_json_fl;
tr2_tgt_evt_printf_va_fl_t *pfn_printf_va_fl;
+ tr2_tgt_evt_timer_t *pfn_timer;
+ tr2_tgt_evt_counter_t *pfn_counter;
};
/* clang-format on */
diff --git a/trace2/tr2_tgt_event.c b/trace2/tr2_tgt_event.c
index 37a3163be12..16f6332755e 100644
--- a/trace2/tr2_tgt_event.c
+++ b/trace2/tr2_tgt_event.c
@@ -9,6 +9,7 @@
#include "trace2/tr2_sysenv.h"
#include "trace2/tr2_tgt.h"
#include "trace2/tr2_tls.h"
+#include "trace2/tr2_tmr.h"
static struct tr2_dst tr2dst_event = {
.sysenv_var = TR2_SYSENV_EVENT,
@@ -90,7 +91,7 @@ static void event_fmt_prepare(const char *event_name, const char *file,
jw_object_string(jw, "event", event_name);
jw_object_string(jw, "sid", tr2_sid_get());
- jw_object_string(jw, "thread", ctx->thread_name.buf);
+ jw_object_string(jw, "thread", ctx->thread_name);
/*
* In brief mode, only emit <time> on these 2 event types.
@@ -617,6 +618,48 @@ static void fn_data_json_fl(const char *file, int line,
}
}
+static void fn_timer(const struct tr2_timer_metadata *meta,
+ const struct tr2_timer *timer,
+ int is_final_data)
+{
+ const char *event_name = is_final_data ? "timer" : "th_timer";
+ struct json_writer jw = JSON_WRITER_INIT;
+ double t_total = NS_TO_SEC(timer->total_ns);
+ double t_min = NS_TO_SEC(timer->min_ns);
+ double t_max = NS_TO_SEC(timer->max_ns);
+
+ jw_object_begin(&jw, 0);
+ event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw);
+ jw_object_string(&jw, "category", meta->category);
+ jw_object_string(&jw, "name", meta->name);
+ jw_object_intmax(&jw, "intervals", timer->interval_count);
+ jw_object_double(&jw, "t_total", 6, t_total);
+ jw_object_double(&jw, "t_min", 6, t_min);
+ jw_object_double(&jw, "t_max", 6, t_max);
+ jw_end(&jw);
+
+ tr2_dst_write_line(&tr2dst_event, &jw.json);
+ jw_release(&jw);
+}
+
+static void fn_counter(const struct tr2_counter_metadata *meta,
+ const struct tr2_counter *counter,
+ int is_final_data)
+{
+ const char *event_name = is_final_data ? "counter" : "th_counter";
+ struct json_writer jw = JSON_WRITER_INIT;
+
+ jw_object_begin(&jw, 0);
+ event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw);
+ jw_object_string(&jw, "category", meta->category);
+ jw_object_string(&jw, "name", meta->name);
+ jw_object_intmax(&jw, "count", counter->value);
+ jw_end(&jw);
+
+ tr2_dst_write_line(&tr2dst_event, &jw.json);
+ jw_release(&jw);
+}
+
struct tr2_tgt tr2_tgt_event = {
.pdst = &tr2dst_event,
@@ -648,4 +691,6 @@ struct tr2_tgt tr2_tgt_event = {
.pfn_data_fl = fn_data_fl,
.pfn_data_json_fl = fn_data_json_fl,
.pfn_printf_va_fl = NULL,
+ .pfn_timer = fn_timer,
+ .pfn_counter = fn_counter,
};
diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c
index 69f80330778..fbbef68dfc0 100644
--- a/trace2/tr2_tgt_normal.c
+++ b/trace2/tr2_tgt_normal.c
@@ -8,6 +8,7 @@
#include "trace2/tr2_tbuf.h"
#include "trace2/tr2_tgt.h"
#include "trace2/tr2_tls.h"
+#include "trace2/tr2_tmr.h"
static struct tr2_dst tr2dst_normal = {
.sysenv_var = TR2_SYSENV_NORMAL,
@@ -329,6 +330,42 @@ static void fn_printf_va_fl(const char *file, int line,
strbuf_release(&buf_payload);
}
+static void fn_timer(const struct tr2_timer_metadata *meta,
+ const struct tr2_timer *timer,
+ int is_final_data)
+{
+ const char *event_name = is_final_data ? "timer" : "th_timer";
+ struct strbuf buf_payload = STRBUF_INIT;
+ double t_total = NS_TO_SEC(timer->total_ns);
+ double t_min = NS_TO_SEC(timer->min_ns);
+ double t_max = NS_TO_SEC(timer->max_ns);
+
+ strbuf_addf(&buf_payload, ("%s %s/%s"
+ " intervals:%"PRIu64
+ " total:%8.6f min:%8.6f max:%8.6f"),
+ event_name, meta->category, meta->name,
+ timer->interval_count,
+ t_total, t_min, t_max);
+
+ normal_io_write_fl(__FILE__, __LINE__, &buf_payload);
+ strbuf_release(&buf_payload);
+}
+
+static void fn_counter(const struct tr2_counter_metadata *meta,
+ const struct tr2_counter *counter,
+ int is_final_data)
+{
+ const char *event_name = is_final_data ? "counter" : "th_counter";
+ struct strbuf buf_payload = STRBUF_INIT;
+
+ strbuf_addf(&buf_payload, "%s %s/%s value:%"PRIu64,
+ event_name, meta->category, meta->name,
+ counter->value);
+
+ normal_io_write_fl(__FILE__, __LINE__, &buf_payload);
+ strbuf_release(&buf_payload);
+}
+
struct tr2_tgt tr2_tgt_normal = {
.pdst = &tr2dst_normal,
@@ -360,4 +397,6 @@ struct tr2_tgt tr2_tgt_normal = {
.pfn_data_fl = NULL,
.pfn_data_json_fl = NULL,
.pfn_printf_va_fl = fn_printf_va_fl,
+ .pfn_timer = fn_timer,
+ .pfn_counter = fn_counter,
};
diff --git a/trace2/tr2_tgt_perf.c b/trace2/tr2_tgt_perf.c
index 8cb792488c8..adae8032639 100644
--- a/trace2/tr2_tgt_perf.c
+++ b/trace2/tr2_tgt_perf.c
@@ -10,6 +10,7 @@
#include "trace2/tr2_tbuf.h"
#include "trace2/tr2_tgt.h"
#include "trace2/tr2_tls.h"
+#include "trace2/tr2_tmr.h"
static struct tr2_dst tr2dst_perf = {
.sysenv_var = TR2_SYSENV_PERF,
@@ -108,7 +109,7 @@ static void perf_fmt_prepare(const char *event_name,
strbuf_addf(buf, "d%d | ", tr2_sid_depth());
strbuf_addf(buf, "%-*s | %-*s | ", TR2_MAX_THREAD_NAME,
- ctx->thread_name.buf, TR2FMT_PERF_MAX_EVENT_NAME,
+ ctx->thread_name, TR2FMT_PERF_MAX_EVENT_NAME,
event_name);
len = buf->len + TR2FMT_PERF_REPO_WIDTH;
@@ -555,6 +556,44 @@ static void fn_printf_va_fl(const char *file, int line,
strbuf_release(&buf_payload);
}
+static void fn_timer(const struct tr2_timer_metadata *meta,
+ const struct tr2_timer *timer,
+ int is_final_data)
+{
+ const char *event_name = is_final_data ? "timer" : "th_timer";
+ struct strbuf buf_payload = STRBUF_INIT;
+ double t_total = NS_TO_SEC(timer->total_ns);
+ double t_min = NS_TO_SEC(timer->min_ns);
+ double t_max = NS_TO_SEC(timer->max_ns);
+
+ strbuf_addf(&buf_payload, ("name:%s"
+ " intervals:%"PRIu64
+ " total:%8.6f min:%8.6f max:%8.6f"),
+ meta->name,
+ timer->interval_count,
+ t_total, t_min, t_max);
+
+ perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, NULL, NULL,
+ meta->category, &buf_payload);
+ strbuf_release(&buf_payload);
+}
+
+static void fn_counter(const struct tr2_counter_metadata *meta,
+ const struct tr2_counter *counter,
+ int is_final_data)
+{
+ const char *event_name = is_final_data ? "counter" : "th_counter";
+ struct strbuf buf_payload = STRBUF_INIT;
+
+ strbuf_addf(&buf_payload, "name:%s value:%"PRIu64,
+ meta->name,
+ counter->value);
+
+ perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, NULL, NULL,
+ meta->category, &buf_payload);
+ strbuf_release(&buf_payload);
+}
+
struct tr2_tgt tr2_tgt_perf = {
.pdst = &tr2dst_perf,
@@ -586,4 +625,6 @@ struct tr2_tgt tr2_tgt_perf = {
.pfn_data_fl = fn_data_fl,
.pfn_data_json_fl = fn_data_json_fl,
.pfn_printf_va_fl = fn_printf_va_fl,
+ .pfn_timer = fn_timer,
+ .pfn_counter = fn_counter,
};
diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c
index 7da94aba522..04900bb4c3a 100644
--- a/trace2/tr2_tls.c
+++ b/trace2/tr2_tls.c
@@ -31,10 +31,11 @@ void tr2tls_start_process_clock(void)
tr2tls_us_start_process = getnanotime() / 1000;
}
-struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name,
+struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_base_name,
uint64_t us_thread_start)
{
struct tr2tls_thread_ctx *ctx = xcalloc(1, sizeof(*ctx));
+ struct strbuf buf = STRBUF_INIT;
/*
* Implicitly "tr2tls_push_self()" to capture the thread's start
@@ -47,12 +48,13 @@ struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name,
ctx->thread_id = tr2tls_locked_increment(&tr2_next_thread_id);
- strbuf_init(&ctx->thread_name, 0);
+ strbuf_init(&buf, 0);
if (ctx->thread_id)
- strbuf_addf(&ctx->thread_name, "th%02d:", ctx->thread_id);
- strbuf_addstr(&ctx->thread_name, thread_name);
- if (ctx->thread_name.len > TR2_MAX_THREAD_NAME)
- strbuf_setlen(&ctx->thread_name, TR2_MAX_THREAD_NAME);
+ strbuf_addf(&buf, "th%02d:", ctx->thread_id);
+ strbuf_addstr(&buf, thread_base_name);
+ if (buf.len > TR2_MAX_THREAD_NAME)
+ strbuf_setlen(&buf, TR2_MAX_THREAD_NAME);
+ ctx->thread_name = strbuf_detach(&buf, NULL);
pthread_setspecific(tr2tls_key, ctx);
@@ -69,9 +71,9 @@ struct tr2tls_thread_ctx *tr2tls_get_self(void)
ctx = pthread_getspecific(tr2tls_key);
/*
- * If the thread-proc did not call trace2_thread_start(), we won't
- * have any TLS data associated with the current thread. Fix it
- * here and silently continue.
+ * If the current thread's thread-proc did not call
+ * trace2_thread_start(), then the thread will not have any
+ * thread-local storage. Create it now and silently continue.
*/
if (!ctx)
ctx = tr2tls_create_self("unknown", getnanotime() / 1000);
@@ -95,7 +97,7 @@ void tr2tls_unset_self(void)
pthread_setspecific(tr2tls_key, NULL);
- strbuf_release(&ctx->thread_name);
+ free((char *)ctx->thread_name);
free(ctx->array_us_start);
free(ctx);
}
@@ -113,7 +115,7 @@ void tr2tls_pop_self(void)
struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
if (!ctx->nr_open_regions)
- BUG("no open regions in thread '%s'", ctx->thread_name.buf);
+ BUG("no open regions in thread '%s'", ctx->thread_name);
ctx->nr_open_regions--;
}
@@ -179,3 +181,13 @@ int tr2tls_locked_increment(int *p)
return current_value;
}
+
+void tr2tls_lock(void)
+{
+ pthread_mutex_lock(&tr2tls_mutex);
+}
+
+void tr2tls_unlock(void)
+{
+ pthread_mutex_unlock(&tr2tls_mutex);
+}
diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h
index b1e327a928e..f9049805d4d 100644
--- a/trace2/tr2_tls.h
+++ b/trace2/tr2_tls.h
@@ -2,6 +2,14 @@
#define TR2_TLS_H
#include "strbuf.h"
+#include "trace2/tr2_ctr.h"
+#include "trace2/tr2_tmr.h"
+
+/*
+ * Notice: the term "TLS" refers to "thread-local storage" in the
+ * Trace2 source files. This usage is borrowed from GCC and Windows.
+ * There is NO relation to "transport layer security".
+ */
/*
* Arbitry limit for thread names for column alignment.
@@ -9,33 +17,40 @@
#define TR2_MAX_THREAD_NAME (24)
struct tr2tls_thread_ctx {
- struct strbuf thread_name;
+ const char *thread_name;
uint64_t *array_us_start;
- int alloc;
- int nr_open_regions; /* plays role of "nr" in ALLOC_GROW */
+ size_t alloc;
+ size_t nr_open_regions; /* plays role of "nr" in ALLOC_GROW */
int thread_id;
+ struct tr2_timer_block timer_block;
+ struct tr2_counter_block counter_block;
+ unsigned int used_any_timer:1;
+ unsigned int used_any_per_thread_timer:1;
+ unsigned int used_any_counter:1;
+ unsigned int used_any_per_thread_counter:1;
};
/*
- * Create TLS data for the current thread. This gives us a place to
- * put per-thread data, such as thread start time, function nesting
- * and a per-thread label for our messages.
- *
- * We assume the first thread is "main". Other threads are given
- * non-zero thread-ids to help distinguish messages from concurrent
- * threads.
+ * Create thread-local storage for the current thread.
*
- * Truncate the thread name if necessary to help with column alignment
- * in printf-style messages.
+ * The first thread in the process will have:
+ * { .thread_id=0, .thread_name="main" }
+ * Subsequent threads are given a non-zero thread_id and a thread_name
+ * constructed from the id and a thread base name (which is usually just
+ * the name of the thread-proc function). For example:
+ * { .thread_id=10, .thread_name="th10:fsm-listen" }
+ * This helps to identify and distinguish messages from concurrent threads.
+ * The ctx.thread_name field is truncated if necessary to help with column
+ * alignment in printf-style messages.
*
* In this and all following functions the term "self" refers to the
* current thread.
*/
-struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name,
+struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_base_name,
uint64_t us_thread_start);
/*
- * Get our TLS data.
+ * Get the thread-local storage pointer of the current thread.
*/
struct tr2tls_thread_ctx *tr2tls_get_self(void);
@@ -45,7 +60,7 @@ struct tr2tls_thread_ctx *tr2tls_get_self(void);
int tr2tls_is_main_thread(void);
/*
- * Free our TLS data.
+ * Free the current thread's thread-local storage.
*/
void tr2tls_unset_self(void);
@@ -81,12 +96,12 @@ uint64_t tr2tls_region_elasped_self(uint64_t us);
uint64_t tr2tls_absolute_elapsed(uint64_t us);
/*
- * Initialize the tr2 TLS system.
+ * Initialize thread-local storage for Trace2.
*/
void tr2tls_init(void);
/*
- * Free all tr2 TLS resources.
+ * Free all Trace2 thread-local storage resources.
*/
void tr2tls_release(void);
@@ -100,4 +115,10 @@ int tr2tls_locked_increment(int *p);
*/
void tr2tls_start_process_clock(void);
+/*
+ * Explicitly lock/unlock our mutex.
+ */
+void tr2tls_lock(void);
+void tr2tls_unlock(void);
+
#endif /* TR2_TLS_H */
diff --git a/trace2/tr2_tmr.c b/trace2/tr2_tmr.c
new file mode 100644
index 00000000000..786762dfd26
--- /dev/null
+++ b/trace2/tr2_tmr.c
@@ -0,0 +1,182 @@
+#include "cache.h"
+#include "thread-utils.h"
+#include "trace2/tr2_tgt.h"
+#include "trace2/tr2_tls.h"
+#include "trace2/tr2_tmr.h"
+
+#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/*
+ * A global timer block to aggregate values from the partial sums from
+ * each thread.
+ */
+static struct tr2_timer_block final_timer_block; /* access under tr2tls_mutex */
+
+/*
+ * Define metadata for each stopwatch timer.
+ *
+ * This array must match "enum trace2_timer_id" and the values
+ * in "struct tr2_timer_block.timer[*]".
+ */
+static struct tr2_timer_metadata tr2_timer_metadata[TRACE2_NUMBER_OF_TIMERS] = {
+ [TRACE2_TIMER_ID_TEST1] = {
+ .category = "test",
+ .name = "test1",
+ .want_per_thread_events = 0,
+ },
+ [TRACE2_TIMER_ID_TEST2] = {
+ .category = "test",
+ .name = "test2",
+ .want_per_thread_events = 1,
+ },
+
+ /* Add additional metadata before here. */
+};
+
+void tr2_start_timer(enum trace2_timer_id tid)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ struct tr2_timer *t = &ctx->timer_block.timer[tid];
+
+ t->recursion_count++;
+ if (t->recursion_count > 1)
+ return; /* ignore recursive starts */
+
+ t->start_ns = getnanotime();
+}
+
+void tr2_stop_timer(enum trace2_timer_id tid)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ struct tr2_timer *t = &ctx->timer_block.timer[tid];
+ uint64_t ns_now;
+ uint64_t ns_interval;
+
+ assert(t->recursion_count > 0);
+
+ t->recursion_count--;
+ if (t->recursion_count)
+ return; /* still in recursive call(s) */
+
+ ns_now = getnanotime();
+ ns_interval = ns_now - t->start_ns;
+
+ t->total_ns += ns_interval;
+
+ /*
+ * min_ns was initialized to zero (in the xcalloc()) rather
+ * than UINT_MAX when the block of timers was allocated,
+ * so we should always set both the min_ns and max_ns values
+ * the first time that the timer is used.
+ */
+ if (!t->interval_count) {
+ t->min_ns = ns_interval;
+ t->max_ns = ns_interval;
+ } else {
+ t->min_ns = MY_MIN(ns_interval, t->min_ns);
+ t->max_ns = MY_MAX(ns_interval, t->max_ns);
+ }
+
+ t->interval_count++;
+
+ ctx->used_any_timer = 1;
+ if (tr2_timer_metadata[tid].want_per_thread_events)
+ ctx->used_any_per_thread_timer = 1;
+}
+
+void tr2_update_final_timers(void)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ enum trace2_timer_id tid;
+
+ if (!ctx->used_any_timer)
+ return;
+
+ /*
+ * Accessing `final_timer_block` requires holding `tr2tls_mutex`.
+ * We assume that our caller is holding the lock.
+ */
+
+ for (tid = 0; tid < TRACE2_NUMBER_OF_TIMERS; tid++) {
+ struct tr2_timer *t_final = &final_timer_block.timer[tid];
+ struct tr2_timer *t = &ctx->timer_block.timer[tid];
+
+ if (t->recursion_count) {
+ /*
+ * The current thread is exiting with
+ * timer[tid] still running.
+ *
+ * Technically, this is a bug, but I'm going
+ * to ignore it.
+ *
+ * I don't think it is worth calling die()
+ * for. I don't think it is worth killing the
+ * process for this bookkeeping error. We
+ * might want to call warning(), but I'm going
+ * to wait on that.
+ *
+ * The downside here is that total_ns won't
+ * include the current open interval (now -
+ * start_ns). I can live with that.
+ */
+ }
+
+ if (!t->interval_count)
+ continue; /* this timer was not used by this thread */
+
+ t_final->total_ns += t->total_ns;
+
+ /*
+ * final_timer_block.timer[tid].min_ns was initialized to
+ * was initialized to zero rather than UINT_MAX, so we should
+ * always set both the min_ns and max_ns values the first time
+ * that we add a partial sum into it.
+ */
+ if (!t_final->interval_count) {
+ t_final->min_ns = t->min_ns;
+ t_final->max_ns = t->max_ns;
+ } else {
+ t_final->min_ns = MY_MIN(t_final->min_ns, t->min_ns);
+ t_final->max_ns = MY_MAX(t_final->max_ns, t->max_ns);
+ }
+
+ t_final->interval_count += t->interval_count;
+ }
+}
+
+void tr2_emit_per_thread_timers(tr2_tgt_evt_timer_t *fn_apply)
+{
+ struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+ enum trace2_timer_id tid;
+
+ if (!ctx->used_any_per_thread_timer)
+ return;
+
+ /*
+ * For each timer, if the timer wants per-thread events and
+ * this thread used it, emit it.
+ */
+ for (tid = 0; tid < TRACE2_NUMBER_OF_TIMERS; tid++)
+ if (tr2_timer_metadata[tid].want_per_thread_events &&
+ ctx->timer_block.timer[tid].interval_count)
+ fn_apply(&tr2_timer_metadata[tid],
+ &ctx->timer_block.timer[tid],
+ 0);
+}
+
+void tr2_emit_final_timers(tr2_tgt_evt_timer_t *fn_apply)
+{
+ enum trace2_timer_id tid;
+
+ /*
+ * Accessing `final_timer_block` requires holding `tr2tls_mutex`.
+ * We assume that our caller is holding the lock.
+ */
+
+ for (tid = 0; tid < TRACE2_NUMBER_OF_TIMERS; tid++)
+ if (final_timer_block.timer[tid].interval_count)
+ fn_apply(&tr2_timer_metadata[tid],
+ &final_timer_block.timer[tid],
+ 1);
+}
diff --git a/trace2/tr2_tmr.h b/trace2/tr2_tmr.h
new file mode 100644
index 00000000000..d5753576134
--- /dev/null
+++ b/trace2/tr2_tmr.h
@@ -0,0 +1,140 @@
+#ifndef TR2_TMR_H
+#define TR2_TMR_H
+
+#include "trace2.h"
+#include "trace2/tr2_tgt.h"
+
+/*
+ * Define a mechanism to allow "stopwatch" timers.
+ *
+ * Timers can be used to measure "interesting" activity that does not
+ * fit the "region" model, such as code called from many different
+ * regions (like zlib) and/or where data for individual calls are not
+ * interesting or are too numerous to be efficiently logged.
+ *
+ * Timer values are accumulated during program execution and emitted
+ * to the Trace2 logs at program exit.
+ *
+ * To make this model efficient, we define a compile-time fixed set of
+ * timers and timer ids using a "timer block" array in thread-local
+ * storage. This gives us constant time access to each timer within
+ * each thread, since we want start/stop operations to be as fast as
+ * possible. This lets us avoid the complexities of dynamically
+ * allocating a timer on the first use by a thread and/or possibly
+ * sharing that timer definition with other concurrent threads.
+ * However, this does require that we define time the set of timers at
+ * compile time.
+ *
+ * Each thread uses the timer block in its thread-local storage to
+ * compute partial sums for each timer (without locking). When a
+ * thread exits, those partial sums are (under lock) added to the
+ * global final sum.
+ *
+ * Using this "timer block" model costs ~48 bytes per timer per thread
+ * (we have about six uint64 fields per timer). This does increase
+ * the size of the thread-local storage block, but it is allocated (at
+ * thread create time) and not on the thread stack, so I'm not worried
+ * about the size.
+ *
+ * Partial sums for each timer are optionally emitted when a thread
+ * exits.
+ *
+ * Final sums for each timer are emitted between the "exit" and
+ * "atexit" events.
+ *
+ * A parallel "timer metadata" table contains the "category" and "name"
+ * fields for each timer. This eliminates the need to include those
+ * args in the various timer APIs.
+ */
+
+/*
+ * The definition of an individual timer and used by an individual
+ * thread.
+ */
+struct tr2_timer {
+ /*
+ * Total elapsed time for this timer in this thread in nanoseconds.
+ */
+ uint64_t total_ns;
+
+ /*
+ * The maximum and minimum interval values observed for this
+ * timer in this thread.
+ */
+ uint64_t min_ns;
+ uint64_t max_ns;
+
+ /*
+ * The value of the clock when this timer was started in this
+ * thread. (Undefined when the timer is not active in this
+ * thread.)
+ */
+ uint64_t start_ns;
+
+ /*
+ * Number of times that this timer has been started and stopped
+ * in this thread. (Recursive starts are ignored.)
+ */
+ uint64_t interval_count;
+
+ /*
+ * Number of nested starts on the stack in this thread. (We
+ * ignore recursive starts and use this to track the recursive
+ * calls.)
+ */
+ unsigned int recursion_count;
+};
+
+/*
+ * Metadata for a timer.
+ */
+struct tr2_timer_metadata {
+ const char *category;
+ const char *name;
+
+ /*
+ * True if we should emit per-thread events for this timer
+ * when individual threads exit.
+ */
+ unsigned int want_per_thread_events:1;
+};
+
+/*
+ * A compile-time fixed-size block of timers to insert into
+ * thread-local storage. This wrapper is used to avoid quirks
+ * of C and the usual need to pass an array size argument.
+ */
+struct tr2_timer_block {
+ struct tr2_timer timer[TRACE2_NUMBER_OF_TIMERS];
+};
+
+/*
+ * Private routines used by trace2.c to actually start/stop an
+ * individual timer in the current thread.
+ */
+void tr2_start_timer(enum trace2_timer_id tid);
+void tr2_stop_timer(enum trace2_timer_id tid);
+
+/*
+ * Add the current thread's timer data to the global totals.
+ * This is called during thread-exit.
+ *
+ * Caller must be holding the tr2tls_mutex.
+ */
+void tr2_update_final_timers(void);
+
+/*
+ * Emit per-thread timer data for the current thread.
+ * This is called during thread-exit.
+ */
+void tr2_emit_per_thread_timers(tr2_tgt_evt_timer_t *fn_apply);
+
+/*
+ * Emit global total timer values.
+ * This is called during atexit handling.
+ *
+ * Caller must be holding the tr2tls_mutex.
+ */
+void tr2_emit_final_timers(tr2_tgt_evt_timer_t *fn_apply);
+
+#endif /* TR2_TMR_H */
diff --git a/trailer.c b/trailer.c
index d419c20735e..0fd5b142a37 100644
--- a/trailer.c
+++ b/trailer.c
@@ -478,7 +478,8 @@ static struct {
{ "ifmissing", TRAILER_IF_MISSING }
};
-static int git_trailer_default_config(const char *conf_key, const char *value, void *cb)
+static int git_trailer_default_config(const char *conf_key, const char *value,
+ void *cb UNUSED)
{
const char *trailer_item, *variable_name;
@@ -509,7 +510,8 @@ static int git_trailer_default_config(const char *conf_key, const char *value, v
return 0;
}
-static int git_trailer_config(const char *conf_key, const char *value, void *cb)
+static int git_trailer_config(const char *conf_key, const char *value,
+ void *cb UNUSED)
{
const char *trailer_item, *variable_name;
struct arg_item *item;
diff --git a/transport-helper.c b/transport-helper.c
index 322c7224782..e95267a4ab5 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1286,6 +1286,8 @@ int transport_helper_init(struct transport *transport, const char *name)
if (getenv("GIT_TRANSPORT_HELPER_DEBUG"))
debug = 1;
+ list_objects_filter_init(&data->transport_options.filter_options);
+
transport->data = data;
transport->vtable = &vtable;
transport->smart_options = &(data->transport_options);
diff --git a/transport.c b/transport.c
index b51e991e443..e7b97194c10 100644
--- a/transport.c
+++ b/transport.c
@@ -142,7 +142,7 @@ static void get_refs_from_bundle_inner(struct transport *transport)
static struct ref *get_refs_from_bundle(struct transport *transport,
int for_push,
- struct transport_ls_refs_options *transport_options)
+ struct transport_ls_refs_options *transport_options UNUSED)
{
struct bundle_transport_data *data = transport->data;
struct ref *result = NULL;
@@ -178,7 +178,7 @@ 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);
+ &extra_index_pack_args, 0);
transport->hash_algo = data->header.hash_algo;
return ret;
}
@@ -386,7 +386,8 @@ static int fetch_refs_via_pack(struct transport *transport,
args.cloning = transport->cloning;
args.update_shallow = data->options.update_shallow;
args.from_promisor = data->options.from_promisor;
- args.filter_options = data->options.filter_options;
+ list_objects_filter_copy(&args.filter_options,
+ &data->options.filter_options);
args.refetch = data->options.refetch;
args.stateless_rpc = transport->stateless_rpc;
args.server_options = transport->server_options;
@@ -453,6 +454,7 @@ cleanup:
free_refs(refs_tmp);
free_refs(refs);
+ list_objects_filter_release(&args.filter_options);
return ret;
}
@@ -893,6 +895,7 @@ static int disconnect_git(struct transport *transport)
finish_connect(data->conn);
}
+ list_objects_filter_release(&data->options.filter_options);
free(data);
return 0;
}
@@ -1006,8 +1009,7 @@ static enum protocol_allow_config get_protocol_config(const char *type)
if (!strcmp(type, "http") ||
!strcmp(type, "https") ||
!strcmp(type, "git") ||
- !strcmp(type, "ssh") ||
- !strcmp(type, "file"))
+ !strcmp(type, "ssh"))
return PROTOCOL_ALLOW_ALWAYS;
/* known scary; err on the side of caution */
@@ -1110,6 +1112,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
* will be checked individually in git_connect.
*/
struct git_transport_data *data = xcalloc(1, sizeof(*data));
+ list_objects_filter_init(&data->options.filter_options);
ret->data = data;
ret->vtable = &builtin_smart_vtable;
ret->smart_options = &(data->options);
diff --git a/unpack-trees.c b/unpack-trees.c
index 90b92114be8..bae812156c4 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1423,7 +1423,7 @@ static void debug_unpack_callback(int n,
* from the tree walk at the given traverse_info.
*/
static int is_sparse_directory_entry(struct cache_entry *ce,
- struct name_entry *name,
+ const struct name_entry *name,
struct traverse_info *info)
{
if (!ce || !name || !S_ISSPARSEDIR(ce->ce_mode))
@@ -1562,7 +1562,7 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
}
}
- if (!is_sparse_directory_entry(src[0], names, info) &&
+ if (!is_sparse_directory_entry(src[0], p, info) &&
!is_new_sparse_dir &&
traverse_trees_recursive(n, dirmask, mask & ~dirmask,
names, info) < 0) {
diff --git a/upload-pack.c b/upload-pack.c
index b217a1f469e..0b8311bd685 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -141,6 +141,7 @@ static void upload_pack_data_init(struct upload_pack_data *data)
data->allow_filter_fallback = 1;
data->tree_filter_max_depth = ULONG_MAX;
packet_writer_init(&data->writer, 1);
+ list_objects_filter_init(&data->filter_options);
data->keepalive = 5;
data->advertise_sid = 0;
@@ -1170,7 +1171,7 @@ static int mark_our_ref(const char *refname, const char *refname_full,
}
static int check_ref(const char *refname_full, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data UNUSED)
{
const char *refname = strip_namespace(refname_full);
@@ -1194,7 +1195,7 @@ static void format_session_id(struct strbuf *buf, struct upload_pack_data *d) {
}
static int send_ref(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED, void *cb_data)
{
static const char *capabilities = "multi_ack thin-pack side-band"
" side-band-64k ofs-delta shallow deepen-since deepen-not"
@@ -1236,7 +1237,8 @@ static int send_ref(const char *refname, const struct object_id *oid,
return 0;
}
-static int find_symref(const char *refname, const struct object_id *oid,
+static int find_symref(const char *refname,
+ const struct object_id *oid UNUSED,
int flag, void *cb_data)
{
const char *symref_target;
@@ -1409,18 +1411,14 @@ static int parse_want(struct packet_writer *writer, const char *line,
const char *arg;
if (skip_prefix(line, "want ", &arg)) {
struct object_id oid;
- struct commit *commit;
struct object *o;
if (get_oid_hex(arg, &oid))
die("git upload-pack: protocol error, "
"expected to get oid, not '%s'", line);
- commit = lookup_commit_in_graph(the_repository, &oid);
- if (commit)
- o = &commit->object;
- else
- o = parse_object(the_repository, &oid);
+ o = parse_object_with_flags(the_repository, &oid,
+ PARSE_OBJECT_SKIP_HASH_CHECK);
if (!o) {
packet_writer_error(writer,
diff --git a/walker.c b/walker.c
index c5e29219795..99d0e0eae04 100644
--- a/walker.c
+++ b/walker.c
@@ -215,8 +215,10 @@ static int interpret_target(struct walker *walker, char *target, struct object_i
return -1;
}
-static int mark_complete(const char *path, const struct object_id *oid,
- int flag, void *cb_data)
+static int mark_complete(const char *path UNUSED,
+ const struct object_id *oid,
+ int flag UNUSED,
+ void *cb_data UNUSED)
{
struct commit *commit = lookup_commit_reference_gently(the_repository,
oid, 1);
diff --git a/worktree.c b/worktree.c
index 257ba4cf1ee..aa43c641191 100644
--- a/worktree.c
+++ b/worktree.c
@@ -489,62 +489,17 @@ int submodule_uses_worktrees(const char *path)
return ret;
}
-int parse_worktree_ref(const char *worktree_ref, const char **name,
- int *name_length, const char **ref)
-{
- if (skip_prefix(worktree_ref, "main-worktree/", &worktree_ref)) {
- if (!*worktree_ref)
- return -1;
- if (name)
- *name = NULL;
- if (name_length)
- *name_length = 0;
- if (ref)
- *ref = worktree_ref;
- return 0;
- }
- if (skip_prefix(worktree_ref, "worktrees/", &worktree_ref)) {
- const char *slash = strchr(worktree_ref, '/');
-
- if (!slash || slash == worktree_ref || !slash[1])
- return -1;
- if (name)
- *name = worktree_ref;
- if (name_length)
- *name_length = slash - worktree_ref;
- if (ref)
- *ref = slash + 1;
- return 0;
- }
- return -1;
-}
-
void strbuf_worktree_ref(const struct worktree *wt,
struct strbuf *sb,
const char *refname)
{
- switch (ref_type(refname)) {
- case REF_TYPE_PSEUDOREF:
- case REF_TYPE_PER_WORKTREE:
- if (wt && !wt->is_current) {
- if (is_main_worktree(wt))
- strbuf_addstr(sb, "main-worktree/");
- else
- strbuf_addf(sb, "worktrees/%s/", wt->id);
- }
- break;
-
- case REF_TYPE_MAIN_PSEUDOREF:
- case REF_TYPE_OTHER_PSEUDOREF:
- break;
-
- case REF_TYPE_NORMAL:
- /*
- * For shared refs, don't prefix worktrees/ or
- * main-worktree/. It's not necessary and
- * files-backend.c can't handle it anyway.
- */
- break;
+ if (parse_worktree_ref(refname, NULL, NULL, NULL) ==
+ REF_WORKTREE_CURRENT &&
+ wt && !wt->is_current) {
+ if (is_main_worktree(wt))
+ strbuf_addstr(sb, "main-worktree/");
+ else
+ strbuf_addf(sb, "worktrees/%s/", wt->id);
}
strbuf_addstr(sb, refname);
}
diff --git a/worktree.h b/worktree.h
index e9e839926b0..9dcea6fc8c1 100644
--- a/worktree.h
+++ b/worktree.h
@@ -167,16 +167,6 @@ const char *worktree_git_path(const struct worktree *wt,
__attribute__((format (printf, 2, 3)));
/*
- * Parse a worktree ref (i.e. with prefix main-worktree/ or
- * worktrees/) and return the position of the worktree's name and
- * length (or NULL and zero if it's main worktree), and ref.
- *
- * All name, name_length and ref arguments could be NULL.
- */
-int parse_worktree_ref(const char *worktree_ref, const char **name,
- int *name_length, const char **ref);
-
-/*
* Return a refname suitable for access from the current ref store.
*/
void strbuf_worktree_ref(const struct worktree *wt,
diff --git a/write-or-die.c b/write-or-die.c
index c4fd91b5b43..aaa0318e824 100644
--- a/write-or-die.c
+++ b/write-or-die.c
@@ -23,6 +23,7 @@ void maybe_flush_or_die(FILE *f, const char *desc)
if (f == stdout) {
if (skip_stdout_flush < 0) {
+ /* NEEDSWORK: make this a normal Boolean */
cp = getenv("GIT_FLUSH");
if (cp)
skip_stdout_flush = (atoi(cp) == 0);
diff --git a/wt-status.c b/wt-status.c
index 867e3e417e9..5813174896c 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -947,9 +947,11 @@ static void wt_longstatus_print_changed(struct wt_status *s)
wt_longstatus_print_trailer(s);
}
-static int stash_count_refs(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
- const char *message, void *cb_data)
+static int stash_count_refs(struct object_id *ooid UNUSED,
+ struct object_id *noid UNUSED,
+ const char *email UNUSED,
+ timestamp_t timestamp UNUSED, int tz UNUSED,
+ const char *message UNUSED, void *cb_data)
{
int *c = cb_data;
(*c)++;
@@ -1612,8 +1614,10 @@ struct grab_1st_switch_cbdata {
struct object_id noid;
};
-static int grab_1st_switch(struct object_id *ooid, struct object_id *noid,
- const char *email, timestamp_t timestamp, int tz,
+static int grab_1st_switch(struct object_id *ooid UNUSED,
+ struct object_id *noid,
+ const char *email UNUSED,
+ timestamp_t timestamp UNUSED, int tz UNUSED,
const char *message, void *cb_data)
{
struct grab_1st_switch_cbdata *cb = cb_data;