]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'fh/transport-push-leakfix'
authorJunio C Hamano <gitster@pobox.com>
Tue, 7 Jun 2022 21:10:57 +0000 (14:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 7 Jun 2022 21:10:57 +0000 (14:10 -0700)
Leakfix.

* fh/transport-push-leakfix:
  transport: free local and remote refs in transport_push()
  transport: unify return values and exit point from transport_push()
  transport: remove unnecessary indenting in transport_push()

383 files changed:
.cirrus.yml
.github/workflows/main.yml
.gitignore
Documentation/CodingGuidelines
Documentation/Makefile
Documentation/MyFirstContribution.txt
Documentation/RelNotes/2.37.0.txt [new file with mode: 0644]
Documentation/SubmittingPatches
Documentation/ToolsForGit.txt [new file with mode: 0644]
Documentation/config/add.txt
Documentation/config/branch.txt
Documentation/config/core.txt
Documentation/config/gc.txt
Documentation/config/http.txt
Documentation/config/mergetool.txt
Documentation/config/push.txt
Documentation/config/repack.txt
Documentation/config/safe.txt
Documentation/git-branch.txt
Documentation/git-gc.txt
Documentation/git-mergetool.txt
Documentation/git-p4.txt
Documentation/git-pack-objects.txt
Documentation/git-read-tree.txt
Documentation/git-rebase.txt
Documentation/git-remote.txt
Documentation/git-repack.txt
Documentation/git-sparse-checkout.txt
Documentation/git.txt
Documentation/mergetools/vimdiff.txt [new file with mode: 0644]
Documentation/rev-list-options.txt
Documentation/technical/api-trace2.txt
Documentation/technical/cruft-packs.txt [new file with mode: 0644]
Documentation/technical/pack-format.txt
GIT-VERSION-GEN
Makefile
RelNotes
add-interactive.c
alloc.c
alloc.h
apply.c
archive.c
bisect.c
bisect.h
blame.c
branch.c
branch.h
builtin/add.c
builtin/am.c
builtin/apply.c
builtin/bisect--helper.c
builtin/blame.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/describe.c
builtin/diff-files.c
builtin/diff-index.c
builtin/diff.c
builtin/fast-export.c
builtin/fetch.c
builtin/gc.c
builtin/index-pack.c
builtin/log.c
builtin/ls-remote.c
builtin/mailsplit.c
builtin/merge.c
builtin/multi-pack-index.c
builtin/pack-objects.c
builtin/pack-redundant.c
builtin/prune.c
builtin/pull.c
builtin/push.c
builtin/rebase.c
builtin/receive-pack.c
builtin/reflog.c
builtin/remote.c
builtin/repack.c
builtin/replace.c
builtin/rev-list.c
builtin/rev-parse.c
builtin/shortlog.c
builtin/show-branch.c
builtin/sparse-checkout.c
builtin/stash.c
builtin/submodule--helper.c
builtin/tag.c
builtin/unpack-objects.c
builtin/update-index.c
bulk-checkin.c
bulk-checkin.h
bundle.c
bundle.h
cache-tree.c
cache-tree.h
cache.h
chunk-format.c
chunk-format.h
ci/install-dependencies.sh
ci/lib.sh
ci/run-build-and-tests.sh
ci/run-static-analysis.sh
ci/run-test-slice.sh
combine-diff.c
commit-graph.c
commit.c
compat/fsmonitor/fsm-listen-darwin.c
compat/mingw.c
compat/mingw.h
compat/mkdir.c
compat/mmap.c
compat/nedmalloc/nedmalloc.c
compat/win32/path-utils.h
compat/win32/syslog.c
config.c
configure.ac
connect.c
contrib/buildsystems/CMakeLists.txt
contrib/coccinelle/equals-null.cocci [new file with mode: 0644]
contrib/coccinelle/free.cocci
contrib/coccinelle/the_repository.pending.cocci
contrib/vscode/README.md
contrib/vscode/init.sh
convert.c
daemon.c
detect-compiler
diff-lib.c
diff.c
dir.c
dir.h
environment.c
ewah/bitmap.c
ewah/ewah_bitmap.c
ewah/ewok.h
fetch-pack.c
fmt-merge-msg.c
fsck.c
git-compat-util.h
git-mergetool--lib.sh
git-p4.py
git.c
gitk-git/gitk
http-fetch.c
http-push.c
http-walker.c
http.c
http.h
kwset.c
ll-merge.c
log-tree.c
mailinfo.c
mailmap.c
merge-ort.c
merge-recursive.c
mergetools/araxis
mergetools/bc
mergetools/codecompare
mergetools/deltawalker
mergetools/diffmerge
mergetools/diffuse
mergetools/ecmerge
mergetools/emerge
mergetools/examdiff
mergetools/guiffy
mergetools/kdiff3
mergetools/kompare
mergetools/meld
mergetools/opendiff
mergetools/p4merge
mergetools/smerge
mergetools/tkdiff
mergetools/tortoisemerge
mergetools/vimdiff
mergetools/winmerge
mergetools/xxdiff
midx.c
object-file.c
object-name.c
object-store.h
pack-bitmap-write.c
pack-bitmap.c
pack-mtimes.c [new file with mode: 0644]
pack-mtimes.h [new file with mode: 0644]
pack-objects.c
pack-objects.h
pack-write.c
pack.h
packfile.c
path.c
po/.gitignore
po/README.md
po/git.pot [deleted file]
prio-queue.c
promisor-remote.c
range-diff.c
reachable.c
reachable.h
read-cache.c
ref-filter.c
reflog-walk.c
reflog-walk.h
refs.c
refs/ref-cache.c
reftable/blocksource.c
reftable/stack_test.c
reftable/tree.c
reftable/writer.c
remote.c
remote.h
rerere.c
revision.c
revision.h
run-command.h
sequencer.c
serve.c
setup.c
sh-i18n--envsubst.c
shallow.c
shared.mak
sparse-index.c
sparse-index.h
submodule-config.c
submodule-config.h
submodule.c
submodule.h
t/README
t/annotate-tests.sh
t/helper/test-fast-rebase.c
t/helper/test-pack-mtimes.c [new file with mode: 0644]
t/helper/test-revision-walking.c
t/helper/test-tool.c
t/helper/test-tool.h
t/lib-git-p4.sh
t/lib-git-svn.sh
t/lib-sudo.sh [new file with mode: 0644]
t/lib-unique-files.sh [new file with mode: 0644]
t/perf/p0008-odb-fsync.sh [new file with mode: 0755]
t/perf/p2000-sparse-operations.sh
t/perf/p4220-log-grep-engines.sh
t/perf/p4221-log-grep-engines-fixed.sh
t/perf/p5302-pack-index.sh
t/perf/p7519-fsmonitor.sh
t/perf/p7820-grep-engines.sh
t/perf/perf-lib.sh
t/t0012-help.sh
t/t0027-auto-crlf.sh
t/t0033-safe-directory.sh
t/t0034-root-safe-directory.sh [new file with mode: 0755]
t/t0056-git-C.sh
t/t0060-path-utils.sh
t/t0062-revision-walking.sh
t/t0100-previous.sh
t/t0101-at-syntax.sh
t/t1001-read-tree-m-2way.sh
t/t1002-read-tree-m-u-2way.sh
t/t1006-cat-file.sh
t/t1011-read-tree-sparse-checkout.sh
t/t1060-object-corruption.sh
t/t1091-sparse-checkout-builtin.sh
t/t1092-sparse-checkout-compatibility.sh
t/t1401-symbolic-ref.sh
t/t1411-reflog-show.sh
t/t1412-reflog-loop.sh
t/t1415-worktree-refs.sh
t/t1450-fsck.sh
t/t2015-checkout-unborn.sh
t/t2016-checkout-patch.sh
t/t2200-add-update.sh
t/t2203-add-intent.sh
t/t3200-branch.sh
t/t3202-show-branch.sh
t/t3302-notes-index-expensive.sh
t/t3303-notes-subtrees.sh
t/t3305-notes-fanout.sh
t/t3408-rebase-multi-line.sh
t/t3416-rebase-onto-threedots.sh
t/t3501-revert-cherry-pick.sh
t/t3602-rm-sparse-checkout.sh
t/t3700-add.sh
t/t3705-add-sparse-checkout.sh
t/t3903-stash.sh
t/t4020-diff-external.sh
t/t4021-format-patch-numbered.sh
t/t4027-diff-submodule.sh
t/t4028-format-patch-mime-headers.sh
t/t4036-format-patch-signer-mime.sh
t/t4039-diff-assume-unchanged.sh
t/t4055-diff-context.sh
t/t4066-diff-emit-delay.sh
t/t4122-apply-symlink-inside.sh
t/t4126-apply-empty.sh
t/t4128-apply-root.sh
t/t4202-log.sh
t/t4206-log-follow-harder-copies.sh
t/t4207-log-decoration-colors.sh
t/t4212-log-corrupt.sh
t/t4217-log-limit.sh [new file with mode: 0755]
t/t5300-pack-object.sh
t/t5301-sliding-window.sh
t/t5313-pack-bounds-checks.sh
t/t5316-pack-delta-depth.sh
t/t5317-pack-objects-filter-objects.sh
t/t5320-delta-islands.sh
t/t5322-pack-objects-sparse.sh
t/t5329-pack-objects-cruft.sh [new file with mode: 0755]
t/t5505-remote.sh
t/t5506-remote-groups.sh
t/t5512-ls-remote.sh
t/t5513-fetch-track.sh
t/t5515-fetch-merge-logic.sh
t/t5518-fetch-exit-status.sh
t/t5526-fetch-submodules.sh
t/t5528-push-default.sh
t/t5532-fetch-proxy.sh
t/t5551-http-fetch-smart.sh
t/t5572-pull-submodule.sh
t/t5600-clone-fail-cleanup.sh
t/t5605-clone-local.sh
t/t5900-repo-selection.sh
t/t6002-rev-list-bisect.sh
t/t6003-rev-list-topo-order.sh
t/t6005-rev-list-count.sh
t/t6018-rev-list-glob.sh
t/t6030-bisect-porcelain.sh
t/t6100-rev-list-in-order.sh
t/t6101-rev-parse-parents.sh
t/t6110-rev-list-sparse.sh
t/t6114-keep-packs.sh
t/t6131-pathspec-icase.sh
t/t6424-merge-unrelated-index-changes.sh
t/t6428-merge-conflicts-sparse.sh
t/t7002-mv-sparse-checkout.sh
t/t7008-filter-branch-null-sha1.sh
t/t7011-skip-worktree-reading.sh
t/t7012-skip-worktree-writing.sh
t/t7063-status-untracked-cache.sh
t/t7524-commit-summary.sh [new file with mode: 0755]
t/t7609-mergetool--lib.sh [new file with mode: 0755]
t/t7702-repack-cyclic-alternate.sh
t/t7703-repack-geometric.sh
t/t7812-grep-icase-non-ascii.sh
t/t9001-send-email.sh
t/t9100-git-svn-basic.sh
t/t9101-git-svn-props.sh
t/t9104-git-svn-follow-parent.sh
t/t9106-git-svn-commit-diff-clobber.sh
t/t9115-git-svn-dcommit-funky-renames.sh
t/t9116-git-svn-log.sh
t/t9122-git-svn-author.sh
t/t9127-git-svn-partial-rebuild.sh
t/t9129-git-svn-i18n-commitencoding.sh
t/t9132-git-svn-broken-symlink.sh
t/t9139-git-svn-non-utf8-commitencoding.sh
t/t9146-git-svn-empty-dirs.sh
t/t9148-git-svn-propset.sh
t/t9160-git-svn-preserve-empty-dirs.sh
t/t9162-git-svn-dcommit-interactive.sh
t/t9164-git-svn-dcommit-concurrent.sh
t/t9501-gitweb-standalone-http-status.sh
t/t9800-git-p4-basic.sh
t/t9801-git-p4-branch.sh
t/t9802-git-p4-filetype.sh
t/t9835-git-p4-metadata-encoding-python2.sh [new file with mode: 0755]
t/t9836-git-p4-metadata-encoding-python3.sh [new file with mode: 0755]
t/test-lib-functions.sh
t/test-lib-github-workflow-markup.sh [new file with mode: 0644]
t/test-lib-junit.sh [new file with mode: 0644]
t/test-lib.sh
tempfile.c
tempfile.h
trailer.c
transport.c
transport.h
unpack-trees.c
wildmatch.c
worktree.c
wrapper.c
wt-status.c
xdiff-interface.c
xdiff/xemit.c
xdiff/xmacros.h
xdiff/xprepare.c
xdiff/xutils.c

index e114ffee1a7fb28bf73b92230a5d70b06e5629a1..4860bebd32f8d3f34c2382f097ac50c0b972d3a0 100644 (file)
@@ -9,7 +9,7 @@ freebsd_12_task:
     DEFAULT_TEST_TARGET: prove
     DEVELOPER: 1
   freebsd_instance:
-    image_family: freebsd-12-2
+    image_family: freebsd-12-3
     memory: 2G
   install_script:
     pkg install -y gettext gmake perl5
index c35200defb9357b6438ba3391bb4e17fed67acdc..3fa88b78b6db04b145f6653ba74e9b4457f40a58 100644 (file)
@@ -119,10 +119,6 @@ jobs:
     - name: test
       shell: bash
       run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10
-    - name: ci/print-test-failures.sh
-      if: failure()
-      shell: bash
-      run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
       uses: actions/upload-artifact@v2
@@ -204,10 +200,6 @@ jobs:
       env:
         NO_SVN_TESTS: 1
       run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10
-    - name: ci/print-test-failures.sh
-      if: failure()
-      shell: bash
-      run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
       uses: actions/upload-artifact@v2
@@ -261,8 +253,6 @@ jobs:
     - uses: actions/checkout@v2
     - run: ci/install-dependencies.sh
     - run: ci/run-build-and-tests.sh
-    - run: ci/print-test-failures.sh
-      if: failure()
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
       uses: actions/upload-artifact@v2
@@ -292,8 +282,6 @@ jobs:
     - uses: actions/checkout@v1
     - run: ci/install-docker-dependencies.sh
     - run: ci/run-build-and-tests.sh
-    - run: ci/print-test-failures.sh
-      if: failure()
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
       uses: actions/upload-artifact@v1
index e81de1063a40048a5c123e3ac9e274480b3aa661..a45221576418e77de53f2776912ad62cce00c85b 100644 (file)
 *.[aos]
 *.o.json
 *.py[co]
+.build/
 .depend/
 *.gcda
 *.gcno
index b20b2f94f11abb7850b56f985b72646b85713d02..4c756be517acbfb0e18daf30bf65cb177dacef20 100644 (file)
@@ -43,7 +43,10 @@ the overall style of existing code. Modifications to existing
 code is expected to match the style the surrounding code already
 uses (even if it doesn't match the overall style of existing code).
 
-But if you must have a list of rules, here they are.
+But if you must have a list of rules, here are some language
+specific ones. Note that Documentation/ToolsForGit.txt document
+has a collection of tips to help you use some external tools
+to conform to these guidelines.
 
 For shell scripts specifically (not exhaustive):
 
@@ -492,17 +495,6 @@ For Perl programs:
 
  - Learn and use Git.pm if you need that functionality.
 
- - For Emacs, it's useful to put the following in
-   GIT_CHECKOUT/.dir-locals.el, assuming you use cperl-mode:
-
-    ;; note the first part is useful for C editing, too
-    ((nil . ((indent-tabs-mode . t)
-                  (tab-width . 8)
-                  (fill-column . 80)))
-     (cperl-mode . ((cperl-indent-level . 8)
-                    (cperl-extra-newline-before-brace . nil)
-                    (cperl-merge-trailing-else . t))))
-
 For Python scripts:
 
  - We follow PEP-8 (http://www.python.org/dev/peps/pep-0008/).
index 44c080e3e5bb0a895ab8834822490f94f758a96d..f2e7fc1daa5f95696510cd38d689a119fd5f2a72 100644 (file)
@@ -93,7 +93,9 @@ SP_ARTICLES += $(API_DOCS)
 TECH_DOCS += MyFirstContribution
 TECH_DOCS += MyFirstObjectWalk
 TECH_DOCS += SubmittingPatches
+TECH_DOCS += ToolsForGit
 TECH_DOCS += technical/bundle-format
+TECH_DOCS += technical/cruft-packs
 TECH_DOCS += technical/hash-function-transition
 TECH_DOCS += technical/http-protocol
 TECH_DOCS += technical/index-format
@@ -302,12 +304,12 @@ $(mergetools_txt): mergetools-list.made
 
 mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*)
        $(QUIET_GEN) \
-       $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && \
+       $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && TOOL_MODE=diff && \
                . ../git-mergetool--lib.sh && \
-               show_tool_names can_diff "* " || :' >mergetools-diff.txt && \
-       $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && \
+               show_tool_names can_diff' | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >mergetools-diff.txt && \
+       $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && TOOL_MODE=merge && \
                . ../git-mergetool--lib.sh && \
-               show_tool_names can_merge "* " || :' >mergetools-merge.txt && \
+               show_tool_names can_merge' | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >mergetools-merge.txt && \
        date >$@
 
 TRACK_ASCIIDOCFLAGS = $(subst ','\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK))
index 63a2ef544939a3ce3ebb468629e7d2a538d081d1..1da15d9ad4461578b671c00329805c4ea9b7312a 100644 (file)
@@ -710,13 +710,104 @@ dependencies. `prove` also makes the output nicer.
 Go ahead and commit this change, as well.
 
 [[ready-to-share]]
-== Getting Ready to Share
+== Getting Ready to Share: Anatomy of a Patch Series
 
 You may have noticed already that the Git project performs its code reviews via
 emailed patches, which are then applied by the maintainer when they are ready
-and approved by the community. The Git project does not accept patches from
+and approved by the community. The Git project does not accept contributions from
 pull requests, and the patches emailed for review need to be formatted a
-specific way. At this point the tutorial diverges, in order to demonstrate two
+specific way.
+
+:patch-series: https://lore.kernel.org/git/pull.1218.git.git.1645209647.gitgitgadget@gmail.com/
+:lore: https://lore.kernel.org/git/
+
+Before taking a look at how to convert your commits into emailed patches,
+let's analyze what the end result, a "patch series", looks like. Here is an
+{patch-series}[example] of the summary view for a patch series on the web interface of
+the {lore}[Git mailing list archive]:
+
+----
+2022-02-18 18:40 [PATCH 0/3] libify reflog John Cai via GitGitGadget
+2022-02-18 18:40 ` [PATCH 1/3] reflog: libify delete reflog function and helpers John Cai via GitGitGadget
+2022-02-18 19:10   ` Ã†var Arnfjörð Bjarmason [this message]
+2022-02-18 19:39     ` Taylor Blau
+2022-02-18 19:48       ` Ã†var Arnfjörð Bjarmason
+2022-02-18 19:35   ` Taylor Blau
+2022-02-21  1:43     ` John Cai
+2022-02-21  1:50       ` Taylor Blau
+2022-02-23 19:50         ` John Cai
+2022-02-18 20:00   ` // other replies ellided
+2022-02-18 18:40 ` [PATCH 2/3] reflog: call reflog_delete from reflog.c John Cai via GitGitGadget
+2022-02-18 19:15   ` Ã†var Arnfjörð Bjarmason
+2022-02-18 20:26     ` Junio C Hamano
+2022-02-18 18:40 ` [PATCH 3/3] stash: call reflog_delete from reflog.c John Cai via GitGitGadget
+2022-02-18 19:20   ` Ã†var Arnfjörð Bjarmason
+2022-02-19  0:21     ` Taylor Blau
+2022-02-22  2:36     ` John Cai
+2022-02-22 10:51       ` Ã†var Arnfjörð Bjarmason
+2022-02-18 19:29 ` [PATCH 0/3] libify reflog Ã†var Arnfjörð Bjarmason
+2022-02-22 18:30 ` [PATCH v2 0/3] libify reflog John Cai via GitGitGadget
+2022-02-22 18:30   ` [PATCH v2 1/3] stash: add test to ensure reflog --rewrite --updatref behavior John Cai via GitGitGadget
+2022-02-23  8:54     ` Ã†var Arnfjörð Bjarmason
+2022-02-23 21:27       ` Junio C Hamano
+// continued
+----
+
+We can note a few things:
+
+- Each commit is sent as a separate email, with the commit message title as
+  subject, prefixed with "[PATCH _i_/_n_]" for the _i_-th commit of an
+  _n_-commit series.
+- Each patch is sent as a reply to an introductory email called the _cover
+  letter_ of the series, prefixed "[PATCH 0/_n_]".
+- Subsequent iterations of the patch series are labelled "PATCH v2", "PATCH
+  v3", etc. in place of "PATCH". For example, "[PATCH v2 1/3]" would be the first of
+  three patches in the second iteration. Each iteration is sent with a new cover
+  letter (like "[PATCH v2 0/3]" above), itself a reply to the cover letter of the
+  previous iteration (more on that below).
+
+NOTE: A single-patch topic is sent with "[PATCH]", "[PATCH v2]", etc. without
+_i_/_n_ numbering (in the above thread overview, no single-patch topic appears,
+though).
+
+[[cover-letter]]
+=== The cover letter
+
+In addition to an email per patch, the Git community also expects your patches
+to come with a cover letter. This is an important component of change
+submission as it explains to the community from a high level what you're trying
+to do, and why, in a way that's more apparent than just looking at your
+patches.
+
+The title of your cover letter should be something which succinctly covers the
+purpose of your entire topic branch. It's often in the imperative mood, just
+like our commit message titles. Here is how we'll title our series:
+
+---
+Add the 'psuh' command
+---
+
+The body of the cover letter is used to give additional context to reviewers.
+Be sure to explain anything your patches don't make clear on their own, but
+remember that since the cover letter is not recorded in the commit history,
+anything that might be useful to future readers of the repository's history
+should also be in your commit messages.
+
+Here's an example body for `psuh`:
+
+----
+Our internal metrics indicate widespread interest in the command
+git-psuh - that is, many users are trying to use it, but finding it is
+unavailable, using some unknown workaround instead.
+
+The following handful of patches add the psuh command and implement some
+handy features on top of it.
+
+This patchset is part of the MyFirstContribution tutorial and should not
+be merged.
+----
+
+At this point the tutorial diverges, in order to demonstrate two
 different methods of formatting your patchset and getting it reviewed.
 
 The first method to be covered is GitGitGadget, which is useful for those
@@ -808,8 +899,22 @@ https://github.com/gitgitgadget/git and open a PR either with the "New pull
 request" button or the convenient "Compare & pull request" button that may
 appear with the name of your newly pushed branch.
 
-Review the PR's title and description, as it's used by GitGitGadget as the cover
-letter for your change. When you're happy, submit your pull request.
+Review the PR's title and description, as they're used by GitGitGadget
+respectively as the subject and body of the cover letter for your change. Refer
+to <<cover-letter,"The cover letter">> above for advice on how to title your
+submission and what content to include in the description.
+
+NOTE: For single-patch contributions, your commit message should already be
+meaningful and explain at a high level the purpose (what is happening and why)
+of your patch, so you usually do not need any additional context. In that case,
+remove the PR description that GitHub automatically generates from your commit
+message (your PR description should be empty). If you do need to supply even
+more context, you can do so in that space and it will be appended to the email
+that GitGitGadget will send, between the three-dash line and the diffstat
+(see <<single-patch,Bonus Chapter: One-Patch Changes>> for how this looks once
+submitted).
+
+When you're happy, submit your pull request.
 
 [[run-ci-ggg]]
 === Running CI and Getting Ready to Send
@@ -952,49 +1057,29 @@ but want reviewers to look at what they have so far. You can add this flag with
 Check and make sure that your patches and cover letter template exist in the
 directory you specified - you're nearly ready to send out your review!
 
-[[cover-letter]]
+[[preparing-cover-letter]]
 === Preparing Email
 
-In addition to an email per patch, the Git community also expects your patches
-to come with a cover letter, typically with a subject line [PATCH 0/x] (where
-x is the number of patches you're sending). Since you invoked `format-patch`
-with `--cover-letter`, you've already got a template ready. Open it up in your
-favorite editor.
+Since you invoked `format-patch` with `--cover-letter`, you've already got a
+cover letter template ready. Open it up in your favorite editor.
 
 You should see a number of headers present already. Check that your `From:`
-header is correct. Then modify your `Subject:` to something which succinctly
-covers the purpose of your entire topic branch, for example:
+header is correct. Then modify your `Subject:` (see <<cover-letter,above>> for
+how to choose good title for your patch series):
 
 ----
-Subject: [PATCH 0/7] adding the 'psuh' command
+Subject: [PATCH 0/7] Add the 'psuh' command
 ----
 
 Make sure you retain the ``[PATCH 0/X]'' part; that's what indicates to the Git
-community that this email is the beginning of a review, and many reviewers
-filter their email for this type of flag.
+community that this email is the beginning of a patch series, and many
+reviewers filter their email for this type of flag.
 
 You'll need to add some extra parameters when you invoke `git send-email` to add
 the cover letter.
 
-Next you'll have to fill out the body of your cover letter. This is an important
-component of change submission as it explains to the community from a high level
-what you're trying to do, and why, in a way that's more apparent than just
-looking at your diff. Be sure to explain anything your diff doesn't make clear
-on its own.
-
-Here's an example body for `psuh`:
-
-----
-Our internal metrics indicate widespread interest in the command
-git-psuh - that is, many users are trying to use it, but finding it is
-unavailable, using some unknown workaround instead.
-
-The following handful of patches add the psuh command and implement some
-handy features on top of it.
-
-This patchset is part of the MyFirstContribution tutorial and should not
-be merged.
-----
+Next you'll have to fill out the body of your cover letter. Again, see
+<<cover-letter,above>> for what content to include.
 
 The template created by `git format-patch --cover-letter` includes a diffstat.
 This gives reviewers a summary of what they're in for when reviewing your topic.
diff --git a/Documentation/RelNotes/2.37.0.txt b/Documentation/RelNotes/2.37.0.txt
new file mode 100644 (file)
index 0000000..345f1b9
--- /dev/null
@@ -0,0 +1,254 @@
+Git v2.37 Release Notes
+=======================
+
+UI, Workflows & Features
+
+ * "vimdiff[123]" mergetool drivers have been reimplemented with a
+   more generic layout mechanism.
+
+ * "git -v" and "git -h" are now understood as "git --version" and
+   "git --help".
+
+ * The temporary files fed to external diff command are now generated
+   inside a new temporary directory under the same basename.
+
+ * "git log --since=X" will stop traversal upon seeing a commit that
+   is older than X, but there may be commits behind it that is younger
+   than X when the commit was created with a faulty clock.  A new
+   option is added to keep digging without stopping, and instead
+   filter out commits with timestamp older than X.
+
+ * "git -c branch.autosetupmerge=simple branch $A $B" will set the $B
+   as $A's upstream only when $A and $B shares the same name, and "git
+   -c push.default=simple" on branch $A would push to update the
+   branch $A at the remote $B came from.  Also more places use the
+   sole remote, if exists, before defaulting to 'origin'.
+
+ * A new doc has been added that lists tips for tools to work with
+   Git's codebase.
+
+ * "git remote -v" now shows the list-objects-filter used during
+   fetching from the remote, if available.
+
+ * With the new http.curloptResolve configuration, the CURLOPT_RESOLVE
+   mechanism that allows cURL based applications to use pre-resolved
+   IP addresses for the requests is exposed to the scripts.
+
+ * "git add -i" was rewritten in C some time ago and has been in
+   testing; the reimplementation is now exposed to general public by
+   default.
+
+ * Deprecate non-cone mode of the sparse-checkout feature.
+
+ * Introduce a filesystem-dependent mechanism to optimize the way the
+   bits for many loose object files are ensured to hit the disk
+   platter.
+
+ * The "do not remove the directory the user started Git in" logic,
+   when Git cannot tell where that directory is, is disabled.  Earlier
+   we refused to run in such a case.
+
+ * A mechanism to pack unreachable objects into a "cruft pack",
+   instead of ejecting them into loose form to be reclaimed later, has
+   been introduced.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * The performance of the "untracked cache" feature has been improved
+   when "--untracked-files=<mode>" and "status.showUntrackedFiles"
+   are combined.
+
+ * "git stash" works better with sparse index entries.
+
+ * "git show :<path>" learned to work better with the sparse-index
+   feature.
+
+ * Introduce and apply coccinelle rule to discourage an explicit
+   comparison between a pointer and NULL, and applies the clean-up to
+   the maintenance track.
+
+ * Preliminary code refactoring around transport and bundle code.
+
+ * "sparse-checkout" learns to work better with the sparse-index
+   feature.
+
+ * A workflow change for translators are being proposed.  git.pot is
+   no longer version controlled and it is local responsibility of
+   translaters to generate it.
+
+
+
+Fixes since v2.36
+-----------------
+
+ * "git submodule update" without pathspec should silently skip an
+   uninitialized submodule, but it started to become noisy by mistake.
+   (merge 4f1ccef87c gc/submodule-update-part2 later to maint).
+
+ * "diff-tree --stdin" has been broken for about a year, but 2.36
+   release broke it even worse by breaking running the command with
+   <pathspec>, which in turn broke "gitk" and got noticed.  This has
+   been corrected by aligning its behaviour to that of "log".
+   (merge f8781bfda3 jc/diff-tree-stdin-fix later to maint).
+
+ * Regression fix for 2.36 where "git name-rev" started to sometimes
+   reference strings after they are freed.
+   (merge 45a14f578e rs/name-rev-fix-free-after-use later to maint).
+
+ * "git show <commit1> <commit2>... -- <pathspec>" lost the pathspec
+   when showing the second and subsequent commits, which has been
+   corrected.
+   (merge 5cdb38458e jc/show-pathspec-fix later to maint).
+
+ * "git fast-export -- <pathspec>" lost the pathspec when showing the
+   second and subsequent commits, which has been corrected.
+   (merge d1c25272f5 rs/fast-export-pathspec-fix later to maint).
+
+ * "git format-patch <args> -- <pathspec>" lost the pathspec when
+   showing the second and subsequent commits, which has been
+   corrected.
+   (merge 91f8f7e46f rs/format-patch-pathspec-fix later to maint).
+
+ * "git clone --origin X" leaked piece of memory that held value read
+   from the clone.defaultRemoteName configuration variable, which has
+   been plugged.
+   (merge 6dfadc8981 jc/clone-remote-name-leak-fix later to maint).
+
+ * Get rid of a bogus and over-eager coccinelle rule.
+   (merge 08bdd3a185 jc/cocci-xstrdup-or-null-fix later to maint).
+
+ * The path taken by "git multi-pack-index" command from the end user
+   was compared with path internally prepared by the tool withut first
+   normalizing, which lead to duplicated paths not being noticed,
+   which has been corrected.
+   (merge 11f9e8de3d ds/midx-normalize-pathname-before-comparison later to maint).
+
+ * Correct choices of C compilers used in various CI jobs.
+   (merge 3506cae04f ab/cc-package-fixes later to maint).
+
+ * Various cleanups to "git p4".
+   (merge 4ff0108d9e jh/p4-various-fixups later to maint).
+
+ * The progress meter of "git blame" was showing incorrect numbers
+   when processing only parts of the file.
+   (merge e5f5d7d42e ea/progress-partial-blame later to maint).
+
+ * "git rebase --keep-base <upstream> <branch-to-rebase>" computed the
+   commit to rebase onto incorrectly, which has been corrected.
+   (merge 9e5ebe9668 ah/rebase-keep-base-fix later to maint).
+
+ * Fix a leak of FILE * in an error codepath.
+   (merge c0befa0c03 kt/commit-graph-plug-fp-leak-on-error later to maint).
+
+ * Avoid problems from interaction between malloc_check and address
+   sanitizer.
+   (merge 067109a5e7 pw/test-malloc-with-sanitize-address later to maint).
+
+ * The commit summary shown after making a commit is matched to what
+   is given in "git status" not to use the break-rewrite heuristics.
+   (merge 84792322ed rs/commit-summary-wo-break-rewrite later to maint).
+
+ * Update a few end-user facing messages around eol conversion.
+   (merge c970d30c2c ah/convert-warning-message later to maint).
+
+ * Trace2 documentation updates.
+   (merge a6c80c313c js/trace2-doc-fixes later to maint).
+
+ * Build procedure fixup.
+   (merge 1fbfd96f50 mg/detect-compiler-in-c-locale later to maint).
+
+ * "git pull" without "--recurse-submodules=<arg>" made
+   submodule.recurse take precedence over fetch.recurseSubmodules by
+   mistake, which has been corrected.
+   (merge 5819417365 gc/pull-recurse-submodules later to maint).
+
+ * "git bisect" was too silent before it is ready to start computing
+   the actual bisection, which has been corrected.
+   (merge f11046e6de cd/bisect-messages-from-pre-flight-states later to maint).
+
+ * macOS CI jobs have been occasionally flaky due to tentative version
+   skew between perforce and the homebrew packager.  Instead of
+   failing the whole CI job, just let it skip the p4 tests when this
+   happens.
+   (merge f15e00b463 cb/ci-make-p4-optional later to maint).
+
+ * A bit of test framework fixes with a few fixes to issues found by
+   valgrind.
+   (merge 7c898554d7 ab/valgrind-fixes later to maint).
+
+ * "git archive --add-file=<path>" picked up the raw permission bits
+   from the path and propagated to zip output in some cases, without
+   normalization, which has been corrected (tar output did not have
+   this issue).
+   (merge 6a61661967 jc/archive-add-file-normalize-mode later to maint).
+
+ * "make coverage-report" without first running "make coverage" did
+   not produce any meaningful result, which has been corrected.
+   (merge 96ddfecc5b ep/coverage-report-wants-test-to-have-run later to maint).
+
+ * The "--current" option of "git show-branch" should have been made
+   incompatible with the "--reflog" mode, but this was not enforced,
+   which has been corrected.
+   (merge 41c64ae0e7 jc/show-branch-g-current later to maint).
+
+ * "git fetch" unnecessarily failed when an unexpected optional
+   section appeared in the output, which has been corrected.
+   (merge 7709acf7be jt/fetch-peek-optional-section later to maint).
+
+ * The way "git fetch" without "--update-head-ok" ensures that HEAD in
+   no worktree points at any ref being updated was too wasteful, which
+   has been optimized a bit.
+   (merge f7400da800 os/fetch-check-not-current-branch later to maint).
+
+ * "git fetch --recurse-submodules" from multiple remotes (either from
+   a remote group, or "--all") used to make one extra "git fetch" in
+   the submodules, which has been corrected.
+   (merge 0353c68818 jc/avoid-redundant-submodule-fetch later to maint).
+
+ * With a recent update to refuse access to repositories of other
+   people by default, "sudo make install" and "sudo git describe"
+   stopped working.  This series intends to loosen it while keeping
+   the safety.
+   (merge b9063afda1 cb/path-owner-check-with-sudo later to maint).
+
+ * The tests that ensured merges stop when interfering local changes
+   are present did not make sure that local changes are preserved; now
+   they do.
+   (merge 4b317450ce jc/t6424-failing-merge-preserve-local-changes later to maint).
+
+ * Some real problems noticed by gcc 12 have been fixed, while false
+   positives have been worked around.
+
+ * Update the version of FreeBSD image used in Cirrus CI.
+   (merge c58bebd4c6 pb/use-freebsd-12.3-in-cirrus-ci later to maint).
+
+ * The multi-pack-index code did not protect the packfile it is going
+   to depend on from getting removed while in use, which has been
+   corrected.
+   (merge 4090511e40 tb/midx-race-in-pack-objects later to maint).
+
+ * Teach "git repack --geometric" work better with "--keep-pack" and
+   avoid corrupting the repository when packsize limit is used.
+   (merge 66731ff921 tb/geom-repack-with-keep-and-max later to maint).
+
+ * Other code cleanup, docfix, build fix, etc.
+   (merge e6b2582da3 cm/reftable-0-length-memset later to maint).
+   (merge 0b75e5bf22 ab/misc-cleanup later to maint).
+   (merge 52e1ab8a76 ea/rebase-code-simplify later to maint).
+   (merge 756d15923b sg/safe-directory-tests-and-docs later to maint).
+   (merge d097a23bfa ds/do-not-call-bug-on-bad-refs later to maint).
+   (merge c36c27e75c rs/t7812-pcre2-ws-bug-test later to maint).
+   (merge 1da312742d gf/unused-includes later to maint).
+   (merge 465b30a92d pb/submodule-recurse-mode-enum later to maint).
+   (merge 82b28c4ed8 km/t3501-use-test-helpers later to maint).
+   (merge 72315e431b sa/t1011-use-helpers later to maint).
+   (merge 95b3002201 cg/vscode-with-gdb later to maint).
+   (merge fbe5f6b804 tk/p4-utf8-bom later to maint).
+   (merge 17f273ffba tk/p4-with-explicity-sync later to maint).
+   (merge 944db25c60 kf/p4-multiple-remotes later to maint).
+   (merge b014cee8de jc/update-ozlabs-url later to maint).
+   (merge 4ec5008062 pb/ggg-in-mfc-doc later to maint).
+   (merge af845a604d tb/receive-pack-code-cleanup later to maint).
+   (merge 2acf4cf001 js/ci-gcc-12-fixes later to maint).
+   (merge 05e280c0a6 jc/http-clear-finished-pointer later to maint).
index a6121d1d4280248ae8d0dd44f8ad5952c6e0ced9..5bd795e5dbf90daff92fcf33a10f7c318e9d0689 100644 (file)
@@ -452,7 +452,10 @@ repositories.
 
 - `gitk-git/` comes from Paul Mackerras's gitk project:
 
-       git://ozlabs.org/~paulus/gitk
+       git://git.ozlabs.org/~paulus/gitk
+
+   Those who are interested in improve gitk can volunteer to help Paul
+   in maintaining it cf. <YntxL/fTplFm8lr6@cleo>.
 
 - `po/` comes from the localization coordinator, Jiang Xin:
 
diff --git a/Documentation/ToolsForGit.txt b/Documentation/ToolsForGit.txt
new file mode 100644 (file)
index 0000000..5060d0d
--- /dev/null
@@ -0,0 +1,51 @@
+Tools for developing Git
+========================
+:sectanchors:
+
+[[summary]]
+== Summary
+
+This document gathers tips, scripts and configuration file to help people
+working on Git's codebase use their favorite tools while following Git's
+coding style.
+
+[[author]]
+=== Author
+
+The Git community.
+
+[[table_of_contents]]
+== Table of contents
+
+- <<vscode>>
+- <<emacs>>
+
+[[vscode]]
+=== Visual Studio Code (VS Code)
+
+The contrib/vscode/init.sh script creates configuration files that enable
+several valuable VS Code features. See contrib/vscode/README.md for more
+information on using the script.
+
+[[emacs]]
+=== Emacs
+
+This is adapted from Linux's suggestion in its CodingStyle document:
+
+- To follow rules of the CodingGuideline, it's useful to put the following in
+GIT_CHECKOUT/.dir-locals.el, assuming you use cperl-mode:
+----
+;; note the first part is useful for C editing, too
+((nil . ((indent-tabs-mode . t)
+        (tab-width . 8)
+        (fill-column . 80)))
+        (cperl-mode . ((cperl-indent-level . 8)
+                       (cperl-extra-newline-before-brace . nil)
+                       (cperl-merge-trailing-else . t))))
+----
+
+For a more complete setup, since Git's codebase uses a coding style
+similar to the Linux kernel's style, tips given in Linux's CodingStyle
+document can be applied here too.
+
+==== https://www.kernel.org/doc/html/v4.10/process/coding-style.html#you-ve-made-a-mess-of-it
index c9f748f81cb1c7c3b4a2cc2298b310ac85cb1d5c..3e859f34197bc43c8d266ec04d569e5353dae27e 100644 (file)
@@ -7,6 +7,6 @@ add.ignore-errors (deprecated)::
        variables.
 
 add.interactive.useBuiltin::
-       [EXPERIMENTAL] Set to `true` to use the experimental built-in
-       implementation of the interactive version of linkgit:git-add[1]
-       instead of the Perl script version. Is `false` by default.
+       Set to `false` to fall back to the original Perl implementation of
+       the interactive version of linkgit:git-add[1] instead of the built-in
+       version. Is `true` by default.
index 1e0c7af014beaf41534f1278cdb156dfdafdd870..445341a906b241ab1ed11093b1b0fa908e0954da 100644 (file)
@@ -9,7 +9,9 @@ branch.autoSetupMerge::
        automatic setup is done when the starting point is either a
        local branch or remote-tracking branch; `inherit` -- if the starting point
        has a tracking configuration, it is copied to the new
-       branch. This option defaults to true.
+       branch; `simple` -- automatic setup is done only when the starting point
+       is a remote-tracking branch and the new branch has the same name as the
+       remote branch. This option defaults to true.
 
 branch.autoSetupRebase::
        When a new branch is created with 'git branch', 'git switch' or 'git checkout'
@@ -38,8 +40,9 @@ branch.<name>.remote::
        may be overridden with `remote.pushDefault` (for all branches).
        The remote to push to, for the current branch, may be further
        overridden by `branch.<name>.pushRemote`.  If no remote is
-       configured, or if you are not on any branch, it defaults to
-       `origin` for fetching and `remote.pushDefault` for pushing.
+       configured, or if you are not on any branch and there is more than
+       one remote defined in the repository, it defaults to `origin` for
+       fetching and `remote.pushDefault` for pushing.
        Additionally, `.` (a period) is the current local repository
        (a dot-repository), see `branch.<name>.merge`'s final note below.
 
index e67392cc838499a039562f058160c500a6451585..41e330f30694da3fb6b580b130e4912b9a891e19 100644 (file)
@@ -628,6 +628,14 @@ core.fsyncMethod::
 * `writeout-only` issues pagecache writeback requests, but depending on the
   filesystem and storage hardware, data added to the repository may not be
   durable in the event of a system crash. This is the default mode on macOS.
+* `batch` enables a mode that uses writeout-only flushes to stage multiple
+  updates in the disk writeback cache and then does a single full fsync of
+  a dummy file to trigger the disk cache flush at the end of the operation.
++
+Currently `batch` mode only applies to loose-object files. Other repository
+data is made durable as if `fsync` was specified. This mode is expected to
+be as safe as `fsync` on macOS for repos stored on HFS+ or APFS filesystems
+and on Windows for repos stored on NTFS or ReFS filesystems.
 
 core.fsyncObjectFiles::
        This boolean will enable 'fsync()' when writing object files.
@@ -698,8 +706,10 @@ core.sparseCheckout::
 
 core.sparseCheckoutCone::
        Enables the "cone mode" of the sparse checkout feature. When the
-       sparse-checkout file contains a limited set of patterns, then this
-       mode provides significant performance advantages. See
+       sparse-checkout file contains a limited set of patterns, this
+       mode provides significant performance advantages. The "non
+       cone mode" can be requested to allow specifying a more flexible
+       patterns by setting this variable to 'false'. See
        linkgit:git-sparse-checkout[1] for more information.
 
 core.abbrev::
index c834e07991fec00d976cc105760814694deb8f68..38fea076a26d0f1f7bf137723baba945675901fc 100644 (file)
@@ -81,14 +81,21 @@ gc.packRefs::
        to enable it within all non-bare repos or it can be set to a
        boolean value.  The default is `true`.
 
+gc.cruftPacks::
+       Store unreachable objects in a cruft pack (see
+       linkgit:git-repack[1]) instead of as loose objects. The default
+       is `false`.
+
 gc.pruneExpire::
-       When 'git gc' is run, it will call 'prune --expire 2.weeks.ago'.
-       Override the grace period with this config variable.  The value
-       "now" may be used to disable this grace period and always prune
-       unreachable objects immediately, or "never" may be used to
-       suppress pruning.  This feature helps prevent corruption when
-       'git gc' runs concurrently with another process writing to the
-       repository; see the "NOTES" section of linkgit:git-gc[1].
+       When 'git gc' is run, it will call 'prune --expire 2.weeks.ago'
+       (and 'repack --cruft --cruft-expiration 2.weeks.ago' if using
+       cruft packs via `gc.cruftPacks` or `--cruft`).  Override the
+       grace period with this config variable.  The value "now" may be
+       used to disable this grace period and always prune unreachable
+       objects immediately, or "never" may be used to suppress pruning.
+       This feature helps prevent corruption when 'git gc' runs
+       concurrently with another process writing to the repository; see
+       the "NOTES" section of linkgit:git-gc[1].
 
 gc.worktreePruneExpire::
        When 'git gc' is run, it calls
index 7003661c0dba393778c0df03d2f26e121392c545..179d03e57b3e0234d437242c3aa25c413b2d173c 100644 (file)
@@ -98,6 +98,22 @@ http.version::
        - HTTP/2
        - HTTP/1.1
 
+http.curloptResolve::
+       Hostname resolution information that will be used first by
+       libcurl when sending HTTP requests.  This information should
+       be in one of the following formats:
+
+       - [+]HOST:PORT:ADDRESS[,ADDRESS]
+       - -HOST:PORT
+
++
+The first format redirects all requests to the given `HOST:PORT`
+to the provided `ADDRESS`(s). The second format clears all
+previous config values for that `HOST:PORT` combination.  To
+allow easy overriding of all the settings inherited from the
+system config, an empty value will reset all resolution
+information to the empty list.
+
 http.sslVersion::
        The SSL version to use when negotiating an SSL connection, if you
        want to force the default.  The available and default version
index cafbbef46ae9c102e9e175e67282badb67e09255..90b380970023a76799206a30789d4f8af7793991 100644 (file)
@@ -45,6 +45,15 @@ mergetool.meld.useAutoMerge::
        value of `false` avoids using `--auto-merge` altogether, and is the
        default value.
 
+mergetool.vimdiff.layout::
+       The vimdiff backend uses this variable to control how its split
+       windows look like. Applies even if you are using Neovim (`nvim`) or
+       gVim (`gvim`) as the merge tool. See BACKEND SPECIFIC HINTS section
+ifndef::git-mergetool[]
+       in linkgit:git-mergetool[1].
+endif::[]
+       for details.
+
 mergetool.hideResolved::
        During a merge Git will automatically resolve as many conflicts as
        possible and write the 'MERGED' file containing conflict markers around
index 632033638c4230f78e9830cde9fa527c3daceac2..e32801e6c91d8145106514021ae200642b7c8366 100644 (file)
@@ -1,3 +1,14 @@
+push.autoSetupRemote::
+       If set to "true" assume `--set-upstream` on default push when no
+       upstream tracking exists for the current branch; this option
+       takes effect with push.default options 'simple', 'upstream',
+       and 'current'. It is useful if by default you want new branches
+       to be pushed to the default remote (like the behavior of
+       'push.default=current') and you also want the upstream tracking
+       to be set. Workflows most likely to benefit from this option are
+       'simple' central workflows where all branches are expected to
+       have the same name on the remote.
+
 push.default::
        Defines the action `git push` should take if no refspec is
        given (whether from the command-line, config, or elsewhere).
index 41ac6953c87eb55f14b01471a5b6013bb318859e..c79af6d7b8b5d7dc03329480d8d418839fe3fef7 100644 (file)
@@ -30,3 +30,12 @@ repack.updateServerInfo::
        If set to false, linkgit:git-repack[1] will not run
        linkgit:git-update-server-info[1]. Defaults to true. Can be overridden
        when true by the `-n` option of linkgit:git-repack[1].
+
+repack.cruftWindow::
+repack.cruftWindowMemory::
+repack.cruftDepth::
+repack.cruftThreads::
+       Parameters used by linkgit:git-pack-objects[1] when generating
+       a cruft pack and the respective parameters are not given over
+       the command line. See similarly named `pack.*` configuration
+       variables for defaults and meaning.
index 6d764fe0ccf3a87dbfeb34da03b7e1dcb380ac99..1ee10fae14b75e45f9259a9380fa5ec955e3ba4b 100644 (file)
@@ -13,8 +13,8 @@ override any such directories specified in the system config), add a
 `safe.directory` entry with an empty value.
 +
 This config setting is only respected when specified in a system or global
-config, not when it is specified in a repository config or via the command
-line option `-c safe.directory=<path>`.
+config, not when it is specified in a repository config, via the command
+line option `-c safe.directory=<path>`, or in environment variables.
 +
 The value of this setting is interpolated, i.e. `~/<path>` expands to a
 path relative to the home directory and `%(prefix)/<path>` expands to a
@@ -26,3 +26,16 @@ directory was listed in the `safe.directory` list. If `safe.directory=*`
 is set in system config and you want to re-enable this protection, then
 initialize your list with an empty value before listing the repositories
 that you deem safe.
++
+As explained, Git only allows you to access repositories owned by
+yourself, i.e. the user who is running Git, by default.  When Git
+is running as 'root' in a non Windows platform that provides sudo,
+ however, git checks the SUDO_UID environment variable that sudo creates
+and will allow access to the uid recorded as its value instead.
+This is to make it easy to perform a common sequence during installation
+"make && sudo make install".  A git process running under 'sudo' runs as
+'root' but the 'sudo' command exports the environment variable to record
+which id the original user has.
+If that is not what you would prefer and want git to only trust
+repositories that are owned by root instead, then you must remove
+the `SUDO_UID` variable from root's environment before invoking git.
index c8b4f9ce3c7059616f867de767a5f43268f90fa6..ae82378349df74745efe26be51903a191fe76c9f 100644 (file)
@@ -221,13 +221,17 @@ The exact upstream branch is chosen depending on the optional argument:
 itself as the upstream; `--track=inherit` means to copy the upstream
 configuration of the start-point branch.
 +
-`--track=direct` is the default when the start point is a remote-tracking branch.
-Set the branch.autoSetupMerge configuration variable to `false` if you
-want `git switch`, `git checkout` and `git branch` to always behave as if `--no-track`
-were given. Set it to `always` if you want this behavior when the
-start-point is either a local or remote-tracking branch. Set it to
-`inherit` if you want to copy the tracking configuration from the
-branch point.
+The branch.autoSetupMerge configuration variable specifies how `git switch`,
+`git checkout` and `git branch` should behave when neither `--track` nor
+`--no-track` are specified:
++
+The default option, `true`, behaves as though `--track=direct`
+were given whenever the start-point is a remote-tracking branch.
+`false` behaves as if `--no-track` were given. `always` behaves as though
+`--track=direct` were given. `inherit` behaves as though `--track=inherit`
+were given. `simple` behaves as though `--track=direct` were given only when
+the start-point is a remote-tracking branch and the new branch has the same
+name as the remote branch.
 +
 See linkgit:git-pull[1] and linkgit:git-config[1] for additional discussion on
 how the `branch.<name>.remote` and `branch.<name>.merge` options are used.
index 853967dea01d0778e8d1d484afa9098ab4532ffc..ba4e67700ec2988de87074914a428737937dbfc3 100644 (file)
@@ -54,6 +54,11 @@ other housekeeping tasks (e.g. rerere, working trees, reflog...) will
 be performed as well.
 
 
+--cruft::
+       When expiring unreachable objects, pack them separately into a
+       cruft pack instead of storing the loose objects as loose
+       objects.
+
 --prune=<date>::
        Prune loose objects older than date (default is 2 weeks ago,
        overridable by the config variable `gc.pruneExpire`).
index e587c7763a7c21664c7586e273f348f70dd061d7..f784027bc13724712f902b115abd98bc1c04b43f 100644 (file)
@@ -101,6 +101,7 @@ success of the resolution after the custom tool has exited.
 
 CONFIGURATION
 -------------
+:git-mergetool: 1
 include::config/mergetool.txt[]
 
 TEMPORARY FILES
@@ -113,6 +114,13 @@ Setting the `mergetool.keepBackup` configuration variable to `false`
 causes `git mergetool` to automatically remove the backup as files
 are successfully merged.
 
+BACKEND SPECIFIC HINTS
+----------------------
+
+vimdiff
+~~~~~~~
+include::mergetools/vimdiff.txt[]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
index e21fcd8f7127a3a8e9e6fcb5a268ab66a097b3a2..de5ee6748e35886fd38cf3a4a73b28f270e06e2c 100644 (file)
@@ -636,7 +636,42 @@ git-p4.pathEncoding::
        Git expects paths encoded as UTF-8. Use this config to tell git-p4
        what encoding Perforce had used for the paths. This encoding is used
        to transcode the paths to UTF-8. As an example, Perforce on Windows
-       often uses "cp1252" to encode path names.
+       often uses "cp1252" to encode path names. If this option is passed
+       into a p4 clone request, it is persisted in the resulting new git
+       repo.
+
+git-p4.metadataDecodingStrategy::
+       Perforce keeps the encoding of a changelist descriptions and user
+       full names as stored by the client on a given OS. The p4v client
+       uses the OS-local encoding, and so different users can end up storing
+       different changelist descriptions or user full names in different
+       encodings, in the same depot.
+       Git tolerates inconsistent/incorrect encodings in commit messages
+       and author names, but expects them to be specified in utf-8.
+       git-p4 can use three different decoding strategies in handling the
+       encoding uncertainty in Perforce: 'passthrough' simply passes the
+       original bytes through from Perforce to git, creating usable but
+       incorrectly-encoded data when the Perforce data is encoded as
+       anything other than utf-8. 'strict' expects the Perforce data to be
+       encoded as utf-8, and fails to import when this is not true.
+       'fallback' attempts to interpret the data as utf-8, and otherwise
+       falls back to using a secondary encoding - by default the common
+       windows encoding 'cp-1252' - with upper-range bytes escaped if
+       decoding with the fallback encoding also fails.
+       Under python2 the default strategy is 'passthrough' for historical
+       reasons, and under python3 the default is 'fallback'.
+       When 'strict' is selected and decoding fails, the error message will
+       propose changing this config parameter as a workaround. If this
+       option is passed into a p4 clone request, it is persisted into the
+       resulting new git repo.
+
+git-p4.metadataFallbackEncoding::
+       Specify the fallback encoding to use when decoding Perforce author
+       names and changelists descriptions using the 'fallback' strategy
+       (see git-p4.metadataDecodingStrategy). The fallback encoding will
+       only be used when decoding as utf-8 fails. This option defaults to
+       cp1252, a common windows encoding. If this option is passed into a
+       p4 clone request, it is persisted into the resulting new git repo.
 
 git-p4.largeFileSystem::
        Specify the system that is used for large (binary) files. Please note
index f8344e1e5baf32a293f0bb574fb2c888e5a153a1..a9995a932ca2d246db2bf756792c92b2431970eb 100644 (file)
@@ -13,6 +13,7 @@ SYNOPSIS
        [--no-reuse-delta] [--delta-base-offset] [--non-empty]
        [--local] [--incremental] [--window=<n>] [--depth=<n>]
        [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
+       [--cruft] [--cruft-expiration=<time>]
        [--stdout [--filter=<filter-spec>] | <base-name>]
        [--shallow] [--keep-true-parents] [--[no-]sparse] < <object-list>
 
@@ -95,6 +96,35 @@ base-name::
 Incompatible with `--revs`, or options that imply `--revs` (such as
 `--all`), with the exception of `--unpacked`, which is compatible.
 
+--cruft::
+       Packs unreachable objects into a separate "cruft" pack, denoted
+       by the existence of a `.mtimes` file. Typically used by `git
+       repack --cruft`. Callers provide a list of pack names and
+       indicate which packs will remain in the repository, along with
+       which packs will be deleted (indicated by the `-` prefix). The
+       contents of the cruft pack are all objects not contained in the
+       surviving packs which have not exceeded the grace period (see
+       `--cruft-expiration` below), or which have exceeded the grace
+       period, but are reachable from an other object which hasn't.
++
+When the input lists a pack containing all reachable objects (and lists
+all other packs as pending deletion), the corresponding cruft pack will
+contain all unreachable objects (with mtime newer than the
+`--cruft-expiration`) along with any unreachable objects whose mtime is
+older than the `--cruft-expiration`, but are reachable from an
+unreachable object whose mtime is newer than the `--cruft-expiration`).
++
+Incompatible with `--unpack-unreachable`, `--keep-unreachable`,
+`--pack-loose-unreachable`, `--stdin-packs`, as well as any other
+options which imply `--revs`. Also incompatible with `--max-pack-size`;
+when this option is set, the maximum pack size is not inferred from
+`pack.packSizeLimit`.
+
+--cruft-expiration=<approxidate>::
+       If specified, objects are eliminated from the cruft pack if they
+       have an mtime older than `<approxidate>`. If unspecified (and
+       given `--cruft`), then no objects are eliminated.
+
 --window=<n>::
 --depth=<n>::
        These two options affect how the objects contained in
index a5356a230bb64a1ae5a71934262df541b0edf7c6..b9bfdc0a319a996c2f1ad9e256dab0f8eac8a0fb 100644 (file)
@@ -375,10 +375,13 @@ have finished your work-in-progress), attempt the merge again.
 SPARSE CHECKOUT
 ---------------
 
-Note: The `update-index` and `read-tree` primitives for supporting the
-skip-worktree bit predated the introduction of
-linkgit:git-sparse-checkout[1].  Users are encouraged to use
-`sparse-checkout` in preference to these low-level primitives.
+Note: The skip-worktree capabilities in linkgit:git-update-index[1]
+and `read-tree` predated the introduction of
+linkgit:git-sparse-checkout[1].  Users are encouraged to use the
+`sparse-checkout` command in preference to these plumbing commands for
+sparse-checkout/skip-worktree related needs.  However, the information
+below might be useful to users trying to understand the pattern style
+used in non-cone mode of the `sparse-checkout` command.
 
 "Sparse checkout" allows populating the working directory sparsely.
 It uses the skip-worktree bit (see linkgit:git-update-index[1]) to
index 9da4647061cdc7e85df685169c81f2f08b9d6707..262fb01aec004c880e16d2630494a194f720a713 100644 (file)
@@ -215,9 +215,10 @@ leave out at most one of A and B, in which case it defaults to HEAD.
 
 --keep-base::
        Set the starting point at which to create the new commits to the
-       merge base of <upstream> <branch>. Running
+       merge base of <upstream> and <branch>. Running
        'git rebase --keep-base <upstream> <branch>' is equivalent to
-       running 'git rebase --onto <upstream>... <upstream>'.
+       running
+       'git rebase --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
index cde9614e362854f4aa091348ef91ba69283cec0c..1dec3148348350bc6f26a53ca2add524d3f8b9bf 100644 (file)
@@ -35,6 +35,8 @@ OPTIONS
 -v::
 --verbose::
        Be a little more verbose and show remote url after name.
+       For promisor remotes, also show which filter (`blob:none` etc.)
+       are configured.
        NOTE: This must be placed between `remote` and subcommand.
 
 
index ee30edc178a4d418610612215935452b6daca567..0bf13893d8147d872dbedeed9def497b2a5a0fea 100644 (file)
@@ -63,6 +63,17 @@ to the new separate pack will be written.
        Also run  'git prune-packed' to remove redundant
        loose object files.
 
+--cruft::
+       Same as `-a`, unless `-d` is used. Then any unreachable objects
+       are packed into a separate cruft pack. Unreachable objects can
+       be pruned using the normal expiry rules with the next `git gc`
+       invocation (see linkgit:git-gc[1]). Incompatible with `-k`.
+
+--cruft-expiration=<approxidate>::
+       Expire unreachable objects older than `<approxidate>`
+       immediately instead of waiting for the next `git gc` invocation.
+       Only useful with `--cruft -d`.
+
 -l::
        Pass the `--local` option to 'git pack-objects'. See
        linkgit:git-pack-objects[1].
index 88e55f432f3a6c83333d9404105d6ae436f180d2..3776705bf5359ecc912e056dbf245afa0e775821 100644 (file)
@@ -15,15 +15,15 @@ SYNOPSIS
 DESCRIPTION
 -----------
 
-This command is used to create sparse checkouts, which means that it
-changes the working tree from having all tracked files present, to only
-have a subset of them.  It can also switch which subset of files are
-present, or undo and go back to having all tracked files present in the
-working copy.
+This command is used to create sparse checkouts, which change the
+working tree from having all tracked files present to only having a
+subset of those files.  It can also switch which subset of files are
+present, or undo and go back to having all tracked files present in
+the working copy.
 
 The subset of files is chosen by providing a list of directories in
-cone mode (which is recommended), or by providing a list of patterns
-in non-cone mode.
+cone mode (the default), or by providing a list of patterns in
+non-cone mode.
 
 When in a sparse-checkout, other Git commands behave a bit differently.
 For example, switching branches will not update paths outside the
@@ -44,9 +44,9 @@ COMMANDS
        Enable the necessary sparse-checkout config settings
        (`core.sparseCheckout`, `core.sparseCheckoutCone`, and
        `index.sparse`) if they are not already set to the desired values,
-       and write a set of patterns to the sparse-checkout file from the
-       list of arguments following the 'set' subcommand. Update the
-       working directory to match the new patterns.
+       populate the sparse-checkout file from the list of arguments
+       following the 'set' subcommand, and update the working directory to
+       match.
 +
 To ensure that adjusting the sparse-checkout settings within a worktree
 does not alter the sparse-checkout settings in other worktrees, the 'set'
@@ -60,22 +60,20 @@ When the `--stdin` option is provided, the directories or patterns are
 read from standard in as a newline-delimited list instead of from the
 arguments.
 +
-When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the
-input list is considered a list of directories.  This allows for
-better performance with a limited set of patterns (see 'CONE PATTERN
-SET' below).  The input format matches the output of `git ls-tree
---name-only`.  This includes interpreting pathnames that begin with a
-double quote (") as C-style quoted strings.  Note that the set command
-will write patterns to the sparse-checkout file to include all files
-contained in those directories (recursively) as well as files that are
-siblings of ancestor directories. This may become the default in the
-future; --no-cone can be passed to request non-cone mode.
+By default, the input list is considered a list of directories, matching
+the output of `git ls-tree -d --name-only`.  This includes interpreting
+pathnames that begin with a double quote (") as C-style quoted strings.
+Note that all files under the specified directories (at any depth) will
+be included in the sparse checkout, as well as files that are siblings
+of either the given directory or any of its ancestors (see 'CONE PATTERN
+SET' below for more details).  In the past, this was not the default,
+and `--cone` needed to be specified or `core.sparseCheckoutCone` needed
+to be enabled.
 +
-When `--no-cone` is passed or `core.sparseCheckoutCone` is not enabled,
-the input list is considered a list of patterns.  This mode is harder
-to use and less performant, and is thus not recommended.  See the
-"Sparse Checkout" section of linkgit:git-read-tree[1] and the "Pattern
-Set" sections below for more details.
+When `--no-cone` is passed, the input list is considered a list of
+patterns.  This mode has a number of drawbacks, including not working
+with some options like `--sparse-index`.  As explained in the
+"Non-cone Problems" section below, we do not recommend using it.
 +
 Use the `--[no-]sparse-index` option to use a sparse index (the
 default is to not use it).  A sparse index reduces the size of the
@@ -137,8 +135,45 @@ paths to pass to a subsequent 'set' or 'add' command.  However,
 the disable command, so the easy restore of calling a plain `init`
 decreased in utility.
 
-SPARSE CHECKOUT
----------------
+EXAMPLES
+--------
+`git sparse-checkout set MY/DIR1 SUB/DIR2`::
+
+       Change to a sparse checkout with all files (at any depth) under
+       MY/DIR1/ and SUB/DIR2/ present in the working copy (plus all
+       files immediately under MY/ and SUB/ and the toplevel
+       directory).  If already in a sparse checkout, change which files
+       are present in the working copy to this new selection.  Note
+       that this command will also delete all ignored files in any
+       directory that no longer has either tracked or
+       non-ignored-untracked files present.
+
+`git sparse-checkout disable`::
+
+       Repopulate the working directory with all files, disabling sparse
+       checkouts.
+
+`git sparse-checkout add SOME/DIR/ECTORY`::
+
+       Add all files under SOME/DIR/ECTORY/ (at any depth) to the
+       sparse checkout, as well as all files immediately under
+       SOME/DIR/ and immediately under SOME/.  Must already be in a
+       sparse checkout before using this command.
+
+`git sparse-checkout reapply`::
+
+       It is possible for commands to update the working tree in a
+       way that does not respect the selected sparsity directories.
+       This can come from tools external to Git writing files, or
+       even affect Git commands because of either special cases (such
+       as hitting conflicts when merging/rebasing), or because some
+       commands didn't fully support sparse checkouts (e.g. the old
+       `recursive` merge backend had only limited support).  This
+       command reapplies the existing sparse directory specifications
+       to make the working directory match.
+
+INTERNALS -- SPARSE CHECKOUT
+----------------------------
 
 "Sparse checkout" allows populating the working directory sparsely.  It
 uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell Git
@@ -155,64 +190,196 @@ directory, it updates the skip-worktree bits in the index based
 on this file. The files matching the patterns in the file will
 appear in the working directory, and the rest will not.
 
-To enable the sparse-checkout feature, run `git sparse-checkout set` to
-set the patterns you want to use.
+INTERNALS -- NON-CONE PROBLEMS
+------------------------------
+
+The `$GIT_DIR/info/sparse-checkout` file populated by the `set` and
+`add` subcommands is defined to be a bunch of patterns (one per line)
+using the same syntax as `.gitignore` files.  In cone mode, these
+patterns are restricted to matching directories (and users only ever
+need supply or see directory names), while in non-cone mode any
+gitignore-style pattern is permitted.  Using the full gitignore-style
+patterns in non-cone mode has a number of shortcomings:
+
+  * Fundamentally, it makes various worktree-updating processes (pull,
+    merge, rebase, switch, reset, checkout, etc.) require O(N*M) pattern
+    matches, where N is the number of patterns and M is the number of
+    paths in the index.  This scales poorly.
+
+  * Avoiding the scaling issue has to be done via limiting the number
+    of patterns via specifying leading directory name or glob.
+
+  * Passing globs on the command line is error-prone as users may
+    forget to quote the glob, causing the shell to expand it into all
+    matching files and pass them all individually along to
+    sparse-checkout set/add.  While this could also be a problem with
+    e.g. "git grep -- *.c", mistakes with grep/log/status appear in
+    the immediate output.  With sparse-checkout, the mistake gets
+    recorded at the time the sparse-checkout command is run and might
+    not be problematic until the user later switches branches or rebases
+    or merges, thus putting a delay between the user's error and when
+    they have a chance to catch/notice it.
+
+  * Related to the previous item, sparse-checkout has an 'add'
+    subcommand but no 'remove' subcommand.  Even if a 'remove'
+    subcommand were added, undoing an accidental unquoted glob runs
+    the risk of "removing too much", as it may remove entries that had
+    been included before the accidental add.
+
+  * Non-cone mode uses gitignore-style patterns to select what to
+    *include* (with the exception of negated patterns), while
+    .gitignore files use gitignore-style patterns to select what to
+    *exclude* (with the exception of negated patterns).  The
+    documentation on gitignore-style patterns usually does not talk in
+    terms of matching or non-matching, but on what the user wants to
+    "exclude".  This can cause confusion for users trying to learn how
+    to specify sparse-checkout patterns to get their desired behavior.
+
+  * Every other git subcommand that wants to provide "special path
+    pattern matching" of some sort uses pathspecs, but non-cone mode
+    for sparse-checkout uses gitignore patterns, which feels
+    inconsistent.
+
+  * It has edge cases where the "right" behavior is unclear.  Two examples:
+
+    First, two users are in a subdirectory, and the first runs
+       git sparse-checkout set '/toplevel-dir/*.c'
+    while the second runs
+       git sparse-checkout set relative-dir
+    Should those arguments be transliterated into
+       current/subdirectory/toplevel-dir/*.c
+    and
+       current/subdirectory/relative-dir
+    before inserting into the sparse-checkout file?  The user who typed
+    the first command is probably aware that arguments to set/add are
+    supposed to be patterns in non-cone mode, and probably would not be
+    happy with such a transliteration.  However, many gitignore-style
+    patterns are just paths, which might be what the user who typed the
+    second command was thinking, and they'd be upset if their argument
+    wasn't transliterated.
+
+    Second, what should bash-completion complete on for set/add commands
+    for non-cone users?  If it suggests paths, is it exacerbating the
+    problem above?  Also, if it suggests paths, what if the user has a
+    file or directory that begins with either a '!' or '#' or has a '*',
+    '\', '?', '[', or ']' in its name?  And if it suggests paths, will
+    it complete "/pro" to "/proc" (in the root filesytem) rather than to
+    "/progress.txt" in the current directory?  (Note that users are
+    likely to want to start paths with a leading '/' in non-cone mode,
+    for the same reason that .gitignore files often have one.)
+    Completing on files or directories might give nasty surprises in
+    all these cases.
+
+  * The excessive flexibility made other extensions essentially
+    impractical.  `--sparse-index` is likely impossible in non-cone
+    mode; even if it is somehow feasible, it would have been far more
+    work to implement and may have been too slow in practice.  Some
+    ideas for adding coupling between partial clones and sparse
+    checkouts are only practical with a more restricted set of paths
+    as well.
+
+For all these reasons, non-cone mode is deprecated.  Please switch to
+using cone mode.
+
+
+INTERNALS -- CONE MODE HANDLING
+-------------------------------
+
+The "cone mode", which is the default, lets you specify only what
+directories to include.  For any directory specified, all paths below
+that directory will be included, and any paths immediately under
+leading directories (including the toplevel directory) will also be
+included.  Thus, if you specified the directory
+    Documentation/technical/
+then your sparse checkout would contain:
+
+  * all files in the toplevel-directory
+  * all files immediately under Documentation/
+  * all files at any depth under Documentation/technical/
+
+Also, in cone mode, even if no directories are specified, then the
+files in the toplevel directory will be included.
 
-To repopulate the working directory with all files, use the
-`git sparse-checkout disable` command.
+When changing the sparse-checkout patterns in cone mode, Git will inspect each
+tracked directory that is not within the sparse-checkout cone to see if it
+contains any untracked files. If all of those files are ignored due to the
+`.gitignore` patterns, then the directory will be deleted. If any of the
+untracked files within that directory is not ignored, then no deletions will
+occur within that directory and a warning message will appear. If these files
+are important, then reset your sparse-checkout definition so they are included,
+use `git add` and `git commit` to store them, then remove any remaining files
+manually to ensure Git can behave optimally.
 
+See also the "Internals -- Cone Pattern Set" section to learn how the
+directories are transformed under the hood into a subset of the
+Full Pattern Set of sparse-checkout.
 
-FULL PATTERN SET
-----------------
 
-By default, the sparse-checkout file uses the same syntax as `.gitignore`
-files.
+INTERNALS -- FULL PATTERN SET
+-----------------------------
 
-While `$GIT_DIR/info/sparse-checkout` is usually used to specify what
-files are included, you can also specify what files are _not_ included,
-using negative patterns. For example, to remove the file `unwanted`:
+The full pattern set allows for arbitrary pattern matches and complicated
+inclusion/exclusion rules. These can result in O(N*M) pattern matches when
+updating the index, where N is the number of patterns and M is the number
+of paths in the index. To combat this performance issue, a more restricted
+pattern set is allowed when `core.sparseCheckoutCone` is enabled.
+
+The sparse-checkout file uses the same syntax as `.gitignore` files;
+see linkgit:gitignore[5] for details.  Here, though, the patterns are
+usually being used to select which files to include rather than which
+files to exclude.  (However, it can get a bit confusing since
+gitignore-style patterns have negations defined by patterns which
+begin with a '!', so you can also select files to _not_ include.)
+
+For example, to select everything, and then to remove the file
+`unwanted` (so that every file will appear in your working tree except
+the file named `unwanted`):
+
+    git sparse-checkout set --no-cone '/*' '!unwanted'
+
+These patterns are just placed into the
+`$GIT_DIR/info/sparse-checkout` as-is, so the contents of that file
+at this point would be
 
 ----------------
 /*
 !unwanted
 ----------------
 
+See also the "Sparse Checkout" section of linkgit:git-read-tree[1] to
+learn more about the gitignore-style patterns used in sparse
+checkouts.
 
-CONE PATTERN SET
-----------------
 
-The full pattern set allows for arbitrary pattern matches and complicated
-inclusion/exclusion rules. These can result in O(N*M) pattern matches when
-updating the index, where N is the number of patterns and M is the number
-of paths in the index. To combat this performance issue, a more restricted
-pattern set is allowed when `core.sparseCheckoutCone` is enabled.
+INTERNALS -- CONE PATTERN SET
+-----------------------------
 
-The accepted patterns in the cone pattern set are:
+In cone mode, only directories are accepted, but they are translated into
+the same gitignore-style patterns used in the full pattern set.  We refer
+to the particular patterns used in those mode as being of one of two types:
 
 1. *Recursive:* All paths inside a directory are included.
 
 2. *Parent:* All files immediately inside a directory are included.
 
-In addition to the above two patterns, we also expect that all files in the
-root directory are included. If a recursive pattern is added, then all
-leading directories are added as parent patterns.
-
-By default, when running `git sparse-checkout init`, the root directory is
-added as a parent pattern. At this point, the sparse-checkout file contains
-the following patterns:
+Since cone mode always includes files at the toplevel, when running
+`git sparse-checkout set` with no directories specified, the toplevel
+directory is added as a parent pattern.  At this point, the
+sparse-checkout file contains the following patterns:
 
 ----------------
 /*
 !/*/
 ----------------
 
-This says "include everything in root, but nothing two levels below root."
+This says "include everything immediately under the toplevel
+directory, but nothing at any level below that."
 
-When in cone mode, the `git sparse-checkout set` subcommand takes a list of
-directories instead of a list of sparse-checkout patterns. In this mode,
-the command `git sparse-checkout set A/B/C` sets the directory `A/B/C` as
-a recursive pattern, the directories `A` and `A/B` are added as parent
-patterns. The resulting sparse-checkout file is now
+When in cone mode, the `git sparse-checkout set` subcommand takes a
+list of directories.  The command `git sparse-checkout set A/B/C` sets
+the directory `A/B/C` as a recursive pattern, the directories `A` and
+`A/B` are added as parent patterns. The resulting sparse-checkout file
+is now
 
 ----------------
 /*
@@ -227,14 +394,18 @@ patterns. The resulting sparse-checkout file is now
 Here, order matters, so the negative patterns are overridden by the positive
 patterns that appear lower in the file.
 
-If `core.sparseCheckoutCone=true`, then Git will parse the sparse-checkout file
-expecting patterns of these types. Git will warn if the patterns do not match.
-If the patterns do match the expected format, then Git will use faster hash-
-based algorithms to compute inclusion in the sparse-checkout.
+Unless `core.sparseCheckoutCone` is explicitly set to `false`, Git will
+parse the sparse-checkout file expecting patterns of these types. Git will
+warn if the patterns do not match.  If the patterns do match the expected
+format, then Git will use faster hash-based algorithms to compute inclusion
+in the sparse-checkout.  If they do not match, git will behave as though
+`core.sparseCheckoutCone` was false, regardless of its setting.
 
-In the cone mode case, the `git sparse-checkout list` subcommand will list the
-directories that define the recursive patterns. For the example sparse-checkout
-file above, the output is as follows:
+In the cone mode case, despite the fact that full patterns are written
+to the $GIT_DIR/info/sparse-checkout file, the `git sparse-checkout
+list` subcommand will list the directories that define the recursive
+patterns. For the example sparse-checkout file above, the output is as
+follows:
 
 --------------------------
 $ git sparse-checkout list
@@ -246,19 +417,9 @@ case-insensitive check. This corrects for case mismatched filenames in the
 'git sparse-checkout set' command to reflect the expected cone in the working
 directory.
 
-When changing the sparse-checkout patterns in cone mode, Git will inspect each
-tracked directory that is not within the sparse-checkout cone to see if it
-contains any untracked files. If all of those files are ignored due to the
-`.gitignore` patterns, then the directory will be deleted. If any of the
-untracked files within that directory is not ignored, then no deletions will
-occur within that directory and a warning message will appear. If these files
-are important, then reset your sparse-checkout definition so they are included,
-use `git add` and `git commit` to store them, then remove any remaining files
-manually to ensure Git can behave optimally.
-
 
-SUBMODULES
-----------
+INTERNALS -- SUBMODULES
+-----------------------
 
 If your repository contains one or more submodules, then submodules
 are populated based on interactions with the `git submodule` command.
index 13f83a2a3a12209791de1032839764a493ec4457..302607a49676d59aef4f1f8d39d3a302b7b66cc2 100644 (file)
@@ -9,7 +9,7 @@ git - the stupid content tracker
 SYNOPSIS
 --------
 [verse]
-'git' [--version] [--help] [-C <path>] [-c <name>=<value>]
+'git' [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
     [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
     [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
     [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
@@ -39,6 +39,7 @@ or https://git-scm.com/docs.
 
 OPTIONS
 -------
+-v::
 --version::
        Prints the Git suite version that the 'git' program came from.
 +
@@ -46,6 +47,7 @@ This option is internally converted to `git version ...` and accepts
 the same options as the linkgit:git-version[1] command. If `--help` is
 also given, it takes precedence over `--version`.
 
+-h::
 --help::
        Prints the synopsis and a list of the most commonly used
        commands. If the option `--all` or `-a` is given then all
diff --git a/Documentation/mergetools/vimdiff.txt b/Documentation/mergetools/vimdiff.txt
new file mode 100644 (file)
index 0000000..2d631e9
--- /dev/null
@@ -0,0 +1,194 @@
+Description
+^^^^^^^^^^^
+
+When specifying `--tool=vimdiff` in `git mergetool` Git will open Vim with a 4
+windows layout distributed in the following way:
+....
+------------------------------------------
+|             |           |              |
+|   LOCAL     |   BASE    |   REMOTE     |
+|             |           |              |
+------------------------------------------
+|                                        |
+|                MERGED                  |
+|                                        |
+------------------------------------------
+....
+`LOCAL`, `BASE` and `REMOTE` are read-only buffers showing the contents of the
+conflicting file in specific commits ("commit you are merging into", "common
+ancestor commit" and "commit you are merging from" respectively)
+
+`MERGED` is a writable buffer where you have to resolve the conflicts (using the
+other read-only buffers as a reference). Once you are done, save and exit Vim as
+usual (`:wq`) or, if you want to abort, exit using `:cq`.
+
+Layout configuration
+^^^^^^^^^^^^^^^^^^^^
+
+You can change the windows layout used by Vim by setting configuration variable
+`mergetool.vimdiff.layout` which accepts a string where the following separators
+have special meaning:
+
+  - `+` is used to "open a new tab"
+  - `,` is used to "open a new vertical split"
+  - `/` is used to "open a new horizontal split"
+  - `@` is used to indicate which is the file containing the final version after
+    solving the conflicts. If not present, `MERGED` will be used by default.
+
+The precedence of the operators is this one (you can use parentheses to change
+it):
+
+    `@` > `+` > `/` > `,`
+
+Let's see some examples to understand how it works:
+
+* `layout = "(LOCAL,BASE,REMOTE)/MERGED"`
++
+--
+This is exactly the same as the default layout we have already seen.
+
+Note that `/` has precedence over `,` and thus the parenthesis are not
+needed in this case. The next layout definition is equivalent:
+
+    layout = "LOCAL,BASE,REMOTE / MERGED"
+--
+* `layout = "LOCAL,MERGED,REMOTE"`
++
+--
+If, for some reason, we are not interested in the `BASE` buffer.
+....
+------------------------------------------
+|             |           |              |
+|             |           |              |
+|   LOCAL     |   MERGED  |   REMOTE     |
+|             |           |              |
+|             |           |              |
+------------------------------------------
+....
+--
+* `layout = "MERGED"`
++
+--
+Only the `MERGED` buffer will be shown. Note, however, that all the other
+ones are still loaded in vim, and you can access them with the "buffers"
+command.
+....
+------------------------------------------
+|                                        |
+|                                        |
+|                 MERGED                 |
+|                                        |
+|                                        |
+------------------------------------------
+....
+--
+* `layout = "@LOCAL,REMOTE"`
++
+--
+When `MERGED` is not present in the layout, you must "mark" one of the
+buffers with an asterisk. That will become the buffer you need to edit and
+save after resolving the conflicts.
+....
+------------------------------------------
+|                   |                    |
+|                   |                    |
+|                   |                    |
+|     LOCAL         |    REMOTE          |
+|                   |                    |
+|                   |                    |
+|                   |                    |
+------------------------------------------
+....
+--
+* `layout = "LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE"`
++
+--
+Three tabs will open: the first one is a copy of the default layout, while
+the other two only show the differences between (`BASE` and `LOCAL`) and
+(`BASE` and `REMOTE`) respectively.
+....
+------------------------------------------
+| <TAB #1> |  TAB #2  |  TAB #3  |       |
+------------------------------------------
+|             |           |              |
+|   LOCAL     |   BASE    |   REMOTE     |
+|             |           |              |
+------------------------------------------
+|                                        |
+|                MERGED                  |
+|                                        |
+------------------------------------------
+....
+....
+------------------------------------------
+|  TAB #1  | <TAB #2> |  TAB #3  |       |
+------------------------------------------
+|                   |                    |
+|                   |                    |
+|                   |                    |
+|     BASE          |    LOCAL           |
+|                   |                    |
+|                   |                    |
+|                   |                    |
+------------------------------------------
+....
+....
+------------------------------------------
+|  TAB #1  |  TAB #2  | <TAB #3> |       |
+------------------------------------------
+|                   |                    |
+|                   |                    |
+|                   |                    |
+|     BASE          |    REMOTE          |
+|                   |                    |
+|                   |                    |
+|                   |                    |
+------------------------------------------
+....
+--
+* `layout = "LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE + (LOCAL/BASE/REMOTE),MERGED"`
++
+--
+Same as the previous example, but adds a fourth tab with the same
+information as the first tab, with a different layout.
+....
+---------------------------------------------
+|  TAB #1  |  TAB #2  |  TAB #3  | <TAB #4> |
+---------------------------------------------
+|       LOCAL         |                     |
+|---------------------|                     |
+|       BASE          |        MERGED       |
+|---------------------|                     |
+|       REMOTE        |                     |
+---------------------------------------------
+....
+Note how in the third tab definition we need to use parenthesis to make `,`
+have precedence over `/`.
+--
+
+Variants
+^^^^^^^^
+
+Instead of `--tool=vimdiff`, you can also use one of these other variants:
+
+  * `--tool=gvimdiff`, to open gVim instead of Vim.
+
+  * `--tool=nvimdiff`, to open Neovim instead of Vim.
+
+When using these variants, in order to specify a custom layout you will have to
+set configuration variables `mergetool.gvimdiff.layout` and
+`mergetool.nvimdiff.layout` instead of `mergetool.vimdiff.layout`
+
+In addition, for backwards compatibility with previous Git versions, you can
+also append `1`, `2` or `3` to either `vimdiff` or any of the variants (ex:
+`vimdiff3`, `nvimdiff1`, etc...) to use a predefined layout.
+In other words, using `--tool=[g,n,]vimdiffx` is the same as using
+`--tool=[g,n,]vimdiff` and setting configuration variable
+`mergetool.[g,n,]vimdiff.layout` to...
+
+  * `x=1`: `"@LOCAL, REMOTE"`
+  * `x=2`: `"LOCAL, MERGED, REMOTE"`
+  * `x=3`: `"MERGED"`
+
+Example: using `--tool=gvimdiff2` will open `gvim` with three columns (LOCAL,
+MERGED and REMOTE).
index fd4f4e26c90face314632ac6c2b81bed648abd17..195e74eec633ea913c0934d2b690b674360376d7 100644 (file)
@@ -25,6 +25,11 @@ ordering and formatting options, such as `--reverse`.
 --after=<date>::
        Show commits more recent than a specific date.
 
+--since-as-filter=<date>::
+       Show all commits more recent than a specific date. This visits
+       all commits in the range, rather than stopping at the first commit which
+       is older than a specific date.
+
 --until=<date>::
 --before=<date>::
        Show commits older than a specific date.
index bb13ca3db8b5f72e5754e8d925cf26a85b8304db..f4a8a69087864fad4faaee74b8edc34f3e1e86a8 100644 (file)
@@ -5,7 +5,7 @@ information to stderr or a file.  The Trace2 feature is inactive unless
 explicitly enabled by enabling one or more Trace2 Targets.
 
 The Trace2 API is intended to replace the existing (Trace1)
-printf-style tracing provided by the existing `GIT_TRACE` and
+`printf()`-style tracing provided by the existing `GIT_TRACE` and
 `GIT_TRACE_PERFORMANCE` facilities.  During initial implementation,
 Trace2 and Trace1 may operate in parallel.
 
@@ -24,8 +24,8 @@ for example.
 
 Trace2 is controlled using `trace2.*` config values in the system and
 global config files and `GIT_TRACE2*` environment variables.  Trace2 does
-not read from repo local or worktree config files or respect `-c`
-command line config settings.
+not read from repo local or worktree config files, nor does it respect
+`-c` command line config settings.
 
 == Trace2 Targets
 
@@ -34,8 +34,8 @@ Format details are given in a later section.
 
 === The Normal Format Target
 
-The normal format target is a tradition printf format and similar
-to GIT_TRACE format.  This format is enabled with the `GIT_TRACE2`
+The normal format target is a traditional `printf()` format and similar
+to the `GIT_TRACE` format.  This format is enabled with the `GIT_TRACE2`
 environment variable or the `trace2.normalTarget` system or global
 config setting.
 
@@ -69,8 +69,8 @@ $ cat ~/log.normal
 === The Performance Format Target
 
 The performance format target (PERF) is a column-based format to
-replace GIT_TRACE_PERFORMANCE and is suitable for development and
-testing, possibly to complement tools like gprof.  This format is
+replace `GIT_TRACE_PERFORMANCE` and is suitable for development and
+testing, possibly to complement tools like `gprof`.  This format is
 enabled with the `GIT_TRACE2_PERF` environment variable or the
 `trace2.perfTarget` system or global config setting.
 
@@ -128,7 +128,7 @@ yields
 
 ------------
 $ cat ~/log.event
-{"event":"version","sid":"sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"3","exe":"2.20.1.155.g426c96fcdb"}
+{"event":"version","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"3","exe":"2.20.1.155.g426c96fcdb"}
 {"event":"start","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621027Z","file":"common-main.c","line":39,"t_abs":0.001173,"argv":["git","version"]}
 {"event":"cmd_name","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621122Z","file":"git.c","line":432,"name":"version","hierarchy":"version"}
 {"event":"exit","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621236Z","file":"git.c","line":662,"t_abs":0.001227,"code":0}
@@ -170,9 +170,9 @@ Some functions have a `_va_fl()` suffix to indicate that they also
 take a `va_list` argument.
 
 Some functions have a `_printf_fl()` suffix to indicate that they also
-take a varargs argument.
+take a `printf()` style format with a variable number of arguments.
 
-There are CPP wrapper macros and ifdefs to hide most of these details.
+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.
 
@@ -234,7 +234,7 @@ Events are written as lines of the form:
        is the event name.
 
 `<event-message>`::
-       is a free-form printf message intended for human consumption.
+       is a free-form `printf()` message intended for human consumption.
 +
 Note that this may contain embedded LF or CRLF characters that are
 not escaped, so the event may spill across multiple lines.
@@ -300,7 +300,7 @@ This field is in anticipation of in-proc submodules in the future.
        indicate a broad category, such as "index" or "status".
 
 `<perf-event-message>`::
-       is a free-form printf message intended for human consumption.
+       is a free-form `printf()` message intended for human consumption.
 
 ------------
 15:33:33.532712 wt-status.c:2310                  | d0 | main                     | region_enter | r1  |  0.126064 |           | status     | label:print
@@ -533,7 +533,7 @@ these special values are used:
 ------------
 
 `"cmd_mode"`::
-       This event, when present, describes the command variant This
+       This event, when present, describes the command variant. This
        event may be emitted more than once.
 +
 ------------
@@ -588,7 +588,7 @@ with "?".
 
 `"child_exit"`::
        This event is generated after the current process has returned
-       from the waitpid() and collected the exit information from the
+       from the `waitpid()` and collected the exit information from the
        child.
 +
 ------------
@@ -609,7 +609,7 @@ process may be a shell script which doesn't have a session-id.)
 +
 Note that the `t_rel` field contains the observed run time in seconds
 for the child process (starting before the fork/exec/spawn and
-stopping after the waitpid() and includes OS process creation overhead).
+stopping after the `waitpid()` and includes OS process creation overhead).
 So this time will be slightly larger than the atexit time reported by
 the child process itself.
 
@@ -635,7 +635,7 @@ process may be a shell script which doesn't have a session-id.)
 +
 This event is generated after the child is started in the background
 and given a little time to boot up and start working.  If the child
-startups normally and while the parent is still waiting, the "ready"
+starts up normally while the parent is still waiting, the "ready"
 field will have the value "ready".
 If the child is too slow to start and the parent times out, the field
 will have the value "timeout".
@@ -949,7 +949,7 @@ atexit elapsed:3.868970 code:0
 
 Regions::
 
-       Regions can be use to time an interesting section of code.
+       Regions can be used to time an interesting section of code.
 +
 ----------------
 void wt_status_collect(struct wt_status *s)
@@ -1103,9 +1103,9 @@ Thread Events::
 
        Thread messages added to a thread-proc.
 +
-For example, the multithreaded preload-index code can be
+For example, the multi-threaded preload-index code can be
 instrumented with a region around the thread pool and then
-per-thread start and exit events within the threadproc.
+per-thread start and exit events within the thread-proc.
 +
 ----------------
 static void *preload_thread(void *_data)
@@ -1214,11 +1214,11 @@ as each thread starts and allocates TLS storage.
 There are a few issues to resolve before we can completely
 switch to Trace2.
 
-* Updating existing tests that assume GIT_TRACE format messages.
+* Updating existing tests that assume `GIT_TRACE` format messages.
 
-* How to best handle custom GIT_TRACE_<key> messages?
+* How to best handle custom `GIT_TRACE_<key>` messages?
 
-** The GIT_TRACE_<key> mechanism allows each <key> to write to a
+** The `GIT_TRACE_<key>` mechanism allows each <key> to write to a
 different file (in addition to just stderr).
 
 ** Do we want to maintain that ability or simply write to the existing
diff --git a/Documentation/technical/cruft-packs.txt b/Documentation/technical/cruft-packs.txt
new file mode 100644 (file)
index 0000000..d81f3a8
--- /dev/null
@@ -0,0 +1,123 @@
+= Cruft packs
+
+The cruft packs feature offer an alternative to Git's traditional mechanism of
+removing unreachable objects. This document provides an overview of Git's
+pruning mechanism, and how a cruft pack can be used instead to accomplish the
+same.
+
+== Background
+
+To remove unreachable objects from your repository, Git offers `git repack -Ad`
+(see linkgit:git-repack[1]). Quoting from the documentation:
+
+[quote]
+[...] unreachable objects in a previous pack become loose, unpacked objects,
+instead of being left in the old pack. [...] loose unreachable objects will be
+pruned according to normal expiry rules with the next 'git gc' invocation.
+
+Unreachable objects aren't removed immediately, since doing so could race with
+an incoming push which may reference an object which is about to be deleted.
+Instead, those unreachable objects are stored as loose objects and stay that way
+until they are older than the expiration window, at which point they are removed
+by linkgit:git-prune[1].
+
+Git must store these unreachable objects loose in order to keep track of their
+per-object mtimes. If these unreachable objects were written into one big pack,
+then either freshening that pack (because an object contained within it was
+re-written) or creating a new pack of unreachable objects would cause the pack's
+mtime to get updated, and the objects within it would never leave the expiration
+window. Instead, objects are stored loose in order to keep track of the
+individual object mtimes and avoid a situation where all cruft objects are
+freshened at once.
+
+This can lead to undesirable situations when a repository contains many
+unreachable objects which have not yet left the grace period. Having large
+directories in the shards of `.git/objects` can lead to decreased performance in
+the repository. But given enough unreachable objects, this can lead to inode
+starvation and degrade the performance of the whole system. Since we
+can never pack those objects, these repositories often take up a large amount of
+disk space, since we can only zlib compress them, but not store them in delta
+chains.
+
+== Cruft packs
+
+A cruft pack eliminates the need for storing unreachable objects in a loose
+state by including the per-object mtimes in a separate file alongside a single
+pack containing all loose objects.
+
+A cruft pack is written by `git repack --cruft` when generating a new pack.
+linkgit:git-pack-objects[1]'s `--cruft` option. Note that `git repack --cruft`
+is a classic all-into-one repack, meaning that everything in the resulting pack is
+reachable, and everything else is unreachable. Once written, the `--cruft`
+option instructs `git repack` to generate another pack containing only objects
+not packed in the previous step (which equates to packing all unreachable
+objects together). This progresses as follows:
+
+  1. Enumerate every object, marking any object which is (a) not contained in a
+     kept-pack, and (b) whose mtime is within the grace period as a traversal
+     tip.
+
+  2. Perform a reachability traversal based on the tips gathered in the previous
+     step, adding every object along the way to the pack.
+
+  3. Write the pack out, along with a `.mtimes` file that records the per-object
+     timestamps.
+
+This mode is invoked internally by linkgit:git-repack[1] when instructed to
+write a cruft pack. Crucially, the set of in-core kept packs is exactly the set
+of packs which will not be deleted by the repack; in other words, they contain
+all of the repository's reachable objects.
+
+When a repository already has a cruft pack, `git repack --cruft` typically only
+adds objects to it. An exception to this is when `git repack` is given the
+`--cruft-expiration` option, which allows the generated cruft pack to omit
+expired objects instead of waiting for linkgit:git-gc[1] to expire those objects
+later on.
+
+It is linkgit:git-gc[1] that is typically responsible for removing expired
+unreachable objects.
+
+== Caution for mixed-version environments
+
+Repositories that have cruft packs in them will continue to work with any older
+version of Git. Note, however, that previous versions of Git which do not
+understand the `.mtimes` file will use the cruft pack's mtime as the mtime for
+all of the objects in it. In other words, do not expect older (pre-cruft pack)
+versions of Git to interpret or even read the contents of the `.mtimes` file.
+
+Note that having mixed versions of Git GC-ing the same repository can lead to
+unreachable objects never being completely pruned. This can happen under the
+following circumstances:
+
+  - An older version of Git running GC explodes the contents of an existing
+    cruft pack loose, using the cruft pack's mtime.
+  - A newer version running GC collects those loose objects into a cruft pack,
+    where the .mtime file reflects the loose object's actual mtimes, but the
+    cruft pack mtime is "now".
+
+Repeating this process will lead to unreachable objects not getting pruned as a
+result of repeatedly resetting the objects' mtimes to the present time.
+
+If you are GC-ing repositories in a mixed version environment, consider omitting
+the `--cruft` option when using linkgit:git-repack[1] and linkgit:git-gc[1], and
+leaving the `gc.cruftPacks` configuration unset until all writers understand
+cruft packs.
+
+== Alternatives
+
+Notable alternatives to this design include:
+
+  - The location of the per-object mtime data, and
+  - Storing unreachable objects in multiple cruft packs.
+
+On the location of mtime data, a new auxiliary file tied to the pack was chosen
+to avoid complicating the `.idx` format. If the `.idx` format were ever to gain
+support for optional chunks of data, it may make sense to consolidate the
+`.mtimes` format into the `.idx` itself.
+
+Storing unreachable objects among multiple cruft packs (e.g., creating a new
+cruft pack during each repacking operation including only unreachable objects
+which aren't already stored in an earlier cruft pack) is significantly more
+complicated to construct, and so aren't pursued here. The obvious drawback to
+the current implementation is that the entire cruft pack must be re-written from
+scratch.
index 6d3efb7d16e10683ab3ad8e6bf87217e443f350e..b520aa9c45bf6cf9b12d6ef798658c298b1888a2 100644 (file)
@@ -294,6 +294,25 @@ Pack file entry: <+
 
 All 4-byte numbers are in network order.
 
+== pack-*.mtimes files have the format:
+
+All 4-byte numbers are in network byte order.
+
+  - A 4-byte magic number '0x4d544d45' ('MTME').
+
+  - A 4-byte version identifier (= 1).
+
+  - A 4-byte hash function identifier (= 1 for SHA-1, 2 for SHA-256).
+
+  - A table of 4-byte unsigned integers. The ith value is the
+    modification time (mtime) of the ith object in the corresponding
+    pack by lexicographic (index) order. The mtimes count standard
+    epoch seconds.
+
+  - A trailer, containing a checksum of the corresponding packfile,
+    and a checksum of all of the above (each having length according
+    to the specified hash function).
+
 == multi-pack-index (MIDX) files have the following format:
 
 The multi-pack-index files refer to multiple pack-files and loose objects.
index c1e8552d27e84c07a65de289f55f11df323701a0..1d667699e1926de980806790e50dfc0610743aad 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.36.1
+DEF_VER=v2.36.GIT
 
 LF='
 '
index f8bccfab5e9c46d39be6fe28b091330d5a3dd895..790382bd1e33685124c5016d35be534a4fa2bf01 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -569,7 +569,9 @@ INSTALL = install
 TCL_PATH = tclsh
 TCLTK_PATH = wish
 XGETTEXT = xgettext
+MSGCAT = msgcat
 MSGFMT = msgfmt
+MSGMERGE = msgmerge
 CURL_CONFIG = curl-config
 GCOV = gcov
 STRIP = strip
@@ -738,6 +740,7 @@ TEST_BUILTINS_OBJS += test-oid-array.o
 TEST_BUILTINS_OBJS += test-oidmap.o
 TEST_BUILTINS_OBJS += test-oidtree.o
 TEST_BUILTINS_OBJS += test-online-cpus.o
+TEST_BUILTINS_OBJS += test-pack-mtimes.o
 TEST_BUILTINS_OBJS += test-parse-options.o
 TEST_BUILTINS_OBJS += test-parse-pathspec-file.o
 TEST_BUILTINS_OBJS += test-partial-clone.o
@@ -844,7 +847,7 @@ generated-hdrs: $(GENERATED_H)
 ## Exhaustive lists of our source files, either dynamically generated,
 ## or hardcoded.
 SOURCES_CMD = ( \
-       git ls-files \
+       git ls-files --deduplicate \
                '*.[hcS]' \
                '*.sh' \
                ':!*[tp][0-9][0-9][0-9][0-9]*' \
@@ -855,12 +858,13 @@ SOURCES_CMD = ( \
                -o \( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \) \
                -o \( -name contrib -type d -prune \) \
                -o \( -name build -type d -prune \) \
+               -o \( -name .build -type d -prune \) \
                -o \( -name 'trash*' -type d -prune \) \
                -o \( -name '*.[hcS]' -type f -print \) \
                -o \( -name '*.sh' -type f -print \) \
                | sed -e 's|^\./||' \
        )
-FOUND_SOURCE_FILES := $(shell $(SOURCES_CMD))
+FOUND_SOURCE_FILES := $(filter-out $(GENERATED_H),$(shell $(SOURCES_CMD)))
 
 FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))
 FOUND_H_SOURCES = $(filter %.h,$(FOUND_SOURCE_FILES))
@@ -993,6 +997,7 @@ LIB_OBJS += oidtree.o
 LIB_OBJS += pack-bitmap-write.o
 LIB_OBJS += pack-bitmap.o
 LIB_OBJS += pack-check.o
+LIB_OBJS += pack-mtimes.o
 LIB_OBJS += pack-objects.o
 LIB_OBJS += pack-revindex.o
 LIB_OBJS += pack-write.o
@@ -1267,8 +1272,9 @@ PTHREAD_CFLAGS =
 SPARSE_FLAGS ?= -std=gnu99
 SP_EXTRA_FLAGS = -Wno-universal-initializer
 
-# For informing GIT-BUILD-OPTIONS of the SANITIZE=leak target
+# For informing GIT-BUILD-OPTIONS of the SANITIZE=leak,address targets
 SANITIZE_LEAK =
+SANITIZE_ADDRESS =
 
 # For the 'coccicheck' target; setting SPATCH_BATCH_SIZE higher will
 # usually result in less CPU usage at the cost of higher peak memory.
@@ -1314,6 +1320,7 @@ SANITIZE_LEAK = YesCompiledWithIt
 endif
 ifneq ($(filter address,$(SANITIZERS)),)
 NO_REGEX = NeededForASAN
+SANITIZE_ADDRESS = YesCompiledWithIt
 endif
 endif
 
@@ -2706,17 +2713,18 @@ XGETTEXT_FLAGS = \
        --force-po \
        --add-comments=TRANSLATORS: \
        --msgid-bugs-address="Git Mailing List <git@vger.kernel.org>" \
-       --from-code=UTF-8
+       --package-name=Git
 XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
        --keyword=_ --keyword=N_ --keyword="Q_:1,2"
 XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
        --keyword=gettextln --keyword=eval_gettextln
 XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
        --keyword=__ --keyword=N__ --keyword="__n:1,2"
-LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
-LOCALIZED_SH = $(SCRIPT_SH)
-LOCALIZED_SH += git-sh-setup.sh
-LOCALIZED_PERL = $(SCRIPT_PERL)
+MSGMERGE_FLAGS = --add-location --backup=off --update
+LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(SCALAR_SOURCES) \
+               $(GENERATED_H))
+LOCALIZED_SH = $(sort $(SCRIPT_SH) git-sh-setup.sh)
+LOCALIZED_PERL = $(sort $(SCRIPT_PERL))
 
 ifdef XGETTEXT_INCLUDE_TESTS
 LOCALIZED_C += t/t0200/test.c
@@ -2724,38 +2732,129 @@ LOCALIZED_SH += t/t0200/test.sh
 LOCALIZED_PERL += t/t0200/test.perl
 endif
 
-## Note that this is meant to be run only by the localization coordinator
-## under a very controlled condition, i.e. (1) it is to be run in a
-## Git repository (not a tarball extract), (2) any local modifications
-## will be lost.
+## We generate intermediate .build/pot/po/%.po files containing a
+## extract of the translations we find in each file in the source
+## tree. We will assemble them using msgcat to create the final
+## "po/git.pot" file.
+LOCALIZED_ALL_GEN_PO =
+
+LOCALIZED_C_GEN_PO = $(LOCALIZED_C:%=.build/pot/po/%.po)
+LOCALIZED_ALL_GEN_PO += $(LOCALIZED_C_GEN_PO)
+
+LOCALIZED_SH_GEN_PO = $(LOCALIZED_SH:%=.build/pot/po/%.po)
+LOCALIZED_ALL_GEN_PO += $(LOCALIZED_SH_GEN_PO)
+
+LOCALIZED_PERL_GEN_PO = $(LOCALIZED_PERL:%=.build/pot/po/%.po)
+LOCALIZED_ALL_GEN_PO += $(LOCALIZED_PERL_GEN_PO)
+
 ## Gettext tools cannot work with our own custom PRItime type, so
 ## we replace PRItime with PRIuMAX.  We need to update this to
 ## PRIdMAX if we switch to a signed type later.
+$(LOCALIZED_C_GEN_PO): .build/pot/po/%.po: %
+       $(call mkdir_p_parent_template)
+       $(QUIET_XGETTEXT) \
+           if grep -q PRItime $<; then \
+               (\
+                       sed -e 's|PRItime|PRIuMAX|g' <$< \
+                               >.build/pot/po/$< && \
+                       cd .build/pot/po && \
+                       $(XGETTEXT) --omit-header \
+                               -o $(@:.build/pot/po/%=%) \
+                               $(XGETTEXT_FLAGS_C) $< && \
+                       rm $<; \
+               ); \
+           else \
+               $(XGETTEXT) --omit-header \
+                       -o $@ $(XGETTEXT_FLAGS_C) $<; \
+           fi
 
-po/git.pot: $(GENERATED_H) FORCE
-       # All modifications will be reverted at the end, so we do not
-       # want to have any local change.
-       git diff --quiet HEAD && git diff --quiet --cached
+$(LOCALIZED_SH_GEN_PO): .build/pot/po/%.po: %
+       $(call mkdir_p_parent_template)
+       $(QUIET_XGETTEXT)$(XGETTEXT) --omit-header \
+               -o$@ $(XGETTEXT_FLAGS_SH) $<
 
-       @for s in $(LOCALIZED_C) $(LOCALIZED_SH) $(LOCALIZED_PERL); \
-       do \
-               sed -e 's|PRItime|PRIuMAX|g' <"$$s" >"$$s+" && \
-               cat "$$s+" >"$$s" && rm "$$s+"; \
-       done
+$(LOCALIZED_PERL_GEN_PO): .build/pot/po/%.po: %
+       $(call mkdir_p_parent_template)
+       $(QUIET_XGETTEXT)$(XGETTEXT) --omit-header \
+               -o$@ $(XGETTEXT_FLAGS_PERL) $<
+
+define gen_pot_header
+$(XGETTEXT) $(XGETTEXT_FLAGS_C) \
+       -o - /dev/null | \
+sed -e 's|charset=CHARSET|charset=UTF-8|' \
+    -e 's|\(Last-Translator: \)FULL NAME <.*>|\1make by the Makefile|' \
+    -e 's|\(Language-Team: \)LANGUAGE <.*>|\1Git Mailing List <git@vger.kernel.org>|' \
+    >$@ && \
+echo '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n"' >>$@
+endef
 
-       $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
-       $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
-               $(LOCALIZED_SH)
-       $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_PERL) \
-               $(LOCALIZED_PERL)
+.build/pot/git.header: $(LOCALIZED_ALL_GEN_PO)
+       $(call mkdir_p_parent_template)
+       $(QUIET_GEN)$(gen_pot_header)
 
-       # Reverting the munged source, leaving only the updated $@
-       git reset --hard
-       mv $@+ $@
+po/git.pot: .build/pot/git.header $(LOCALIZED_ALL_GEN_PO)
+       $(QUIET_GEN)$(MSGCAT) $^ >$@
 
 .PHONY: pot
 pot: po/git.pot
 
+define check_po_file_envvar
+       $(if $(PO_FILE), \
+               $(if $(filter po/%.po,$(PO_FILE)), , \
+                       $(error PO_FILE should match pattern: "po/%.po")), \
+               $(error PO_FILE is not defined))
+endef
+
+.PHONY: po-update
+po-update: po/git.pot
+       $(check_po_file_envvar)
+       @if test ! -e $(PO_FILE); then \
+               echo >&2 "error: $(PO_FILE) does not exist"; \
+               echo >&2 'To create an initial po file, use: "make po-init PO_FILE=po/XX.po"'; \
+               exit 1; \
+       fi
+       $(QUIET_MSGMERGE)$(MSGMERGE) $(MSGMERGE_FLAGS) $(PO_FILE) po/git.pot
+
+.PHONY: check-pot
+check-pot: $(LOCALIZED_ALL_GEN_PO)
+
+### TODO FIXME: Translating everything in these files is a bad
+### heuristic for "core", as we'll translate obscure error() messages
+### along with commonly seen i18n messages. A better heuristic would
+### be to e.g. use spatch to first remove error/die/warning
+### etc. messages.
+LOCALIZED_C_CORE =
+LOCALIZED_C_CORE += builtin/checkout.c
+LOCALIZED_C_CORE += builtin/clone.c
+LOCALIZED_C_CORE += builtin/index-pack.c
+LOCALIZED_C_CORE += builtin/push.c
+LOCALIZED_C_CORE += builtin/reset.c
+LOCALIZED_C_CORE += remote.c
+LOCALIZED_C_CORE += wt-status.c
+
+LOCALIZED_C_CORE_GEN_PO = $(LOCALIZED_C_CORE:%=.build/pot/po/%.po)
+
+.build/pot/git-core.header: $(LOCALIZED_C_CORE_GEN_PO)
+       $(call mkdir_p_parent_template)
+       $(QUIET_GEN)$(gen_pot_header)
+
+po/git-core.pot: .build/pot/git-core.header $(LOCALIZED_C_CORE_GEN_PO)
+       $(QUIET_GEN)$(MSGCAT) $^ >$@
+
+.PHONY: po-init
+po-init: po/git-core.pot
+       $(check_po_file_envvar)
+       @if test -e $(PO_FILE); then \
+               echo >&2 "error: $(PO_FILE) exists already"; \
+               exit 1; \
+       fi
+       $(QUIET_MSGINIT)msginit \
+               --input=$< \
+               --output=$(PO_FILE) \
+               --no-translator \
+               --locale=$(PO_FILE:po/%.po=%)
+
+## po/*.po files & their rules
 ifdef NO_GETTEXT
 POFILES :=
 MOFILES :=
@@ -2862,6 +2961,7 @@ GIT-BUILD-OPTIONS: FORCE
        @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)\' >>$@+
 ifdef FSMONITOR_DAEMON_BACKEND
        @echo FSMONITOR_DAEMON_BACKEND=\''$(subst ','\'',$(subst ','\'',$(FSMONITOR_DAEMON_BACKEND)))'\' >>$@+
@@ -3290,6 +3390,8 @@ cocciclean:
        $(RM) contrib/coccinelle/*.cocci.patch*
 
 clean: profile-clean coverage-clean cocciclean
+       $(RM) -r .build
+       $(RM) po/git.pot po/git-core.pot
        $(RM) *.res
        $(RM) $(OBJECTS)
        $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)
@@ -3407,6 +3509,7 @@ coverage-clean-results:
        $(RM) coverage-untested-functions
        $(RM) -r cover_db/
        $(RM) -r cover_db_html/
+       $(RM) coverage-test.made
 
 coverage-clean: coverage-clean-results
        $(RM) $(addsuffix *.gcno,$(object_dirs))
@@ -3421,13 +3524,17 @@ coverage-compile:
 coverage-test: coverage-clean-results coverage-compile
        $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
                DEFAULT_TEST_TARGET=test -j1 test
+       touch coverage-test.made
+
+coverage-test.made:
+       $(MAKE) coverage-test
 
 coverage-prove: coverage-clean-results coverage-compile
        $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
                DEFAULT_TEST_TARGET=prove GIT_PROVE_OPTS="$(GIT_PROVE_OPTS) -j1" \
                -j1 test
 
-coverage-report:
+coverage-report: coverage-test.made
        $(QUIET_GCOV)for dir in $(object_dirs); do \
                $(GCOV) $(GCOVFLAGS) --object-directory=$$dir $$dir*.c || exit; \
        done
index 4600187f85ed014f1b2ded58da0722461436c7ca..51144b6e83418a44108511632565ef053f8c7712 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.36.1.txt
\ No newline at end of file
+Documentation/RelNotes/2.37.0.txt
\ No newline at end of file
index 72472103017920ac227641042f05383a40e5c673..6047e8f6489fa3e6695e3925cd513963d05a5615 100644 (file)
@@ -568,8 +568,7 @@ static int get_modified_files(struct repository *r,
                        run_diff_files(&rev, 0);
                }
 
-               if (ps)
-                       clear_pathspec(&rev.prune_data);
+               release_revisions(&rev);
        }
        hashmap_clear_and_free(&s.file_map, struct pathname_entry, ent);
        if (unmerged_count)
diff --git a/alloc.c b/alloc.c
index 957a0af3626432b0c9c2dd1301f20c4ff339a0a4..27f697e4c87a05ef7cc847a17e83e14e9cfd2a4d 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -27,7 +27,6 @@ union any_object {
 };
 
 struct alloc_state {
-       int count; /* total number of nodes allocated */
        int nr;    /* number of nodes left in current allocation */
        void *p;   /* first free node in current allocation */
 
@@ -63,7 +62,6 @@ static inline void *alloc_node(struct alloc_state *s, size_t node_size)
                s->slabs[s->slab_nr++] = s->p;
        }
        s->nr--;
-       s->count++;
        ret = s->p;
        s->p = (char *)s->p + node_size;
        memset(ret, 0, node_size);
@@ -122,22 +120,3 @@ void *alloc_commit_node(struct repository *r)
        init_commit_node(c);
        return c;
 }
-
-static void report(const char *name, unsigned int count, size_t size)
-{
-       fprintf(stderr, "%10s: %8u (%"PRIuMAX" kB)\n",
-                       name, count, (uintmax_t) size);
-}
-
-#define REPORT(name, type)     \
-    report(#name, r->parsed_objects->name##_state->count, \
-                 r->parsed_objects->name##_state->count * sizeof(type) >> 10)
-
-void alloc_report(struct repository *r)
-{
-       REPORT(blob, struct blob);
-       REPORT(tree, struct tree);
-       REPORT(commit, struct commit);
-       REPORT(tag, struct tag);
-       REPORT(object, union any_object);
-}
diff --git a/alloc.h b/alloc.h
index 371d388b552fb01824b4ec208abe7fdf11d95eec..3f4a0ad310a94bd026f48f48491985e3e2053ee2 100644 (file)
--- a/alloc.h
+++ b/alloc.h
@@ -13,7 +13,6 @@ void init_commit_node(struct commit *c);
 void *alloc_commit_node(struct repository *r);
 void *alloc_tag_node(struct repository *r);
 void *alloc_object_node(struct repository *r);
-void alloc_report(struct repository *r);
 
 struct alloc_state *allocate_alloc_state(void);
 void clear_alloc_state(struct alloc_state *s);
diff --git a/apply.c b/apply.c
index d19c26d332e7908b364be4e2eddea4c2f1bde0b5..2b7cd930efa3bd31fec9ac72b94bac31272c4c09 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -3274,11 +3274,11 @@ static struct patch *in_fn_table(struct apply_state *state, const char *name)
 {
        struct string_list_item *item;
 
-       if (name == NULL)
+       if (!name)
                return NULL;
 
        item = string_list_lookup(&state->fn_table, name);
-       if (item != NULL)
+       if (item)
                return (struct patch *)item->util;
 
        return NULL;
@@ -3318,7 +3318,7 @@ static void add_to_fn_table(struct apply_state *state, struct patch *patch)
         * This should cover the cases for normal diffs,
         * file creations and copies
         */
-       if (patch->new_name != NULL) {
+       if (patch->new_name) {
                item = string_list_insert(&state->fn_table, patch->new_name);
                item->util = patch;
        }
index e29d0e00f6cc4ecb7883b3661807dfc4b705d0b9..e2121ebefb0451deeaacd65687eba46149ffe844 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -342,7 +342,7 @@ int write_archive_entries(struct archiver_args *args,
                else
                        err = write_entry(args, &fake_oid, path_in_archive.buf,
                                          path_in_archive.len,
-                                         info->stat.st_mode,
+                                         canon_mode(info->stat.st_mode),
                                          content.buf, content.len);
                if (err)
                        break;
@@ -465,7 +465,7 @@ static void parse_treeish_arg(const char **argv,
        }
 
        tree = parse_tree_indirect(&oid);
-       if (tree == NULL)
+       if (!tree)
                die(_("not a tree object: %s"), oid_to_hex(&oid));
 
        if (prefix) {
index 9e6a2b7f201a604f40d074c13be6d0c892cdf46d..b63669cc9d768fd1de2cbc06e20e942f77ffcda7 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -884,6 +884,7 @@ static int check_ancestors(struct repository *r, int rev_nr,
        /* Clean up objects used, as they will be reused. */
        clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS);
 
+       release_revisions(&revs);
        return res;
 }
 
@@ -964,6 +965,7 @@ static void show_diff_tree(struct repository *r,
 
        setup_revisions(ARRAY_SIZE(argv) - 1, argv, &opt, NULL);
        log_tree_commit(&opt, commit);
+       release_revisions(&opt);
 }
 
 /*
@@ -1008,7 +1010,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good)
  */
 enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
 {
-       struct rev_info revs;
+       struct rev_info revs = REV_INFO_INIT;
        struct commit_list *tried;
        int reaches = 0, all = 0, nr, steps;
        enum bisect_error res = BISECT_OK;
@@ -1033,7 +1035,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
 
        res = check_good_are_ancestors_of_bad(r, prefix, no_checkout);
        if (res)
-               return res;
+               goto cleanup;
 
        bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1);
 
@@ -1058,14 +1060,16 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
                       term_good,
                       term_bad);
 
-               return BISECT_FAILED;
+               res = BISECT_FAILED;
+               goto cleanup;
        }
 
        if (!all) {
                fprintf(stderr, _("No testable commit found.\n"
                        "Maybe you started with bad path arguments?\n"));
 
-               return BISECT_NO_TESTABLE_COMMIT;
+               res = BISECT_NO_TESTABLE_COMMIT;
+               goto cleanup;
        }
 
        bisect_rev = &revs.commits->item->object.oid;
@@ -1085,7 +1089,8 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
                 * for negative return values for early returns up
                 * until the cmd_bisect__helper() caller.
                 */
-               return BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;
+               res = BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;
+               goto cleanup;
        }
 
        nr = all - reaches - 1;
@@ -1104,7 +1109,10 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
        /* Clean up objects used, as they will be reused. */
        repo_clear_commit_marks(r, ALL_REV_FLAGS);
 
-       return bisect_checkout(bisect_rev, no_checkout);
+       res = bisect_checkout(bisect_rev, no_checkout);
+cleanup:
+       release_revisions(&revs);
+       return res;
 }
 
 static inline int log2i(int n)
index 1015aeb8eaeaee7f539a4631b6dbf1c27175c7fb..ee3fd65f3bdb89611d7575239ee79e8c50bcd703 100644 (file)
--- a/bisect.h
+++ b/bisect.h
@@ -62,6 +62,15 @@ enum bisect_error {
        BISECT_INTERNAL_SUCCESS_MERGE_BASE = -11
 };
 
+/*
+ * Stores how many good/bad commits we have stored for a bisect. nr_bad can
+ * only be 0 or 1.
+ */
+struct bisect_state {
+       unsigned int nr_good;
+       unsigned int nr_bad;
+};
+
 enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
 
 int estimate_bisect_steps(int all);
diff --git a/blame.c b/blame.c
index 186ad96120983107d10417e52829e60df12c2bc4..da1052ac94bb47282fb6191e457dda6597c3e8fc 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -1072,7 +1072,7 @@ static struct blame_entry *blame_merge(struct blame_entry *list1,
        if (p1->s_lno <= p2->s_lno) {
                do {
                        tail = &p1->next;
-                       if ((p1 = *tail) == NULL) {
+                       if (!(p1 = *tail)) {
                                *tail = p2;
                                return list1;
                        }
@@ -1082,7 +1082,7 @@ static struct blame_entry *blame_merge(struct blame_entry *list1,
                *tail = p2;
                do {
                        tail = &p2->next;
-                       if ((p2 = *tail) == NULL)  {
+                       if (!(p2 = *tail))  {
                                *tail = p1;
                                return list1;
                        }
@@ -1090,7 +1090,7 @@ static struct blame_entry *blame_merge(struct blame_entry *list1,
                *tail = p1;
                do {
                        tail = &p1->next;
-                       if ((p1 = *tail) == NULL) {
+                       if (!(p1 = *tail)) {
                                *tail = p2;
                                return list1;
                        }
index 01ecb816d5c4181786e7affab5aabd6a270a1db8..2d6569b0c62eb59488f19ed4aee8b65ed0cea78a 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -44,9 +44,9 @@ static int find_tracked_branch(struct remote *remote, void *priv)
                        string_list_clear(tracking->srcs, 0);
                break;
                }
+               /* remote_find_tracking() searches by src if present */
                tracking->spec.src = NULL;
        }
-
        return 0;
 }
 
@@ -264,15 +264,23 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
 
        if (!tracking.matches)
                switch (track) {
+               /* If ref is not remote, still use local */
                case BRANCH_TRACK_ALWAYS:
                case BRANCH_TRACK_EXPLICIT:
                case BRANCH_TRACK_OVERRIDE:
+               /* Remote matches not evaluated */
                case BRANCH_TRACK_INHERIT:
                        break;
+               /* Otherwise, if no remote don't track */
                default:
                        goto cleanup;
                }
 
+       /*
+        * This check does not apply to BRANCH_TRACK_INHERIT;
+        * that supports multiple entries in tracking_srcs but
+        * leaves tracking.matches at 0.
+        */
        if (tracking.matches > 1) {
                int status = die_message(_("not tracking: ambiguous information for ref '%s'"),
                                            orig_ref);
@@ -307,6 +315,21 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
                exit(status);
        }
 
+       if (track == BRANCH_TRACK_SIMPLE) {
+               /*
+                * Only track if remote branch name matches.
+                * Reaching into items[0].string is safe because
+                * we know there is at least one and not more than
+                * one entry (because only BRANCH_TRACK_INHERIT can
+                * produce more than one entry).
+                */
+               const char *tracked_branch;
+               if (!skip_prefix(tracking.srcs->items[0].string,
+                                "refs/heads/", &tracked_branch) ||
+                   strcmp(tracked_branch, new_ref))
+                       return;
+       }
+
        if (tracking.srcs->nr < 1)
                string_list_append(tracking.srcs, orig_ref);
        if (install_branch_config_multiple_remotes(config_flags, new_ref,
@@ -466,7 +489,7 @@ static void dwim_branch_start(struct repository *r, const char *start_name,
                break;
        }
 
-       if ((commit = lookup_commit_reference(r, &oid)) == NULL)
+       if (!(commit = lookup_commit_reference(r, &oid)))
                die(_("not a valid branch point: '%s'"), start_name);
        if (out_real_ref) {
                *out_real_ref = real_ref;
@@ -603,6 +626,8 @@ static int submodule_create_branch(struct repository *r,
                /* Default for "git checkout". Do not pass --track. */
        case BRANCH_TRACK_REMOTE:
                /* Default for "git branch". Do not pass --track. */
+       case BRANCH_TRACK_SIMPLE:
+               /* Config-driven only. Do not pass --track. */
                break;
        }
 
@@ -653,7 +678,7 @@ void create_branches_recursively(struct repository *r, const char *name,
         * be created in every submodule.
         */
        for (i = 0; i < submodule_entry_list.entry_nr; i++) {
-               if (submodule_entry_list.entries[i].repo == NULL) {
+               if (!submodule_entry_list.entries[i].repo) {
                        int code = die_message(
                                _("submodule '%s': unable to find submodule"),
                                submodule_entry_list.entries[i].submodule->name);
index 04df2aa5b515e9e9372d6db75ff09ebe017ffffe..560b6b96a8f307baac31ea699321e17ed2c22dbe 100644 (file)
--- a/branch.h
+++ b/branch.h
@@ -12,6 +12,7 @@ enum branch_track {
        BRANCH_TRACK_EXPLICIT,
        BRANCH_TRACK_OVERRIDE,
        BRANCH_TRACK_INHERIT,
+       BRANCH_TRACK_SIMPLE,
 };
 
 extern enum branch_track git_branch_track;
index 3ffb86a43384f21cad4fdcc0d8549e37dba12227..f84372964c8c486601941c927d6e39bb8da42084 100644 (file)
@@ -141,8 +141,17 @@ int add_files_to_cache(const char *prefix,
        rev.diffopt.format_callback_data = &data;
        rev.diffopt.flags.override_submodule_config = 1;
        rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
+
+       /*
+        * Use an ODB transaction to optimize adding multiple objects.
+        * This function is invoked from commands other than 'add', which
+        * may not have their own transaction active.
+        */
+       begin_odb_transaction();
        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
-       clear_pathspec(&rev.prune_data);
+       end_odb_transaction();
+
+       release_revisions(&rev);
        return !!data.add_errors;
 }
 
@@ -236,17 +245,12 @@ int run_add_interactive(const char *revision, const char *patch_mode,
        int use_builtin_add_i =
                git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
 
-       if (use_builtin_add_i < 0) {
-               int experimental;
-               if (!git_config_get_bool("add.interactive.usebuiltin",
-                                        &use_builtin_add_i))
-                       ; /* ok */
-               else if (!git_config_get_bool("feature.experimental", &experimental) &&
-                        experimental)
-                       use_builtin_add_i = 1;
-       }
+       if (use_builtin_add_i < 0 &&
+           git_config_get_bool("add.interactive.usebuiltin",
+                               &use_builtin_add_i))
+               use_builtin_add_i = 1;
 
-       if (use_builtin_add_i == 1) {
+       if (use_builtin_add_i != 0) {
                enum add_p_mode mode;
 
                if (!patch_mode)
@@ -340,6 +344,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
 
        unlink(file);
        free(file);
+       release_revisions(&rev);
        return 0;
 }
 
@@ -670,7 +675,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
                string_list_clear(&only_match_skip_worktree, 0);
        }
 
-       plug_bulk_checkin();
+       begin_odb_transaction();
 
        if (add_renormalize)
                exit_status |= renormalize_tracked_files(&pathspec, flags);
@@ -682,7 +687,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
        if (chmod_arg && pathspec.nr)
                exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only);
-       unplug_bulk_checkin();
+       end_odb_transaction();
 
 finish:
        if (write_locked_index(&the_index, &lock_file,
index 0f4111bafa0b0887ae29903509a0af7447ab13ff..93bec62afa993cb236ce09c13b38932ee396f250 100644 (file)
@@ -1397,6 +1397,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm
        add_pending_object(&rev_info, &commit->object, "");
        diff_setup_done(&rev_info.diffopt);
        log_tree_commit(&rev_info, commit);
+       release_revisions(&rev_info);
 }
 
 /**
@@ -1429,6 +1430,7 @@ static void write_index_patch(const struct am_state *state)
        add_pending_object(&rev_info, &tree->object, "");
        diff_setup_done(&rev_info.diffopt);
        run_diff_index(&rev_info, 1);
+       release_revisions(&rev_info);
 }
 
 /**
@@ -1582,6 +1584,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
                add_pending_oid(&rev_info, "HEAD", &our_tree, 0);
                diff_setup_done(&rev_info.diffopt);
                run_diff_index(&rev_info, 1);
+               release_revisions(&rev_info);
        }
 
        if (run_apply(state, index_path))
index 3f099b960565ff2944209ba514ea7274dad852f5..555219de40fa7e3097612a60eb953f81580a8de9 100644 (file)
@@ -1,7 +1,6 @@
 #include "cache.h"
 #include "builtin.h"
 #include "parse-options.h"
-#include "lockfile.h"
 #include "apply.h"
 
 static const char * const apply_usage[] = {
index 8b2b259ff0d11ebf6d28765b2a926a5efb1b644e..8a052c7111f97f02690a31e98ef4102961796800 100644 (file)
@@ -329,12 +329,12 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
        return 0;
 }
 
-static int mark_good(const char *refname, const struct object_id *oid,
-                    int flag, void *cb_data)
+static int inc_nr(const char *refname, const struct object_id *oid,
+                 int flag, void *cb_data)
 {
-       int *m_good = (int *)cb_data;
-       *m_good = 0;
-       return 1;
+       unsigned int *nr = (unsigned int *)cb_data;
+       (*nr)++;
+       return 0;
 }
 
 static const char need_bad_and_good_revision_warning[] =
@@ -384,23 +384,64 @@ static int decide_next(const struct bisect_terms *terms,
                             vocab_good, vocab_bad, vocab_good, vocab_bad);
 }
 
-static int bisect_next_check(const struct bisect_terms *terms,
-                            const char *current_term)
+static void bisect_status(struct bisect_state *state,
+                         const struct bisect_terms *terms)
 {
-       int missing_good = 1, missing_bad = 1;
        char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
        char *good_glob = xstrfmt("%s-*", terms->term_good);
 
        if (ref_exists(bad_ref))
-               missing_bad = 0;
+               state->nr_bad = 1;
 
-       for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
-                            (void *) &missing_good);
+       for_each_glob_ref_in(inc_nr, good_glob, "refs/bisect/",
+                            (void *) &state->nr_good);
 
        free(good_glob);
        free(bad_ref);
+}
 
-       return decide_next(terms, current_term, missing_good, missing_bad);
+__attribute__((format (printf, 1, 2)))
+static void bisect_log_printf(const char *fmt, ...)
+{
+       struct strbuf buf = STRBUF_INIT;
+       va_list ap;
+
+       va_start(ap, fmt);
+       strbuf_vaddf(&buf, fmt, ap);
+       va_end(ap);
+
+       printf("%s", buf.buf);
+       append_to_file(git_path_bisect_log(), "# %s", buf.buf);
+
+       strbuf_release(&buf);
+}
+
+static void bisect_print_status(const struct bisect_terms *terms)
+{
+       struct bisect_state state = { 0 };
+
+       bisect_status(&state, terms);
+
+       /* If we had both, we'd already be started, and shouldn't get here. */
+       if (state.nr_good && state.nr_bad)
+               return;
+
+       if (!state.nr_good && !state.nr_bad)
+               bisect_log_printf(_("status: waiting for both good and bad commits\n"));
+       else if (state.nr_good)
+               bisect_log_printf(Q_("status: waiting for bad commit, %d good commit known\n",
+                                    "status: waiting for bad commit, %d good commits known\n",
+                                    state.nr_good), state.nr_good);
+       else
+               bisect_log_printf(_("status: waiting for good commit(s), bad commit known\n"));
+}
+
+static int bisect_next_check(const struct bisect_terms *terms,
+                            const char *current_term)
+{
+       struct bisect_state state = { 0 };
+       bisect_status(&state, terms);
+       return decide_next(terms, current_term, !state.nr_good, !state.nr_bad);
 }
 
 static int get_terms(struct bisect_terms *terms)
@@ -433,7 +474,7 @@ static int bisect_terms(struct bisect_terms *terms, const char *option)
        if (get_terms(terms))
                return error(_("no terms defined"));
 
-       if (option == NULL) {
+       if (!option) {
                printf(_("Your current terms are %s for the old state\n"
                         "and %s for the new state.\n"),
                       terms->term_good, terms->term_bad);
@@ -555,6 +596,7 @@ static int bisect_skipped_commits(struct bisect_terms *terms)
        reset_revision_walk();
 
        strbuf_release(&commit_name);
+       release_revisions(&revs);
        fclose(fp);
        return 0;
 }
@@ -606,8 +648,10 @@ static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
 
 static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix)
 {
-       if (bisect_next_check(terms, NULL))
+       if (bisect_next_check(terms, NULL)) {
+               bisect_print_status(terms);
                return BISECT_OK;
+       }
 
        return bisect_next(terms, prefix);
 }
@@ -1041,6 +1085,7 @@ static enum bisect_error bisect_skip(struct bisect_terms *terms, const char **ar
                                                oid_to_hex(&commit->object.oid));
 
                        reset_revision_walk();
+                       release_revisions(&revs);
                } else {
                        strvec_push(&argv_state, argv[i]);
                }
index 8d15b68afc9da3ffe0e1bce952e1e0fe72afd428..02e39420b62babb5124708f3305985ebe6e316a9 100644 (file)
@@ -898,6 +898,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        unsigned int range_i;
        long anchor;
        const int hexsz = the_hash_algo->hexsz;
+       long num_lines = 0;
 
        setup_default_color_by_age();
        git_config(git_blame_config, &output_option);
@@ -1129,7 +1130,10 @@ parse_done:
        for (range_i = ranges.nr; range_i > 0; --range_i) {
                const struct range *r = &ranges.ranges[range_i - 1];
                ent = blame_entry_prepend(ent, r->start, r->end, o);
+               num_lines += (r->end - r->start);
        }
+       if (!num_lines)
+               num_lines = sb.num_lines;
 
        o->suspects = ent;
        prio_queue_put(&sb.commits, o->commit);
@@ -1158,7 +1162,7 @@ parse_done:
        sb.found_guilty_entry = &found_guilty_entry;
        sb.found_guilty_entry_data = &pi;
        if (show_progress)
-               pi.progress = start_delayed_progress(_("Blaming lines"), sb.num_lines);
+               pi.progress = start_delayed_progress(_("Blaming lines"), num_lines);
 
        assign_blame(&sb, opt);
 
@@ -1167,7 +1171,7 @@ parse_done:
        if (!incremental)
                setup_pager();
        else
-               return 0;
+               goto cleanup;
 
        blame_sort_final(&sb);
 
@@ -1201,6 +1205,8 @@ parse_done:
                printf("num commits: %d\n", sb.num_commits);
        }
 
+cleanup:
        cleanup_scoreboard(&sb);
+       release_revisions(&revs);
        return 0;
 }
index 797681481d10b552e645237c99a8d9bff7df766a..2eefda81d8cf89f6d5405e1ee218f0c698f4fb78 100644 (file)
@@ -629,7 +629,7 @@ static void show_local_changes(struct object *head,
        diff_setup_done(&rev.diffopt);
        add_pending_object(&rev, head, NULL);
        run_diff_index(&rev, 0);
-       object_array_clear(&rev.pending);
+       release_revisions(&rev);
 }
 
 static void describe_detached_head(const char *msg, struct commit *commit)
@@ -834,7 +834,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
                        if (ret)
                                return ret;
                        o.ancestor = old_branch_info->name;
-                       if (old_branch_info->name == NULL) {
+                       if (!old_branch_info->name) {
                                strbuf_add_unique_abbrev(&old_commit_shortname,
                                                         &old_branch_info->commit->object.oid,
                                                         DEFAULT_ABBREV);
@@ -1082,6 +1082,7 @@ static void orphaned_commit_warning(struct commit *old_commit, struct commit *ne
 
        /* Clean up objects used, as they will be reused. */
        repo_clear_commit_marks(the_repository, ALL_REV_FLAGS);
+       release_revisions(&revs);
 }
 
 static int switch_branches(const struct checkout_opts *opts,
index 52316563795fe34638b3ae22263ebf4e5f456ca5..89a91b0017725990345b6f91e61069c2f35819a6 100644 (file)
@@ -1106,10 +1106,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
         * apply the remote name provided by --origin only after this second
         * call to git_config, to ensure it overrides all config-based values.
         */
-       if (option_origin != NULL)
+       if (option_origin) {
+               free(remote_name);
                remote_name = xstrdup(option_origin);
+       }
 
-       if (remote_name == NULL)
+       if (!remote_name)
                remote_name = xstrdup("origin");
 
        if (!valid_remote_name(remote_name))
index 009a1de0a3d3f69e05a802d7d2356935018b0f81..fcf9c85947e6a1fbe2e96baee2d1cdd3f4764e89 100644 (file)
@@ -861,7 +861,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
        }
 
        s->fp = fopen_for_writing(git_path_commit_editmsg());
-       if (s->fp == NULL)
+       if (!s->fp)
                die_errno(_("could not open '%s'"), git_path_commit_editmsg());
 
        /* Ignore status.displayCommentPrefix: we do need comments in COMMIT_EDITMSG. */
@@ -1100,7 +1100,6 @@ static const char *find_author_by_nickname(const char *name)
        struct rev_info revs;
        struct commit *commit;
        struct strbuf buf = STRBUF_INIT;
-       struct string_list mailmap = STRING_LIST_INIT_NODUP;
        const char *av[20];
        int ac = 0;
 
@@ -1111,7 +1110,8 @@ static const char *find_author_by_nickname(const char *name)
        av[++ac] = buf.buf;
        av[++ac] = NULL;
        setup_revisions(ac, av, &revs, NULL);
-       revs.mailmap = &mailmap;
+       revs.mailmap = xmalloc(sizeof(struct string_list));
+       string_list_init_nodup(revs.mailmap);
        read_mailmap(revs.mailmap);
 
        if (prepare_revision_walk(&revs))
@@ -1122,7 +1122,7 @@ static const char *find_author_by_nickname(const char *name)
                ctx.date_mode.type = DATE_NORMAL;
                strbuf_release(&buf);
                format_commit_message(commit, "%aN <%aE>", &buf, &ctx);
-               clear_mailmap(&mailmap);
+               release_revisions(&revs);
                return strbuf_detach(&buf, NULL);
        }
        die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name);
@@ -1687,6 +1687,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        struct commit *current_head = NULL;
        struct commit_extra_header *extra = NULL;
        struct strbuf err = STRBUF_INIT;
+       int ret = 0;
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage_with_options(builtin_commit_usage, builtin_commit_options);
@@ -1721,8 +1722,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
           running hooks, writing the trees, and interacting with the user.  */
        if (!prepare_to_commit(index_file, prefix,
                               current_head, &s, &author_ident)) {
+               ret = 1;
                rollback_index_files();
-               return 1;
+               goto cleanup;
        }
 
        /* Determine parents */
@@ -1820,7 +1822,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                rollback_index_files();
                die(_("failed to write commit object"));
        }
-       strbuf_release(&author_ident);
        free_commit_extra_headers(extra);
 
        if (update_head_with_reflog(current_head, &oid, reflog_msg, &sb,
@@ -1862,7 +1863,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
        apply_autostash(git_path_merge_autostash(the_repository));
 
+cleanup:
+       UNLEAK(author_ident);
        UNLEAK(err);
        UNLEAK(sb);
-       return 0;
+       return ret;
 }
index 42159cd26bd80797ab082d4d2509cf17ec8fc113..a76f1a1a7a7004cc95f392024cc1a27d54c870df 100644 (file)
@@ -517,6 +517,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst)
 
        traverse_commit_list(&revs, process_commit, process_object, &pcd);
        reset_revision_walk();
+       release_revisions(&revs);
 }
 
 static void describe(const char *arg, int last_one)
@@ -667,6 +668,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
                                suffix = NULL;
                        else
                                suffix = dirty;
+                       release_revisions(&revs);
                }
                describe("HEAD", 1);
        } else if (dirty) {
index 70103c40952093100e41361e15ab6dbe54ef0268..2bfaf9ba7ae6beba1ce0a014af66fc137627b9e0 100644 (file)
@@ -77,8 +77,12 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
 
        if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
                perror("read_cache_preload");
-               return -1;
+               result = -1;
+               goto cleanup;
        }
+cleanup:
        result = run_diff_files(&rev, options);
-       return diff_result_code(&rev.diffopt, result);
+       result = diff_result_code(&rev.diffopt, result);
+       release_revisions(&rev);
+       return result;
 }
index 5fd23ab5b6c5b634be82e91339d4920fe9e15b99..7d158af6b6d4a88de34569dedee0bb425c8f89e1 100644 (file)
@@ -70,6 +70,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
                return -1;
        }
        result = run_diff_index(&rev, option);
-       UNLEAK(rev);
-       return diff_result_code(&rev.diffopt, result);
+       result = diff_result_code(&rev.diffopt, result);
+       release_revisions(&rev);
+       return result;
 }
index bb7fafca61815460ba085859322314b4c41c8b6b..54bb3de964cb5a1e815702a8cbcedab166b96ee3 100644 (file)
@@ -352,7 +352,7 @@ static void symdiff_prepare(struct rev_info *rev, struct symdiff *sym)
                        othercount++;
                        continue;
                }
-               if (map == NULL)
+               if (!map)
                        map = bitmap_new();
                bitmap_set(map, i);
        }
@@ -594,7 +594,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        result = diff_result_code(&rev.diffopt, result);
        if (1 < rev.diffopt.skip_stat_unmatch)
                refresh_index_quietly();
-       UNLEAK(rev);
+       release_revisions(&rev);
        UNLEAK(ent);
        UNLEAK(blob);
        return result;
index 1355b5a96d3c900503fed1b09f1b7e8ad8d6ee3c..e1748fb98be5b970a8d31bf43f3f708d6a60c3d9 100644 (file)
@@ -1276,6 +1276,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
                printf("done\n");
 
        refspec_clear(&refspecs);
+       release_revisions(&revs);
 
        return 0;
 }
index e3791f09ed51d0d96b945b747d3dd74ad2d63165..ac29c2b1ae34df79f8a2bd62318dc714a1f37e24 100644 (file)
@@ -1440,6 +1440,7 @@ static void check_not_current_branch(struct ref *ref_map,
        const struct worktree *wt;
        for (; ref_map; ref_map = ref_map->next)
                if (ref_map->peer_ref &&
+                   starts_with(ref_map->peer_ref->name, "refs/heads/") &&
                    (wt = find_shared_symref(worktrees, "HEAD",
                                             ref_map->peer_ref->name)) &&
                    !wt->is_bare)
@@ -2187,6 +2188,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
                else if (argc > 1)
                        die(_("fetch --all does not make sense with refspecs"));
                (void) for_each_remote(get_one_remote_for_fetch, &list);
+
+               /* do not do fetch_multiple() of one */
+               if (list.nr == 1)
+                       remote = remote_get(list.items[0].string);
        } else if (argc == 0) {
                /* No arguments -- use default remote */
                remote = remote_get(NULL);
@@ -2261,7 +2266,17 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
                result = fetch_multiple(&list, max_children);
        }
 
-       if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
+
+       /*
+        * This is only needed after fetch_one(), which does not fetch
+        * submodules by itself.
+        *
+        * When we fetch from multiple remotes, fetch_multiple() has
+        * already updated submodules to grab commits necessary for
+        * the fetched history from each remote, so there is no need
+        * to fetch submodules from here.
+        */
+       if (!result && remote && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
                struct strvec options = STRVEC_INIT;
                int max_children = max_jobs;
 
index b335cffa33561fa80f268260a7edbc7af9ae4136..4ea70089c914df2041eed10d2cd71fdfd0f8276f 100644 (file)
@@ -42,6 +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 aggressive_depth = 50;
 static int aggressive_window = 250;
 static int gc_auto_threshold = 6700;
@@ -152,6 +153,7 @@ static void gc_config(void)
        git_config_get_int("gc.auto", &gc_auto_threshold);
        git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
        git_config_get_bool("gc.autodetach", &detach_auto);
+       git_config_get_bool("gc.cruftpacks", &cruft_packs);
        git_config_get_expiry("gc.pruneexpire", &prune_expire);
        git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
        git_config_get_expiry("gc.logexpiry", &gc_log_expire);
@@ -331,7 +333,11 @@ static void add_repack_all_option(struct string_list *keep_pack)
 {
        if (prune_expire && !strcmp(prune_expire, "now"))
                strvec_push(&repack, "-a");
-       else {
+       else if (cruft_packs) {
+               strvec_push(&repack, "--cruft");
+               if (prune_expire)
+                       strvec_pushf(&repack, "--cruft-expiration=%s", prune_expire);
+       } else {
                strvec_push(&repack, "-A");
                if (prune_expire)
                        strvec_pushf(&repack, "--unpack-unreachable=%s", prune_expire);
@@ -446,7 +452,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
                        fscanf(fp, scan_fmt, &pid, locking_host) == 2 &&
                        /* be gentle to concurrent "gc" on remote hosts */
                        (strcmp(locking_host, my_host) || !kill(pid, 0) || errno == EPERM);
-               if (fp != NULL)
+               if (fp)
                        fclose(fp);
                if (should_exit) {
                        if (fd >= 0)
@@ -551,6 +557,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                { OPTION_STRING, 0, "prune", &prune_expire, N_("date"),
                        N_("prune unreferenced objects"),
                        PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
+               OPT_BOOL(0, "cruft", &cruft_packs, N_("pack unreferenced objects separately")),
                OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
                OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"),
                           PARSE_OPT_NOCOMPLETE),
@@ -670,6 +677,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                        die(FAILED_RUN, repack.v[0]);
 
                if (prune_expire) {
+                       /* run `git prune` even if using cruft packs */
                        strvec_push(&prune, prune_expire);
                        if (quiet)
                                strvec_push(&prune, "--no-progress");
@@ -2238,7 +2246,7 @@ static int systemd_timer_write_unit_templates(const char *exec_path)
                goto error;
        }
        file = fopen_or_warn(filename, "w");
-       if (file == NULL)
+       if (!file)
                goto error;
 
        unit = "# This file was created and is maintained by Git.\n"
@@ -2267,7 +2275,7 @@ static int systemd_timer_write_unit_templates(const char *exec_path)
 
        filename = xdg_config_home_systemd("git-maintenance@.service");
        file = fopen_or_warn(filename, "w");
-       if (file == NULL)
+       if (!file)
                goto error;
 
        unit = "# This file was created and is maintained by Git.\n"
index 680b66b0636522be7bf831e69be3adf2115ff94a..3e385b4800258d5c2e0d964d34b4238980f8b06c 100644 (file)
@@ -1942,11 +1942,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        free(objects);
        strbuf_release(&index_name_buf);
        strbuf_release(&rev_index_name_buf);
-       if (pack_name == NULL)
+       if (!pack_name)
                free((void *) curr_pack);
-       if (index_name == NULL)
+       if (!index_name)
                free((void *) curr_index);
-       if (rev_index_name == NULL)
+       if (!rev_index_name)
                free((void *) curr_rev_index);
 
        /*
index 3ac479bec3c17aa7734195bc31dbacfb22a1523e..88a5e98875adb0398b2855460bddd5fa43e073ec 100644 (file)
@@ -231,7 +231,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
        }
 
        if (mailmap) {
-               rev->mailmap = xcalloc(1, sizeof(struct string_list));
+               rev->mailmap = xmalloc(sizeof(struct string_list));
+               string_list_init_nodup(rev->mailmap);
                read_mailmap(rev->mailmap);
        }
 
@@ -294,6 +295,12 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
        cmd_log_init_finish(argc, argv, prefix, rev, opt);
 }
 
+static int cmd_log_deinit(int ret, struct rev_info *rev)
+{
+       release_revisions(rev);
+       return ret;
+}
+
 /*
  * This gives a rough estimate for how many commits we
  * will print out in the list.
@@ -565,7 +572,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
        cmd_log_init(argc, argv, prefix, &rev, &opt);
        if (!rev.diffopt.output_format)
                rev.diffopt.output_format = DIFF_FORMAT_RAW;
-       return cmd_log_walk(&rev);
+       return cmd_log_deinit(cmd_log_walk(&rev), &rev);
 }
 
 static void show_tagger(const char *buf, struct rev_info *rev)
@@ -669,6 +676,11 @@ int cmd_show(int argc, const char **argv, const char *prefix)
        init_log_defaults();
        git_config(git_log_config, NULL);
 
+       if (the_repository->gitdir) {
+               prepare_repo_settings(the_repository);
+               the_repository->settings.command_requires_full_index = 0;
+       }
+
        memset(&match_all, 0, sizeof(match_all));
        repo_init_revisions(the_repository, &rev, prefix);
        git_config(grep_config, &rev.grep_filter);
@@ -684,7 +696,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
        cmd_log_init(argc, argv, prefix, &rev, &opt);
 
        if (!rev.no_walk)
-               return cmd_log_walk(&rev);
+               return cmd_log_deinit(cmd_log_walk(&rev), &rev);
 
        count = rev.pending.nr;
        objects = rev.pending.objects;
@@ -744,8 +756,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
        rev.diffopt.no_free = 0;
        diff_free(&rev.diffopt);
 
-       free(objects);
-       return ret;
+       return cmd_log_deinit(ret, &rev);
 }
 
 /*
@@ -773,7 +784,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
        rev.always_show_header = 1;
        cmd_log_init_finish(argc, argv, prefix, &rev, &opt);
 
-       return cmd_log_walk(&rev);
+       return cmd_log_deinit(cmd_log_walk(&rev), &rev);
 }
 
 static void log_setup_revisions_tweak(struct rev_info *rev,
@@ -804,7 +815,7 @@ int cmd_log(int argc, const char **argv, const char *prefix)
        opt.revarg_opt = REVARG_COMMITTISH;
        opt.tweak = log_setup_revisions_tweak;
        cmd_log_init(argc, argv, prefix, &rev, &opt);
-       return cmd_log_walk(&rev);
+       return cmd_log_deinit(cmd_log_walk(&rev), &rev);
 }
 
 /* format-patch */
@@ -1025,7 +1036,7 @@ static int open_next_file(struct commit *commit, const char *subject,
        if (!quiet)
                printf("%s\n", filename.buf + outdir_offset);
 
-       if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL) {
+       if (!(rev->diffopt.file = fopen(filename.buf, "w"))) {
                error_errno(_("cannot open patch file %s"), filename.buf);
                strbuf_release(&filename);
                return -1;
@@ -1759,6 +1770,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        struct commit *commit;
        struct commit **list = NULL;
        struct rev_info rev;
+       char *to_free = NULL;
        struct setup_revision_opt s_r_opt;
        int nr = 0, total, i;
        int use_stdout = 0;
@@ -1960,7 +1972,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                strbuf_addch(&buf, '\n');
        }
 
-       rev.extra_headers = strbuf_detach(&buf, NULL);
+       rev.extra_headers = to_free = strbuf_detach(&buf, NULL);
 
        if (from) {
                if (split_ident_line(&rev.from_ident, from, strlen(from)))
@@ -2181,8 +2193,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                prepare_bases(&bases, base, list, nr);
        }
 
-       if (in_reply_to || thread || cover_letter)
-               rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
+       if (in_reply_to || thread || cover_letter) {
+               rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids));
+               string_list_init_nodup(rev.ref_message_ids);
+       }
        if (in_reply_to) {
                const char *msgid = clean_message_id(in_reply_to);
                string_list_append(rev.ref_message_ids, msgid);
@@ -2289,8 +2303,11 @@ done:
        strbuf_release(&rdiff1);
        strbuf_release(&rdiff2);
        strbuf_release(&rdiff_title);
-       UNLEAK(rev);
-       return 0;
+       free(to_free);
+       if (rev.ref_message_ids)
+               string_list_clear(rev.ref_message_ids, 0);
+       free(rev.ref_message_ids);
+       return cmd_log_deinit(0, &rev);
 }
 
 static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
index d856085e9414a2bea070cbe9c84268c66158c33a..df44e5cc0d1171334a846817ef19e6f98feca48f 100644 (file)
@@ -114,7 +114,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
        }
 
        transport = transport_get(remote, NULL);
-       if (uploadpack != NULL)
+       if (uploadpack)
                transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
        if (server_options.nr)
                transport->server_options = &server_options;
index 30952353a370a3343f614ee5a14a3f5ca9560444..73509f651bda4805e8399d75eda80ec8976bda07 100644 (file)
@@ -120,7 +120,7 @@ static int populate_maildir_list(struct string_list *list, const char *path)
        for (sub = subs; *sub; ++sub) {
                free(name);
                name = xstrfmt("%s/%s", path, *sub);
-               if ((dir = opendir(name)) == NULL) {
+               if (!(dir = opendir(name))) {
                        if (errno == ENOENT)
                                continue;
                        error_errno("cannot opendir %s", name);
index f178f5a3ee18c71d2acda9455b020f9c03da9509..d9784d4891c92bbc27f7e0ecdcf1d17b7bcded5b 100644 (file)
@@ -443,6 +443,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead
        }
        write_file_buf(git_path_squash_msg(the_repository), out.buf, out.len);
        strbuf_release(&out);
+       release_revisions(&rev);
 }
 
 static void finish(struct commit *head_commit,
@@ -998,6 +999,7 @@ static int evaluate_result(void)
         */
        cnt += count_unmerged_entries();
 
+       release_revisions(&rev);
        return cnt;
 }
 
index 4480ba398277d4edc67e60eff47686d579de53c8..5edbb7fe86e81fb09ca2245ba920bc8bccd18726 100644 (file)
@@ -44,7 +44,7 @@ static char const * const builtin_multi_pack_index_usage[] = {
 };
 
 static struct opts_multi_pack_index {
-       const char *object_dir;
+       char *object_dir;
        const char *preferred_pack;
        const char *refs_snapshot;
        unsigned long batch_size;
@@ -52,9 +52,23 @@ static struct opts_multi_pack_index {
        int stdin_packs;
 } opts;
 
+
+static int parse_object_dir(const struct option *opt, const char *arg,
+                           int unset)
+{
+       free(opts.object_dir);
+       if (unset)
+               opts.object_dir = xstrdup(get_object_directory());
+       else
+               opts.object_dir = real_pathdup(arg, 1);
+       return 0;
+}
+
 static struct option common_opts[] = {
-       OPT_FILENAME(0, "object-dir", &opts.object_dir,
-         N_("object directory containing set of packfile and pack-index pairs")),
+       OPT_CALLBACK(0, "object-dir", &opts.object_dir,
+         N_("directory"),
+         N_("object directory containing set of packfile and pack-index pairs"),
+         parse_object_dir),
        OPT_END(),
 };
 
@@ -232,31 +246,40 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv)
 int cmd_multi_pack_index(int argc, const char **argv,
                         const char *prefix)
 {
+       int res;
        struct option *builtin_multi_pack_index_options = common_opts;
 
        git_config(git_default_config, NULL);
 
+       if (the_repository &&
+           the_repository->objects &&
+           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 (!opts.object_dir)
-               opts.object_dir = get_object_directory();
-
        if (!argc)
                goto usage;
 
        if (!strcmp(argv[0], "repack"))
-               return cmd_multi_pack_index_repack(argc, argv);
+               res = cmd_multi_pack_index_repack(argc, argv);
        else if (!strcmp(argv[0], "write"))
-               return cmd_multi_pack_index_write(argc, argv);
+               res =  cmd_multi_pack_index_write(argc, argv);
        else if (!strcmp(argv[0], "verify"))
-               return cmd_multi_pack_index_verify(argc, argv);
+               res =  cmd_multi_pack_index_verify(argc, argv);
        else if (!strcmp(argv[0], "expire"))
-               return cmd_multi_pack_index_expire(argc, argv);
+               res =  cmd_multi_pack_index_expire(argc, argv);
+       else {
+               error(_("unrecognized subcommand: %s"), argv[0]);
+               goto usage;
+       }
+
+       free(opts.object_dir);
+       return res;
 
-       error(_("unrecognized subcommand: %s"), argv[0]);
 usage:
        usage_with_options(builtin_multi_pack_index_usage,
                           builtin_multi_pack_index_options);
index 014dcd4bc98459315b6fbac672df828e06299be0..cc5f41086daea19dc0600a8a4f450c844f293166 100644 (file)
@@ -36,6 +36,7 @@
 #include "trace2.h"
 #include "shallow.h"
 #include "promisor-remote.h"
+#include "pack-mtimes.h"
 
 /*
  * Objects we are going to pack are collected in the `to_pack` structure.
@@ -194,6 +195,8 @@ static int reuse_delta = 1, reuse_object = 1;
 static int keep_unreachable, unpack_unreachable, include_tag;
 static timestamp_t unpack_unreachable_expiration;
 static int pack_loose_unreachable;
+static int cruft;
+static timestamp_t cruft_expiration;
 static int local;
 static int have_non_local_packs;
 static int incremental;
@@ -1260,9 +1263,13 @@ static void write_pack_file(void)
                                        &to_pack, written_list, nr_written);
                        }
 
+                       if (cruft)
+                               pack_idx_opts.flags |= WRITE_MTIMES;
+
                        stage_tmp_packfiles(&tmpname, pack_tmp_name,
                                            written_list, nr_written,
-                                           &pack_idx_opts, hash, &idx_tmp_name);
+                                           &to_pack, &pack_idx_opts, hash,
+                                           &idx_tmp_name);
 
                        if (write_bitmap_index) {
                                size_t tmpname_len = tmpname.len;
@@ -1357,6 +1364,9 @@ static int want_found_object(const struct object_id *oid, int exclude,
        if (incremental)
                return 0;
 
+       if (!is_pack_valid(p))
+               return -1;
+
        /*
         * When asked to do --local (do not include an object that appears in a
         * pack we borrow from elsewhere) or --honor-pack-keep (do not include
@@ -1472,6 +1482,9 @@ static int want_object_in_pack(const struct object_id *oid,
                want = want_found_object(oid, exclude, *found_pack);
                if (want != -1)
                        return want;
+
+               *found_pack = NULL;
+               *found_offset = 0;
        }
 
        for (m = get_multi_pack_index(the_repository); m; m = m->next) {
@@ -1515,13 +1528,13 @@ static int want_object_in_pack(const struct object_id *oid,
        return 1;
 }
 
-static void create_object_entry(const struct object_id *oid,
-                               enum object_type type,
-                               uint32_t hash,
-                               int exclude,
-                               int no_try_delta,
-                               struct packed_git *found_pack,
-                               off_t found_offset)
+static struct object_entry *create_object_entry(const struct object_id *oid,
+                                               enum object_type type,
+                                               uint32_t hash,
+                                               int exclude,
+                                               int no_try_delta,
+                                               struct packed_git *found_pack,
+                                               off_t found_offset)
 {
        struct object_entry *entry;
 
@@ -1538,6 +1551,8 @@ static void create_object_entry(const struct object_id *oid,
        }
 
        entry->no_try_delta = no_try_delta;
+
+       return entry;
 }
 
 static const char no_closure_warning[] = N_(
@@ -3201,10 +3216,8 @@ static int add_object_entry_from_pack(const struct object_id *oid,
                                      uint32_t pos,
                                      void *_data)
 {
-       struct rev_info *revs = _data;
-       struct object_info oi = OBJECT_INFO_INIT;
        off_t ofs;
-       enum object_type type;
+       enum object_type type = OBJ_NONE;
 
        display_progress(progress_state, ++nr_seen);
 
@@ -3215,19 +3228,24 @@ static int add_object_entry_from_pack(const struct object_id *oid,
        if (!want_object_in_pack(oid, 0, &p, &ofs))
                return 0;
 
-       oi.typep = &type;
-       if (packed_object_info(the_repository, p, ofs, &oi) < 0)
-               die(_("could not get type of object %s in pack %s"),
-                   oid_to_hex(oid), p->pack_name);
-       else if (type == OBJ_COMMIT) {
-               /*
-                * commits in included packs are used as starting points for the
-                * subsequent revision walk
-                */
-               add_pending_oid(revs, NULL, oid, 0);
-       }
+       if (p) {
+               struct rev_info *revs = _data;
+               struct object_info oi = OBJECT_INFO_INIT;
 
-       stdin_packs_found_nr++;
+               oi.typep = &type;
+               if (packed_object_info(the_repository, p, ofs, &oi) < 0) {
+                       die(_("could not get type of object %s in pack %s"),
+                           oid_to_hex(oid), p->pack_name);
+               } else if (type == OBJ_COMMIT) {
+                       /*
+                        * commits in included packs are used as starting points for the
+                        * subsequent revision walk
+                        */
+                       add_pending_oid(revs, NULL, oid, 0);
+               }
+
+               stdin_packs_found_nr++;
+       }
 
        create_object_entry(oid, type, 0, 0, 0, p, ofs);
 
@@ -3346,6 +3364,8 @@ static void read_packs_list_from_stdin(void)
                struct packed_git *p = item->util;
                if (!p)
                        die(_("could not find pack '%s'"), item->string);
+               if (!is_pack_valid(p))
+                       die(_("packfile %s cannot be accessed"), p->pack_name);
        }
 
        /*
@@ -3369,8 +3389,6 @@ static void read_packs_list_from_stdin(void)
 
        for_each_string_list_item(item, &include_packs) {
                struct packed_git *p = item->util;
-               if (!p)
-                       die(_("could not find pack '%s'"), item->string);
                for_each_object_in_pack(p,
                                        add_object_entry_from_pack,
                                        &revs,
@@ -3394,6 +3412,217 @@ static void read_packs_list_from_stdin(void)
        string_list_clear(&exclude_packs, 0);
 }
 
+static void add_cruft_object_entry(const struct object_id *oid, enum object_type type,
+                                  struct packed_git *pack, off_t offset,
+                                  const char *name, uint32_t mtime)
+{
+       struct object_entry *entry;
+
+       display_progress(progress_state, ++nr_seen);
+
+       entry = packlist_find(&to_pack, oid);
+       if (entry) {
+               if (name) {
+                       entry->hash = pack_name_hash(name);
+                       entry->no_try_delta = no_try_delta(name);
+               }
+       } else {
+               if (!want_object_in_pack(oid, 0, &pack, &offset))
+                       return;
+               if (!pack && type == OBJ_BLOB && !has_loose_object(oid)) {
+                       /*
+                        * If a traversed tree has a missing blob then we want
+                        * to avoid adding that missing object to our pack.
+                        *
+                        * This only applies to missing blobs, not trees,
+                        * because the traversal needs to parse sub-trees but
+                        * not blobs.
+                        *
+                        * Note we only perform this check when we couldn't
+                        * already find the object in a pack, so we're really
+                        * limited to "ensure non-tip blobs which don't exist in
+                        * packs do exist via loose objects". Confused?
+                        */
+                       return;
+               }
+
+               entry = create_object_entry(oid, type, pack_name_hash(name),
+                                           0, name && no_try_delta(name),
+                                           pack, offset);
+       }
+
+       if (mtime > oe_cruft_mtime(&to_pack, entry))
+               oe_set_cruft_mtime(&to_pack, entry, mtime);
+       return;
+}
+
+static void show_cruft_object(struct object *obj, const char *name, void *data)
+{
+       /*
+        * if we did not record it earlier, it's at least as old as our
+        * expiration value. Rather than find it exactly, just use that
+        * value.  This may bump it forward from its real mtime, but it
+        * will still be "too old" next time we run with the same
+        * expiration.
+        *
+        * if obj does appear in the packing list, this call is a noop (or may
+        * set the namehash).
+        */
+       add_cruft_object_entry(&obj->oid, obj->type, NULL, 0, name, cruft_expiration);
+}
+
+static void show_cruft_commit(struct commit *commit, void *data)
+{
+       show_cruft_object((struct object*)commit, NULL, data);
+}
+
+static int cruft_include_check_obj(struct object *obj, void *data)
+{
+       return !has_object_kept_pack(&obj->oid, IN_CORE_KEEP_PACKS);
+}
+
+static int cruft_include_check(struct commit *commit, void *data)
+{
+       return cruft_include_check_obj((struct object*)commit, data);
+}
+
+static void set_cruft_mtime(const struct object *object,
+                           struct packed_git *pack,
+                           off_t offset, time_t mtime)
+{
+       add_cruft_object_entry(&object->oid, object->type, pack, offset, NULL,
+                              mtime);
+}
+
+static void mark_pack_kept_in_core(struct string_list *packs, unsigned keep)
+{
+       struct string_list_item *item = NULL;
+       for_each_string_list_item(item, packs) {
+               struct packed_git *p = item->util;
+               if (!p)
+                       die(_("could not find pack '%s'"), item->string);
+               p->pack_keep_in_core = keep;
+       }
+}
+
+static void add_unreachable_loose_objects(void);
+static void add_objects_in_unpacked_packs(void);
+
+static void enumerate_cruft_objects(void)
+{
+       if (progress)
+               progress_state = start_progress(_("Enumerating cruft objects"), 0);
+
+       add_objects_in_unpacked_packs();
+       add_unreachable_loose_objects();
+
+       stop_progress(&progress_state);
+}
+
+static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs)
+{
+       struct packed_git *p;
+       struct rev_info revs;
+       int ret;
+
+       repo_init_revisions(the_repository, &revs, NULL);
+
+       revs.tag_objects = 1;
+       revs.tree_objects = 1;
+       revs.blob_objects = 1;
+
+       revs.include_check = cruft_include_check;
+       revs.include_check_obj = cruft_include_check_obj;
+
+       revs.ignore_missing_links = 1;
+
+       if (progress)
+               progress_state = start_progress(_("Enumerating cruft objects"), 0);
+       ret = add_unseen_recent_objects_to_traversal(&revs, cruft_expiration,
+                                                    set_cruft_mtime, 1);
+       stop_progress(&progress_state);
+
+       if (ret)
+               die(_("unable to add cruft objects"));
+
+       /*
+        * Re-mark only the fresh packs as kept so that objects in
+        * unknown packs do not halt the reachability traversal early.
+        */
+       for (p = get_all_packs(the_repository); p; p = p->next)
+               p->pack_keep_in_core = 0;
+       mark_pack_kept_in_core(fresh_packs, 1);
+
+       if (prepare_revision_walk(&revs))
+               die(_("revision walk setup failed"));
+       if (progress)
+               progress_state = start_progress(_("Traversing cruft objects"), 0);
+       nr_seen = 0;
+       traverse_commit_list(&revs, show_cruft_commit, show_cruft_object, NULL);
+
+       stop_progress(&progress_state);
+}
+
+static void read_cruft_objects(void)
+{
+       struct strbuf buf = STRBUF_INIT;
+       struct string_list discard_packs = STRING_LIST_INIT_DUP;
+       struct string_list fresh_packs = STRING_LIST_INIT_DUP;
+       struct packed_git *p;
+
+       ignore_packed_keep_in_core = 1;
+
+       while (strbuf_getline(&buf, stdin) != EOF) {
+               if (!buf.len)
+                       continue;
+
+               if (*buf.buf == '-')
+                       string_list_append(&discard_packs, buf.buf + 1);
+               else
+                       string_list_append(&fresh_packs, buf.buf);
+               strbuf_reset(&buf);
+       }
+
+       string_list_sort(&discard_packs);
+       string_list_sort(&fresh_packs);
+
+       for (p = get_all_packs(the_repository); p; p = p->next) {
+               const char *pack_name = pack_basename(p);
+               struct string_list_item *item;
+
+               item = string_list_lookup(&fresh_packs, pack_name);
+               if (!item)
+                       item = string_list_lookup(&discard_packs, pack_name);
+
+               if (item) {
+                       item->util = p;
+               } else {
+                       /*
+                        * This pack wasn't mentioned in either the "fresh" or
+                        * "discard" list, so the caller didn't know about it.
+                        *
+                        * Mark it as kept so that its objects are ignored by
+                        * add_unseen_recent_objects_to_traversal(). We'll
+                        * unmark it before starting the traversal so it doesn't
+                        * halt the traversal early.
+                        */
+                       p->pack_keep_in_core = 1;
+               }
+       }
+
+       mark_pack_kept_in_core(&fresh_packs, 1);
+       mark_pack_kept_in_core(&discard_packs, 0);
+
+       if (cruft_expiration)
+               enumerate_and_traverse_cruft_objects(&fresh_packs);
+       else
+               enumerate_cruft_objects();
+
+       strbuf_release(&buf);
+       string_list_clear(&discard_packs, 0);
+       string_list_clear(&fresh_packs, 0);
+}
+
 static void read_object_list_from_stdin(void)
 {
        char line[GIT_MAX_HEXSZ + 1 + PATH_MAX + 2];
@@ -3526,7 +3755,24 @@ static int add_object_in_unpacked_pack(const struct object_id *oid,
                                       uint32_t pos,
                                       void *_data)
 {
-       add_object_entry(oid, OBJ_NONE, "", 0);
+       if (cruft) {
+               off_t offset;
+               time_t mtime;
+
+               if (pack->is_cruft) {
+                       if (load_pack_mtimes(pack) < 0)
+                               die(_("could not load cruft pack .mtimes"));
+                       mtime = nth_packed_mtime(pack, pos);
+               } else {
+                       mtime = pack->mtime;
+               }
+               offset = nth_packed_object_offset(pack, pos);
+
+               add_cruft_object_entry(oid, OBJ_NONE, pack, offset,
+                                      NULL, mtime);
+       } else {
+               add_object_entry(oid, OBJ_NONE, "", 0);
+       }
        return 0;
 }
 
@@ -3550,7 +3796,19 @@ static int add_loose_object(const struct object_id *oid, const char *path,
                return 0;
        }
 
-       add_object_entry(oid, type, "", 0);
+       if (cruft) {
+               struct stat st;
+               if (stat(path, &st) < 0) {
+                       if (errno == ENOENT)
+                               return 0;
+                       return error_errno("unable to stat %s", oid_to_hex(oid));
+               }
+
+               add_cruft_object_entry(oid, type, NULL, 0, NULL,
+                                      st.st_mtime);
+       } else {
+               add_object_entry(oid, type, "", 0);
+       }
        return 0;
 }
 
@@ -3790,7 +4048,7 @@ static void get_object_list(struct rev_info *revs, int ac, const char **av)
        if (unpack_unreachable_expiration) {
                revs->ignore_missing_links = 1;
                if (add_unseen_recent_objects_to_traversal(revs,
-                               unpack_unreachable_expiration))
+                               unpack_unreachable_expiration, NULL, 0))
                        die(_("unable to add recent objects"));
                if (prepare_revision_walk(revs))
                        die(_("revision walk setup failed"));
@@ -3867,6 +4125,20 @@ static int option_parse_unpack_unreachable(const struct option *opt,
        return 0;
 }
 
+static int option_parse_cruft_expiration(const struct option *opt,
+                                        const char *arg, int unset)
+{
+       if (unset) {
+               cruft = 0;
+               cruft_expiration = 0;
+       } else {
+               cruft = 1;
+               if (arg)
+                       cruft_expiration = approxidate(arg);
+       }
+       return 0;
+}
+
 struct po_filter_data {
        unsigned have_revs:1;
        struct rev_info revs;
@@ -3956,6 +4228,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                OPT_CALLBACK_F(0, "unpack-unreachable", NULL, N_("time"),
                  N_("unpack unreachable objects newer than <time>"),
                  PARSE_OPT_OPTARG, option_parse_unpack_unreachable),
+               OPT_BOOL(0, "cruft", &cruft, N_("create a cruft pack")),
+               OPT_CALLBACK_F(0, "cruft-expiration", NULL, N_("time"),
+                 N_("expire cruft objects older than <time>"),
+                 PARSE_OPT_OPTARG, option_parse_cruft_expiration),
                OPT_BOOL(0, "sparse", &sparse,
                         N_("use the sparse reachability algorithm")),
                OPT_BOOL(0, "thin", &thin,
@@ -4082,7 +4358,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 
        if (!HAVE_THREADS && delta_search_threads != 1)
                warning(_("no threads support, ignoring --threads"));
-       if (!pack_to_stdout && !pack_size_limit)
+       if (!pack_to_stdout && !pack_size_limit && !cruft)
                pack_size_limit = pack_size_limit_cfg;
        if (pack_to_stdout && pack_size_limit)
                die(_("--max-pack-size cannot be used to build a pack for transfer"));
@@ -4109,6 +4385,15 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (stdin_packs && use_internal_rev_list)
                die(_("cannot use internal rev list with --stdin-packs"));
 
+       if (cruft) {
+               if (use_internal_rev_list)
+                       die(_("cannot use internal rev list with --cruft"));
+               if (stdin_packs)
+                       die(_("cannot use --stdin-packs with --cruft"));
+               if (pack_size_limit)
+                       die(_("cannot use --max-pack-size with --cruft"));
+       }
+
        /*
         * "soft" reasons not to use bitmaps - for on-disk repack by default we want
         *
@@ -4165,7 +4450,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                            the_repository);
        prepare_packing_data(the_repository, &to_pack);
 
-       if (progress)
+       if (progress && !cruft)
                progress_state = start_progress(_("Enumerating objects"), 0);
        if (stdin_packs) {
                /* avoids adding objects in excluded packs */
@@ -4173,15 +4458,19 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                read_packs_list_from_stdin();
                if (rev_list_unpacked)
                        add_unreachable_loose_objects();
+       } else if (cruft) {
+               read_cruft_objects();
        } else if (!use_internal_rev_list) {
                read_object_list_from_stdin();
        } else if (pfd.have_revs) {
                get_object_list(&pfd.revs, rp.nr, rp.v);
+               release_revisions(&pfd.revs);
        } else {
                struct rev_info revs;
 
                repo_init_revisions(the_repository, &revs, NULL);
                get_object_list(&revs, rp.nr, rp.v);
+               release_revisions(&revs);
        }
        cleanup_preferred_base();
        if (include_tag && nr_result)
index 8bf5c0acad2023967abf498832006f37924d9ca1..ed9b9013a5fea10c0e99616ac928661130b4c21e 100644 (file)
@@ -101,7 +101,7 @@ static inline struct llist_item *llist_insert(struct llist *list,
        oidread(&new_item->oid, oid);
        new_item->next = NULL;
 
-       if (after != NULL) {
+       if (after) {
                new_item->next = after->next;
                after->next = new_item;
                if (after == list->back)
@@ -157,7 +157,7 @@ redo_from_start:
                if (cmp > 0) /* not in list, since sorted */
                        return prev;
                if (!cmp) { /* found */
-                       if (prev == NULL) {
+                       if (!prev) {
                                if (hint != NULL && hint != list->front) {
                                        /* we don't know the previous element */
                                        hint = NULL;
@@ -219,7 +219,7 @@ static struct pack_list * pack_list_difference(const struct pack_list *A,
        struct pack_list *ret;
        const struct pack_list *pl;
 
-       if (A == NULL)
+       if (!A)
                return NULL;
 
        pl = B;
@@ -317,7 +317,7 @@ static size_t get_pack_redundancy(struct pack_list *pl)
        struct pack_list *subset;
        size_t ret = 0;
 
-       if (pl == NULL)
+       if (!pl)
                return 0;
 
        while ((subset = pl->next)) {
@@ -611,7 +611,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
                while (*(argv + i) != NULL)
                        add_pack_file(*(argv + i++));
 
-       if (local_packs == NULL)
+       if (!local_packs)
                die("Zero packs found!");
 
        load_all_objects();
index c2bcdc07db46a76559ecbccda756642f7cd5b6b4..df376b2ed1e0920e727e5e0a373fbb053ddf3d5a 100644 (file)
@@ -196,5 +196,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
                prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0);
        }
 
+       release_revisions(&revs);
        return 0;
 }
index 4d667abc19d91c0c83ef9faf6b1944f73d2ff48c..01155ba67b20d6593e09b239d8a5bbb3eb195535 100644 (file)
@@ -72,6 +72,7 @@ static const char * const pull_usage[] = {
 static int opt_verbosity;
 static char *opt_progress;
 static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
 
 /* Options passed to git-merge or git-rebase */
 static enum rebase_type opt_rebase = -1;
@@ -120,7 +121,7 @@ static struct option pull_options[] = {
                N_("force progress reporting"),
                PARSE_OPT_NOARG),
        OPT_CALLBACK_F(0, "recurse-submodules",
-                  &recurse_submodules, N_("on-demand"),
+                  &recurse_submodules_cli, N_("on-demand"),
                   N_("control for recursive fetching of submodules"),
                   PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules),
 
@@ -536,8 +537,8 @@ static int run_fetch(const char *repo, const char **refspecs)
                strvec_push(&args, opt_tags);
        if (opt_prune)
                strvec_push(&args, opt_prune);
-       if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
-               switch (recurse_submodules) {
+       if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
+               switch (recurse_submodules_cli) {
                case RECURSE_SUBMODULES_ON:
                        strvec_push(&args, "--recurse-submodules=on");
                        break;
@@ -1001,6 +1002,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
        argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
 
+       if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
+               recurse_submodules = recurse_submodules_cli;
+
        if (cleanup_arg)
                /*
                 * this only checks the validity of cleanup_arg; we don't need
index cad997965a7fb73d757f7a74570b634cbc9408e9..86b44f8aa71518c711dd3cd5aee27f5c59c0272b 100644 (file)
@@ -2,6 +2,7 @@
  * "git push"
  */
 #include "cache.h"
+#include "branch.h"
 #include "config.h"
 #include "refs.h"
 #include "refspec.h"
@@ -151,7 +152,8 @@ static NORETURN void die_push_simple(struct branch *branch,
         * upstream to a non-branch, we should probably be showing
         * them the big ugly fully qualified ref.
         */
-       const char *advice_maybe = "";
+       const char *advice_pushdefault_maybe = "";
+       const char *advice_automergesimple_maybe = "";
        const char *short_upstream = branch->merge[0]->src;
 
        skip_prefix(short_upstream, "refs/heads/", &short_upstream);
@@ -161,9 +163,16 @@ static NORETURN void die_push_simple(struct branch *branch,
         * push.default.
         */
        if (push_default == PUSH_DEFAULT_UNSPECIFIED)
-               advice_maybe = _("\n"
+               advice_pushdefault_maybe = _("\n"
                                 "To choose either option permanently, "
-                                "see push.default in 'git help config'.");
+                                "see push.default in 'git help config'.\n");
+       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 "
+                                "'simple' of branch.autosetupmerge\n"
+                                "in 'git help config'.\n");
        die(_("The upstream branch of your current branch does not match\n"
              "the name of your current branch.  To push to the upstream branch\n"
              "on the remote, use\n"
@@ -173,9 +182,10 @@ static NORETURN void die_push_simple(struct branch *branch,
              "To push to the branch of the same name on the remote, use\n"
              "\n"
              "    git push %s HEAD\n"
-             "%s"),
+             "%s%s"),
            remote->name, short_upstream,
-           remote->name, advice_maybe);
+           remote->name, advice_pushdefault_maybe,
+           advice_automergesimple_maybe);
 }
 
 static const char message_detached_head_die[] =
@@ -185,16 +195,32 @@ static const char message_detached_head_die[] =
           "\n"
           "    git push %s HEAD:<name-of-remote-branch>\n");
 
-static const char *get_upstream_ref(struct branch *branch, const char *remote_name)
+static const char *get_upstream_ref(int flags, struct branch *branch, const char *remote_name)
 {
-       if (!branch->merge_nr || !branch->merge || !branch->remote_name)
+       if (branch->merge_nr == 0 && (flags & TRANSPORT_PUSH_AUTO_UPSTREAM)) {
+               /* if missing, assume same; set_upstream will be defined later */
+               return branch->refname;
+       }
+
+       if (!branch->merge_nr || !branch->merge || !branch->remote_name) {
+               const char *advice_autosetup_maybe = "";
+               if (!(flags & TRANSPORT_PUSH_AUTO_UPSTREAM)) {
+                       advice_autosetup_maybe = _("\n"
+                                          "To have this happen automatically for "
+                                          "branches without a tracking\n"
+                                          "upstream, see 'push.autoSetupRemote' "
+                                          "in 'git help config'.\n");
+               }
                die(_("The current branch %s has no upstream branch.\n"
                    "To push the current branch and set the remote as upstream, use\n"
                    "\n"
-                   "    git push --set-upstream %s %s\n"),
+                   "    git push --set-upstream %s %s\n"
+                   "%s"),
                    branch->name,
                    remote_name,
-                   branch->name);
+                   branch->name,
+                   advice_autosetup_maybe);
+       }
        if (branch->merge_nr != 1)
                die(_("The current branch %s has multiple upstream branches, "
                    "refusing to push."), branch->name);
@@ -202,7 +228,7 @@ static const char *get_upstream_ref(struct branch *branch, const char *remote_na
        return branch->merge[0]->src;
 }
 
-static void setup_default_push_refspecs(struct remote *remote)
+static void setup_default_push_refspecs(int *flags, struct remote *remote)
 {
        struct branch *branch;
        const char *dst;
@@ -234,7 +260,7 @@ static void setup_default_push_refspecs(struct remote *remote)
        case PUSH_DEFAULT_SIMPLE:
                if (!same_remote)
                        break;
-               if (strcmp(branch->refname, get_upstream_ref(branch, remote->name)))
+               if (strcmp(branch->refname, get_upstream_ref(*flags, branch, remote->name)))
                        die_push_simple(branch, remote);
                break;
 
@@ -244,13 +270,21 @@ static void setup_default_push_refspecs(struct remote *remote)
                              "your current branch '%s', without telling me what to push\n"
                              "to update which remote branch."),
                            remote->name, branch->name);
-               dst = get_upstream_ref(branch, remote->name);
+               dst = get_upstream_ref(*flags, branch, remote->name);
                break;
 
        case PUSH_DEFAULT_CURRENT:
                break;
        }
 
+       /*
+        * this is a default push - if auto-upstream is enabled and there is
+        * no upstream defined, then set it (with options 'simple', 'upstream',
+        * and 'current').
+        */
+       if ((*flags & TRANSPORT_PUSH_AUTO_UPSTREAM) && branch->merge_nr == 0)
+               *flags |= TRANSPORT_PUSH_SET_UPSTREAM;
+
        refspec_appendf(&rs, "%s:%s", branch->refname, dst);
 }
 
@@ -401,7 +435,7 @@ static int do_push(int flags,
                if (remote->push.nr) {
                        push_refspec = &remote->push;
                } else if (!(flags & TRANSPORT_PUSH_MIRROR))
-                       setup_default_push_refspecs(remote);
+                       setup_default_push_refspecs(&flags, remote);
        }
        errs = 0;
        url_nr = push_url_of_remote(remote, &url);
@@ -472,6 +506,10 @@ static int git_push_config(const char *k, const char *v, void *cb)
                else
                        *flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
                return 0;
+       } else if (!strcmp(k, "push.autosetupremote")) {
+               if (git_config_bool(k, v))
+                       *flags |= TRANSPORT_PUSH_AUTO_UPSTREAM;
+               return 0;
        } else if (!strcmp(k, "push.gpgsign")) {
                const char *value;
                if (!git_config_get_value("push.gpgsign", &value)) {
index 27fde7bf2815d3f7af22f87d14c098edce5c552d..7ab50cda2ad09f127e5840dd3cc4e0aad6ef36c3 100644 (file)
@@ -1187,11 +1187,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                } else {
                        strbuf_reset(&buf);
                        strbuf_addf(&buf, "%s/interactive", merge_dir());
-                       if(file_exists(buf.buf)) {
-                               options.type = REBASE_MERGE;
+                       options.type = REBASE_MERGE;
+                       if (file_exists(buf.buf))
                                options.flags |= REBASE_INTERACTIVE_EXPLICIT;
-                       } else
-                               options.type = REBASE_MERGE;
                }
                options.state_dir = merge_dir();
        }
@@ -1583,33 +1581,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                options.upstream_arg = "--root";
        }
 
-       /* Make sure the branch to rebase onto is valid. */
-       if (keep_base) {
-               strbuf_reset(&buf);
-               strbuf_addstr(&buf, options.upstream_name);
-               strbuf_addstr(&buf, "...");
-               options.onto_name = xstrdup(buf.buf);
-       } 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 (keep_base)
-                               die(_("'%s': need exactly one merge base with branch"),
-                                   options.upstream_name);
-                       else
-                               die(_("'%s': need exactly one merge base"),
-                                   options.onto_name);
-               }
-               options.onto = lookup_commit_or_die(&merge_base,
-                                                   options.onto_name);
-       } else {
-               options.onto =
-                       lookup_commit_reference_by_name(options.onto_name);
-               if (!options.onto)
-                       die(_("Does not point to a valid commit '%s'"),
-                               options.onto_name);
-       }
-
        /*
         * If the branch to rebase is given, that is the branch we will rebase
         * branch_name -- branch/commit being rebased, or
@@ -1659,6 +1630,34 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
        } else
                BUG("unexpected number of arguments left to parse");
 
+       /* Make sure the branch to rebase onto is valid. */
+       if (keep_base) {
+               strbuf_reset(&buf);
+               strbuf_addstr(&buf, options.upstream_name);
+               strbuf_addstr(&buf, "...");
+               strbuf_addstr(&buf, branch_name);
+               options.onto_name = xstrdup(buf.buf);
+       } 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 (keep_base)
+                               die(_("'%s': need exactly one merge base with branch"),
+                                   options.upstream_name);
+                       else
+                               die(_("'%s': need exactly one merge base"),
+                                   options.onto_name);
+               }
+               options.onto = lookup_commit_or_die(&merge_base,
+                                                   options.onto_name);
+       } else {
+               options.onto =
+                       lookup_commit_reference_by_name(options.onto_name);
+               if (!options.onto)
+                       die(_("Does not point to a valid commit '%s'"),
+                               options.onto_name);
+       }
+
        if (options.fork_point > 0) {
                struct commit *head =
                        lookup_commit_reference(the_repository,
index 9aabffa1afb646f0513068de3d6366a7bc58809a..daa153d04461005fc031f9c4e51fc299bbef2883 100644 (file)
@@ -1664,7 +1664,7 @@ static void check_aliased_update_internal(struct command *cmd,
        }
        dst_name = strip_namespace(dst_name);
 
-       if ((item = string_list_lookup(list, dst_name)) == NULL)
+       if (!(item = string_list_lookup(list, dst_name)))
                return;
 
        cmd->skip_update = 1;
@@ -2214,8 +2214,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                        close(err_fd);
                return "unable to create temporary object directory";
        }
-       if (tmp_objdir)
-               strvec_pushv(&child.env_array, tmp_objdir_env(tmp_objdir));
+       strvec_pushv(&child.env_array, tmp_objdir_env(tmp_objdir));
 
        /*
         * Normally we just pass the tmp_objdir environment to the child
@@ -2538,7 +2537,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
                           PACKET_READ_CHOMP_NEWLINE |
                           PACKET_READ_DIE_ON_ERR_PACKET);
 
-       if ((commands = read_head_info(&reader, &shallow)) != NULL) {
+       if ((commands = read_head_info(&reader, &shallow))) {
                const char *unpack_status = NULL;
                struct string_list push_options = STRING_LIST_INIT_DUP;
 
index c943c2aabe6e00ebad5fbb9c795ffd3a2639d6bb..4dd297dce86e5212087ee1202d5b9dd1f754f9d1 100644 (file)
@@ -293,6 +293,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
                if (verbose)
                        printf(_("Marking reachable objects..."));
                mark_reachable_objects(&revs, 0, 0, NULL);
+               release_revisions(&revs);
                if (verbose)
                        putchar('\n');
        }
index 5f4cde9d784e310e939dc7952e4096e45f60cbb7..d4b69fe77898977d4b4dead8059c667ee17110cd 100644 (file)
@@ -1185,14 +1185,22 @@ static int show_push_info_item(struct string_list_item *item, void *cb_data)
 static int get_one_entry(struct remote *remote, void *priv)
 {
        struct string_list *list = priv;
-       struct strbuf url_buf = STRBUF_INIT;
+       struct strbuf remote_info_buf = STRBUF_INIT;
        const char **url;
        int i, url_nr;
 
        if (remote->url_nr > 0) {
-               strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
+               struct strbuf promisor_config = STRBUF_INIT;
+               const char *partial_clone_filter = NULL;
+
+               strbuf_addf(&promisor_config, "remote.%s.partialclonefilter", remote->name);
+               strbuf_addf(&remote_info_buf, "%s (fetch)", remote->url[0]);
+               if (!git_config_get_string_tmp(promisor_config.buf, &partial_clone_filter))
+                       strbuf_addf(&remote_info_buf, " [%s]", partial_clone_filter);
+
+               strbuf_release(&promisor_config);
                string_list_append(list, remote->name)->util =
-                               strbuf_detach(&url_buf, NULL);
+                               strbuf_detach(&remote_info_buf, NULL);
        } else
                string_list_append(list, remote->name)->util = NULL;
        if (remote->pushurl_nr) {
@@ -1204,9 +1212,9 @@ static int get_one_entry(struct remote *remote, void *priv)
        }
        for (i = 0; i < url_nr; i++)
        {
-               strbuf_addf(&url_buf, "%s (push)", url[i]);
+               strbuf_addf(&remote_info_buf, "%s (push)", url[i]);
                string_list_append(list, remote->name)->util =
-                               strbuf_detach(&url_buf, NULL);
+                               strbuf_detach(&remote_info_buf, NULL);
        }
 
        return 0;
index d1a563d5b65666b68596ad353a945e8e11c6ac70..c957b2959f7865ce58eea0737f3b8d20c340bcec 100644 (file)
 #include "pack-bitmap.h"
 #include "refs.h"
 
+#define ALL_INTO_ONE 1
+#define LOOSEN_UNREACHABLE 2
+#define PACK_CRUFT 4
+
+#define DELETE_PACK 1
+#define CRUFT_PACK 2
+
+static int pack_everything;
 static int delta_base_offset = 1;
 static int pack_kept_objects = -1;
 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>]"),
@@ -35,9 +44,21 @@ static const char incremental_bitmap_conflict_error[] = N_(
 "--no-write-bitmap-index or disable the pack.writebitmaps configuration."
 );
 
+struct pack_objects_args {
+       const char *window;
+       const char *window_memory;
+       const char *depth;
+       const char *threads;
+       const char *max_pack_size;
+       int no_reuse_delta;
+       int no_reuse_object;
+       int quiet;
+       int local;
+};
 
 static int repack_config(const char *var, const char *value, void *cb)
 {
+       struct pack_objects_args *cruft_po_args = cb;
        if (!strcmp(var, "repack.usedeltabaseoffset")) {
                delta_base_offset = git_config_bool(var, value);
                return 0;
@@ -59,6 +80,14 @@ static int repack_config(const char *var, const char *value, void *cb)
                run_update_server_info = git_config_bool(var, value);
                return 0;
        }
+       if (!strcmp(var, "repack.cruftwindow"))
+               return git_config_string(&cruft_po_args->window, var, value);
+       if (!strcmp(var, "repack.cruftwindowmemory"))
+               return git_config_string(&cruft_po_args->window_memory, var, value);
+       if (!strcmp(var, "repack.cruftdepth"))
+               return git_config_string(&cruft_po_args->depth, var, value);
+       if (!strcmp(var, "repack.cruftthreads"))
+               return git_config_string(&cruft_po_args->threads, var, value);
        return git_default_config(var, value, cb);
 }
 
@@ -131,12 +160,19 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list,
                fname = xmemdupz(e->d_name, len);
 
                if ((extra_keep->nr > 0 && i < extra_keep->nr) ||
-                   (file_exists(mkpath("%s/%s.keep", packdir, fname))))
+                   (file_exists(mkpath("%s/%s.keep", packdir, fname)))) {
                        string_list_append_nodup(fname_kept_list, fname);
-               else
-                       string_list_append_nodup(fname_nonkept_list, fname);
+               } else {
+                       struct string_list_item *item;
+                       item = string_list_append_nodup(fname_nonkept_list,
+                                                       fname);
+                       if (file_exists(mkpath("%s/%s.mtimes", packdir, fname)))
+                               item->util = (void*)(uintptr_t)CRUFT_PACK;
+               }
        }
        closedir(dir);
+
+       string_list_sort(fname_kept_list);
 }
 
 static void remove_redundant_pack(const char *dir_name, const char *base_name)
@@ -151,18 +187,6 @@ static void remove_redundant_pack(const char *dir_name, const char *base_name)
        strbuf_release(&buf);
 }
 
-struct pack_objects_args {
-       const char *window;
-       const char *window_memory;
-       const char *depth;
-       const char *threads;
-       const char *max_pack_size;
-       int no_reuse_delta;
-       int no_reuse_object;
-       int quiet;
-       int local;
-};
-
 static void prepare_pack_objects(struct child_process *cmd,
                                 const struct pack_objects_args *args)
 {
@@ -217,6 +241,7 @@ static struct {
 } exts[] = {
        {".pack"},
        {".rev", 1},
+       {".mtimes", 1},
        {".bitmap", 1},
        {".promisor", 1},
        {".idx"},
@@ -304,9 +329,6 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
                die(_("could not finish pack-objects to repack promisor objects"));
 }
 
-#define ALL_INTO_ONE 1
-#define LOOSEN_UNREACHABLE 2
-
 struct pack_geometry {
        struct packed_git **pack;
        uint32_t pack_nr, pack_alloc;
@@ -332,16 +354,39 @@ static int geometry_cmp(const void *va, const void *vb)
        return 0;
 }
 
-static void init_pack_geometry(struct pack_geometry **geometry_p)
+static void init_pack_geometry(struct pack_geometry **geometry_p,
+                              struct string_list *existing_kept_packs)
 {
        struct packed_git *p;
        struct pack_geometry *geometry;
+       struct strbuf buf = STRBUF_INIT;
 
        *geometry_p = xcalloc(1, sizeof(struct pack_geometry));
        geometry = *geometry_p;
 
        for (p = get_all_packs(the_repository); p; p = p->next) {
-               if (!pack_kept_objects && p->pack_keep)
+               if (!pack_kept_objects) {
+                       /*
+                        * Any pack that has its pack_keep bit set will appear
+                        * in existing_kept_packs below, but this saves us from
+                        * doing a more expensive check.
+                        */
+                       if (p->pack_keep)
+                               continue;
+
+                       /*
+                        * The pack may be kept via the --keep-pack option;
+                        * check 'existing_kept_packs' to determine whether to
+                        * ignore it.
+                        */
+                       strbuf_reset(&buf);
+                       strbuf_addstr(&buf, pack_basename(p));
+                       strbuf_strip_suffix(&buf, ".pack");
+
+                       if (string_list_has_string(existing_kept_packs, buf.buf))
+                               continue;
+               }
+               if (p->is_cruft)
                        continue;
 
                ALLOC_GROW(geometry->pack,
@@ -353,6 +398,7 @@ static void init_pack_geometry(struct pack_geometry **geometry_p)
        }
 
        QSORT(geometry->pack, geometry->pack_nr, geometry_cmp);
+       strbuf_release(&buf);
 }
 
 static void split_pack_geometry(struct pack_geometry *geometry, int factor)
@@ -548,9 +594,20 @@ static void midx_included_packs(struct string_list *include,
 
                        string_list_insert(include, strbuf_detach(&buf, NULL));
                }
+
+               for_each_string_list_item(item, existing_nonkept_packs) {
+                       if (!((uintptr_t)item->util & CRUFT_PACK)) {
+                               /*
+                                * no need to check DELETE_PACK, since we're not
+                                * doing an ALL_INTO_ONE repack
+                                */
+                               continue;
+                       }
+                       string_list_insert(include, xstrfmt("%s.idx", item->string));
+               }
        } else {
                for_each_string_list_item(item, existing_nonkept_packs) {
-                       if (item->util)
+                       if ((uintptr_t)item->util & DELETE_PACK)
                                continue;
                        string_list_insert(include, xstrfmt("%s.idx", item->string));
                }
@@ -604,6 +661,67 @@ static int write_midx_included_packs(struct string_list *include,
        return finish_command(&cmd);
 }
 
+static int write_cruft_pack(const struct pack_objects_args *args,
+                           const char *pack_prefix,
+                           struct string_list *names,
+                           struct string_list *existing_packs,
+                           struct string_list *existing_kept_packs)
+{
+       struct child_process cmd = CHILD_PROCESS_INIT;
+       struct strbuf line = STRBUF_INIT;
+       struct string_list_item *item;
+       FILE *in, *out;
+       int ret;
+
+       prepare_pack_objects(&cmd, args);
+
+       strvec_push(&cmd.args, "--cruft");
+       if (cruft_expiration)
+               strvec_pushf(&cmd.args, "--cruft-expiration=%s",
+                            cruft_expiration);
+
+       strvec_push(&cmd.args, "--honor-pack-keep");
+       strvec_push(&cmd.args, "--non-empty");
+       strvec_push(&cmd.args, "--max-pack-size=0");
+
+       cmd.in = -1;
+
+       ret = start_command(&cmd);
+       if (ret)
+               return ret;
+
+       /*
+        * names has a confusing double use: it both provides the list
+        * of just-written new packs, and accepts the name of the cruft
+        * pack we are writing.
+        *
+        * 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.
+        */
+       in = xfdopen(cmd.in, "w");
+       for_each_string_list_item(item, names)
+               fprintf(in, "%s-%s.pack\n", pack_prefix, item->string);
+       for_each_string_list_item(item, existing_packs)
+               fprintf(in, "-%s.pack\n", item->string);
+       for_each_string_list_item(item, existing_kept_packs)
+               fprintf(in, "%s.pack\n", item->string);
+       fclose(in);
+
+       out = xfdopen(cmd.out, "r");
+       while (strbuf_getline_lf(&line, out) != EOF) {
+               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);
+       }
+       fclose(out);
+
+       strbuf_release(&line);
+
+       return finish_command(&cmd);
+}
+
 int cmd_repack(int argc, const char **argv, const char *prefix)
 {
        struct child_process cmd = CHILD_PROCESS_INIT;
@@ -620,12 +738,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        int show_progress;
 
        /* variables to be filled by option parsing */
-       int pack_everything = 0;
        int delete_redundant = 0;
        const char *unpack_unreachable = NULL;
        int keep_unreachable = 0;
        struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
        struct pack_objects_args po_args = {NULL};
+       struct pack_objects_args cruft_po_args = {NULL};
        int geometric_factor = 0;
        int write_midx = 0;
 
@@ -635,6 +753,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                OPT_BIT('A', NULL, &pack_everything,
                                N_("same as -a, and turn unreachable objects loose"),
                                   LOOSEN_UNREACHABLE | ALL_INTO_ONE),
+               OPT_BIT(0, "cruft", &pack_everything,
+                               N_("same as -a, pack unreachable cruft objects separately"),
+                                  PACK_CRUFT),
+               OPT_STRING(0, "cruft-expiration", &cruft_expiration, N_("approxidate"),
+                               N_("with -C, expire objects older than this")),
                OPT_BOOL('d', NULL, &delete_redundant,
                                N_("remove redundant packs, and run git-prune-packed")),
                OPT_BOOL('f', NULL, &po_args.no_reuse_delta,
@@ -675,7 +798,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                OPT_END()
        };
 
-       git_config(repack_config, NULL);
+       git_config(repack_config, &cruft_po_args);
 
        argc = parse_options(argc, argv, prefix, builtin_repack_options,
                                git_repack_usage, 0);
@@ -687,6 +810,15 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
            (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE)))
                die(_("options '%s' and '%s' cannot be used together"), "--keep-unreachable", "-A");
 
+       if (pack_everything & PACK_CRUFT) {
+               pack_everything |= ALL_INTO_ONE;
+
+               if (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE))
+                       die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-A");
+               if (keep_unreachable)
+                       die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-k");
+       }
+
        if (write_bitmaps < 0) {
                if (!write_midx &&
                    (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository()))
@@ -714,17 +846,20 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                strbuf_release(&path);
        }
 
+       packdir = mkpathdup("%s/pack", get_object_directory());
+       packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid());
+       packtmp = mkpathdup("%s/%s", packdir, packtmp_name);
+
+       collect_pack_filenames(&existing_nonkept_packs, &existing_kept_packs,
+                              &keep_pack_list);
+
        if (geometric_factor) {
                if (pack_everything)
                        die(_("options '%s' and '%s' cannot be used together"), "--geometric", "-A/-a");
-               init_pack_geometry(&geometry);
+               init_pack_geometry(&geometry, &existing_kept_packs);
                split_pack_geometry(geometry, geometric_factor);
        }
 
-       packdir = mkpathdup("%s/pack", get_object_directory());
-       packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid());
-       packtmp = mkpathdup("%s/%s", packdir, packtmp_name);
-
        sigchain_push_common(remove_pack_on_signal);
 
        prepare_pack_objects(&cmd, &po_args);
@@ -764,13 +899,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        if (use_delta_islands)
                strvec_push(&cmd.args, "--delta-islands");
 
-       collect_pack_filenames(&existing_nonkept_packs, &existing_kept_packs,
-                              &keep_pack_list);
-
        if (pack_everything & ALL_INTO_ONE) {
                repack_promisor_objects(&po_args, &names);
 
-               if (existing_nonkept_packs.nr && delete_redundant) {
+               if (existing_nonkept_packs.nr && delete_redundant &&
+                   !(pack_everything & PACK_CRUFT)) {
                        for_each_string_list_item(item, &names) {
                                strvec_pushf(&cmd.args, "--keep-pack=%s-%s.pack",
                                             packtmp_name, item->string);
@@ -832,6 +965,35 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        if (!names.nr && !po_args.quiet)
                printf_ln(_("Nothing new to pack."));
 
+       if (pack_everything & PACK_CRUFT) {
+               const char *pack_prefix;
+               if (!skip_prefix(packtmp, packdir, &pack_prefix))
+                       die(_("pack prefix %s does not begin with objdir %s"),
+                           packtmp, packdir);
+               if (*pack_prefix == '/')
+                       pack_prefix++;
+
+               if (!cruft_po_args.window)
+                       cruft_po_args.window = po_args.window;
+               if (!cruft_po_args.window_memory)
+                       cruft_po_args.window_memory = po_args.window_memory;
+               if (!cruft_po_args.depth)
+                       cruft_po_args.depth = po_args.depth;
+               if (!cruft_po_args.threads)
+                       cruft_po_args.threads = po_args.threads;
+
+               cruft_po_args.local = po_args.local;
+               cruft_po_args.quiet = po_args.quiet;
+
+               ret = write_cruft_pack(&cruft_po_args, pack_prefix, &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);
        }
@@ -872,7 +1034,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
 
        if (delete_redundant && pack_everything & ALL_INTO_ONE) {
                const int hexsz = the_hash_algo->hexsz;
-               string_list_sort(&names);
                for_each_string_list_item(item, &existing_nonkept_packs) {
                        char *sha1;
                        size_t len = strlen(item->string);
@@ -885,7 +1046,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                         * was given) and that we will actually delete this pack
                         * (if `-d` was given).
                         */
-                       item->util = (void*)(intptr_t)!string_list_has_string(&names, sha1);
+                       if (!string_list_has_string(&names, sha1))
+                               item->util = (void*)(uintptr_t)((size_t)item->util | DELETE_PACK);
                }
        }
 
@@ -909,7 +1071,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        if (delete_redundant) {
                int opts = 0;
                for_each_string_list_item(item, &existing_nonkept_packs) {
-                       if (!item->util)
+                       if (!((uintptr_t)item->util & DELETE_PACK))
                                continue;
                        remove_redundant_pack(packdir, item->string);
                }
index 5068f4f0b2acf8e4b0f342319999cedffccc4223..583702a0980e8ced3f91e1b88a9a1698be16fc6e 100644 (file)
@@ -72,7 +72,7 @@ static int list_replace_refs(const char *pattern, const char *format)
 {
        struct show_data data;
 
-       if (pattern == NULL)
+       if (!pattern)
                pattern = "*";
        data.pattern = pattern;
 
index 572da1472e5adf933c7680339ed3409cf62f3e24..30fd8e83eaf2ca767802343d2dcff1825f6b1b50 100644 (file)
@@ -213,10 +213,8 @@ static void show_commit(struct commit *commit, void *data)
 
 static void finish_commit(struct commit *commit)
 {
-       if (commit->parents) {
-               free_commit_list(commit->parents);
-               commit->parents = NULL;
-       }
+       free_commit_list(commit->parents);
+       commit->parents = NULL;
        free_commit_buffer(the_repository->parsed_objects,
                           commit);
 }
@@ -502,6 +500,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
        int use_bitmap_index = 0;
        int filter_provided_objects = 0;
        const char *show_progress = NULL;
+       int ret = 0;
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage(rev_list_usage);
@@ -585,7 +584,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
                }
                if (!strcmp(arg, "--test-bitmap")) {
                        test_bitmap_walk(&revs);
-                       return 0;
+                       goto cleanup;
                }
                if (skip_prefix(arg, "--progress=", &arg)) {
                        show_progress = arg;
@@ -674,11 +673,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 
        if (use_bitmap_index) {
                if (!try_bitmap_count(&revs, filter_provided_objects))
-                       return 0;
+                       goto cleanup;
                if (!try_bitmap_disk_usage(&revs, filter_provided_objects))
-                       return 0;
+                       goto cleanup;
                if (!try_bitmap_traversal(&revs, filter_provided_objects))
-                       return 0;
+                       goto cleanup;
        }
 
        if (prepare_revision_walk(&revs))
@@ -698,8 +697,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 
                find_bisection(&revs.commits, &reaches, &all, bisect_flags);
 
-               if (bisect_show_vars)
-                       return show_bisect_vars(&info, reaches, all);
+               if (bisect_show_vars) {
+                       ret = show_bisect_vars(&info, reaches, all);
+                       goto cleanup;
+               }
        }
 
        if (filter_provided_objects) {
@@ -754,5 +755,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
        if (show_disk_usage)
                printf("%"PRIuMAX"\n", (uintmax_t)total_disk_usage);
 
-       return 0;
+cleanup:
+       release_revisions(&revs);
+       return ret;
 }
index 8480a59f573e28d7777ee7e0dd21a2a640657641..b259d8990a681d1804d434cea2f1e28193e6693f 100644 (file)
@@ -476,7 +476,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
 
                /* name(s) */
                s = strpbrk(sb.buf, flag_chars);
-               if (s == NULL)
+               if (!s)
                        s = help;
 
                if (s - sb.buf == 1) /* short option only */
@@ -723,6 +723,9 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                        prefix = setup_git_directory();
                        git_config(git_default_config, NULL);
                        did_repo_setup = 1;
+
+                       prepare_repo_settings(the_repository);
+                       the_repository->settings.command_requires_full_index = 0;
                }
 
                if (!strcmp(arg, "--")) {
index 26c5c0cf93545777301c27f02279450347425fde..35825f075e3b219bb36bbffe6907f37b5140907a 100644 (file)
@@ -81,8 +81,10 @@ static void insert_one_record(struct shortlog *log,
                format_subject(&subject, oneline, " ");
                buffer = strbuf_detach(&subject, NULL);
 
-               if (item->util == NULL)
-                       item->util = xcalloc(1, sizeof(struct string_list));
+               if (!item->util) {
+                       item->util = xmalloc(sizeof(struct string_list));
+                       string_list_init_nodup(item->util);
+               }
                string_list_append(item->util, buffer);
        }
 }
@@ -420,6 +422,8 @@ parse_done:
        else
                get_from_rev(&rev, &log);
 
+       release_revisions(&rev);
+
        shortlog_output(&log);
        if (log.file != stdout)
                fclose(log.file);
index 330b0553b9d72d9befb0ecf1f3c58540b6f26877..64c649c6a238605cb847bbf515cbdca58cde990c 100644 (file)
@@ -712,6 +712,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                                "--all/--remotes/--independent/--merge-base");
        }
 
+       if (with_current_branch && reflog)
+               die(_("options '%s' and '%s' cannot be used together"),
+                   "--reflog", "--current");
+
        /* If nothing is specified, show all branches by default */
        if (ac <= topics && all_heads + all_remotes == 0)
                all_heads = 1;
index 0217d44c5b1c409c858a8df2f9c9b623a78b4804..f91e29b56a97eea0f8814a0bfcca45c512a3ab06 100644 (file)
@@ -128,7 +128,7 @@ static void clean_tracked_sparse_directories(struct repository *r)
         * sparse index will not delete directories that contain
         * conflicted entries or submodules.
         */
-       if (!r->index->sparse_index) {
+       if (r->index->sparse_index == INDEX_EXPANDED) {
                /*
                 * If something, such as a merge conflict or other concern,
                 * prevents us from converting to a sparse index, then do
@@ -395,7 +395,7 @@ static int update_modes(int *cone_mode, int *sparse_index)
 
        /* Set cone/non-cone mode appropriately */
        core_apply_sparse_checkout = 1;
-       if (*cone_mode == 1) {
+       if (*cone_mode == 1 || *cone_mode == -1) {
                mode = MODE_CONE_PATTERNS;
                core_sparse_checkout_cone = 1;
        } else {
@@ -413,6 +413,9 @@ static int update_modes(int *cone_mode, int *sparse_index)
                /* force an index rewrite */
                repo_read_index(the_repository);
                the_repository->index->updated_workdir = 1;
+
+               if (!*sparse_index)
+                       ensure_full_index(the_repository->index);
        }
 
        return 0;
@@ -934,6 +937,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
 
        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);
index 0c7b6a95882d9405e3cdf4a8d3d2d251dc0588db..68b28f2375e14b961c5e451b753d4a4307fd6c82 100644 (file)
@@ -7,6 +7,7 @@
 #include "cache-tree.h"
 #include "unpack-trees.h"
 #include "merge-recursive.h"
+#include "merge-ort-wrappers.h"
 #include "strvec.h"
 #include "run-command.h"
 #include "dir.h"
@@ -116,6 +117,10 @@ struct stash_info {
        int has_u;
 };
 
+#define STASH_INFO_INIT { \
+       .revision = STRBUF_INIT, \
+}
+
 static void free_stash_info(struct stash_info *info)
 {
        strbuf_release(&info->revision);
@@ -157,10 +162,8 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv)
        if (argc == 1)
                commit = argv[0];
 
-       strbuf_init(&info->revision, 0);
        if (!commit) {
                if (!ref_exists(ref_stash)) {
-                       free_stash_info(info);
                        fprintf_ln(stderr, _("No stash entries found."));
                        return -1;
                }
@@ -174,11 +177,8 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv)
 
        revision = info->revision.buf;
 
-       if (get_oid(revision, &info->w_commit)) {
-               error(_("%s is not a valid reference"), revision);
-               free_stash_info(info);
-               return -1;
-       }
+       if (get_oid(revision, &info->w_commit))
+               return error(_("%s is not a valid reference"), revision);
 
        assert_stash_like(info, revision);
 
@@ -197,7 +197,7 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv)
                info->is_stash_ref = !strcmp(expanded_ref, ref_stash);
                break;
        default: /* Invalid or ambiguous */
-               free_stash_info(info);
+               break;
        }
 
        free(expanded_ref);
@@ -492,13 +492,13 @@ static void unstage_changes_unless_new(struct object_id *orig_tree)
 static int do_apply_stash(const char *prefix, struct stash_info *info,
                          int index, int quiet)
 {
-       int ret;
+       int clean, ret;
        int has_index = index;
        struct merge_options o;
        struct object_id c_tree;
        struct object_id index_tree;
-       struct commit *result;
-       const struct object_id *bases[1];
+       struct tree *head, *merge, *merge_base;
+       struct lock_file lock = LOCK_INIT;
 
        read_cache_preload(NULL);
        if (refresh_and_write_cache(REFRESH_QUIET, 0, 0))
@@ -541,6 +541,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
 
        o.branch1 = "Updated upstream";
        o.branch2 = "Stashed changes";
+       o.ancestor = "Stash base";
 
        if (oideq(&info->b_tree, &c_tree))
                o.branch1 = "Version stash was based on";
@@ -551,10 +552,26 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
        if (o.verbosity >= 3)
                printf_ln(_("Merging %s with %s"), o.branch1, o.branch2);
 
-       bases[0] = &info->b_tree;
+       head = lookup_tree(o.repo, &c_tree);
+       merge = lookup_tree(o.repo, &info->w_tree);
+       merge_base = lookup_tree(o.repo, &info->b_tree);
+
+       repo_hold_locked_index(o.repo, &lock, LOCK_DIE_ON_ERROR);
+       clean = merge_ort_nonrecursive(&o, head, merge, merge_base);
+
+       /*
+        * If 'clean' >= 0, reverse the value for 'ret' so 'ret' is 0 when the
+        * merge was clean, and nonzero if the merge was unclean or encountered
+        * an error.
+        */
+       ret = clean >= 0 ? !clean : clean;
+
+       if (ret < 0)
+               rollback_lock_file(&lock);
+       else if (write_locked_index(o.repo->index, &lock,
+                                     COMMIT_LOCK | SKIP_IF_UNCHANGED))
+               ret = error(_("could not write index"));
 
-       ret = merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases,
-                                     &result);
        if (ret) {
                rerere(0);
 
@@ -598,10 +615,10 @@ restore_untracked:
 
 static int apply_stash(int argc, const char **argv, const char *prefix)
 {
-       int ret;
+       int ret = -1;
        int quiet = 0;
        int index = 0;
-       struct stash_info info;
+       struct stash_info info = STASH_INFO_INIT;
        struct option options[] = {
                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
                OPT_BOOL(0, "index", &index,
@@ -613,9 +630,10 @@ static int apply_stash(int argc, const char **argv, const char *prefix)
                             git_stash_apply_usage, 0);
 
        if (get_stash_info(&info, argc, argv))
-               return -1;
+               goto cleanup;
 
        ret = do_apply_stash(prefix, &info, index, quiet);
+cleanup:
        free_stash_info(&info);
        return ret;
 }
@@ -651,20 +669,25 @@ static int do_drop_stash(struct stash_info *info, int quiet)
        return 0;
 }
 
-static void assert_stash_ref(struct stash_info *info)
+static int get_stash_info_assert(struct stash_info *info, int argc,
+                                const char **argv)
 {
-       if (!info->is_stash_ref) {
-               error(_("'%s' is not a stash reference"), info->revision.buf);
-               free_stash_info(info);
-               exit(1);
-       }
+       int ret = get_stash_info(info, argc, argv);
+
+       if (ret < 0)
+               return ret;
+
+       if (!info->is_stash_ref)
+               return error(_("'%s' is not a stash reference"), info->revision.buf);
+
+       return 0;
 }
 
 static int drop_stash(int argc, const char **argv, const char *prefix)
 {
-       int ret;
+       int ret = -1;
        int quiet = 0;
-       struct stash_info info;
+       struct stash_info info = STASH_INFO_INIT;
        struct option options[] = {
                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
                OPT_END()
@@ -673,22 +696,21 @@ static int drop_stash(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, options,
                             git_stash_drop_usage, 0);
 
-       if (get_stash_info(&info, argc, argv))
-               return -1;
-
-       assert_stash_ref(&info);
+       if (get_stash_info_assert(&info, argc, argv))
+               goto cleanup;
 
        ret = do_drop_stash(&info, quiet);
+cleanup:
        free_stash_info(&info);
        return ret;
 }
 
 static int pop_stash(int argc, const char **argv, const char *prefix)
 {
-       int ret;
+       int ret = -1;
        int index = 0;
        int quiet = 0;
-       struct stash_info info;
+       struct stash_info info = STASH_INFO_INIT;
        struct option options[] = {
                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
                OPT_BOOL(0, "index", &index,
@@ -699,25 +721,25 @@ static int pop_stash(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, options,
                             git_stash_pop_usage, 0);
 
-       if (get_stash_info(&info, argc, argv))
-               return -1;
+       if (get_stash_info_assert(&info, argc, argv))
+               goto cleanup;
 
-       assert_stash_ref(&info);
        if ((ret = do_apply_stash(prefix, &info, index, quiet)))
                printf_ln(_("The stash entry is kept in case "
                            "you need it again."));
        else
                ret = do_drop_stash(&info, quiet);
 
+cleanup:
        free_stash_info(&info);
        return ret;
 }
 
 static int branch_stash(int argc, const char **argv, const char *prefix)
 {
-       int ret;
+       int ret = -1;
        const char *branch = NULL;
-       struct stash_info info;
+       struct stash_info info = STASH_INFO_INIT;
        struct child_process cp = CHILD_PROCESS_INIT;
        struct option options[] = {
                OPT_END()
@@ -734,7 +756,7 @@ static int branch_stash(int argc, const char **argv, const char *prefix)
        branch = argv[0];
 
        if (get_stash_info(&info, argc - 1, argv + 1))
-               return -1;
+               goto cleanup;
 
        cp.git_cmd = 1;
        strvec_pushl(&cp.args, "checkout", "-b", NULL);
@@ -746,8 +768,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix)
        if (!ret && info.is_stash_ref)
                ret = do_drop_stash(&info, 0);
 
+cleanup:
        free_stash_info(&info);
-
        return ret;
 }
 
@@ -825,8 +847,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op
 static int show_stash(int argc, const char **argv, const char *prefix)
 {
        int i;
-       int ret = 0;
-       struct stash_info info;
+       int ret = -1;
+       struct stash_info info = STASH_INFO_INIT;
        struct rev_info rev;
        struct strvec stash_args = STRVEC_INIT;
        struct strvec revision_args = STRVEC_INIT;
@@ -844,6 +866,7 @@ static int show_stash(int argc, const char **argv, const char *prefix)
                              UNTRACKED_ONLY, PARSE_OPT_NONEG),
                OPT_END()
        };
+       int do_usage = 0;
 
        init_diff_ui_defaults();
        git_config(git_diff_ui_config, NULL);
@@ -861,10 +884,8 @@ static int show_stash(int argc, const char **argv, const char *prefix)
                        strvec_push(&revision_args, argv[i]);
        }
 
-       ret = get_stash_info(&info, stash_args.nr, stash_args.v);
-       strvec_clear(&stash_args);
-       if (ret)
-               return -1;
+       if (get_stash_info(&info, stash_args.nr, stash_args.v))
+               goto cleanup;
 
        /*
         * The config settings are applied only if there are not passed
@@ -878,16 +899,14 @@ static int show_stash(int argc, const char **argv, const char *prefix)
                        rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
 
                if (!show_stat && !show_patch) {
-                       free_stash_info(&info);
-                       return 0;
+                       ret = 0;
+                       goto cleanup;
                }
        }
 
        argc = setup_revisions(revision_args.nr, revision_args.v, &rev, NULL);
-       if (argc > 1) {
-               free_stash_info(&info);
-               usage_with_options(git_stash_show_usage, options);
-       }
+       if (argc > 1)
+               goto usage;
        if (!rev.diffopt.output_format) {
                rev.diffopt.output_format = DIFF_FORMAT_PATCH;
                diff_setup_done(&rev.diffopt);
@@ -912,8 +931,17 @@ static int show_stash(int argc, const char **argv, const char *prefix)
        }
        log_tree_diff_flush(&rev);
 
+       ret = diff_result_code(&rev.diffopt, 0);
+cleanup:
+       strvec_clear(&stash_args);
        free_stash_info(&info);
-       return diff_result_code(&rev.diffopt, 0);
+       release_revisions(&rev);
+       if (do_usage)
+               usage_with_options(git_stash_show_usage, options);
+       return ret;
+usage:
+       do_usage = 1;
+       goto cleanup;
 }
 
 static int do_store_stash(const struct object_id *w_commit, const char *stash_msg,
@@ -1047,7 +1075,6 @@ static int check_changes_tracked_files(const struct pathspec *ps)
                goto done;
        }
 
-       object_array_clear(&rev.pending);
        result = run_diff_files(&rev, 0);
        if (diff_result_code(&rev.diffopt, result)) {
                ret = 1;
@@ -1055,7 +1082,7 @@ static int check_changes_tracked_files(const struct pathspec *ps)
        }
 
 done:
-       clear_pathspec(&rev.prune_data);
+       release_revisions(&rev);
        return ret;
 }
 
@@ -1266,9 +1293,7 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps
 
 done:
        discard_index(&istate);
-       UNLEAK(rev);
-       object_array_clear(&rev.pending);
-       clear_pathspec(&rev.prune_data);
+       release_revisions(&rev);
        strbuf_release(&diff_output);
        remove_path(stash_index_path.buf);
        return ret;
@@ -1410,9 +1435,9 @@ done:
 
 static int create_stash(int argc, const char **argv, const char *prefix)
 {
-       int ret = 0;
+       int ret;
        struct strbuf stash_msg_buf = STRBUF_INIT;
-       struct stash_info info;
+       struct stash_info info = STASH_INFO_INIT;
        struct pathspec ps;
 
        /* Starting with argv[1], since argv[0] is "create" */
@@ -1427,6 +1452,7 @@ static int create_stash(int argc, const char **argv, const char *prefix)
        if (!ret)
                printf_ln("%s", oid_to_hex(&info.w_commit));
 
+       free_stash_info(&info);
        strbuf_release(&stash_msg_buf);
        return ret;
 }
@@ -1435,7 +1461,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
                         int keep_index, int patch_mode, int include_untracked, int only_staged)
 {
        int ret = 0;
-       struct stash_info info;
+       struct stash_info info = STASH_INFO_INIT;
        struct strbuf patch = STRBUF_INIT;
        struct strbuf stash_msg_buf = STRBUF_INIT;
        struct strbuf untracked_files = STRBUF_INIT;
@@ -1634,6 +1660,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
        }
 
 done:
+       free_stash_info(&info);
        strbuf_release(&stash_msg_buf);
        return ret;
 }
@@ -1770,6 +1797,9 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, options, git_stash_usage,
                             PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH);
 
+       prepare_repo_settings(the_repository);
+       the_repository->settings.command_requires_full_index = 0;
+
        index_file = get_index_file();
        strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
                    (uintmax_t)pid);
index 1a8e5d062149ec7c7ea2e031c286fbfd15b1d386..c6c2ba1b6dc49c4d7ab398948dfad835b009b0a1 100644 (file)
@@ -72,135 +72,6 @@ static char *get_default_remote(void)
        return repo_get_default_remote(the_repository);
 }
 
-static int starts_with_dot_slash(const char *str)
-{
-       return str[0] == '.' && is_dir_sep(str[1]);
-}
-
-static int starts_with_dot_dot_slash(const char *str)
-{
-       return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]);
-}
-
-/*
- * Returns 1 if it was the last chop before ':'.
- */
-static int chop_last_dir(char **remoteurl, int is_relative)
-{
-       char *rfind = find_last_dir_sep(*remoteurl);
-       if (rfind) {
-               *rfind = '\0';
-               return 0;
-       }
-
-       rfind = strrchr(*remoteurl, ':');
-       if (rfind) {
-               *rfind = '\0';
-               return 1;
-       }
-
-       if (is_relative || !strcmp(".", *remoteurl))
-               die(_("cannot strip one component off url '%s'"),
-                       *remoteurl);
-
-       free(*remoteurl);
-       *remoteurl = xstrdup(".");
-       return 0;
-}
-
-/*
- * The `url` argument is the URL that navigates to the submodule origin
- * repo. When relative, this URL is relative to the superproject origin
- * URL repo. The `up_path` argument, if specified, is the relative
- * path that navigates from the submodule working tree to the superproject
- * working tree. Returns the origin URL of the submodule.
- *
- * Return either an absolute URL or filesystem path (if the superproject
- * origin URL is an absolute URL or filesystem path, respectively) or a
- * relative file system path (if the superproject origin URL is a relative
- * file system path).
- *
- * When the output is a relative file system path, the path is either
- * relative to the submodule working tree, if up_path is specified, or to
- * the superproject working tree otherwise.
- *
- * NEEDSWORK: This works incorrectly on the domain and protocol part.
- * remote_url      url              outcome          expectation
- * http://a.com/b  ../c             http://a.com/c   as is
- * http://a.com/b/ ../c             http://a.com/c   same as previous line, but
- *                                                   ignore trailing slash in url
- * http://a.com/b  ../../c          http://c         error out
- * http://a.com/b  ../../../c       http:/c          error out
- * http://a.com/b  ../../../../c    http:c           error out
- * http://a.com/b  ../../../../../c    .:c           error out
- * NEEDSWORK: Given how chop_last_dir() works, this function is broken
- * when a local part has a colon in its path component, too.
- */
-static char *relative_url(const char *remote_url,
-                               const char *url,
-                               const char *up_path)
-{
-       int is_relative = 0;
-       int colonsep = 0;
-       char *out;
-       char *remoteurl = xstrdup(remote_url);
-       struct strbuf sb = STRBUF_INIT;
-       size_t len = strlen(remoteurl);
-
-       if (is_dir_sep(remoteurl[len-1]))
-               remoteurl[len-1] = '\0';
-
-       if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl))
-               is_relative = 0;
-       else {
-               is_relative = 1;
-               /*
-                * Prepend a './' to ensure all relative
-                * remoteurls start with './' or '../'
-                */
-               if (!starts_with_dot_slash(remoteurl) &&
-                   !starts_with_dot_dot_slash(remoteurl)) {
-                       strbuf_reset(&sb);
-                       strbuf_addf(&sb, "./%s", remoteurl);
-                       free(remoteurl);
-                       remoteurl = strbuf_detach(&sb, NULL);
-               }
-       }
-       /*
-        * When the url starts with '../', remove that and the
-        * last directory in remoteurl.
-        */
-       while (url) {
-               if (starts_with_dot_dot_slash(url)) {
-                       url += 3;
-                       colonsep |= chop_last_dir(&remoteurl, is_relative);
-               } else if (starts_with_dot_slash(url))
-                       url += 2;
-               else
-                       break;
-       }
-       strbuf_reset(&sb);
-       strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url);
-       if (ends_with(url, "/"))
-               strbuf_setlen(&sb, sb.len - 1);
-       free(remoteurl);
-
-       if (starts_with_dot_slash(sb.buf))
-               out = xstrdup(sb.buf + 2);
-       else
-               out = xstrdup(sb.buf);
-
-       if (!up_path || !is_relative) {
-               strbuf_release(&sb);
-               return out;
-       }
-
-       strbuf_reset(&sb);
-       strbuf_addf(&sb, "%s%s", up_path, out);
-       free(out);
-       return strbuf_detach(&sb, NULL);
-}
-
 static char *resolve_relative_url(const char *rel_url, const char *up_path, int quiet)
 {
        char *remoteurl, *resolved_url;
@@ -592,6 +463,18 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
+static int starts_with_dot_slash(const char *const path)
+{
+       return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH |
+                               PATH_MATCH_XPLATFORM);
+}
+
+static int starts_with_dot_dot_slash(const char *const path)
+{
+       return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH |
+                               PATH_MATCH_XPLATFORM);
+}
+
 struct init_cb {
        const char *prefix;
        const char *superprefix;
@@ -766,7 +649,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
 {
        char *displaypath;
        struct strvec diff_files_args = STRVEC_INIT;
-       struct rev_info rev;
+       struct rev_info rev = REV_INFO_INIT;
        int diff_files_result;
        struct strbuf buf = STRBUF_INIT;
        const char *git_dir;
@@ -853,6 +736,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
 cleanup:
        strvec_clear(&diff_files_args);
        free(displaypath);
+       release_revisions(&rev);
 }
 
 static void status_submodule_cb(const struct cache_entry *list_item,
@@ -1231,6 +1115,7 @@ static int compute_summary_module_list(struct object_id *head_oid,
        struct strvec diff_args = STRVEC_INIT;
        struct rev_info rev;
        struct module_cb_list list = MODULE_CB_LIST_INIT;
+       int ret = 0;
 
        strvec_push(&diff_args, get_diff_cmd(diff_cmd));
        if (info->cached)
@@ -1256,11 +1141,13 @@ static int compute_summary_module_list(struct object_id *head_oid,
                        setup_work_tree();
                if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
                        perror("read_cache_preload");
-                       return -1;
+                       ret = -1;
+                       goto cleanup;
                }
        } else if (read_cache() < 0) {
                perror("read_cache");
-               return -1;
+               ret = -1;
+               goto cleanup;
        }
 
        if (diff_cmd == DIFF_INDEX)
@@ -1268,8 +1155,10 @@ static int compute_summary_module_list(struct object_id *head_oid,
        else
                run_diff_files(&rev, 0);
        prepare_submodule_summary(info, &list);
+cleanup:
        strvec_clear(&diff_args);
-       return 0;
+       release_revisions(&rev);
+       return ret;
 }
 
 static int module_summary(int argc, const char **argv, const char *prefix)
@@ -3377,7 +3266,7 @@ static int module_add(int argc, const char **argv, const char *prefix)
                           N_("reference repository")),
                OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
                OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
-                          N_("sets the submodule’s name to the given string "
+                          N_("sets the submodule's name to the given string "
                              "instead of defaulting to its path")),
                OPT_INTEGER(0, "depth", &add_data.depth, N_("depth for shallow clones")),
                OPT_END()
index e5a8f856936a1e494d91aa8ebfa2ff9f64f375d8..75dece0e4f1c90c592f86a4881a01e6553d87613 100644 (file)
@@ -364,7 +364,7 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
                strbuf_addstr(sb, "object of unknown type");
                break;
        case OBJ_COMMIT:
-               if ((buf = read_object_file(oid, &type, &size)) != NULL) {
+               if ((buf = read_object_file(oid, &type, &size))) {
                        subject_len = find_commit_subject(buf, &subject_start);
                        strbuf_insert(sb, sb->len, subject_start, subject_len);
                } else {
@@ -372,7 +372,7 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
                }
                free(buf);
 
-               if ((c = lookup_commit_reference(the_repository, oid)) != NULL)
+               if ((c = lookup_commit_reference(the_repository, oid)))
                        strbuf_addf(sb, ", %s", show_date(c->date, 0, DATE_MODE(SHORT)));
                break;
        case OBJ_TREE:
index dbeb0680a5856300e3a14db9387193a5fe65a0fc..56d05e2725db45f1fc2ffba48fc4930dddd13ed7 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "bulk-checkin.h"
 #include "config.h"
 #include "object-store.h"
 #include "object.h"
@@ -503,10 +504,12 @@ static void unpack_all(void)
        if (!quiet)
                progress = start_progress(_("Unpacking objects"), nr_objects);
        CALLOC_ARRAY(obj_list, nr_objects);
+       begin_odb_transaction();
        for (i = 0; i < nr_objects; i++) {
                unpack_one(i);
                display_progress(progress, i + 1);
        }
+       end_odb_transaction();
        stop_progress(&progress);
 
        if (delta_list)
index 876112abb21a4dbc6f222dc8da8838be4819de3d..43c713c0873a7dc04dd62ba518b1f2744a5b6d35 100644 (file)
@@ -5,6 +5,7 @@
  */
 #define USE_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
+#include "bulk-checkin.h"
 #include "config.h"
 #include "lockfile.h"
 #include "quote.h"
@@ -57,6 +58,14 @@ static void report(const char *fmt, ...)
        if (!verbose)
                return;
 
+       /*
+        * It is possible, though unlikely, that a caller could use the verbose
+        * output to synchronize with addition of objects to the object
+        * database. The current implementation of ODB transactions leaves
+        * objects invisible while a transaction is active, so flush the
+        * transaction here before reporting a change made by update-index.
+        */
+       flush_odb_transaction();
        va_start(vp, fmt);
        vprintf(fmt, vp);
        putchar('\n');
@@ -1116,6 +1125,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
         */
        parse_options_start(&ctx, argc, argv, prefix,
                            options, PARSE_OPT_STOP_AT_NON_OPTION);
+
+       /*
+        * Allow the object layer to optimize adding multiple objects in
+        * a batch.
+        */
+       begin_odb_transaction();
        while (ctx.argc) {
                if (parseopt_state != PARSE_OPT_DONE)
                        parseopt_state = parse_options_step(&ctx, options,
@@ -1190,6 +1205,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                strbuf_release(&buf);
        }
 
+       /*
+        * By now we have added all of the new objects
+        */
+       end_odb_transaction();
+
        if (split_index > 0) {
                if (git_config_get_split_index() == 0)
                        warning(_("core.splitIndex is set to false; "
index 6d6c37171c9578b45cc41587f9cdfecb75ebc826..98ec8938424406ef5973df797b8eca37fda71041 100644 (file)
@@ -3,16 +3,21 @@
  */
 #include "cache.h"
 #include "bulk-checkin.h"
+#include "lockfile.h"
 #include "repository.h"
 #include "csum-file.h"
 #include "pack.h"
 #include "strbuf.h"
+#include "string-list.h"
+#include "tmp-objdir.h"
 #include "packfile.h"
 #include "object-store.h"
 
-static struct bulk_checkin_state {
-       unsigned plugged:1;
+static int odb_transaction_nesting;
 
+static struct tmp_objdir *bulk_fsync_objdir;
+
+static struct bulk_checkin_packfile {
        char *pack_tmp_name;
        struct hashfile *f;
        off_t offset;
@@ -21,7 +26,7 @@ static struct bulk_checkin_state {
        struct pack_idx_entry **written;
        uint32_t alloc_written;
        uint32_t nr_written;
-} state;
+} bulk_checkin_packfile;
 
 static void finish_tmp_packfile(struct strbuf *basename,
                                const char *pack_tmp_name,
@@ -33,13 +38,13 @@ static void finish_tmp_packfile(struct strbuf *basename,
        char *idx_tmp_name = NULL;
 
        stage_tmp_packfiles(basename, pack_tmp_name, written_list, nr_written,
-                           pack_idx_opts, hash, &idx_tmp_name);
+                           NULL, pack_idx_opts, hash, &idx_tmp_name);
        rename_tmp_packfile_idx(basename, &idx_tmp_name);
 
        free(idx_tmp_name);
 }
 
-static void finish_bulk_checkin(struct bulk_checkin_state *state)
+static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)
 {
        unsigned char hash[GIT_MAX_RAWSZ];
        struct strbuf packname = STRBUF_INIT;
@@ -80,7 +85,41 @@ clear_exit:
        reprepare_packed_git(the_repository);
 }
 
-static int already_written(struct bulk_checkin_state *state, struct object_id *oid)
+/*
+ * Cleanup after batch-mode fsync_object_files.
+ */
+static void flush_batch_fsync(void)
+{
+       struct strbuf temp_path = STRBUF_INIT;
+       struct tempfile *temp;
+
+       if (!bulk_fsync_objdir)
+               return;
+
+       /*
+        * Issue a full hardware flush against a temporary file to ensure
+        * that all objects are durable before any renames occur. The code in
+        * fsync_loose_object_bulk_checkin has already issued a writeout
+        * request, but it has not flushed any writeback cache in the storage
+        * hardware or any filesystem logs. This fsync call acts as a barrier
+        * to ensure that the data in each new object file is durable before
+        * the final name is visible.
+        */
+       strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", get_object_directory());
+       temp = xmks_tempfile(temp_path.buf);
+       fsync_or_die(get_tempfile_fd(temp), get_tempfile_path(temp));
+       delete_tempfile(&temp);
+       strbuf_release(&temp_path);
+
+       /*
+        * Make the object files visible in the primary ODB after their data is
+        * fully durable.
+        */
+       tmp_objdir_migrate(bulk_fsync_objdir);
+       bulk_fsync_objdir = NULL;
+}
+
+static int already_written(struct bulk_checkin_packfile *state, struct object_id *oid)
 {
        int i;
 
@@ -112,7 +151,7 @@ static int already_written(struct bulk_checkin_state *state, struct object_id *o
  * status before calling us just in case we ask it to call us again
  * with a new pack.
  */
-static int stream_to_pack(struct bulk_checkin_state *state,
+static int stream_to_pack(struct bulk_checkin_packfile *state,
                          git_hash_ctx *ctx, off_t *already_hashed_to,
                          int fd, size_t size, enum object_type type,
                          const char *path, unsigned flags)
@@ -189,7 +228,7 @@ static int stream_to_pack(struct bulk_checkin_state *state,
 }
 
 /* Lazily create backing packfile for the state */
-static void prepare_to_stream(struct bulk_checkin_state *state,
+static void prepare_to_stream(struct bulk_checkin_packfile *state,
                              unsigned flags)
 {
        if (!(flags & HASH_WRITE_OBJECT) || state->f)
@@ -204,7 +243,7 @@ static void prepare_to_stream(struct bulk_checkin_state *state,
                die_errno("unable to write pack header");
 }
 
-static int deflate_to_pack(struct bulk_checkin_state *state,
+static int deflate_to_pack(struct bulk_checkin_packfile *state,
                           struct object_id *result_oid,
                           int fd, size_t size,
                           enum object_type type, const char *path,
@@ -251,7 +290,7 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
                        BUG("should not happen");
                hashfile_truncate(state->f, &checkpoint);
                state->offset = checkpoint.offset;
-               finish_bulk_checkin(state);
+               flush_bulk_checkin_packfile(state);
                if (lseek(fd, seekback, SEEK_SET) == (off_t) -1)
                        return error("cannot seek back");
        }
@@ -274,25 +313,67 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
        return 0;
 }
 
+void prepare_loose_object_bulk_checkin(void)
+{
+       /*
+        * We lazily create the temporary object directory
+        * the first time an object might be added, since
+        * callers may not know whether any objects will be
+        * added at the time they call begin_odb_transaction.
+        */
+       if (!odb_transaction_nesting || bulk_fsync_objdir)
+               return;
+
+       bulk_fsync_objdir = tmp_objdir_create("bulk-fsync");
+       if (bulk_fsync_objdir)
+               tmp_objdir_replace_primary_odb(bulk_fsync_objdir, 0);
+}
+
+void fsync_loose_object_bulk_checkin(int fd, const char *filename)
+{
+       /*
+        * If we have an active ODB transaction, we issue a call that
+        * cleans the filesystem page cache but avoids a hardware flush
+        * command. Later on we will issue a single hardware flush
+        * before renaming the objects to their final names as part of
+        * flush_batch_fsync.
+        */
+       if (!bulk_fsync_objdir ||
+           git_fsync(fd, FSYNC_WRITEOUT_ONLY) < 0) {
+               fsync_or_die(fd, filename);
+       }
+}
+
 int index_bulk_checkin(struct object_id *oid,
                       int fd, size_t size, enum object_type type,
                       const char *path, unsigned flags)
 {
-       int status = deflate_to_pack(&state, oid, fd, size, type,
+       int status = deflate_to_pack(&bulk_checkin_packfile, oid, fd, size, type,
                                     path, flags);
-       if (!state.plugged)
-               finish_bulk_checkin(&state);
+       if (!odb_transaction_nesting)
+               flush_bulk_checkin_packfile(&bulk_checkin_packfile);
        return status;
 }
 
-void plug_bulk_checkin(void)
+void begin_odb_transaction(void)
 {
-       state.plugged = 1;
+       odb_transaction_nesting += 1;
 }
 
-void unplug_bulk_checkin(void)
+void flush_odb_transaction(void)
 {
-       state.plugged = 0;
-       if (state.f)
-               finish_bulk_checkin(&state);
+       flush_batch_fsync();
+       flush_bulk_checkin_packfile(&bulk_checkin_packfile);
+}
+
+void end_odb_transaction(void)
+{
+       odb_transaction_nesting -= 1;
+       if (odb_transaction_nesting < 0)
+               BUG("Unbalanced ODB transaction nesting");
+
+       if (odb_transaction_nesting)
+               return;
+
+       flush_odb_transaction();
 }
index b26f3dc3b74cb9ccb4ea630fafe8cd0cdcf5a012..8281b9cb159691530eb2f74b46daf535261f6c93 100644 (file)
@@ -6,11 +6,34 @@
 
 #include "cache.h"
 
+void prepare_loose_object_bulk_checkin(void);
+void fsync_loose_object_bulk_checkin(int fd, const char *filename);
+
 int index_bulk_checkin(struct object_id *oid,
                       int fd, size_t size, enum object_type type,
                       const char *path, unsigned flags);
 
-void plug_bulk_checkin(void);
-void unplug_bulk_checkin(void);
+/*
+ * Tell the object database to optimize for adding
+ * multiple objects. end_odb_transaction must be called
+ * to make new objects visible. Transactions can be nested,
+ * and objects are only visible after the outermost transaction
+ * is complete or the transaction is flushed.
+ */
+void begin_odb_transaction(void);
+
+/*
+ * Make any objects that are currently part of a pending object
+ * database transaction visible. It is valid to call this function
+ * even if no transaction is active.
+ */
+void flush_odb_transaction(void);
+
+/*
+ * Tell the object database to make any objects from the
+ * current transaction visible if this is the final nested
+ * transaction.
+ */
+void end_odb_transaction(void);
 
 #endif
index d50cfb5aa7e9c28afc121f9bf27499518a3fee37..0208e6d90d30f02828a9b6d668eb6a4feac9a971 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -66,8 +66,8 @@ static int parse_bundle_signature(struct bundle_header *header, const char *line
        return -1;
 }
 
-static int parse_bundle_header(int fd, struct bundle_header *header,
-                              const char *report_path)
+int read_bundle_header_fd(int fd, struct bundle_header *header,
+                         const char *report_path)
 {
        struct strbuf buf = STRBUF_INIT;
        int status = 0;
@@ -143,7 +143,7 @@ int read_bundle_header(const char *path, struct bundle_header *header)
 
        if (fd < 0)
                return error(_("could not open '%s'"), path);
-       return parse_bundle_header(fd, header, path);
+       return read_bundle_header_fd(fd, header, path);
 }
 
 int is_bundle(const char *path, int quiet)
@@ -153,7 +153,7 @@ int is_bundle(const char *path, int quiet)
 
        if (fd < 0)
                return 0;
-       fd = parse_bundle_header(fd, &header, quiet ? NULL : path);
+       fd = read_bundle_header_fd(fd, &header, quiet ? NULL : path);
        if (fd >= 0)
                close(fd);
        bundle_header_release(&header);
@@ -196,14 +196,16 @@ int verify_bundle(struct repository *r,
         * to be verbose about the errors
         */
        struct string_list *p = &header->prerequisites;
-       struct rev_info revs;
+       struct rev_info revs = REV_INFO_INIT;
        const char *argv[] = {NULL, "--all", NULL};
        struct commit *commit;
        int i, ret = 0, req_nr;
        const char *message = _("Repository lacks these prerequisite commits:");
 
-       if (!r || !r->objects || !r->objects->odb)
-               return error(_("need a repository to verify a bundle"));
+       if (!r || !r->objects || !r->objects->odb) {
+               ret = error(_("need a repository to verify a bundle"));
+               goto cleanup;
+       }
 
        repo_init_revisions(r, &revs, NULL);
        for (i = 0; i < p->nr; i++) {
@@ -221,7 +223,7 @@ int verify_bundle(struct repository *r,
                error("%s %s", oid_to_hex(oid), name);
        }
        if (revs.pending.nr != p->nr)
-               return ret;
+               goto cleanup;
        req_nr = revs.pending.nr;
        setup_revisions(2, argv, &revs, NULL);
 
@@ -284,6 +286,8 @@ int verify_bundle(struct repository *r,
                        printf_ln("The bundle uses this filter: %s",
                                  list_objects_filter_spec(&header->filter));
        }
+cleanup:
+       release_revisions(&revs);
        return ret;
 }
 
index 7fef2108f436861726ca4efb6937f9d434e61d7e..0c052f54964f110688c6b2edf02f4c7dfca8a623 100644 (file)
--- a/bundle.h
+++ b/bundle.h
@@ -24,6 +24,8 @@ void bundle_header_release(struct bundle_header *header);
 
 int is_bundle(const char *path, int quiet);
 int read_bundle_header(const char *path, struct bundle_header *header);
+int read_bundle_header_fd(int fd, struct bundle_header *header,
+                         const char *report_path);
 int create_bundle(struct repository *r, const char *path,
                  int argc, const char **argv, struct strvec *pack_options,
                  int version);
index 6752f69d515e12f7bd8c98ac2e27548b68da46d5..a92c23eec35101a6c96812baed17cd11861c56f9 100644 (file)
@@ -3,6 +3,7 @@
 #include "tree.h"
 #include "tree-walk.h"
 #include "cache-tree.h"
+#include "bulk-checkin.h"
 #include "object-store.h"
 #include "replace-object.h"
 #include "promisor-remote.h"
@@ -100,6 +101,33 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *it, const char *path)
        return find_subtree(it, path, pathlen, 1);
 }
 
+struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path)
+{
+       const char *slash;
+       int namelen;
+       struct cache_tree_sub it_sub = {
+               .cache_tree = it,
+       };
+       struct cache_tree_sub *down = &it_sub;
+
+       while (down) {
+               slash = strchrnul(path, '/');
+               namelen = slash - path;
+               down->cache_tree->entry_count = -1;
+               if (!*slash) {
+                       int pos;
+                       pos = cache_tree_subtree_pos(down->cache_tree, path, namelen);
+                       if (0 <= pos)
+                               return down->cache_tree->down[pos]->cache_tree;
+                       return NULL;
+               }
+               down = find_subtree(it, path, namelen, 0);
+               path = slash + 1;
+       }
+
+       return NULL;
+}
+
 static int do_invalidate_path(struct cache_tree *it, const char *path)
 {
        /* a/b/c
@@ -474,8 +502,10 @@ int cache_tree_update(struct index_state *istate, int flags)
 
        trace_performance_enter();
        trace2_region_enter("cache_tree", "update", the_repository);
+       begin_odb_transaction();
        i = update_one(istate->cache_tree, istate->cache, istate->cache_nr,
                       "", 0, &skip, flags);
+       end_odb_transaction();
        trace2_region_leave("cache_tree", "update", the_repository);
        trace_performance_leave("cache_tree_update");
        if (i < 0)
index 8efeccebfc9f0bf8c9cfda1aa4ac531108b52650..f75f8e74dcdb86131d90a83b7d8ebd9861839fd2 100644 (file)
@@ -29,6 +29,8 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
 
 int cache_tree_subtree_pos(struct cache_tree *it, const char *path, int pathlen);
 
+struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path);
+
 void cache_tree_write(struct strbuf *, struct cache_tree *root);
 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
 
diff --git a/cache.h b/cache.h
index 6226f6a8a53f65083e67ed747d56f4ca84c43302..ac5ab4ef9d341088d2b7a0aa5052e982197cf574 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -310,6 +310,29 @@ struct untracked_cache;
 struct progress;
 struct pattern_list;
 
+enum sparse_index_mode {
+       /*
+        * There are no sparse directories in the index at all.
+        *
+        * Repositories that don't use cone-mode sparse-checkout will
+        * always have their indexes in this mode.
+        */
+       INDEX_EXPANDED = 0,
+
+       /*
+        * The index has already been collapsed to sparse directories
+        * whereever possible.
+        */
+       INDEX_COLLAPSED,
+
+       /*
+        * The sparse directories that exist are outside the
+        * sparse-checkout boundary, but it is possible that some file
+        * entries could collapse to sparse directory entries.
+        */
+       INDEX_PARTIALLY_SPARSE,
+};
+
 struct index_state {
        struct cache_entry **cache;
        unsigned int version;
@@ -323,14 +346,8 @@ struct index_state {
                 drop_cache_tree : 1,
                 updated_workdir : 1,
                 updated_skipworktree : 1,
-                fsmonitor_has_run_once : 1,
-
-                /*
-                 * sparse_index == 1 when sparse-directory
-                 * entries exist. Requires sparse-checkout
-                 * in cone mode.
-                 */
-                sparse_index : 1;
+                fsmonitor_has_run_once : 1;
+       enum sparse_index_mode sparse_index;
        struct hashmap name_hash;
        struct hashmap dir_hash;
        struct object_id oid;
@@ -566,7 +583,7 @@ extern char *git_work_tree_cfg;
 int is_inside_work_tree(void);
 const char *get_git_dir(void);
 const char *get_git_common_dir(void);
-char *get_object_directory(void);
+const char *get_object_directory(void);
 char *get_index_file(void);
 char *get_graft_file(struct repository *r);
 void set_git_dir(const char *path, int make_realpath);
@@ -1031,6 +1048,10 @@ enum fsync_component {
                              FSYNC_COMPONENT_INDEX | \
                              FSYNC_COMPONENT_REFERENCE)
 
+#ifndef FSYNC_COMPONENTS_PLATFORM_DEFAULT
+#define FSYNC_COMPONENTS_PLATFORM_DEFAULT FSYNC_COMPONENTS_DEFAULT
+#endif
+
 /*
  * A bitmask indicating which components of the repo should be fsynced.
  */
@@ -1040,7 +1061,8 @@ extern int use_fsync;
 
 enum fsync_method {
        FSYNC_METHOD_FSYNC,
-       FSYNC_METHOD_WRITEOUT_ONLY
+       FSYNC_METHOD_WRITEOUT_ONLY,
+       FSYNC_METHOD_BATCH,
 };
 
 extern enum fsync_method fsync_method;
@@ -1766,6 +1788,11 @@ void fsync_or_die(int fd, const char *);
 int fsync_component(enum fsync_component component, int fd);
 void fsync_component_or_die(enum fsync_component component, int fd, const char *msg);
 
+static inline int batch_fsync_enabled(enum fsync_component component)
+{
+       return (fsync_components & component) && (fsync_method == FSYNC_METHOD_BATCH);
+}
+
 ssize_t read_in_full(int fd, void *buf, size_t count);
 ssize_t write_in_full(int fd, const void *buf, size_t count);
 ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset);
index 1c3dca62e2057bbdb8339e13e10f962befd26857..0275b74a895a17bb62b7fe12299e6f12aa503d92 100644 (file)
@@ -181,3 +181,15 @@ int read_chunk(struct chunkfile *cf,
 
        return CHUNK_NOT_FOUND;
 }
+
+uint8_t oid_version(const struct git_hash_algo *algop)
+{
+       switch (hash_algo_by_ptr(algop)) {
+       case GIT_HASH_SHA1:
+               return 1;
+       case GIT_HASH_SHA256:
+               return 2;
+       default:
+               die(_("invalid hash version"));
+       }
+}
index 9ccbe0037792c36620644996de66f5f779f93e98..7885aa084878dde2f2786545b7edc05e7d3fee24 100644 (file)
@@ -2,6 +2,7 @@
 #define CHUNK_FORMAT_H
 
 #include "git-compat-util.h"
+#include "hash.h"
 
 struct hashfile;
 struct chunkfile;
@@ -65,4 +66,6 @@ int read_chunk(struct chunkfile *cf,
               chunk_read_fn fn,
               void *data);
 
+uint8_t oid_version(const struct git_hash_algo *algop);
+
 #endif
index dbcebad2fb293303f9271850094a29c3a249bda6..107757a1fea4c2839de8ebe871b648e91c5b97a6 100755 (executable)
@@ -5,7 +5,7 @@
 
 . ${0%/*}/lib.sh
 
-P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION
+P4WHENCE=https://cdist2.perforce.com/perforce/r$LINUX_P4_VERSION
 LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
 UBUNTU_COMMON_PKGS="make libssl-dev libcurl4-openssl-dev libexpat-dev
  tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl
@@ -37,13 +37,15 @@ macos-latest)
        test -z "$BREW_INSTALL_PACKAGES" ||
        brew install $BREW_INSTALL_PACKAGES
        brew link --force gettext
-       brew install --cask --no-quarantine perforce || {
-               # Update the definitions and try again
-               cask_repo="$(brew --repository)"/Library/Taps/homebrew/homebrew-cask &&
-               git -C "$cask_repo" pull --no-stat --ff-only &&
-               brew install --cask --no-quarantine perforce
-       } ||
-       brew install homebrew/cask/perforce
+       mkdir -p $HOME/bin
+       (
+               cd $HOME/bin
+               wget -q "https://cdist2.perforce.com/perforce/r21.2/bin.macosx1015x86_64/helix-core-server.tgz" &&
+               tar -xf helix-core-server.tgz &&
+               sudo xattr -d com.apple.quarantine p4 p4d 2>/dev/null || true
+       )
+       PATH="$PATH:${HOME}/bin"
+       export PATH
 
        if test -n "$CC_PACKAGE"
        then
@@ -78,15 +80,19 @@ linux-gcc-default)
        ;;
 esac
 
-if type p4d >/dev/null && type p4 >/dev/null
+if type p4d >/dev/null 2>&1 && type p4 >/dev/null 2>&1
 then
        echo "$(tput setaf 6)Perforce Server Version$(tput sgr0)"
        p4d -V | grep Rev.
        echo "$(tput setaf 6)Perforce Client Version$(tput sgr0)"
        p4 -V | grep Rev.
+else
+       echo >&2 "WARNING: perforce wasn't installed, see above for clues why"
 fi
-if type git-lfs >/dev/null
+if type git-lfs >/dev/null 2>&1
 then
        echo "$(tput setaf 6)Git-LFS Version$(tput sgr0)"
        git-lfs version
+else
+       echo >&2 "WARNING: git-lfs wasn't installed, see above for clues why"
 fi
index 86e37da9bc50abeda8082ae374b960da845073fb..2f6d9d26e4033a927d9dcbaadbcc29c533cae5b4 100755 (executable)
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -1,5 +1,50 @@
 # Library of functions shared by all CI scripts
 
+if test true != "$GITHUB_ACTIONS"
+then
+       begin_group () { :; }
+       end_group () { :; }
+
+       group () {
+               shift
+               "$@"
+       }
+       set -x
+else
+       begin_group () {
+               need_to_end_group=t
+               echo "::group::$1" >&2
+               set -x
+       }
+
+       end_group () {
+               test -n "$need_to_end_group" || return 0
+               set +x
+               need_to_end_group=
+               echo '::endgroup::' >&2
+       }
+       trap end_group EXIT
+
+       group () {
+               set +x
+               begin_group "$1"
+               shift
+               "$@"
+               res=$?
+               end_group
+               return $res
+       }
+
+       begin_group "CI setup"
+fi
+
+# Set 'exit on error' for all CI scripts to let the caller know that
+# something went wrong.
+#
+# We already enabled tracing executed commands earlier. This helps by showing
+# how # environment variables are set and and dependencies are installed.
+set -e
+
 skip_branch_tip_with_tag () {
        # Sometimes, a branch is pushed at the same time the tag that points
        # at the same commit as the tip of the branch is pushed, and building
@@ -69,8 +114,7 @@ skip_good_tree () {
        exit 0
 }
 
-check_unignored_build_artifacts ()
-{
+check_unignored_build_artifacts () {
        ! git ls-files --other --exclude-standard --error-unmatch \
                -- ':/*' 2>/dev/null ||
        {
@@ -79,18 +123,16 @@ check_unignored_build_artifacts ()
        }
 }
 
+handle_failed_tests () {
+       return 1
+}
+
 # GitHub Action doesn't set TERM, which is required by tput
 export TERM=${TERM:-dumb}
 
 # Clear MAKEFLAGS that may come from the outside world.
 export MAKEFLAGS=
 
-# Set 'exit on error' for all CI scripts to let the caller know that
-# something went wrong.
-# Set tracing executed commands, primarily setting environment variables
-# and installing dependencies.
-set -ex
-
 if test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI"
 then
        CI_TYPE=azure-pipelines
@@ -124,11 +166,31 @@ then
        CI_JOB_ID="$GITHUB_RUN_ID"
        CC="${CC_PACKAGE:-${CC:-gcc}}"
        DONT_SKIP_TAGS=t
+       handle_failed_tests () {
+               mkdir -p t/failed-test-artifacts
+               echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV
+
+               for test_exit in t/test-results/*.exit
+               do
+                       test 0 != "$(cat "$test_exit")" || continue
+
+                       test_name="${test_exit%.exit}"
+                       test_name="${test_name##*/}"
+                       printf "\\e[33m\\e[1m=== Failed test: ${test_name} ===\\e[m\\n"
+                       echo "The full logs are in the artifacts attached to this run."
+                       cat "t/test-results/$test_name.markup"
+
+                       trash_dir="t/trash directory.$test_name"
+                       cp "t/test-results/$test_name.out" t/failed-test-artifacts/
+                       tar czf t/failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
+               done
+               return 1
+       }
 
        cache_dir="$HOME/none"
 
        export GIT_PROVE_OPTS="--timer --jobs 10"
-       export GIT_TEST_OPTS="--verbose-log -x"
+       export GIT_TEST_OPTS="--verbose-log -x --github-workflow-markup"
        MAKEFLAGS="$MAKEFLAGS --jobs=10"
        test windows != "$CI_OS_NAME" ||
        GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS"
@@ -211,3 +273,6 @@ linux-leaks)
 esac
 
 MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}"
+
+end_group
+set -x
index 280dda7d285674e121ac98ed444e72380168dd13..8ebff4259676e303b953385ba14cf17b78c1a4de 100755 (executable)
@@ -10,7 +10,7 @@ windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";;
 *) ln -s "$cache_dir/.prove" t/.prove;;
 esac
 
-export MAKE_TARGETS="all test"
+run_tests=t
 
 case "$jobname" in
 linux-gcc)
@@ -26,7 +26,7 @@ linux-TEST-vars)
        export GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=1
        export GIT_TEST_MULTI_PACK_INDEX=1
        export GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=1
-       export GIT_TEST_ADD_I_USE_BUILTIN=1
+       export GIT_TEST_ADD_I_USE_BUILTIN=0
        export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
        export GIT_TEST_WRITE_REV_INDEX=1
        export GIT_TEST_CHECKOUT_WORKERS=2
@@ -41,14 +41,16 @@ pedantic)
        # Don't run the tests; we only care about whether Git can be
        # built.
        export DEVOPTS=pedantic
-       export MAKE_TARGETS=all
+       run_tests=
        ;;
 esac
 
-# Any new "test" targets should not go after this "make", but should
-# adjust $MAKE_TARGETS. Otherwise compilation-only targets above will
-# start running tests.
-make $MAKE_TARGETS
+group Build make
+if test -n "$run_tests"
+then
+       group "Run tests" make test ||
+       handle_failed_tests
+fi
 check_unignored_build_artifacts
 
 save_good_tree
index 65bcebda41a0dfb47676a1d0528fdaa0addf2271..0d51e5ce0e7cb42e0101df607c925ccd066d4433 100755 (executable)
@@ -29,4 +29,6 @@ fi
 make hdr-check ||
 exit 1
 
+make check-pot
+
 save_good_tree
index f8c2c3106a2ef43af525ec0a770d6697160ec91f..a3c67956a8df8f803bc81eee1b86a8f5559db57b 100755 (executable)
@@ -10,8 +10,9 @@ windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";;
 *) ln -s "$cache_dir/.prove" t/.prove;;
 esac
 
-make --quiet -C t T="$(cd t &&
+group "Run tests" make --quiet -C t T="$(cd t &&
        ./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh |
-       tr '\n' ' ')"
+       tr '\n' ' ')" ||
+handle_failed_tests
 
 check_unignored_build_artifacts
index d93782daeb37fee21f5898600ff15628b32d4779..b724f02123d838547fa87fb785d94a2a3141c3e8 100644 (file)
@@ -195,10 +195,10 @@ static struct lline *coalesce_lines(struct lline *base, int *lenbase,
        struct lline *baseend, *newend = NULL;
        int i, j, origbaselen = *lenbase;
 
-       if (newline == NULL)
+       if (!newline)
                return base;
 
-       if (base == NULL) {
+       if (!base) {
                *lenbase = lennew;
                return newline;
        }
index 441b36016ba796c13665603b4c523c9baa52c12d..92d450333664d4298eb9cbcda332fe857fd22458 100644 (file)
@@ -193,18 +193,6 @@ char *get_commit_graph_chain_filename(struct object_directory *odb)
        return xstrfmt("%s/info/commit-graphs/commit-graph-chain", odb->path);
 }
 
-static uint8_t oid_version(void)
-{
-       switch (hash_algo_by_ptr(the_hash_algo)) {
-       case GIT_HASH_SHA1:
-               return 1;
-       case GIT_HASH_SHA256:
-               return 2;
-       default:
-               die(_("invalid hash version"));
-       }
-}
-
 static struct commit_graph *alloc_commit_graph(void)
 {
        struct commit_graph *g = xcalloc(1, sizeof(*g));
@@ -365,9 +353,9 @@ struct commit_graph *parse_commit_graph(struct repository *r,
        }
 
        hash_version = *(unsigned char*)(data + 5);
-       if (hash_version != oid_version()) {
+       if (hash_version != oid_version(the_hash_algo)) {
                error(_("commit-graph hash version %X does not match version %X"),
-                     hash_version, oid_version());
+                     hash_version, oid_version(the_hash_algo));
                return NULL;
        }
 
@@ -523,10 +511,13 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r,
        stat_res = stat(chain_name, &st);
        free(chain_name);
 
-       if (!fp ||
-           stat_res ||
-           st.st_size <= the_hash_algo->hexsz)
+       if (!fp)
                return NULL;
+       if (stat_res ||
+           st.st_size <= the_hash_algo->hexsz) {
+               fclose(fp);
+               return NULL;
+       }
 
        count = st.st_size / (the_hash_algo->hexsz + 1);
        CALLOC_ARRAY(oids, count);
@@ -1921,7 +1912,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
        hashwrite_be32(f, GRAPH_SIGNATURE);
 
        hashwrite_u8(f, GRAPH_VERSION);
-       hashwrite_u8(f, oid_version());
+       hashwrite_u8(f, oid_version(the_hash_algo));
        hashwrite_u8(f, get_num_chunks(cf));
        hashwrite_u8(f, ctx->num_commit_graphs_after - 1);
 
@@ -2206,7 +2197,8 @@ static void mark_commit_graphs(struct write_commit_graph_context *ctx)
                struct stat st;
                struct utimbuf updated_time;
 
-               stat(ctx->commit_graph_filenames_before[i], &st);
+               if (stat(ctx->commit_graph_filenames_before[i], &st) < 0)
+                       continue;
 
                updated_time.actime = st.st_atime;
                updated_time.modtime = now;
@@ -2247,7 +2239,8 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
                strbuf_setlen(&path, dirnamelen);
                strbuf_addstr(&path, de->d_name);
 
-               stat(path.buf, &st);
+               if (stat(path.buf, &st) < 0)
+                       continue;
 
                if (st.st_mtime > expire_time)
                        continue;
@@ -2567,7 +2560,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
                odb_parents = odb_commit->parents;
 
                while (graph_parents) {
-                       if (odb_parents == NULL) {
+                       if (!odb_parents) {
                                graph_report(_("commit-graph parent list for commit %s is too long"),
                                             oid_to_hex(&cur_oid));
                                break;
@@ -2590,7 +2583,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
                        odb_parents = odb_parents->next;
                }
 
-               if (odb_parents != NULL)
+               if (odb_parents)
                        graph_report(_("commit-graph parent list for commit %s terminates early"),
                                     oid_to_hex(&cur_oid));
 
index 59b6c3e45525c5f5c1d19577612364992e245a6d..9628716bf2f1e1c8d2a9ab324cd5240cc00c1733 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -407,17 +407,14 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
 
        if (item->object.parsed)
                return 0;
-
-       if (item->parents) {
-               /*
-                * Presumably this is leftover from an earlier failed parse;
-                * clear it out in preparation for us re-parsing (we'll hit the
-                * same error, but that's good, since it lets our caller know
-                * the result cannot be trusted.
-                */
-               free_commit_list(item->parents);
-               item->parents = NULL;
-       }
+       /*
+        * Presumably this is leftover from an earlier failed parse;
+        * clear it out in preparation for us re-parsing (we'll hit the
+        * same error, but that's good, since it lets our caller know
+        * the result cannot be trusted.
+        */
+       free_commit_list(item->parents);
+       item->parents = NULL;
 
        tail += size;
        if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) ||
index 0741fe834c3168a0c88e4a7c67275554fe5cc5c0..dc8a33130a5ea0584686e903d8628f2dc3145e91 100644 (file)
@@ -342,7 +342,7 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state)
                                           data->cfar_paths_to_watch,
                                           kFSEventStreamEventIdSinceNow,
                                           0.001, flags);
-       if (data->stream == NULL)
+       if (!data->stream)
                goto failed;
 
        /*
index 6fe80fdf014021ee1620e941a5214aba92ba4ca5..2607de93af594034413e4512c4d7dd33fb133023 100644 (file)
@@ -1060,7 +1060,7 @@ char *mingw_mktemp(char *template)
 int mkstemp(char *template)
 {
        char *filename = mktemp(template);
-       if (filename == NULL)
+       if (!filename)
                return -1;
        return open(filename, O_RDWR | O_CREAT, 0600);
 }
@@ -2332,7 +2332,7 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out)
        static const struct timeval zero;
        static int atexit_done;
 
-       if (out != NULL)
+       if (out)
                return errno = EINVAL,
                        error("setitimer param 3 != NULL not implemented");
        if (!is_timeval_eq(&in->it_interval, &zero) &&
@@ -2361,7 +2361,7 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out)
        if (sig != SIGALRM)
                return errno = EINVAL,
                        error("sigaction only implemented for SIGALRM");
-       if (out != NULL)
+       if (out)
                return errno = EINVAL,
                        error("sigaction: param 3 != NULL not implemented");
 
@@ -2830,7 +2830,7 @@ not_a_reserved_name:
                        }
 
                        c = path[i];
-                       if (c && c != '.' && c != ':' && c != '/' && c != '\\')
+                       if (c && c != '.' && c != ':' && !is_xplatform_dir_sep(c))
                                goto not_a_reserved_name;
 
                        /* contains reserved name */
index 494cc8de92221bab3c71d49baaf17f9cd0faeb04..a74da68f31321c18b25ed86299f7d84fa38a69aa 100644 (file)
@@ -332,6 +332,9 @@ int mingw_getpagesize(void);
 int win32_fsync_no_flush(int fd);
 #define fsync_no_flush win32_fsync_no_flush
 
+#define FSYNC_COMPONENTS_PLATFORM_DEFAULT (FSYNC_COMPONENTS_DEFAULT | FSYNC_COMPONENT_LOOSE_OBJECT)
+#define FSYNC_METHOD_DEFAULT (FSYNC_METHOD_BATCH)
+
 struct rlimit {
        unsigned int rlim_cur;
 };
index 9e253fb72f2df92a09b562dde59f347c4c207a57..02aea3b32ef1e3c8944985edca52f3b0413e1739 100644 (file)
@@ -9,7 +9,7 @@ int compat_mkdir_wo_trailing_slash(const char *dir, mode_t mode)
        size_t len = strlen(dir);
 
        if (len && dir[len-1] == '/') {
-               if ((tmp_dir = strdup(dir)) == NULL)
+               if (!(tmp_dir = strdup(dir)))
                        return -1;
                tmp_dir[len-1] = '\0';
        }
index 8d6c02d4bccc0160e69d3c0892946bfc79f10d00..2fe1c7732eea9491e4bb26902f60430b6c0bb828 100644 (file)
@@ -13,7 +13,7 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
        }
 
        start = malloc(length);
-       if (start == NULL) {
+       if (!start) {
                errno = ENOMEM;
                return MAP_FAILED;
        }
index edb438a7776aed1c1559352ce3b32e051cac806a..2c0ace7075a34e43b929e91a5c1ffcffe4d135b5 100644 (file)
@@ -323,7 +323,6 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in
 }
 static void DestroyCaches(nedpool *p) THROWSPEC
 {
-       if(p->caches)
        {
                threadcache *tc;
                int n;
index bba2b644080f064cb5160ce41da16841afadeeed..65fa3b9263a47c2dfaad4a110c253cbaae88fc7b 100644 (file)
@@ -6,11 +6,7 @@ int win32_has_dos_drive_prefix(const char *path);
 
 int win32_skip_dos_drive_prefix(char **path);
 #define skip_dos_drive_prefix win32_skip_dos_drive_prefix
-static inline int win32_is_dir_sep(int c)
-{
-       return c == '/' || c == '\\';
-}
-#define is_dir_sep win32_is_dir_sep
+#define is_dir_sep is_xplatform_dir_sep
 static inline char *win32_find_last_dir_sep(const char *path)
 {
        char *ret = NULL;
index 161978d720aed9db5a00c77d1c6bd9a073544f15..1f8d8934cc90dc2a5988265c555271c8afd18084 100644 (file)
@@ -43,6 +43,7 @@ void syslog(int priority, const char *fmt, ...)
        va_end(ap);
 
        while ((pos = strstr(str, "%1")) != NULL) {
+               size_t offset = pos - str;
                char *oldstr = str;
                str = realloc(str, st_add(++str_len, 1));
                if (!str) {
@@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...)
                        warning_errno("realloc failed");
                        return;
                }
+               pos = str + offset;
                memmove(pos + 2, pos + 1, strlen(pos));
                pos[1] = ' ';
        }
index a5e11aad7fe3b7f684b18b58a1cd1a11da5516d8..9b0e9c93285fb33a69ab3ee0b20ae95ad2e202e1 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1342,7 +1342,7 @@ static const struct fsync_component_name {
 
 static enum fsync_component parse_fsync_components(const char *var, const char *string)
 {
-       enum fsync_component current = FSYNC_COMPONENTS_DEFAULT;
+       enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT;
        enum fsync_component positive = 0, negative = 0;
 
        while (string) {
@@ -1688,6 +1688,8 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
                        fsync_method = FSYNC_METHOD_FSYNC;
                else if (!strcmp(value, "writeout-only"))
                        fsync_method = FSYNC_METHOD_WRITEOUT_ONLY;
+               else if (!strcmp(value, "batch"))
+                       fsync_method = FSYNC_METHOD_BATCH;
                else
                        warning(_("ignoring unknown core.fsyncMethod value '%s'"), value);
 
@@ -1781,6 +1783,9 @@ static int git_default_branch_config(const char *var, const char *value)
                } else if (value && !strcmp(value, "inherit")) {
                        git_branch_track = BRANCH_TRACK_INHERIT;
                        return 0;
+               } else if (value && !strcmp(value, "simple")) {
+                       git_branch_track = BRANCH_TRACK_SIMPLE;
+                       return 0;
                }
                git_branch_track = git_config_bool(var, value);
                return 0;
@@ -3190,7 +3195,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                        goto out_free;
                }
                /* if nothing to unset, error out */
-               if (value == NULL) {
+               if (!value) {
                        ret = CONFIG_NOTHING_SET;
                        goto out_free;
                }
@@ -3206,7 +3211,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                int i, new_line = 0;
                struct config_options opts;
 
-               if (value_pattern == NULL)
+               if (!value_pattern)
                        store.value_pattern = NULL;
                else if (value_pattern == CONFIG_REGEX_NONE)
                        store.value_pattern = CONFIG_REGEX_NONE;
@@ -3346,7 +3351,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                }
 
                /* write the pair (value == NULL means unset) */
-               if (value != NULL) {
+               if (value) {
                        if (!store.section_seen) {
                                if (write_section(fd, key, &store) < 0)
                                        goto write_err_out;
@@ -3567,7 +3572,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
                        offset = section_name_match(&buf[i], old_name);
                        if (offset > 0) {
                                ret++;
-                               if (new_name == NULL) {
+                               if (!new_name) {
                                        remove = 1;
                                        continue;
                                }
index 316a31d2313380dfe62385da237ef7d4418d11a5..7dcd04820429481adf3d504ca187c7d5263f3cee 100644 (file)
@@ -1189,9 +1189,6 @@ AC_COMPILE_IFELSE([BSD_SYSCTL_SRC],
 GIT_CONF_SUBST([HAVE_BSD_SYSCTL])
 
 ## Other checks.
-# Define USE_PIC if you need the main git objects to be built with -fPIC
-# in order to build and link perl/Git.so.  x86-64 seems to need this.
-#
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
 # Enable it on Windows.  By default, symrefs are still used.
 #
index afc79a6236e8d5fa7d4f6092c0e89d45e46cba41..e6d0b1d34bd61c626b855edb8879c12b35538ade 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -473,6 +473,24 @@ void check_stateless_delimiter(int stateless_rpc,
                die("%s", error);
 }
 
+static void send_capabilities(int fd_out, struct packet_reader *reader)
+{
+       const char *hash_name;
+
+       if (server_supports_v2("agent", 0))
+               packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
+
+       if (server_feature_v2("object-format", &hash_name)) {
+               int hash_algo = hash_algo_by_name(hash_name);
+               if (hash_algo == GIT_HASH_UNKNOWN)
+                       die(_("unknown object format '%s' specified by server"), hash_name);
+               reader->hash_algo = &hash_algos[hash_algo];
+               packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name);
+       } else {
+               reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
+       }
+}
+
 struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
                             struct ref **list, int for_push,
                             struct transport_ls_refs_options *transport_options,
@@ -480,7 +498,6 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
                             int stateless_rpc)
 {
        int i;
-       const char *hash_name;
        struct strvec *ref_prefixes = transport_options ?
                &transport_options->ref_prefixes : NULL;
        const char **unborn_head_target = transport_options ?
@@ -490,18 +507,8 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
        if (server_supports_v2("ls-refs", 1))
                packet_write_fmt(fd_out, "command=ls-refs\n");
 
-       if (server_supports_v2("agent", 0))
-               packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
-
-       if (server_feature_v2("object-format", &hash_name)) {
-               int hash_algo = hash_algo_by_name(hash_name);
-               if (hash_algo == GIT_HASH_UNKNOWN)
-                       die(_("unknown object format '%s' specified by server"), hash_name);
-               reader->hash_algo = &hash_algos[hash_algo];
-               packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name);
-       } else {
-               reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
-       }
+       /* Send capabilities */
+       send_capabilities(fd_out, reader);
 
        if (server_options && server_options->nr &&
            server_supports_v2("server-option", 1))
index 185f56f414f4b75109857cdf9d4a0a240e2069b6..29acc4f0e15e29c274550ff164fa9cd9f1050649 100644 (file)
@@ -54,7 +54,7 @@ set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
 
 option(USE_VCPKG "Whether or not to use vcpkg for obtaining dependencies.  Only applicable to Windows platforms" ON)
 if(NOT WIN32)
-       set(USE_VCPKG OFF CACHE BOOL FORCE)
+       set(USE_VCPKG OFF CACHE BOOL "" FORCE)
 endif()
 
 if(NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS)
@@ -108,7 +108,6 @@ project(git
 
 #TODO gitk git-gui gitweb
 #TODO Enable NLS on windows natively
-#TODO Add pcre support
 
 #macros for parsing the Makefile for sources and scripts
 macro(parse_makefile_for_sources list_var regex)
@@ -160,6 +159,14 @@ if(NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_ID ST
        find_package(Intl)
 endif()
 
+find_package(PkgConfig)
+if(PkgConfig_FOUND)
+       pkg_check_modules(PCRE2 libpcre2-8)
+       if(PCRE2_FOUND)
+               add_compile_definitions(USE_LIBPCRE2)
+       endif()
+endif()
+
 if(NOT Intl_FOUND)
        add_compile_definitions(NO_GETTEXT)
        if(NOT Iconv_FOUND)
@@ -180,6 +187,9 @@ endif()
 if(Intl_FOUND)
        include_directories(SYSTEM ${Intl_INCLUDE_DIRS})
 endif()
+if(PCRE2_FOUND)
+       include_directories(SYSTEM ${PCRE2_INCLUDE_DIRS})
+endif()
 
 
 if(WIN32 AND NOT MSVC)#not required for visual studio builds
@@ -260,7 +270,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
                                _CONSOLE DETECT_MSYS_TTY STRIP_EXTENSION=".exe"  NO_SYMLINK_HEAD UNRELIABLE_FSTAT
                                NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0
                                USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP
-                               UNICODE _UNICODE HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET HAVE_RTLGENRANDOM)
+                               HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET HAVE_RTLGENRANDOM)
        list(APPEND compat_SOURCES
                compat/mingw.c
                compat/winansi.c
@@ -277,7 +287,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
 
 elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
        add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY )
-       list(APPEND compat_SOURCES unix-socket.c unix-stream-server.c)
+       list(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c)
 endif()
 
 if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
@@ -700,6 +710,10 @@ endif()
 if(Iconv_FOUND)
        target_link_libraries(common-main ${Iconv_LIBRARIES})
 endif()
+if(PCRE2_FOUND)
+       target_link_libraries(common-main ${PCRE2_LIBRARIES})
+       target_link_directories(common-main PUBLIC ${PCRE2_LIBRARY_DIRS})
+endif()
 if(WIN32)
        target_link_libraries(common-main ws2_32 ntdll ${CMAKE_BINARY_DIR}/git.res)
        add_dependencies(common-main git-rc)
diff --git a/contrib/coccinelle/equals-null.cocci b/contrib/coccinelle/equals-null.cocci
new file mode 100644 (file)
index 0000000..92c7054
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+@@
+expression e;
+statement s;
+@@
+if (
+(
+!e
+|
+- e == NULL
++ !e
+)
+   )
+   {...}
+else s
+
+@@
+expression e;
+statement s;
+@@
+if (
+(
+e
+|
+- e != NULL
++ e
+)
+   )
+   {...}
+else s
index 4490069df9650df6be58a8ad3f566329f7afd6ae..6fb9eb6e88379a8897ca65057af3291e90a15be3 100644 (file)
@@ -2,13 +2,21 @@
 expression E;
 @@
 - if (E)
+(
   free(E);
+|
+  free_commit_list(E);
+)
 
 @@
 expression E;
 @@
 - if (!E)
+(
   free(E);
+|
+  free_commit_list(E);
+)
 
 @@
 expression E;
@@ -16,3 +24,22 @@ expression E;
 - free(E);
 + FREE_AND_NULL(E);
 - E = NULL;
+
+@@
+expression E;
+@@
+- if (E)
+- {
+  free_commit_list(E);
+  E = NULL;
+- }
+
+@@
+expression E;
+statement S;
+@@
+- if (E) {
++ if (E)
+  S
+  free_commit_list(E);
+- }
index 2ee702ecf7fe9d45c2c28faa7eccc79cba38e184..072ea0d92287a780f80a4d8e0ecb1cd46bdcd064 100644 (file)
@@ -11,21 +11,6 @@ expression G;
 + repo_read_object_file(the_repository,
   E, F, G)
 
-@@
-expression E;
-@@
-- has_sha1_file(
-+ repo_has_sha1_file(the_repository,
-  E)
-
-@@
-expression E;
-expression F;
-@@
-- has_sha1_file_with_flags(
-+ repo_has_sha1_file_with_flags(the_repository,
-  E)
-
 @@
 expression E;
 @@
index 8202d62035f98e38d3326dabf6d7f94364f3d842..f383c95e1f96258bc2b7ce4dcd089523f86cba95 100644 (file)
@@ -6,7 +6,11 @@ code editor which runs on your desktop and is available for
 [Windows](https://code.visualstudio.com/docs/setup/windows),
 [macOS](https://code.visualstudio.com/docs/setup/mac) and
 [Linux](https://code.visualstudio.com/docs/setup/linux). Among other languages,
-it has [support for C/C++ via an extension](https://github.com/Microsoft/vscode-cpptools).
+it has [support for C/C++ via an extension](https://github.com/Microsoft/vscode-cpptools) with
+[debugging support](https://code.visualstudio.com/docs/editor/debugging)
+
+To get help about "how to personalize your settings" read:
+[How to set up your settings](https://code.visualstudio.com/docs/getstarted/settings)
 
 To start developing Git with VS Code, simply run the Unix shell script called
 `init.sh` in this directory, which creates the configuration files in
index 27de94994b5dc5fef855ef983d0eb53a512d70c9..f139fd864446262da45cc5ed9bb4180beae2b5a0 100755 (executable)
@@ -271,7 +271,6 @@ cat >.vscode/launch.json.new <<EOF ||
             "stopAtEntry": false,
             "cwd": "\${workspaceFolder}",
             "environment": [],
-            "externalConsole": true,
             "MIMode": "gdb",
             "miDebuggerPath": "$GDBPATH",
             "setupCommands": [
index 8e39731efb0bd26e9aa6c6341f049f2965e659f2..4d153729da0f185207b85d103905b30e3183796b 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -195,9 +195,9 @@ static void check_global_conv_flags_eol(const char *path,
                if (conv_flags & CONV_EOL_RNDTRP_DIE)
                        die(_("CRLF would be replaced by LF in %s"), path);
                else if (conv_flags & CONV_EOL_RNDTRP_WARN)
-                       warning(_("CRLF will be replaced by LF in %s.\n"
-                                 "The file will have its original line"
-                                 " endings in your working directory"), path);
+                       warning(_("in the working copy of '%s', CRLF will be"
+                                 " replaced by LF the next time Git touches"
+                                 " it"), path);
        } else if (old_stats->lonelf && !new_stats->lonelf ) {
                /*
                 * CRLFs would be added by checkout
@@ -205,9 +205,9 @@ static void check_global_conv_flags_eol(const char *path,
                if (conv_flags & CONV_EOL_RNDTRP_DIE)
                        die(_("LF would be replaced by CRLF in %s"), path);
                else if (conv_flags & CONV_EOL_RNDTRP_WARN)
-                       warning(_("LF will be replaced by CRLF in %s.\n"
-                                 "The file will have its original line"
-                                 " endings in your working directory"), path);
+                       warning(_("in the working copy of '%s', LF will be"
+                                 " replaced by CRLF the next time Git touches"
+                                 " it"), path);
        }
 }
 
index 94a5b8a36453f67d6d7de945c0d2427acd2f8188..aeda6966f05e928f453ee231a8d2f41da37ff0a6 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -447,7 +447,7 @@ static void copy_to_log(int fd)
        FILE *fp;
 
        fp = fdopen(fd, "r");
-       if (fp == NULL) {
+       if (!fp) {
                logerror("fdopen of error channel failed");
                close(fd);
                return;
index 11d60da5b72512332185c703658cee6d14f551bc..50087f567062c4ff858bd6cae83fb3c59a0e4038 100755 (executable)
@@ -9,7 +9,7 @@ CC="$*"
 #
 # FreeBSD clang version 3.4.1 (tags/RELEASE...)
 get_version_line() {
-       $CC -v 2>&1 | grep ' version '
+       LANG=C LC_ALL=C $CC -v 2>&1 | grep ' version '
 }
 
 get_family() {
index ca085a03efc280deecd7cefce7ce00f5492a0d4c..7eb66a417aa08daa6f22753eba5c52f32361dfc8 100644 (file)
@@ -641,7 +641,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
 
        if (diff_cache(&revs, tree_oid, NULL, 1))
                exit(128);
-       clear_pathspec(&revs.prune_data);
+       release_revisions(&revs);
        return 0;
 }
 
@@ -651,6 +651,7 @@ int index_differs_from(struct repository *r,
 {
        struct rev_info rev;
        struct setup_revision_opt opt;
+       unsigned has_changes;
 
        repo_init_revisions(r, &rev, NULL);
        memset(&opt, 0, sizeof(opt));
@@ -662,8 +663,9 @@ int index_differs_from(struct repository *r,
                diff_flags_or(&rev.diffopt.flags, flags);
        rev.diffopt.ita_invisible_in_index = ita_invisible_in_index;
        run_diff_index(&rev, 1);
-       object_array_clear(&rev.pending);
-       return (rev.diffopt.flags.has_changes != 0);
+       has_changes = rev.diffopt.flags.has_changes;
+       release_revisions(&rev);
+       return (has_changes != 0);
 }
 
 static struct strbuf *idiff_prefix_cb(struct diff_options *opt, void *data)
diff --git a/diff.c b/diff.c
index ef7159968b68c43c361a4cacc4558e14fe82fd4f..e71cf758861bd7596ce122611a4c92fe6b27d8c5 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -4136,18 +4136,13 @@ static void prep_temp_blob(struct index_state *istate,
                           int mode)
 {
        struct strbuf buf = STRBUF_INIT;
-       struct strbuf tempfile = STRBUF_INIT;
        char *path_dup = xstrdup(path);
        const char *base = basename(path_dup);
        struct checkout_metadata meta;
 
        init_checkout_metadata(&meta, NULL, NULL, oid);
 
-       /* Generate "XXXXXX_basename.ext" */
-       strbuf_addstr(&tempfile, "XXXXXX_");
-       strbuf_addstr(&tempfile, base);
-
-       temp->tempfile = mks_tempfile_ts(tempfile.buf, strlen(base) + 1);
+       temp->tempfile = mks_tempfile_dt("git-blob-XXXXXX", base);
        if (!temp->tempfile)
                die_errno("unable to create temp-file");
        if (convert_to_working_tree(istate, path,
@@ -4162,7 +4157,6 @@ static void prep_temp_blob(struct index_state *istate,
        oid_to_hex_r(temp->hex, oid);
        xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode);
        strbuf_release(&buf);
-       strbuf_release(&tempfile);
        free(path_dup);
 }
 
diff --git a/dir.c b/dir.c
index f2b0f242101b290d4fc4615dda7b0e1a892947d3..6ca2ef5f04e1f551842a9bad06dd771e56b3ebd3 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -2747,13 +2747,33 @@ static void set_untracked_ident(struct untracked_cache *uc)
        strbuf_addch(&uc->ident, 0);
 }
 
-static void new_untracked_cache(struct index_state *istate)
+static unsigned new_untracked_cache_flags(struct index_state *istate)
+{
+       struct repository *repo = istate->repo;
+       char *val;
+
+       /*
+        * This logic is coordinated with the setting of these flags in
+        * wt-status.c#wt_status_collect_untracked(), and the evaluation
+        * of the config setting in commit.c#git_status_config()
+        */
+       if (!repo_config_get_string(repo, "status.showuntrackedfiles", &val) &&
+           !strcmp(val, "all"))
+               return 0;
+
+       /*
+        * The default, if "all" is not set, is "normal" - leading us here.
+        * If the value is "none" then it really doesn't matter.
+        */
+       return DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
+}
+
+static void new_untracked_cache(struct index_state *istate, int flags)
 {
        struct untracked_cache *uc = xcalloc(1, sizeof(*uc));
        strbuf_init(&uc->ident, 100);
        uc->exclude_per_dir = ".gitignore";
-       /* should be the same flags used by git-status */
-       uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
+       uc->dir_flags = flags >= 0 ? flags : new_untracked_cache_flags(istate);
        set_untracked_ident(uc);
        istate->untracked = uc;
        istate->cache_changed |= UNTRACKED_CHANGED;
@@ -2762,11 +2782,11 @@ static void new_untracked_cache(struct index_state *istate)
 void add_untracked_cache(struct index_state *istate)
 {
        if (!istate->untracked) {
-               new_untracked_cache(istate);
+               new_untracked_cache(istate, -1);
        } else {
                if (!ident_in_untracked(istate->untracked)) {
                        free_untracked_cache(istate->untracked);
-                       new_untracked_cache(istate);
+                       new_untracked_cache(istate, -1);
                }
        }
 }
@@ -2814,17 +2834,9 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
        if (base_len || (pathspec && pathspec->nr))
                return NULL;
 
-       /* Different set of flags may produce different results */
-       if (dir->flags != dir->untracked->dir_flags ||
-           /*
-            * See treat_directory(), case index_nonexistent. Without
-            * this flag, we may need to also cache .git file content
-            * for the resolve_gitlink_ref() call, which we don't.
-            */
-           !(dir->flags & DIR_SHOW_OTHER_DIRECTORIES) ||
-           /* We don't support collecting ignore files */
-           (dir->flags & (DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO |
-                          DIR_COLLECT_IGNORED)))
+       /* We don't support collecting ignore files */
+       if (dir->flags & (DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO |
+                       DIR_COLLECT_IGNORED))
                return NULL;
 
        /*
@@ -2847,6 +2859,50 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
                return NULL;
        }
 
+       /*
+        * If the untracked structure we received does not have the same flags
+        * as requested in this run, we're going to need to either discard the
+        * existing structure (and potentially later recreate), or bypass the
+        * untracked cache mechanism for this run.
+        */
+       if (dir->flags != dir->untracked->dir_flags) {
+               /*
+                * If the untracked structure we received does not have the same flags
+                * as configured, then we need to reset / create a new "untracked"
+                * structure to match the new config.
+                *
+                * Keeping the saved and used untracked cache consistent with the
+                * configuration provides an opportunity for frequent users of
+                * "git status -uall" to leverage the untracked cache by aligning their
+                * configuration - setting "status.showuntrackedfiles" to "all" or
+                * "normal" as appropriate.
+                *
+                * Previously using -uall (or setting "status.showuntrackedfiles" to
+                * "all") was incompatible with untracked cache and *consistently*
+                * caused surprisingly bad performance (with fscache and fsmonitor
+                * enabled) on Windows.
+                *
+                * IMPROVEMENT OPPORTUNITY: If we reworked the untracked cache storage
+                * to not be as bound up with the desired output in a given run,
+                * and instead iterated through and stored enough information to
+                * correctly serve both "modes", then users could get peak performance
+                * with or without '-uall' regardless of their
+                * "status.showuntrackedfiles" config.
+                */
+               if (dir->untracked->dir_flags != new_untracked_cache_flags(istate)) {
+                       free_untracked_cache(istate->untracked);
+                       new_untracked_cache(istate, dir->flags);
+                       dir->untracked = istate->untracked;
+               }
+               else {
+                       /*
+                        * Current untracked cache data is consistent with config, but not
+                        * usable in this request/run; just bypass untracked cache.
+                        */
+                       return NULL;
+               }
+       }
+
        if (!dir->untracked->root) {
                /* Untracked cache existed but is not initialized; fix that */
                FLEX_ALLOC_STR(dir->untracked->root, name, "");
@@ -3054,7 +3110,7 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare)
         * Skip scheme.
         */
        start = strstr(repo, "://");
-       if (start == NULL)
+       if (!start)
                start = repo;
        else
                start += 3;
@@ -3081,6 +3137,15 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare)
                        end--;
        }
 
+       /*
+        * It should not be possible to overflow `ptrdiff_t` by passing in an
+        * insanely long URL, but GCC does not know that and will complain
+        * without this check.
+        */
+       if (end - start < 0)
+               die(_("No directory name could be guessed.\n"
+                     "Please specify a directory on the command line"));
+
        /*
         * Strip trailing port number if we've got only a
         * hostname (that is, there is no dir separator but a
@@ -3890,3 +3955,32 @@ void relocate_gitdir(const char *path, const char *old_git_dir, const char *new_
 
        connect_work_tree_and_git_dir(path, new_git_dir, 0);
 }
+
+int path_match_flags(const char *const str, const enum path_match_flags flags)
+{
+       const char *p = str;
+
+       if (flags & PATH_MATCH_NATIVE &&
+           flags & PATH_MATCH_XPLATFORM)
+               BUG("path_match_flags() must get one match kind, not multiple!");
+       else if (!(flags & PATH_MATCH_KINDS_MASK))
+               BUG("path_match_flags() must get at least one match kind!");
+
+       if (flags & PATH_MATCH_STARTS_WITH_DOT_SLASH &&
+           flags & PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH)
+               BUG("path_match_flags() must get one platform kind, not multiple!");
+       else if (!(flags & PATH_MATCH_PLATFORM_MASK))
+               BUG("path_match_flags() must get at least one platform kind!");
+
+       if (*p++ != '.')
+               return 0;
+       if (flags & PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH &&
+           *p++ != '.')
+               return 0;
+
+       if (flags & PATH_MATCH_NATIVE)
+               return is_dir_sep(*p);
+       else if (flags & PATH_MATCH_XPLATFORM)
+               return is_xplatform_dir_sep(*p);
+       BUG("unreachable");
+}
diff --git a/dir.h b/dir.h
index 8e02dfb505d163eca3c33d17e495be8f166b83e5..7bc862030cfb3bbc97cd3b9f6523696662e12633 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -578,4 +578,67 @@ void connect_work_tree_and_git_dir(const char *work_tree,
 void relocate_gitdir(const char *path,
                     const char *old_git_dir,
                     const char *new_git_dir);
+
+/**
+ * The "enum path_matches_kind" determines how path_match_flags() will
+ * behave. The flags come in sets, and one (and only one) must be
+ * provided out of each "set":
+ *
+ * PATH_MATCH_NATIVE:
+ *     Path separator is is_dir_sep()
+ * PATH_MATCH_XPLATFORM:
+ *     Path separator is is_xplatform_dir_sep()
+ *
+ * Do we use is_dir_sep() to check for a directory separator
+ * (*_NATIVE), or do we always check for '/' or '\' (*_XPLATFORM). The
+ * "*_NATIVE" version on Windows is the same as "*_XPLATFORM",
+ * everywhere else "*_NATIVE" means "only /".
+ *
+ * PATH_MATCH_STARTS_WITH_DOT_SLASH:
+ *     Match a path starting with "./"
+ * PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH:
+ *     Match a path starting with "../"
+ *
+ * The "/" in the above is adjusted based on the "*_NATIVE" and
+ * "*_XPLATFORM" flags.
+ */
+enum path_match_flags {
+       PATH_MATCH_NATIVE = 1 << 0,
+       PATH_MATCH_XPLATFORM = 1 << 1,
+       PATH_MATCH_STARTS_WITH_DOT_SLASH = 1 << 2,
+       PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH = 1 << 3,
+};
+#define PATH_MATCH_KINDS_MASK (PATH_MATCH_STARTS_WITH_DOT_SLASH | \
+       PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH)
+#define PATH_MATCH_PLATFORM_MASK (PATH_MATCH_NATIVE | PATH_MATCH_XPLATFORM)
+
+/**
+ * path_match_flags() checks if a given "path" matches a given "enum
+ * path_match_flags" criteria.
+ */
+int path_match_flags(const char *const path, const enum path_match_flags f);
+
+/**
+ * starts_with_dot_slash_native(): convenience wrapper for
+ * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_SLASH and
+ * PATH_MATCH_NATIVE.
+ */
+static inline int starts_with_dot_slash_native(const char *const path)
+{
+       const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_SLASH;
+
+       return path_match_flags(path, what | PATH_MATCH_NATIVE);
+}
+
+/**
+ * starts_with_dot_slash_native(): convenience wrapper for
+ * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH and
+ * PATH_MATCH_NATIVE.
+ */
+static inline int starts_with_dot_dot_slash_native(const char *const path)
+{
+       const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH;
+
+       return path_match_flags(path, what | PATH_MATCH_NATIVE);
+}
 #endif
index 5bff1b386fd8823b0205b7e473b91b7aa44d7f73..b3296ce7d15140bff12299b25d1450f69f8508ee 100644 (file)
@@ -273,7 +273,7 @@ const char *get_git_work_tree(void)
        return the_repository->worktree;
 }
 
-char *get_object_directory(void)
+const char *get_object_directory(void)
 {
        if (!the_repository->objects->odb)
                BUG("git environment hasn't been setup");
index 38a47c44db4c6cd43bd384890ed414d4665bf456..ac618641632f8c347b2a2900fb15b0de9ed8dd8a 100644 (file)
@@ -216,14 +216,9 @@ int bitmap_is_subset(struct bitmap *self, struct bitmap *other)
        return 0;
 }
 
-void bitmap_reset(struct bitmap *bitmap)
-{
-       memset(bitmap->words, 0x0, bitmap->word_alloc * sizeof(eword_t));
-}
-
 void bitmap_free(struct bitmap *bitmap)
 {
-       if (bitmap == NULL)
+       if (!bitmap)
                return;
 
        free(bitmap->words);
index 2a8c7c5c33ab864788baaa7b6a52a5c59f84f7d0..6fe48d3ae0449a0298deb109b967ef3479ef0c47 100644 (file)
@@ -451,7 +451,7 @@ struct ewah_bitmap *ewah_pool_new(void)
 
 void ewah_pool_free(struct ewah_bitmap *self)
 {
-       if (self == NULL)
+       if (!self)
                return;
 
        if (bitmap_pool_size == BITMAP_POOL_MAX ||
index 66920965da19ab4a38db18d1b18e0f5fbaa4776f..7eb8b9b63013daa70c91687108307d38a9eb1e09 100644 (file)
@@ -177,7 +177,6 @@ struct bitmap *bitmap_dup(const struct bitmap *src);
 void bitmap_set(struct bitmap *self, size_t pos);
 void bitmap_unset(struct bitmap *self, size_t pos);
 int bitmap_get(struct bitmap *self, size_t pos);
-void bitmap_reset(struct bitmap *self);
 void bitmap_free(struct bitmap *self);
 int bitmap_equals(struct bitmap *self, struct bitmap *other);
 int bitmap_is_subset(struct bitmap *self, struct bitmap *other);
index 4e1e88eea097dde85dbbe200ed28d2886a5f2dca..cb6647d65703aca1ec1ec7014ac433de31852fcc 100644 (file)
@@ -115,11 +115,12 @@ static void for_each_cached_alternate(struct fetch_negotiator *negotiator,
                cb(negotiator, cache.items[i]);
 }
 
-static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
-                                              int mark_tags_complete)
+static struct commit *deref_without_lazy_fetch_extended(const struct object_id *oid,
+                                                       int mark_tags_complete,
+                                                       enum object_type *type,
+                                                       unsigned int oi_flags)
 {
-       enum object_type type;
-       struct object_info info = { .typep = &type };
+       struct object_info info = { .typep = type };
        struct commit *commit;
 
        commit = lookup_commit_in_graph(the_repository, oid);
@@ -128,9 +129,9 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
 
        while (1) {
                if (oid_object_info_extended(the_repository, oid, &info,
-                                            OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK))
+                                            oi_flags))
                        return NULL;
-               if (type == OBJ_TAG) {
+               if (*type == OBJ_TAG) {
                        struct tag *tag = (struct tag *)
                                parse_object(the_repository, oid);
 
@@ -144,7 +145,7 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
                }
        }
 
-       if (type == OBJ_COMMIT) {
+       if (*type == OBJ_COMMIT) {
                struct commit *commit = lookup_commit(the_repository, oid);
                if (!commit || repo_parse_commit(the_repository, commit))
                        return NULL;
@@ -154,6 +155,16 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
        return NULL;
 }
 
+
+static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
+                                              int mark_tags_complete)
+{
+       enum object_type type;
+       unsigned flags = OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK;
+       return deref_without_lazy_fetch_extended(oid, mark_tags_complete,
+                                                &type, flags);
+}
+
 static int rev_list_insert_ref(struct fetch_negotiator *negotiator,
                               const struct object_id *oid)
 {
@@ -836,6 +847,16 @@ static void parse_gitmodules_oids(int fd, struct oidset *gitmodules_oids)
        } while (1);
 }
 
+static void add_index_pack_keep_option(struct strvec *args)
+{
+       char hostname[HOST_NAME_MAX + 1];
+
+       if (xgethostname(hostname, sizeof(hostname)))
+               xsnprintf(hostname, sizeof(hostname), "localhost");
+       strvec_pushf(args, "--keep=fetch-pack %"PRIuMAX " on %s",
+                    (uintmax_t)getpid(), hostname);
+}
+
 /*
  * If packfile URIs were provided, pass a non-NULL pointer to index_pack_args.
  * The strings to pass as the --index-pack-arg arguments to http-fetch will be
@@ -905,14 +926,8 @@ static int get_pack(struct fetch_pack_args *args,
                        strvec_push(&cmd.args, "-v");
                if (args->use_thin_pack)
                        strvec_push(&cmd.args, "--fix-thin");
-               if ((do_keep || index_pack_args) && (args->lock_pack || unpack_limit)) {
-                       char hostname[HOST_NAME_MAX + 1];
-                       if (xgethostname(hostname, sizeof(hostname)))
-                               xsnprintf(hostname, sizeof(hostname), "localhost");
-                       strvec_pushf(&cmd.args,
-                                    "--keep=fetch-pack %"PRIuMAX " on %s",
-                                    (uintmax_t)getpid(), hostname);
-               }
+               if ((do_keep || index_pack_args) && (args->lock_pack || unpack_limit))
+                       add_index_pack_keep_option(&cmd.args);
                if (!index_pack_args && args->check_self_contained_and_connected)
                        strvec_push(&cmd.args, "--check-self-contained-and-connected");
                else
@@ -1370,17 +1385,20 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
 static int process_section_header(struct packet_reader *reader,
                                  const char *section, int peek)
 {
-       int ret;
-
-       if (packet_reader_peek(reader) != PACKET_READ_NORMAL)
-               die(_("error reading section header '%s'"), section);
+       int ret = 0;
 
-       ret = !strcmp(reader->line, section);
+       if (packet_reader_peek(reader) == PACKET_READ_NORMAL &&
+           !strcmp(reader->line, section))
+               ret = 1;
 
        if (!peek) {
-               if (!ret)
-                       die(_("expected '%s', received '%s'"),
-                           section, reader->line);
+               if (!ret) {
+                       if (reader->line)
+                               die(_("expected '%s', received '%s'"),
+                                   section, reader->line);
+                       else
+                               die(_("expected '%s'"), section);
+               }
                packet_reader_read(reader);
        }
 
index baca57d5b64c9f30bad08a505ccd7f1a9ba38546..f48f44f9cd1dbdd3aeafbe5a4bd3598e783d0e25 100644 (file)
@@ -699,6 +699,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
                        shortlog(origins.items[i].string,
                                 origins.items[i].util,
                                 head, &rev, opts, out);
+               release_revisions(&rev);
        }
 
        strbuf_complete_line(out);
diff --git a/fsck.c b/fsck.c
index 3ec500d707aaf602e4e1c12139ccad075feb8046..dd4822ba1be7fe2de830613757110e6d55bfb566 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -975,27 +975,16 @@ done:
        return ret;
 }
 
-/*
- * Like builtin/submodule--helper.c's starts_with_dot_slash, but without
- * relying on the platform-dependent is_dir_sep helper.
- *
- * This is for use in checking whether a submodule URL is interpreted as
- * relative to the current directory on any platform, since \ is a
- * directory separator on Windows but not on other platforms.
- */
-static int starts_with_dot_slash(const char *str)
+static int starts_with_dot_slash(const char *const path)
 {
-       return str[0] == '.' && (str[1] == '/' || str[1] == '\\');
+       return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH |
+                               PATH_MATCH_XPLATFORM);
 }
 
-/*
- * Like starts_with_dot_slash, this is a variant of submodule--helper's
- * helper of the same name with the twist that it accepts backslash as a
- * directory separator even on non-Windows platforms.
- */
-static int starts_with_dot_dot_slash(const char *str)
+static int starts_with_dot_dot_slash(const char *const path)
 {
-       return str[0] == '.' && starts_with_dot_slash(str + 1);
+       return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH |
+                               PATH_MATCH_XPLATFORM);
 }
 
 static int submodule_url_is_relative(const char *url)
index 58fd813bd012f12150bd27d72a9ebdc5cf491dd3..d9457b9aae4f88a3afd461826d77a87e7e776ddb 100644 (file)
 #include <sys/sysctl.h>
 #endif
 
+/* Used by compat/win32/path-utils.h, and more */
+static inline int is_xplatform_dir_sep(int c)
+{
+       return c == '/' || c == '\\';
+}
+
 #if defined(__CYGWIN__)
 #include "compat/win32/path-utils.h"
 #endif
@@ -416,11 +422,11 @@ static inline int git_skip_dos_drive_prefix(char **path)
 #define skip_dos_drive_prefix git_skip_dos_drive_prefix
 #endif
 
-#ifndef is_dir_sep
 static inline int git_is_dir_sep(int c)
 {
        return c == '/';
 }
+#ifndef is_dir_sep
 #define is_dir_sep git_is_dir_sep
 #endif
 
@@ -437,12 +443,63 @@ static inline int git_offset_1st_component(const char *path)
 #endif
 
 #ifndef is_path_owned_by_current_user
+
+#ifdef __TANDEM
+#define ROOT_UID 65535
+#else
+#define ROOT_UID 0
+#endif
+
+/*
+ * Do not use this function when
+ * (1) geteuid() did not say we are running as 'root', or
+ * (2) using this function will compromise the system.
+ *
+ * PORTABILITY WARNING:
+ * This code assumes uid_t is unsigned because that is what sudo does.
+ * If your uid_t type is signed and all your ids are positive then it
+ * should all work fine.
+ * If your version of sudo uses negative values for uid_t or it is
+ * buggy and return an overflowed value in SUDO_UID, then git might
+ * fail to grant access to your repository properly or even mistakenly
+ * grant access to someone else.
+ * In the unlikely scenario this happened to you, and that is how you
+ * got to this message, we would like to know about it; so sent us an
+ * email to git@vger.kernel.org indicating which platform you are
+ * using and which version of sudo, so we can improve this logic and
+ * maybe provide you with a patch that would prevent this issue again
+ * in the future.
+ */
+static inline void extract_id_from_env(const char *env, uid_t *id)
+{
+       const char *real_uid = getenv(env);
+
+       /* discard anything empty to avoid a more complex check below */
+       if (real_uid && *real_uid) {
+               char *endptr = NULL;
+               unsigned long env_id;
+
+               errno = 0;
+               /* silent overflow errors could trigger a bug here */
+               env_id = strtoul(real_uid, &endptr, 10);
+               if (!*endptr && !errno)
+                       *id = env_id;
+       }
+}
+
 static inline int is_path_owned_by_current_uid(const char *path)
 {
        struct stat st;
+       uid_t euid;
+
        if (lstat(path, &st))
                return 0;
-       return st.st_uid == geteuid();
+
+       euid = geteuid();
+       if (euid == ROOT_UID)
+               extract_id_from_env("SUDO_UID", &euid);
+
+       return st.st_uid == euid;
 }
 
 #define is_path_owned_by_current_user is_path_owned_by_current_uid
@@ -1273,11 +1330,13 @@ __attribute__((format (printf, 3, 4))) NORETURN
 void BUG_fl(const char *file, int line, const char *fmt, ...);
 #define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__)
 
+#ifndef FSYNC_METHOD_DEFAULT
 #ifdef __APPLE__
 #define FSYNC_METHOD_DEFAULT FSYNC_METHOD_WRITEOUT_ONLY
 #else
 #define FSYNC_METHOD_DEFAULT FSYNC_METHOD_FSYNC
 #endif
+#endif
 
 enum fsync_action {
        FSYNC_WRITEOUT_ONLY,
index 542a6a75eb3c4b93d8b4a394551d5d38d2a88f6e..9f99201bcca1eada84c3f19d1ca44cb41b3f3c59 100644 (file)
@@ -63,7 +63,7 @@ $(list_tool_variants)"
                                        preamble=
                                fi
                                shown_any=yes
-                               printf "%s%s\n" "$per_line_prefix" "$toolname"
+                               printf "%s%-15s  %s\n" "$per_line_prefix" "$toolname" $(diff_mode && diff_cmd_help "$toolname" || merge_cmd_help "$toolname")
                        fi
                done
 
@@ -162,10 +162,18 @@ setup_tool () {
                return 1
        }
 
+       diff_cmd_help () {
+               return 0
+       }
+
        merge_cmd () {
                return 1
        }
 
+       merge_cmd_help () {
+               return 0
+       }
+
        hide_resolved_enabled () {
                return 0
        }
index a9b1f9044108e4dce94b865f1f777039d8755613..8fbf6eb1fe385090489f55c87913d0867ad8c349 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -7,34 +7,52 @@
 #            2007 Trolltech ASA
 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
 #
-# pylint: disable=invalid-name,missing-docstring,too-many-arguments,broad-except
-# pylint: disable=no-self-use,wrong-import-position,consider-iterating-dictionary
-# pylint: disable=wrong-import-order,unused-import,too-few-public-methods
-# pylint: disable=too-many-lines,ungrouped-imports,fixme,too-many-locals
-# pylint: disable=line-too-long,bad-whitespace,superfluous-parens
-# pylint: disable=too-many-statements,too-many-instance-attributes
-# pylint: disable=too-many-branches,too-many-nested-blocks
+# pylint: disable=bad-whitespace
+# pylint: disable=broad-except
+# pylint: disable=consider-iterating-dictionary
+# pylint: disable=disable
+# pylint: disable=fixme
+# pylint: disable=invalid-name
+# pylint: disable=line-too-long
+# pylint: disable=missing-docstring
+# pylint: disable=no-self-use
+# pylint: disable=superfluous-parens
+# pylint: disable=too-few-public-methods
+# pylint: disable=too-many-arguments
+# pylint: disable=too-many-branches
+# pylint: disable=too-many-instance-attributes
+# pylint: disable=too-many-lines
+# pylint: disable=too-many-locals
+# pylint: disable=too-many-nested-blocks
+# pylint: disable=too-many-statements
+# pylint: disable=ungrouped-imports
+# pylint: disable=unused-import
+# pylint: disable=wrong-import-order
+# pylint: disable=wrong-import-position
 #
+
+import struct
 import sys
 if sys.version_info.major < 3 and sys.version_info.minor < 7:
     sys.stderr.write("git-p4: requires Python 2.7 or later.\n")
     sys.exit(1)
-import os
-import optparse
+
+import ctypes
+import errno
 import functools
+import glob
 import marshal
-import subprocess
-import tempfile
-import time
+import optparse
+import os
 import platform
 import re
 import shutil
 import stat
+import subprocess
+import tempfile
+import time
 import zipfile
 import zlib
-import ctypes
-import errno
-import glob
 
 # On python2.7 where raw_input() and input() are both availble,
 # we want raw_input's semantics, but aliased to input for python3
@@ -52,17 +70,21 @@ verbose = False
 defaultLabelRegexp = r'[a-zA-Z0-9_\-.]+$'
 
 # The block size is reduced automatically if required
-defaultBlockSize = 1<<20
+defaultBlockSize = 1 << 20
+
+defaultMetadataDecodingStrategy = 'passthrough' if sys.version_info.major == 2 else 'fallback'
+defaultFallbackMetadataEncoding = 'cp1252'
 
 p4_access_checked = False
 
 re_ko_keywords = re.compile(br'\$(Id|Header)(:[^$\n]+)?\$')
 re_k_keywords = re.compile(br'\$(Id|Header|Author|Date|DateTime|Change|File|Revision)(:[^$\n]+)?\$')
 
+
 def format_size_human_readable(num):
-    """ Returns a number of units (typically bytes) formatted as a human-readable
-        string.
-    """
+    """Returns a number of units (typically bytes) formatted as a
+       human-readable string.
+       """
     if num < 1024:
         return '{:d} B'.format(num)
     for unit in ["Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
@@ -71,18 +93,19 @@ def format_size_human_readable(num):
             return "{:3.1f} {}B".format(num, unit)
     return "{:.1f} YiB".format(num)
 
+
 def p4_build_cmd(cmd):
     """Build a suitable p4 command line.
 
-    This consolidates building and returning a p4 command line into one
-    location. It means that hooking into the environment, or other configuration
-    can be done more easily.
-    """
+       This consolidates building and returning a p4 command line into one
+       location. It means that hooking into the environment, or other
+       configuration can be done more easily.
+       """
     real_cmd = ["p4"]
 
     user = gitConfig("git-p4.user")
     if len(user) > 0:
-        real_cmd += ["-u",user]
+        real_cmd += ["-u", user]
 
     password = gitConfig("git-p4.password")
     if len(password) > 0:
@@ -118,31 +141,31 @@ def p4_build_cmd(cmd):
 
     return real_cmd
 
+
 def git_dir(path):
-    """ Return TRUE if the given path is a git directory (/path/to/dir/.git).
-        This won't automatically add ".git" to a directory.
-    """
+    """Return TRUE if the given path is a git directory (/path/to/dir/.git).
+       This won't automatically add ".git" to a directory.
+       """
     d = read_pipe(["git", "--git-dir", path, "rev-parse", "--git-dir"], True).strip()
     if not d or len(d) == 0:
         return None
     else:
         return d
 
+
 def chdir(path, is_client_path=False):
-    """Do chdir to the given path, and set the PWD environment
-       variable for use by P4.  It does not look at getcwd() output.
-       Since we're not using the shell, it is necessary to set the
-       PWD environment variable explicitly.
-
-       Normally, expand the path to force it to be absolute.  This
-       addresses the use of relative path names inside P4 settings,
-       e.g. P4CONFIG=.p4config.  P4 does not simply open the filename
-       as given; it looks for .p4config using PWD.
-
-       If is_client_path, the path was handed to us directly by p4,
-       and may be a symbolic link.  Do not call os.getcwd() in this
-       case, because it will cause p4 to think that PWD is not inside
-       the client path.
+    """Do chdir to the given path, and set the PWD environment variable for use
+       by P4.  It does not look at getcwd() output.  Since we're not using the
+       shell, it is necessary to set the PWD environment variable explicitly.
+
+       Normally, expand the path to force it to be absolute.  This addresses
+       the use of relative path names inside P4 settings, e.g.
+       P4CONFIG=.p4config.  P4 does not simply open the filename as given; it
+       looks for .p4config using PWD.
+
+       If is_client_path, the path was handed to us directly by p4, and may be
+       a symbolic link.  Do not call os.getcwd() in this case, because it will
+       cause p4 to think that PWD is not inside the client path.
        """
 
     os.chdir(path)
@@ -150,6 +173,7 @@ def chdir(path, is_client_path=False):
         path = os.getcwd()
     os.environ['PWD'] = path
 
+
 def calcDiskFree():
     """Return free space in bytes on the disk of the given dirname."""
     if platform.system() == 'Windows':
@@ -160,52 +184,124 @@ def calcDiskFree():
         st = os.statvfs(os.getcwd())
         return st.f_bavail * st.f_frsize
 
+
 def die(msg):
-    """ Terminate execution. Make sure that any running child processes have been wait()ed for before
-        calling this.
-    """
+    """Terminate execution. Make sure that any running child processes have
+       been wait()ed for before calling this.
+       """
     if verbose:
         raise Exception(msg)
     else:
         sys.stderr.write(msg + "\n")
         sys.exit(1)
 
+
 def prompt(prompt_text):
-    """ Prompt the user to choose one of the choices
+    """Prompt the user to choose one of the choices.
 
-    Choices are identified in the prompt_text by square brackets around
-    a single letter option.
-    """
+       Choices are identified in the prompt_text by square brackets around a
+       single letter option.
+       """
     choices = set(m.group(1) for m in re.finditer(r"\[(.)\]", prompt_text))
     while True:
         sys.stderr.flush()
         sys.stdout.write(prompt_text)
         sys.stdout.flush()
-        response=sys.stdin.readline().strip().lower()
+        response = sys.stdin.readline().strip().lower()
         if not response:
             continue
         response = response[0]
         if response in choices:
             return response
 
+
 # We need different encoding/decoding strategies for text data being passed
 # around in pipes depending on python version
 if bytes is not str:
     # For python3, always encode and decode as appropriate
     def decode_text_stream(s):
         return s.decode() if isinstance(s, bytes) else s
+
     def encode_text_stream(s):
         return s.encode() if isinstance(s, str) else s
 else:
     # For python2.7, pass read strings as-is, but also allow writing unicode
     def decode_text_stream(s):
         return s
+
     def encode_text_stream(s):
         return s.encode('utf_8') if isinstance(s, unicode) else s
 
+
+class MetadataDecodingException(Exception):
+    def __init__(self, input_string):
+        self.input_string = input_string
+
+    def __str__(self):
+        return """Decoding perforce metadata failed!
+The failing string was:
+---
+{}
+---
+Consider setting the git-p4.metadataDecodingStrategy config option to
+'fallback', to allow metadata to be decoded using a fallback encoding,
+defaulting to cp1252.""".format(self.input_string)
+
+
+encoding_fallback_warning_issued = False
+encoding_escape_warning_issued = False
+def metadata_stream_to_writable_bytes(s):
+    encodingStrategy = gitConfig('git-p4.metadataDecodingStrategy') or defaultMetadataDecodingStrategy
+    fallbackEncoding = gitConfig('git-p4.metadataFallbackEncoding') or defaultFallbackMetadataEncoding
+    if not isinstance(s, bytes):
+        return s.encode('utf_8')
+    if encodingStrategy == 'passthrough':
+        return s
+    try:
+        s.decode('utf_8')
+        return s
+    except UnicodeDecodeError:
+        if encodingStrategy == 'fallback' and fallbackEncoding:
+            global encoding_fallback_warning_issued
+            global encoding_escape_warning_issued
+            try:
+                if not encoding_fallback_warning_issued:
+                    print("\nCould not decode value as utf-8; using configured fallback encoding %s: %s" % (fallbackEncoding, s))
+                    print("\n(this warning is only displayed once during an import)")
+                    encoding_fallback_warning_issued = True
+                return s.decode(fallbackEncoding).encode('utf_8')
+            except Exception as exc:
+                if not encoding_escape_warning_issued:
+                    print("\nCould not decode value with configured fallback encoding %s; escaping bytes over 127: %s" % (fallbackEncoding, s))
+                    print("\n(this warning is only displayed once during an import)")
+                    encoding_escape_warning_issued = True
+                escaped_bytes = b''
+                # bytes and strings work very differently in python2 vs python3...
+                if str is bytes:
+                    for byte in s:
+                        byte_number = struct.unpack('>B', byte)[0]
+                        if byte_number > 127:
+                            escaped_bytes += b'%'
+                            escaped_bytes += hex(byte_number)[2:].upper()
+                        else:
+                            escaped_bytes += byte
+                else:
+                    for byte_number in s:
+                        if byte_number > 127:
+                            escaped_bytes += b'%'
+                            escaped_bytes += hex(byte_number).upper().encode()[2:]
+                        else:
+                            escaped_bytes += bytes([byte_number])
+                return escaped_bytes
+
+        raise MetadataDecodingException(s)
+
+
 def decode_path(path):
-    """Decode a given string (bytes or otherwise) using configured path encoding options
-    """
+    """Decode a given string (bytes or otherwise) using configured path
+       encoding options.
+       """
+
     encoding = gitConfig('git-p4.pathEncoding') or 'utf_8'
     if bytes is not str:
         return path.decode(encoding, errors='replace') if isinstance(path, bytes) else path
@@ -218,6 +314,7 @@ def decode_path(path):
                 print('Path with non-ASCII characters detected. Used {} to decode: {}'.format(encoding, path))
         return path
 
+
 def run_git_hook(cmd, param=[]):
     """Execute a hook if the hook exists."""
     args = ['git', 'hook', 'run', '--ignore-missing', cmd]
@@ -227,6 +324,7 @@ def run_git_hook(cmd, param=[]):
             args.append(p)
     return subprocess.call(args) == 0
 
+
 def write_pipe(c, stdin, *k, **kw):
     if verbose:
         sys.stderr.write('Writing pipe: {}\n'.format(' '.join(c)))
@@ -240,33 +338,35 @@ def write_pipe(c, stdin, *k, **kw):
 
     return val
 
+
 def p4_write_pipe(c, stdin, *k, **kw):
     real_cmd = p4_build_cmd(c)
     if bytes is not str and isinstance(stdin, str):
         stdin = encode_text_stream(stdin)
     return write_pipe(real_cmd, stdin, *k, **kw)
 
+
 def read_pipe_full(c, *k, **kw):
-    """ Read output from  command. Returns a tuple
-        of the return status, stdout text and stderr
-        text.
-    """
+    """Read output from command. Returns a tuple of the return status, stdout
+       text and stderr text.
+       """
     if verbose:
         sys.stderr.write('Reading pipe: {}\n'.format(' '.join(c)))
 
     p = subprocess.Popen(
         c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, *k, **kw)
-    (out, err) = p.communicate()
+    out, err = p.communicate()
     return (p.returncode, out, decode_text_stream(err))
 
+
 def read_pipe(c, ignore_error=False, raw=False, *k, **kw):
-    """ Read output from  command. Returns the output text on
-        success. On failure, terminates execution, unless
-        ignore_error is True, when it returns an empty string.
+    """Read output from  command. Returns the output text on success. On
+       failure, terminates execution, unless ignore_error is True, when it
+       returns an empty string.
 
-        If raw is True, do not attempt to decode output text.
-    """
-    (retcode, out, err) = read_pipe_full(c, *k, **kw)
+       If raw is True, do not attempt to decode output text.
+       """
+    retcode, out, err = read_pipe_full(c, *k, **kw)
     if retcode != 0:
         if ignore_error:
             out = ""
@@ -276,20 +376,23 @@ def read_pipe(c, ignore_error=False, raw=False, *k, **kw):
         out = decode_text_stream(out)
     return out
 
+
 def read_pipe_text(c, *k, **kw):
-    """ Read output from a command with trailing whitespace stripped.
-        On error, returns None.
-    """
-    (retcode, out, err) = read_pipe_full(c, *k, **kw)
+    """Read output from a command with trailing whitespace stripped. On error,
+       returns None.
+       """
+    retcode, out, err = read_pipe_full(c, *k, **kw)
     if retcode != 0:
         return None
     else:
         return decode_text_stream(out).rstrip()
 
+
 def p4_read_pipe(c, ignore_error=False, raw=False, *k, **kw):
     real_cmd = p4_build_cmd(c)
     return read_pipe(real_cmd, ignore_error, raw=raw, *k, **kw)
 
+
 def read_pipe_lines(c, raw=False, *k, **kw):
     if verbose:
         sys.stderr.write('Reading pipe: {}\n'.format(' '.join(c)))
@@ -303,31 +406,36 @@ def read_pipe_lines(c, raw=False, *k, **kw):
         die('Command failed: {}'.format(' '.join(c)))
     return lines
 
+
 def p4_read_pipe_lines(c, *k, **kw):
-    """Specifically invoke p4 on the command supplied. """
+    """Specifically invoke p4 on the command supplied."""
     real_cmd = p4_build_cmd(c)
     return read_pipe_lines(real_cmd, *k, **kw)
 
+
 def p4_has_command(cmd):
-    """Ask p4 for help on this command.  If it returns an error, the
-       command does not exist in this version of p4."""
+    """Ask p4 for help on this command.  If it returns an error, the command
+       does not exist in this version of p4.
+       """
     real_cmd = p4_build_cmd(["help", cmd])
     p = subprocess.Popen(real_cmd, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
     p.communicate()
     return p.returncode == 0
 
+
 def p4_has_move_command():
-    """See if the move command exists, that it supports -k, and that
-       it has not been administratively disabled.  The arguments
-       must be correct, but the filenames do not have to exist.  Use
-       ones with wildcards so even if they exist, it will fail."""
+    """See if the move command exists, that it supports -k, and that it has not
+       been administratively disabled.  The arguments must be correct, but the
+       filenames do not have to exist.  Use ones with wildcards so even if they
+       exist, it will fail.
+       """
 
     if not p4_has_command("move"):
         return False
     cmd = p4_build_cmd(["move", "-k", "@from", "@to"])
     p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    (out, err) = p.communicate()
+    out, err = p.communicate()
     err = decode_text_stream(err)
     # return code will be 1 in either case
     if err.find("Invalid option") >= 0:
@@ -337,6 +445,7 @@ def p4_has_move_command():
     # assume it failed because @... was invalid changelist
     return True
 
+
 def system(cmd, ignore_error=False, *k, **kw):
     if verbose:
         sys.stderr.write("executing {}\n".format(
@@ -347,19 +456,22 @@ def system(cmd, ignore_error=False, *k, **kw):
 
     return retcode
 
+
 def p4_system(cmd, *k, **kw):
-    """Specifically invoke p4 as the system command. """
+    """Specifically invoke p4 as the system command."""
     real_cmd = p4_build_cmd(cmd)
     retcode = subprocess.call(real_cmd, *k, **kw)
     if retcode:
         raise subprocess.CalledProcessError(retcode, real_cmd)
 
+
 def die_bad_access(s):
     die("failure accessing depot: {0}".format(s.rstrip()))
 
+
 def p4_check_access(min_expiration=1):
-    """ Check if we can access Perforce - account still logged in
-    """
+    """Check if we can access Perforce - account still logged in."""
+
     results = p4CmdList(["login", "-s"])
 
     if len(results) == 0:
@@ -402,62 +514,78 @@ def p4_check_access(min_expiration=1):
     else:
         die_bad_access("unknown error code {0}".format(code))
 
+
 _p4_version_string = None
+
+
 def p4_version_string():
-    """Read the version string, showing just the last line, which
-       hopefully is the interesting version bit.
+    """Read the version string, showing just the last line, which hopefully is
+       the interesting version bit.
 
        $ p4 -V
        Perforce - The Fast Software Configuration Management System.
        Copyright 1995-2011 Perforce Software.  All rights reserved.
        Rev. P4/NTX86/2011.1/393975 (2011/12/16).
-    """
+       """
     global _p4_version_string
     if not _p4_version_string:
         a = p4_read_pipe_lines(["-V"])
         _p4_version_string = a[-1].rstrip()
     return _p4_version_string
 
+
 def p4_integrate(src, dest):
     p4_system(["integrate", "-Dt", wildcard_encode(src), wildcard_encode(dest)])
 
+
 def p4_sync(f, *options):
     p4_system(["sync"] + list(options) + [wildcard_encode(f)])
 
+
 def p4_add(f):
-    # forcibly add file names with wildcards
+    """Forcibly add file names with wildcards."""
     if wildcard_present(f):
         p4_system(["add", "-f", f])
     else:
         p4_system(["add", f])
 
+
 def p4_delete(f):
     p4_system(["delete", wildcard_encode(f)])
 
+
 def p4_edit(f, *options):
     p4_system(["edit"] + list(options) + [wildcard_encode(f)])
 
+
 def p4_revert(f):
     p4_system(["revert", wildcard_encode(f)])
 
+
 def p4_reopen(type, f):
     p4_system(["reopen", "-t", type, wildcard_encode(f)])
 
+
 def p4_reopen_in_change(changelist, files):
     cmd = ["reopen", "-c", str(changelist)] + files
     p4_system(cmd)
 
+
 def p4_move(src, dest):
     p4_system(["move", "-k", wildcard_encode(src), wildcard_encode(dest)])
 
+
 def p4_last_change():
     results = p4CmdList(["changes", "-m", "1"], skip_info=True)
     return int(results[0]['change'])
 
+
 def p4_describe(change, shelved=False):
-    """Make sure it returns a valid result by checking for
-       the presence of field "time".  Return a dict of the
-       results."""
+    """Make sure it returns a valid result by checking for the presence of
+       field "time".
+
+       Return a dict of the results.
+       """
 
     cmd = ["describe", "-s"]
     if shelved:
@@ -482,12 +610,11 @@ def p4_describe(change, shelved=False):
 
     return d
 
-#
-# Canonicalize the p4 type and return a tuple of the
-# base type, plus any modifiers.  See "p4 help filetypes"
-# for a list and explanation.
-#
+
 def split_p4_type(p4type):
+    """Canonicalize the p4 type and return a tuple of the base type, plus any
+       modifiers.  See "p4 help filetypes" for a list and explanation.
+       """
 
     p4_filetypes_historical = {
         "ctempobj": "binary+Sw",
@@ -517,18 +644,19 @@ def split_p4_type(p4type):
         mods = s[1]
     return (base, mods)
 
-#
-# return the raw p4 type of a file (text, text+ko, etc)
-#
+
 def p4_type(f):
+    """Return the raw p4 type of a file (text, text+ko, etc)."""
+
     results = p4CmdList(["fstat", "-T", "headType", wildcard_encode(f)])
     return results[0]['headType']
 
-#
-# Given a type base and modifier, return a regexp matching
-# the keywords that can be expanded in the file
-#
+
 def p4_keywords_regexp_for_type(base, type_mods):
+    """Given a type base and modifier, return a regexp matching the keywords
+       that can be expanded in the file.
+       """
+
     if base in ("text", "unicode", "binary"):
         if "ko" in type_mods:
             return re_ko_keywords
@@ -539,21 +667,23 @@ def p4_keywords_regexp_for_type(base, type_mods):
     else:
         return None
 
-#
-# Given a file, return a regexp matching the possible
-# RCS keywords that will be expanded, or None for files
-# with kw expansion turned off.
-#
+
 def p4_keywords_regexp_for_file(file):
+    """Given a file, return a regexp matching the possible RCS keywords that
+       will be expanded, or None for files with kw expansion turned off.
+       """
+
     if not os.path.exists(file):
         return None
     else:
-        (type_base, type_mods) = split_p4_type(p4_type(file))
+        type_base, type_mods = split_p4_type(p4_type(file))
         return p4_keywords_regexp_for_type(type_base, type_mods)
 
+
 def setP4ExecBit(file, mode):
-    # Reopens an already open file and changes the execute bit to match
-    # the execute bit setting in the passed in mode.
+    """Reopens an already open file and changes the execute bit to match the
+       execute bit setting in the passed in mode.
+       """
 
     p4Type = "+x"
 
@@ -566,8 +696,9 @@ def setP4ExecBit(file, mode):
 
     p4_reopen(p4Type, file)
 
+
 def getP4OpenedType(file):
-    # Returns the perforce file type for the given file.
+    """Returns the perforce file type for the given file."""
 
     result = p4_read_pipe(["opened", wildcard_encode(file)])
     match = re.match(".*\((.+)\)( \*exclusive\*)?\r?$", result)
@@ -576,8 +707,10 @@ def getP4OpenedType(file):
     else:
         die("Could not determine file type for %s (result: '%s')" % (file, result))
 
-# Return the set of all p4 labels
+
 def getP4Labels(depotPaths):
+    """Return the set of all p4 labels."""
+
     labels = set()
     if not isinstance(depotPaths, list):
         depotPaths = [depotPaths]
@@ -588,34 +721,39 @@ def getP4Labels(depotPaths):
 
     return labels
 
-# Return the set of all git tags
+
 def getGitTags():
+    """Return the set of all git tags."""
+
     gitTags = set()
     for line in read_pipe_lines(["git", "tag"]):
         tag = line.strip()
         gitTags.add(tag)
     return gitTags
 
+
 _diff_tree_pattern = None
 
+
 def parseDiffTreeEntry(entry):
     """Parses a single diff tree entry into its component elements.
 
-    See git-diff-tree(1) manpage for details about the format of the diff
-    output. This method returns a dictionary with the following elements:
-
-    src_mode - The mode of the source file
-    dst_mode - The mode of the destination file
-    src_sha1 - The sha1 for the source file
-    dst_sha1 - The sha1 fr the destination file
-    status - The one letter status of the diff (i.e. 'A', 'M', 'D', etc)
-    status_score - The score for the status (applicable for 'C' and 'R'
-                   statuses). This is None if there is no score.
-    src - The path for the source file.
-    dst - The path for the destination file. This is only present for
-          copy or renames. If it is not present, this is None.
-
-    If the pattern is not matched, None is returned."""
+       See git-diff-tree(1) manpage for details about the format of the diff
+       output. This method returns a dictionary with the following elements:
+
+       src_mode - The mode of the source file
+       dst_mode - The mode of the destination file
+       src_sha1 - The sha1 for the source file
+       dst_sha1 - The sha1 fr the destination file
+       status - The one letter status of the diff (i.e. 'A', 'M', 'D', etc)
+       status_score - The score for the status (applicable for 'C' and 'R'
+                      statuses). This is None if there is no score.
+       src - The path for the source file.
+       dst - The path for the destination file. This is only present for
+             copy or renames. If it is not present, this is None.
+
+       If the pattern is not matched, None is returned.
+       """
 
     global _diff_tree_pattern
     if not _diff_tree_pattern:
@@ -635,41 +773,55 @@ def parseDiffTreeEntry(entry):
         }
     return None
 
+
 def isModeExec(mode):
-    # Returns True if the given git mode represents an executable file,
-    # otherwise False.
+    """Returns True if the given git mode represents an executable file,
+       otherwise False.
+       """
     return mode[-3:] == "755"
 
+
 class P4Exception(Exception):
-    """ Base class for exceptions from the p4 client """
+    """Base class for exceptions from the p4 client."""
+
     def __init__(self, exit_code):
         self.p4ExitCode = exit_code
 
+
 class P4ServerException(P4Exception):
-    """ Base class for exceptions where we get some kind of marshalled up result from the server """
+    """Base class for exceptions where we get some kind of marshalled up result
+       from the server.
+       """
+
     def __init__(self, exit_code, p4_result):
         super(P4ServerException, self).__init__(exit_code)
         self.p4_result = p4_result
         self.code = p4_result[0]['code']
         self.data = p4_result[0]['data']
 
+
 class P4RequestSizeException(P4ServerException):
-    """ One of the maxresults or maxscanrows errors """
+    """One of the maxresults or maxscanrows errors."""
+
     def __init__(self, exit_code, p4_result, limit):
         super(P4RequestSizeException, self).__init__(exit_code, p4_result)
         self.limit = limit
 
+
 class P4CommandException(P4Exception):
-    """ Something went wrong calling p4 which means we have to give up """
+    """Something went wrong calling p4 which means we have to give up."""
+
     def __init__(self, msg):
         self.msg = msg
 
     def __str__(self):
         return self.msg
 
+
 def isModeExecChanged(src_mode, dst_mode):
     return isModeExec(src_mode) != isModeExec(dst_mode)
 
+
 def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
         errors_as_exceptions=False, *k, **kw):
 
@@ -702,11 +854,12 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
             if bytes is not str:
                 # Decode unmarshalled dict to use str keys and values, except for:
                 #   - `data` which may contain arbitrary binary data
-                #   - `depotFile[0-9]*`, `path`, or `clientFile` which may contain non-UTF8 encoded text
+                #   - `desc` or `FullName` which may contain non-UTF8 encoded text handled below, eagerly converted to bytes
+                #   - `depotFile[0-9]*`, `path`, or `clientFile` which may contain non-UTF8 encoded text, handled by decode_path()
                 decoded_entry = {}
                 for key, value in entry.items():
                     key = key.decode()
-                    if isinstance(value, bytes) and not (key in ('data', 'path', 'clientFile') or key.startswith('depotFile')):
+                    if isinstance(value, bytes) and not (key in ('data', 'desc', 'FullName', 'path', 'clientFile') or key.startswith('depotFile')):
                         value = value.decode()
                     decoded_entry[key] = value
                 # Parse out data if it's an error response
@@ -716,6 +869,10 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
             if skip_info:
                 if 'code' in entry and entry['code'] == 'info':
                     continue
+            if 'desc' in entry:
+                entry['desc'] = metadata_stream_to_writable_bytes(entry['desc'])
+            if 'FullName' in entry:
+                entry['FullName'] = metadata_stream_to_writable_bytes(entry['FullName'])
             if cb is not None:
                 cb(entry)
             else:
@@ -746,12 +903,14 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
 
     return result
 
+
 def p4Cmd(cmd, *k, **kw):
     list = p4CmdList(cmd, *k, **kw)
     result = {}
     for entry in list:
         result.update(entry)
-    return result;
+    return result
+
 
 def p4Where(depotPath):
     if not depotPath.endswith("/"):
@@ -773,7 +932,7 @@ def p4Where(depotPath):
             if data[:space] == depotPath:
                 output = entry
                 break
-    if output == None:
+    if output is None:
         return ""
     if output["code"] == "error":
         return ""
@@ -789,48 +948,54 @@ def p4Where(depotPath):
         clientPath = clientPath[:-3]
     return clientPath
 
+
 def currentGitBranch():
     return read_pipe_text(["git", "symbolic-ref", "--short", "-q", "HEAD"])
 
+
 def isValidGitDir(path):
-    return git_dir(path) != None
+    return git_dir(path) is not None
+
 
 def parseRevision(ref):
     return read_pipe(["git", "rev-parse", ref]).strip()
 
+
 def branchExists(ref):
     rev = read_pipe(["git", "rev-parse", "-q", "--verify", ref],
                      ignore_error=True)
     return len(rev) > 0
 
+
 def extractLogMessageFromGitCommit(commit):
     logMessage = ""
 
-    ## fixme: title is first line of commit, not 1st paragraph.
+    # fixme: title is first line of commit, not 1st paragraph.
     foundTitle = False
     for log in read_pipe_lines(["git", "cat-file", "commit", commit]):
-       if not foundTitle:
-           if len(log) == 1:
-               foundTitle = True
-           continue
+        if not foundTitle:
+            if len(log) == 1:
+                foundTitle = True
+            continue
 
-       logMessage += log
+        logMessage += log
     return logMessage
 
+
 def extractSettingsGitLog(log):
     values = {}
     for line in log.split("\n"):
         line = line.strip()
-        m = re.search (r"^ *\[git-p4: (.*)\]$", line)
+        m = re.search(r"^ *\[git-p4: (.*)\]$", line)
         if not m:
             continue
 
-        assignments = m.group(1).split (':')
+        assignments = m.group(1).split(':')
         for a in assignments:
-            vals = a.split ('=')
+            vals = a.split('=')
             key = vals[0].strip()
-            val = ('='.join (vals[1:])).strip()
-            if val.endswith ('\"') and val.startswith('"'):
+            val = ('='.join(vals[1:])).strip()
+            if val.endswith('\"') and val.startswith('"'):
                 val = val[1:-1]
 
             values[key] = val
@@ -842,41 +1007,49 @@ def extractSettingsGitLog(log):
         values['depot-paths'] = paths.split(',')
     return values
 
+
 def gitBranchExists(branch):
     proc = subprocess.Popen(["git", "rev-parse", branch],
-                            stderr=subprocess.PIPE, stdout=subprocess.PIPE);
-    return proc.wait() == 0;
+                            stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+    return proc.wait() == 0
+
 
 def gitUpdateRef(ref, newvalue):
     subprocess.check_call(["git", "update-ref", ref, newvalue])
 
+
 def gitDeleteRef(ref):
     subprocess.check_call(["git", "update-ref", "-d", ref])
 
+
 _gitConfig = {}
 
+
 def gitConfig(key, typeSpecifier=None):
     if key not in _gitConfig:
-        cmd = [ "git", "config" ]
+        cmd = ["git", "config"]
         if typeSpecifier:
-            cmd += [ typeSpecifier ]
-        cmd += [ key ]
+            cmd += [typeSpecifier]
+        cmd += [key]
         s = read_pipe(cmd, ignore_error=True)
         _gitConfig[key] = s.strip()
     return _gitConfig[key]
 
+
 def gitConfigBool(key):
     """Return a bool, using git config --bool.  It is True only if the
        variable is set to true, and False if set to false or not present
-       in the config."""
+       in the config.
+       """
 
     if key not in _gitConfig:
         _gitConfig[key] = gitConfig(key, '--bool') == "true"
     return _gitConfig[key]
 
+
 def gitConfigInt(key):
     if key not in _gitConfig:
-        cmd = [ "git", "config", "--int", key ]
+        cmd = ["git", "config", "--int", key]
         s = read_pipe(cmd, ignore_error=True)
         v = s.strip()
         try:
@@ -885,6 +1058,7 @@ def gitConfigInt(key):
             _gitConfig[key] = None
     return _gitConfig[key]
 
+
 def gitConfigList(key):
     if key not in _gitConfig:
         s = read_pipe(["git", "config", "--get-all", key], ignore_error=True)
@@ -893,12 +1067,43 @@ def gitConfigList(key):
             _gitConfig[key] = []
     return _gitConfig[key]
 
+def fullP4Ref(incomingRef, importIntoRemotes=True):
+    """Standardize a given provided p4 ref value to a full git ref:
+         refs/foo/bar/branch -> use it exactly
+         p4/branch -> prepend refs/remotes/ or refs/heads/
+         branch -> prepend refs/remotes/p4/ or refs/heads/p4/"""
+    if incomingRef.startswith("refs/"):
+        return incomingRef
+    if importIntoRemotes:
+        prepend = "refs/remotes/"
+    else:
+        prepend = "refs/heads/"
+    if not incomingRef.startswith("p4/"):
+        prepend += "p4/"
+    return prepend + incomingRef
+
+def shortP4Ref(incomingRef, importIntoRemotes=True):
+    """Standardize to a "short ref" if possible:
+         refs/foo/bar/branch -> ignore
+         refs/remotes/p4/branch or refs/heads/p4/branch -> shorten
+         p4/branch -> shorten"""
+    if importIntoRemotes:
+        longprefix = "refs/remotes/p4/"
+    else:
+        longprefix = "refs/heads/p4/"
+    if incomingRef.startswith(longprefix):
+        return incomingRef[len(longprefix):]
+    if incomingRef.startswith("p4/"):
+        return incomingRef[3:]
+    return incomingRef
+
 def p4BranchesInGit(branchesAreInRemotes=True):
     """Find all the branches whose names start with "p4/", looking
        in remotes or heads as specified by the argument.  Return
        a dictionary of { branch: revision } for each one found.
        The branch names are the short names, without any
-       "p4/" prefix."""
+       "p4/" prefix.
+       """
 
     branches = {}
 
@@ -925,10 +1130,11 @@ def p4BranchesInGit(branchesAreInRemotes=True):
 
     return branches
 
+
 def branch_exists(branch):
     """Make sure that the given ref name really exists."""
 
-    cmd = [ "git", "rev-parse", "--symbolic", "--verify", branch ]
+    cmd = ["git", "rev-parse", "--symbolic", "--verify", branch]
     p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     out, _ = p.communicate()
     out = decode_text_stream(out)
@@ -937,7 +1143,8 @@ def branch_exists(branch):
     # expect exactly one line of output: the branch name
     return out.rstrip() == branch
 
-def findUpstreamBranchPoint(head = "HEAD"):
+
+def findUpstreamBranchPoint(head="HEAD"):
     branches = p4BranchesInGit()
     # map from depot-path to branch name
     branchByDepotPath = {}
@@ -946,8 +1153,12 @@ def findUpstreamBranchPoint(head = "HEAD"):
         log = extractLogMessageFromGitCommit(tip)
         settings = extractSettingsGitLog(log)
         if "depot-paths" in settings:
+            git_branch = "remotes/p4/" + branch
             paths = ",".join(settings["depot-paths"])
-            branchByDepotPath[paths] = "remotes/p4/" + branch
+            branchByDepotPath[paths] = git_branch
+            if "change" in settings:
+                paths = paths + ";" + settings["change"]
+                branchByDepotPath[paths] = git_branch
 
     settings = None
     parent = 0
@@ -957,6 +1168,10 @@ def findUpstreamBranchPoint(head = "HEAD"):
         settings = extractSettingsGitLog(log)
         if "depot-paths" in settings:
             paths = ",".join(settings["depot-paths"])
+            if "change" in settings:
+                expaths = paths + ";" + settings["change"]
+                if expaths in branchByDepotPath:
+                    return [branchByDepotPath[expaths], settings]
             if paths in branchByDepotPath:
                 return [branchByDepotPath[paths], settings]
 
@@ -964,7 +1179,8 @@ def findUpstreamBranchPoint(head = "HEAD"):
 
     return ["", settings]
 
-def createOrUpdateBranchesFromOrigin(localRefPrefix = "refs/remotes/p4/", silent=True):
+
+def createOrUpdateBranchesFromOrigin(localRefPrefix="refs/remotes/p4/", silent=True):
     if not silent:
         print("Creating/updating branch(es) in %s based on origin branch(es)"
                % localRefPrefix)
@@ -981,8 +1197,7 @@ def createOrUpdateBranchesFromOrigin(localRefPrefix = "refs/remotes/p4/", silent
         originHead = line
 
         original = extractSettingsGitLog(extractLogMessageFromGitCommit(originHead))
-        if ('depot-paths' not in original
-            or 'change' not in original):
+        if 'depot-paths' not in original or 'change' not in original:
             continue
 
         update = False
@@ -1011,8 +1226,9 @@ def createOrUpdateBranchesFromOrigin(localRefPrefix = "refs/remotes/p4/", silent
         if update:
             system(["git", "update-ref", remoteHead, originHead])
 
+
 def originP4BranchesExist():
-        return gitBranchExists("origin") or gitBranchExists("origin/p4") or gitBranchExists("origin/p4/master")
+    return gitBranchExists("origin") or gitBranchExists("origin/p4") or gitBranchExists("origin/p4/master")
 
 
 def p4ParseNumericChangeRange(parts):
@@ -1024,12 +1240,14 @@ def p4ParseNumericChangeRange(parts):
 
     return (changeStart, changeEnd)
 
+
 def chooseBlockSize(blockSize):
     if blockSize:
         return blockSize
     else:
         return defaultBlockSize
 
+
 def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
     assert depotPaths
 
@@ -1047,7 +1265,7 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
         parts = changeRange.split(',')
         assert len(parts) == 2
         try:
-            (changeStart, changeEnd) = p4ParseNumericChangeRange(parts)
+            changeStart, changeEnd = p4ParseNumericChangeRange(parts)
             block_size = chooseBlockSize(requestedBlockSize)
         except ValueError:
             changeStart = parts[0][1:]
@@ -1085,7 +1303,8 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
             else:
                 block_size = max(2, block_size // 2)
 
-            if verbose: print("block size error, retrying with block size {0}".format(block_size))
+            if verbose:
+                print("block size error, retrying with block size {0}".format(block_size))
             continue
         except P4Exception as e:
             die('Error retrieving changes description ({0})'.format(e.p4ExitCode))
@@ -1107,21 +1326,25 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
     changes = sorted(changes)
     return changes
 
+
 def p4PathStartsWith(path, prefix):
-    # This method tries to remedy a potential mixed-case issue:
-    #
-    # If UserA adds  //depot/DirA/file1
-    # and UserB adds //depot/dira/file2
-    #
-    # we may or may not have a problem. If you have core.ignorecase=true,
-    # we treat DirA and dira as the same directory
+    """This method tries to remedy a potential mixed-case issue:
+
+       If UserA adds  //depot/DirA/file1
+       and UserB adds //depot/dira/file2
+
+       we may or may not have a problem. If you have core.ignorecase=true,
+       we treat DirA and dira as the same directory.
+       """
     if gitConfigBool("core.ignorecase"):
         return path.lower().startswith(prefix.lower())
     return path.startswith(prefix)
 
+
 def getClientSpec():
     """Look at the p4 client spec, create a View() object that contains
-       all the mappings, and return it."""
+       all the mappings, and return it.
+       """
 
     specList = p4CmdList(["client", "-o"])
     if len(specList) != 1:
@@ -1135,7 +1358,7 @@ def getClientSpec():
     client_name = entry["Client"]
 
     # just the keys that start with "View"
-    view_keys = [ k for k in entry.keys() if k.startswith("View") ]
+    view_keys = [k for k in entry.keys() if k.startswith("View")]
 
     # hold this new View
     view = View(client_name)
@@ -1149,6 +1372,7 @@ def getClientSpec():
 
     return view
 
+
 def getClientRoot():
     """Grab the client directory."""
 
@@ -1162,12 +1386,15 @@ def getClientRoot():
 
     return entry["Root"]
 
-#
-# P4 wildcards are not allowed in filenames.  P4 complains
-# if you simply add them, but you can force it with "-f", in
-# which case it translates them into %xx encoding internally.
-#
+
 def wildcard_decode(path):
+    """Decode P4 wildcards into %xx encoding
+
+       P4 wildcards are not allowed in filenames.  P4 complains if you simply
+       add them, but you can force it with "-f", in which case it translates
+       them into %xx encoding internally.
+       """
+
     # Search for and fix just these four characters.  Do % last so
     # that fixing it does not inadvertently create new %-escapes.
     # Cannot have * in a filename in windows; untested as to
@@ -1179,7 +1406,10 @@ def wildcard_decode(path):
                .replace("%25", "%")
     return path
 
+
 def wildcard_encode(path):
+    """Encode %xx coded wildcards into P4 coding."""
+
     # do % first to avoid double-encoding the %s introduced here
     path = path.replace("%", "%25") \
                .replace("*", "%2A") \
@@ -1187,10 +1417,12 @@ def wildcard_encode(path):
                .replace("@", "%40")
     return path
 
+
 def wildcard_present(path):
     m = re.search("[*#@%]", path)
     return m is not None
 
+
 class LargeFileSystem(object):
     """Base class for large file system support."""
 
@@ -1199,13 +1431,15 @@ class LargeFileSystem(object):
         self.writeToGitStream = writeToGitStream
 
     def generatePointer(self, cloneDestination, contentFile):
-        """Return the content of a pointer file that is stored in Git instead of
-           the actual content."""
+        """Return the content of a pointer file that is stored in Git instead
+           of the actual content.
+           """
         assert False, "Method 'generatePointer' required in " + self.__class__.__name__
 
     def pushFile(self, localLargeFile):
         """Push the actual content which is not stored in the Git repository to
-           a server."""
+           a server.
+           """
         assert False, "Method 'pushFile' required in " + self.__class__.__name__
 
     def hasLargeFileExtension(self, relPath):
@@ -1253,10 +1487,11 @@ class LargeFileSystem(object):
     def processContent(self, git_mode, relPath, contents):
         """Processes the content of git fast import. This method decides if a
            file is stored in the large file system and handles all necessary
-           steps."""
+           steps.
+           """
         if self.exceedsLargeFileThreshold(relPath, contents) or self.hasLargeFileExtension(relPath):
             contentTempFile = self.generateTempFile(contents)
-            (pointer_git_mode, contents, localLargeFile) = self.generatePointer(contentTempFile)
+            pointer_git_mode, contents, localLargeFile = self.generatePointer(contentTempFile)
             if pointer_git_mode:
                 git_mode = pointer_git_mode
             if localLargeFile:
@@ -1272,12 +1507,14 @@ class LargeFileSystem(object):
                     sys.stderr.write("%s moved to large file system (%s)\n" % (relPath, localLargeFile))
         return (git_mode, contents)
 
+
 class MockLFS(LargeFileSystem):
     """Mock large file system for testing."""
 
     def generatePointer(self, contentFile):
         """The pointer content is the original content prefixed with "pointer-".
-           The local filename of the large file storage is derived from the file content.
+           The local filename of the large file storage is derived from the
+           file content.
            """
         with open(contentFile, 'r') as f:
             content = next(f)
@@ -1287,17 +1524,19 @@ class MockLFS(LargeFileSystem):
             return (gitMode, pointerContents, localLargeFile)
 
     def pushFile(self, localLargeFile):
-        """The remote filename of the large file storage is the same as the local
-           one but in a different directory.
+        """The remote filename of the large file storage is the same as the
+           local one but in a different directory.
            """
         remotePath = os.path.join(os.path.dirname(localLargeFile), '..', 'remote')
         if not os.path.exists(remotePath):
             os.makedirs(remotePath)
         shutil.copyfile(localLargeFile, os.path.join(remotePath, os.path.basename(localLargeFile)))
 
+
 class GitLFS(LargeFileSystem):
     """Git LFS as backend for the git-p4 large file system.
-       See https://git-lfs.github.com/ for details."""
+       See https://git-lfs.github.com/ for details.
+       """
 
     def __init__(self, *args):
         LargeFileSystem.__init__(self, *args)
@@ -1383,9 +1622,10 @@ class GitLFS(LargeFileSystem):
         else:
             return LargeFileSystem.processContent(self, git_mode, relPath, contents)
 
+
 class Command:
-    delete_actions = ( "delete", "move/delete", "purge" )
-    add_actions = ( "add", "branch", "move/add" )
+    delete_actions = ("delete", "move/delete", "purge")
+    add_actions = ("add", "branch", "move/add")
 
     def __init__(self):
         self.usage = "usage: %prog [options]"
@@ -1398,6 +1638,7 @@ class Command:
             setattr(self, attr, value)
         return getattr(self, attr)
 
+
 class P4UserMap:
     def __init__(self):
         self.userMapFromPerforceServer = False
@@ -1415,7 +1656,7 @@ class P4UserMap:
         die("Could not find your p4 user id")
 
     def p4UserIsMe(self, p4User):
-        # return True if the given p4 user is actually me
+        """Return True if the given p4 user is actually me."""
         me = self.p4UserId()
         if not p4User or p4User != me:
             return False
@@ -1435,7 +1676,13 @@ class P4UserMap:
         for output in p4CmdList(["users"]):
             if "User" not in output:
                 continue
-            self.users[output["User"]] = output["FullName"] + " <" + output["Email"] + ">"
+            # "FullName" is bytes. "Email" on the other hand might be bytes
+            # or unicode string depending on whether we are running under
+            # python2 or python3. To support
+            # git-p4.metadataDecodingStrategy=fallback, self.users dict values
+            # are always bytes, ready to be written to git.
+            emailbytes = metadata_stream_to_writable_bytes(output["Email"])
+            self.users[output["User"]] = output["FullName"] + b" <" + emailbytes + b">"
             self.emails[output["Email"]] = output["User"]
 
         mapUserConfigRegex = re.compile(r"^\s*(\S+)\s*=\s*(.+)\s*<(\S+)>\s*$", re.VERBOSE)
@@ -1445,29 +1692,32 @@ class P4UserMap:
                 user = mapUser[0][0]
                 fullname = mapUser[0][1]
                 email = mapUser[0][2]
-                self.users[user] = fullname + " <" + email + ">"
+                fulluser = fullname + " <" + email + ">"
+                self.users[user] = metadata_stream_to_writable_bytes(fulluser)
                 self.emails[email] = user
 
-        s = ''
+        s = b''
         for (key, val) in self.users.items():
-            s += "%s\t%s\n" % (key.expandtabs(1), val.expandtabs(1))
+            keybytes = metadata_stream_to_writable_bytes(key)
+            s += b"%s\t%s\n" % (keybytes.expandtabs(1), val.expandtabs(1))
 
-        open(self.getUserCacheFilename(), 'w').write(s)
+        open(self.getUserCacheFilename(), 'wb').write(s)
         self.userMapFromPerforceServer = True
 
     def loadUserMapFromCache(self):
         self.users = {}
         self.userMapFromPerforceServer = False
         try:
-            cache = open(self.getUserCacheFilename(), 'r')
+            cache = open(self.getUserCacheFilename(), 'rb')
             lines = cache.readlines()
             cache.close()
             for line in lines:
-                entry = line.strip().split("\t")
-                self.users[entry[0]] = entry[1]
+                entry = line.strip().split(b"\t")
+                self.users[entry[0].decode('utf_8')] = entry[1]
         except IOError:
             self.getUserMapFromPerforceServer()
 
+
 class P4Submit(Command, P4UserMap):
 
     conflict_behavior_choices = ("ask", "skip", "quit")
@@ -1560,20 +1810,20 @@ class P4Submit(Command, P4UserMap):
             die("You have files opened with perforce! Close them before starting the sync.")
 
     def separate_jobs_from_description(self, message):
-        """Extract and return a possible Jobs field in the commit
-           message.  It goes into a separate section in the p4 change
-           specification.
+        """Extract and return a possible Jobs field in the commit message.  It
+           goes into a separate section in the p4 change specification.
 
-           A jobs line starts with "Jobs:" and looks like a new field
-           in a form.  Values are white-space separated on the same
-           line or on following lines that start with a tab.
+           A jobs line starts with "Jobs:" and looks like a new field in a
+           form.  Values are white-space separated on the same line or on
+           following lines that start with a tab.
 
-           This does not parse and extract the full git commit message
-           like a p4 form.  It just sees the Jobs: line as a marker
-           to pass everything from then on directly into the p4 form,
-           but outside the description section.
+           This does not parse and extract the full git commit message like a
+           p4 form.  It just sees the Jobs: line as a marker to pass everything
+           from then on directly into the p4 form, but outside the description
+           section.
 
-           Return a tuple (stripped log message, jobs string)."""
+           Return a tuple (stripped log message, jobs string).
+           """
 
         m = re.search(r'^Jobs:', message, re.MULTILINE)
         if m is None:
@@ -1584,9 +1834,10 @@ class P4Submit(Command, P4UserMap):
         return (stripped_message, jobtext)
 
     def prepareLogMessage(self, template, message, jobs):
-        """Edits the template returned from "p4 change -o" to insert
-           the message in the Description field, and the jobs text in
-           the Jobs field."""
+        """Edits the template returned from "p4 change -o" to insert the
+           message in the Description field, and the jobs text in the Jobs
+           field.
+           """
         result = ""
 
         inDescriptionSection = False
@@ -1616,8 +1867,10 @@ class P4Submit(Command, P4UserMap):
         return result
 
     def patchRCSKeywords(self, file, regexp):
-        # Attempt to zap the RCS keywords in a p4 controlled file matching the given regex
-        (handle, outFileName) = tempfile.mkstemp(dir='.')
+        """Attempt to zap the RCS keywords in a p4 controlled file matching the
+           given regex.
+           """
+        handle, outFileName = tempfile.mkstemp(dir='.')
         try:
             with os.fdopen(handle, "wb") as outFile, open(file, "rb") as inFile:
                 for line in inFile.readlines():
@@ -1633,21 +1886,23 @@ class P4Submit(Command, P4UserMap):
 
         print("Patched up RCS keywords in %s" % file)
 
-    def p4UserForCommit(self,id):
-        # Return the tuple (perforce user,git email) for a given git commit id
+    def p4UserForCommit(self, id):
+        """Return the tuple (perforce user,git email) for a given git commit
+           id.
+           """
         self.getUserMapFromPerforceServer()
         gitEmail = read_pipe(["git", "log", "--max-count=1",
                               "--format=%ae", id])
         gitEmail = gitEmail.strip()
         if gitEmail not in self.emails:
-            return (None,gitEmail)
+            return (None, gitEmail)
         else:
-            return (self.emails[gitEmail],gitEmail)
+            return (self.emails[gitEmail], gitEmail)
 
-    def checkValidP4Users(self,commits):
-        # check if any git authors cannot be mapped to p4 users
+    def checkValidP4Users(self, commits):
+        """Check if any git authors cannot be mapped to p4 users."""
         for id in commits:
-            (user,email) = self.p4UserForCommit(id)
+            user, email = self.p4UserForCommit(id)
             if not user:
                 msg = "Cannot find p4 user for email %s in commit %s." % (email, id)
                 if gitConfigBool("git-p4.allowMissingP4Users"):
@@ -1656,10 +1911,12 @@ class P4Submit(Command, P4UserMap):
                     die("Error: %s\nSet git-p4.allowMissingP4Users to true to allow this." % msg)
 
     def lastP4Changelist(self):
-        # Get back the last changelist number submitted in this client spec. This
-        # then gets used to patch up the username in the change. If the same
-        # client spec is being used by multiple processes then this might go
-        # wrong.
+        """Get back the last changelist number submitted in this client spec.
+
+           This then gets used to patch up the username in the change. If the
+           same client spec is being used by multiple processes then this might
+           go wrong.
+           """
         results = p4CmdList(["client", "-o"])        # find the current client
         client = None
         for r in results:
@@ -1675,14 +1932,16 @@ class P4Submit(Command, P4UserMap):
         die("Could not get changelist number for last submit - cannot patch up user details")
 
     def modifyChangelistUser(self, changelist, newUser):
-        # fixup the user field of a changelist after it has been submitted.
+        """Fixup the user field of a changelist after it has been submitted."""
         changes = p4CmdList(["change", "-o", changelist])
         if len(changes) != 1:
             die("Bad output from p4 change modifying %s to user %s" %
                 (changelist, newUser))
 
         c = changes[0]
-        if c['User'] == newUser: return   # nothing to do
+        if c['User'] == newUser:
+            # Nothing to do
+            return
         c['User'] = newUser
         # p4 does not understand format version 3 and above
         input = marshal.dumps(c, 2)
@@ -1698,8 +1957,9 @@ class P4Submit(Command, P4UserMap):
         die("Could not modify user field of changelist %s to %s" % (changelist, newUser))
 
     def canChangeChangelists(self):
-        # check to see if we have p4 admin or super-user permissions, either of
-        # which are required to modify changelists.
+        """Check to see if we have p4 admin or super-user permissions, either
+           of which are required to modify changelists.
+           """
         results = p4CmdList(["protects", self.depotPath])
         for r in results:
             if 'perm' in r:
@@ -1711,13 +1971,15 @@ class P4Submit(Command, P4UserMap):
 
     def prepareSubmitTemplate(self, changelist=None):
         """Run "p4 change -o" to grab a change specification template.
+
            This does not use "p4 -G", as it is nice to keep the submission
            template in original order, since a human might edit it.
 
            Remove lines in the Files section that show changes to files
-           outside the depot path we're committing into."""
+           outside the depot path we're committing into.
+           """
 
-        [upstream, settings] = findUpstreamBranchPoint()
+        upstream, settings = findUpstreamBranchPoint()
 
         template = """\
 # A Perforce Change Specification.
@@ -1778,8 +2040,10 @@ class P4Submit(Command, P4UserMap):
         return template
 
     def edit_template(self, template_file):
-        """Invoke the editor to let the user change the submission
-           message.  Return true if okay to continue with the submit."""
+        """Invoke the editor to let the user change the submission message.
+
+           Return true if okay to continue with the submit.
+           """
 
         # if configured to skip the editing part, just submit
         if gitConfigBool("git-p4.skipSubmitEdit"):
@@ -1838,7 +2102,9 @@ class P4Submit(Command, P4UserMap):
                     for line in f.readlines():
                         newdiff += "+" + line
                 except UnicodeDecodeError:
-                    pass # Found non-text data and skip, since diff description should only include text
+                    # Found non-text data and skip, since diff description
+                    # should only include text
+                    pass
                 f.close()
 
         return (diff + newdiff).replace('\r\n', '\n')
@@ -1849,7 +2115,7 @@ class P4Submit(Command, P4UserMap):
         print("Applying", read_pipe(["git", "show", "-s",
                                      "--format=format:%h %s", id]))
 
-        (p4User, gitEmail) = self.p4UserForCommit(id)
+        p4User, gitEmail = self.p4UserForCommit(id)
 
         diff = read_pipe_lines(
             ["git", "diff-tree", "-r"] + self.diffOpts + ["{}^".format(id), id])
@@ -1956,8 +2222,8 @@ class P4Submit(Command, P4UserMap):
                     if regexp:
                         # this file is a possibility...look for RCS keywords.
                         for line in read_pipe_lines(
-                            ["git", "diff", "%s^..%s" % (id, id), file],
-                            raw=True):
+                                ["git", "diff", "%s^..%s" % (id, id), file],
+                                raw=True):
                             if regexp.search(line):
                                 if verbose:
                                     print("got keyword match on %s in %s in %s" % (regex.pattern, line, file))
@@ -2014,13 +2280,13 @@ class P4Submit(Command, P4UserMap):
         #
         logMessage = extractLogMessageFromGitCommit(id)
         logMessage = logMessage.strip()
-        (logMessage, jobs) = self.separate_jobs_from_description(logMessage)
+        logMessage, jobs = self.separate_jobs_from_description(logMessage)
 
         template = self.prepareSubmitTemplate(update_shelve)
         submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
 
         if self.preserveUser:
-           submitTemplate += "\n######## Actual user %s, modified after commit\n" % p4User
+            submitTemplate += "\n######## Actual user %s, modified after commit\n" % p4User
 
         if self.checkAuthorship and not self.p4UserIsMe(p4User):
             submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
@@ -2032,7 +2298,7 @@ class P4Submit(Command, P4UserMap):
             submitTemplate += separatorLine
             submitTemplate += self.get_diff_description(editedFiles, filesToAdd, symlinks)
 
-        (handle, fileName) = tempfile.mkstemp()
+        handle, fileName = tempfile.mkstemp()
         tmpFile = os.fdopen(handle, "w+b")
         if self.isWindows:
             submitTemplate = submitTemplate.replace("\n", "\r\n")
@@ -2059,13 +2325,13 @@ class P4Submit(Command, P4UserMap):
                 print("  " + self.clientPath)
                 print("")
                 print("To submit, use \"p4 submit\" to write a new description,")
-                print("or \"p4 submit -i <%s\" to use the one prepared by" \
+                print("or \"p4 submit -i <%s\" to use the one prepared by"
                       " \"git p4\"." % fileName)
                 print("You can delete the file \"%s\" when finished." % fileName)
 
                 if self.preserveUser and p4User and not self.p4UserIsMe(p4User):
-                    print("To preserve change ownership by user %s, you must\n" \
-                          "do \"p4 change -f <change>\" after submitting and\n" \
+                    print("To preserve change ownership by user %s, you must\n"
+                          "do \"p4 change -f <change>\" after submitting and\n"
                           "edit the User field.")
                 if pureRenameCopy:
                     print("After submitting, renamed files must be re-synced.")
@@ -2133,9 +2399,9 @@ class P4Submit(Command, P4UserMap):
             # Revert changes if we skip this patch
             if not submitted or self.shelve:
                 if self.shelve:
-                    print ("Reverting shelved files.")
+                    print("Reverting shelved files.")
                 else:
-                    print ("Submission cancelled, undoing p4 changes.")
+                    print("Submission cancelled, undoing p4 changes.")
                 sys.stdout.flush()
                 for f in editedFiles | filesToDelete:
                     p4_revert(f)
@@ -2147,9 +2413,11 @@ class P4Submit(Command, P4UserMap):
                 os.remove(fileName)
         return submitted
 
-    # Export git tags as p4 labels. Create a p4 label and then tag
-    # with that.
     def exportGitTags(self, gitTags):
+        """Export git tags as p4 labels. Create a p4 label and then tag with
+           that.
+           """
+
         validLabelRegexp = gitConfig("git-p4.labelExportRegexp")
         if len(validLabelRegexp) == 0:
             validLabelRegexp = defaultLabelRegexp
@@ -2195,7 +2463,7 @@ class P4Submit(Command, P4UserMap):
             # Create the label - use the same view as the client spec we are using
             clientSpec = getClientSpec()
 
-            labelTemplate  = "Label: %s\n" % name
+            labelTemplate = "Label: %s\n" % name
             labelTemplate += "Description:\n"
             for b in body:
                 labelTemplate += "\t" + b + "\n"
@@ -2206,7 +2474,7 @@ class P4Submit(Command, P4UserMap):
             if self.dry_run:
                 print("Would create p4 label %s for tag" % name)
             elif self.prepare_p4_only:
-                print("Not creating p4 label %s for tag due to option" \
+                print("Not creating p4 label %s for tag due to option"
                       " --prepare-p4-only" % name)
             else:
                 p4_write_pipe(["label", "-i"], labelTemplate)
@@ -2237,7 +2505,7 @@ class P4Submit(Command, P4UserMap):
             if len(allowSubmit) > 0 and not self.master in allowSubmit.split(","):
                 die("%s is not in git-p4.allowSubmit" % self.master)
 
-        [upstream, settings] = findUpstreamBranchPoint()
+        upstream, settings = findUpstreamBranchPoint()
         self.depotPath = settings['depot-paths'][0]
         if len(self.origin) == 0:
             self.origin = upstream
@@ -2371,13 +2639,13 @@ class P4Submit(Command, P4UserMap):
         if not self.no_verify:
             try:
                 if not run_git_hook("p4-pre-submit"):
-                    print("\nThe p4-pre-submit hook failed, aborting the submit.\n\nYou can skip " \
-                        "this pre-submission check by adding\nthe command line option '--no-verify', " \
+                    print("\nThe p4-pre-submit hook failed, aborting the submit.\n\nYou can skip "
+                        "this pre-submission check by adding\nthe command line option '--no-verify', "
                         "however,\nthis will also skip the p4-changelist hook as well.")
                     sys.exit(1)
             except Exception as e:
-                print("\nThe p4-pre-submit hook failed, aborting the submit.\n\nThe hook failed "\
-                    "with the error '{0}'".format(e.message) )
+                print("\nThe p4-pre-submit hook failed, aborting the submit.\n\nThe hook failed "
+                    "with the error '{0}'".format(e.message))
                 sys.exit(1)
 
         #
@@ -2399,7 +2667,7 @@ class P4Submit(Command, P4UserMap):
                 applied.append(commit)
                 if self.prepare_p4_only:
                     if i < last:
-                        print("Processing only the first commit due to option" \
+                        print("Processing only the first commit due to option"
                                 " --prepare-p4-only")
                     break
             else:
@@ -2469,13 +2737,15 @@ class P4Submit(Command, P4UserMap):
 
         # exit with error unless everything applied perfectly
         if len(commits) != len(applied):
-                sys.exit(1)
+            sys.exit(1)
 
         return True
 
+
 class View(object):
-    """Represent a p4 view ("p4 help views"), and map files in a
-       repo according to the view."""
+    """Represent a p4 view ("p4 help views"), and map files in a repo according
+       to the view.
+       """
 
     def __init__(self, client_name):
         self.mappings = []
@@ -2484,9 +2754,10 @@ class View(object):
         self.client_spec_path_cache = {}
 
     def append(self, view_line):
-        """Parse a view line, splitting it into depot and client
-           sides.  Append to self.mappings, preserving order.  This
-           is only needed for tag creation."""
+        """Parse a view line, splitting it into depot and client sides.  Append
+           to self.mappings, preserving order.  This is only needed for tag
+           creation.
+           """
 
         # Split the view line into exactly two words.  P4 enforces
         # structure on these lines that simplifies this quite a bit.
@@ -2535,7 +2806,7 @@ class View(object):
         return clientFile[len(self.client_prefix):]
 
     def update_client_spec_path_cache(self, files):
-        """ Caching file paths by "p4 where" batch query """
+        """Caching file paths by "p4 where" batch query."""
 
         # List depot file paths exclude that already cached
         fileArgs = [f['path'] for f in files if decode_path(f['path']) not in self.client_spec_path_cache]
@@ -2567,9 +2838,11 @@ class View(object):
                 self.client_spec_path_cache[depotFile] = b''
 
     def map_in_client(self, depot_path):
-        """Return the relative location in the client where this
-           depot file should live.  Returns "" if the file should
-           not be mapped in the client."""
+        """Return the relative location in the client where this depot file
+           should live.
+
+           Returns "" if the file should not be mapped in the client.
+           """
 
         if gitConfigBool("core.ignorecase"):
             depot_path = depot_path.lower()
@@ -2577,14 +2850,16 @@ class View(object):
         if depot_path in self.client_spec_path_cache:
             return self.client_spec_path_cache[depot_path]
 
-        die( "Error: %s is not found in client spec path" % depot_path )
+        die("Error: %s is not found in client spec path" % depot_path)
         return ""
 
+
 def cloneExcludeCallback(option, opt_str, value, parser):
     # prepend "/" because the first "/" was consumed as part of the option itself.
     # ("-//depot/A/..." becomes "/depot/A/..." after option parsing)
     parser.values.cloneExclude += ["/" + re.sub(r"\.\.\.$", "", value)]
 
+
 class P4Sync(Command, P4UserMap):
 
     def __init__(self):
@@ -2665,8 +2940,8 @@ class P4Sync(Command, P4UserMap):
         self.tz = "%+03d%02d" % (- time.timezone / 3600, ((- time.timezone % 3600) / 60))
         self.labels = {}
 
-    # Force a checkpoint in fast-import and wait for it to finish
     def checkpoint(self):
+        """Force a checkpoint in fast-import and wait for it to finish."""
         self.gitStream.write("checkpoint\n\n")
         self.gitStream.write("progress checkpoint\n\n")
         self.gitStream.flush()
@@ -2687,11 +2962,11 @@ class P4Sync(Command, P4UserMap):
                 return True
         return False
 
-    def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0):
+    def extractFilesFromCommit(self, commit, shelved=False, shelved_cl=0):
         files = []
         fnum = 0
         while "depotFile%s" % fnum in commit:
-            path =  commit["depotFile%s" % fnum]
+            path = commit["depotFile%s" % fnum]
             found = self.isPathWanted(decode_path(path))
             if not found:
                 fnum = fnum + 1
@@ -2718,10 +2993,10 @@ class P4Sync(Command, P4UserMap):
         return jobs
 
     def stripRepoPath(self, path, prefixes):
-        """When streaming files, this is called to map a p4 depot path
-           to where it should go in git.  The prefixes are either
-           self.depotPaths, or self.branchPrefixes in the case of
-           branch detection."""
+        """When streaming files, this is called to map a p4 depot path to where
+           it should go in git.  The prefixes are either self.depotPaths, or
+           self.branchPrefixes in the case of branch detection.
+           """
 
         if self.useClientSpec:
             # branch detection moves files up a level (the branch name)
@@ -2750,8 +3025,9 @@ class P4Sync(Command, P4UserMap):
         return path
 
     def splitFilesIntoBranches(self, commit):
-        """Look at each depotFile in the commit to figure out to what
-           branch it belongs."""
+        """Look at each depotFile in the commit to figure out to what branch it
+           belongs.
+           """
 
         if self.clientSpecDirs:
             files = self.extractFilesFromCommit(commit)
@@ -2811,10 +3087,12 @@ class P4Sync(Command, P4UserMap):
                 print('Path with non-ASCII characters detected. Used %s to encode: %s ' % (encoding, path))
         return path
 
-    # output one file from the P4 stream
-    # - helper for streamP4Files
-
     def streamOneP4File(self, file, contents):
+        """Output one file from the P4 stream.
+
+           This is a helper for streamP4Files().
+           """
+
         file_path = file['depotFile']
         relPath = self.stripRepoPath(decode_path(file_path), self.branchPrefixes)
 
@@ -2822,12 +3100,13 @@ class P4Sync(Command, P4UserMap):
             if 'fileSize' in self.stream_file:
                 size = int(self.stream_file['fileSize'])
             else:
-                size = 0 # deleted files don't get a fileSize apparently
+                # Deleted files don't get a fileSize apparently
+                size = 0
             sys.stdout.write('\r%s --> %s (%s)\n' % (
                 file_path, relPath, format_size_human_readable(size)))
             sys.stdout.flush()
 
-        (type_base, type_mods) = split_p4_type(file["type"])
+        type_base, type_mods = split_p4_type(file["type"])
 
         git_mode = "100644"
         if "x" in type_mods:
@@ -2870,7 +3149,7 @@ class P4Sync(Command, P4UserMap):
             else:
                 if p4_version_string().find('/NT') >= 0:
                     text = text.replace(b'\r\n', b'\n')
-                contents = [ text ]
+                contents = [text]
 
         if type_base == "apple":
             # Apple filetype files will be streamed as a concatenation of
@@ -2885,6 +3164,16 @@ class P4Sync(Command, P4UserMap):
             print("\nIgnoring apple filetype file %s" % file['depotFile'])
             return
 
+        if type_base == "utf8":
+            # The type utf8 explicitly means utf8 *with BOM*. These are
+            # streamed just like regular text files, however, without
+            # the BOM in the stream.
+            # Therefore, to accurately import these files into git, we
+            # need to explicitly re-add the BOM before writing.
+            # 'contents' is a set of bytes in this case, so create the
+            # BOM prefix as a b'' literal.
+            contents = [b'\xef\xbb\xbf' + contents[0]] + contents[1:]
+
         # Note that we do not try to de-mangle keywords on utf16 files,
         # even though in theory somebody may want that.
         regexp = p4_keywords_regexp_for_type(type_base, type_mods)
@@ -2892,7 +3181,7 @@ class P4Sync(Command, P4UserMap):
             contents = [regexp.sub(br'$\1$', c) for c in contents]
 
         if self.largeFileSystem:
-            (git_mode, contents) = self.largeFileSystem.processContent(git_mode, relPath, contents)
+            git_mode, contents = self.largeFileSystem.processContent(git_mode, relPath, contents)
 
         self.writeToGitStream(git_mode, relPath, contents)
 
@@ -2906,8 +3195,8 @@ class P4Sync(Command, P4UserMap):
         if self.largeFileSystem and self.largeFileSystem.isLargeFile(relPath):
             self.largeFileSystem.removeLargeFile(relPath)
 
-    # handle another chunk of streaming data
     def streamP4FilesCb(self, marshalled):
+        """Handle another chunk of streaming data."""
 
         # catch p4 errors and complain
         err = None
@@ -2958,9 +3247,9 @@ class P4Sync(Command, P4UserMap):
                 self.stream_file[k] = marshalled[k]
 
         if (verbose and
-            'streamContentSize' in self.stream_file and
-            'fileSize' in self.stream_file and
-            'depotFile' in self.stream_file):
+                'streamContentSize' in self.stream_file and
+                'fileSize' in self.stream_file and
+                'depotFile' in self.stream_file):
             size = int(self.stream_file["fileSize"])
             if size > 0:
                 progress = 100*self.stream_file['streamContentSize']/size
@@ -2971,8 +3260,9 @@ class P4Sync(Command, P4UserMap):
 
         self.stream_have_file_info = True
 
-    # Stream directly from "p4 files" into "git fast-import"
     def streamP4Files(self, files):
+        """Stream directly from "p4 files" into "git fast-import."""
+
         filesForCommit = []
         filesToRead = []
         filesToDelete = []
@@ -3020,12 +3310,14 @@ class P4Sync(Command, P4UserMap):
         if userid in self.users:
             return self.users[userid]
         else:
-            return "%s <a@b>" % userid
+            userid_bytes = metadata_stream_to_writable_bytes(userid)
+            return b"%s <a@b>" % userid_bytes
 
     def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):
-        """ Stream a p4 tag.
-        commit is either a git commit, or a fast-import mark, ":<p4commit>"
-        """
+        """Stream a p4 tag.
+
+           Commit is either a git commit, or a fast-import mark, ":<p4commit>".
+           """
 
         if verbose:
             print("writing tag %s for commit %s" % (labelName, commit))
@@ -3043,11 +3335,12 @@ class P4Sync(Command, P4UserMap):
             email = self.make_email(owner)
         else:
             email = self.make_email(self.p4UserId())
-        tagger = "%s %s %s" % (email, epoch, self.tz)
 
-        gitStream.write("tagger %s\n" % tagger)
+        gitStream.write("tagger ")
+        gitStream.write(email)
+        gitStream.write(" %s %s\n" % (epoch, self.tz))
 
-        print("labelDetails=",labelDetails)
+        print("labelDetails=", labelDetails)
         if 'Description' in labelDetails:
             description = labelDetails['Description']
         else:
@@ -3075,15 +3368,18 @@ class P4Sync(Command, P4UserMap):
         return hasPrefix
 
     def findShadowedFiles(self, files, change):
-        # Perforce allows you commit files and directories with the same name,
-        # so you could have files //depot/foo and //depot/foo/bar both checked
-        # in.  A p4 sync of a repository in this state fails.  Deleting one of
-        # the files recovers the repository.
-        #
-        # Git will not allow the broken state to exist and only the most recent
-        # of the conflicting names is left in the repository.  When one of the
-        # conflicting files is deleted we need to re-add the other one to make
-        # sure the git repository recovers in the same way as perforce.
+        """Perforce allows you commit files and directories with the same name,
+           so you could have files //depot/foo and //depot/foo/bar both checked
+           in.  A p4 sync of a repository in this state fails.  Deleting one of
+           the files recovers the repository.
+
+           Git will not allow the broken state to exist and only the most
+           recent of the conflicting names is left in the repository.  When one
+           of the conflicting files is deleted we need to re-add the other one
+           to make sure the git repository recovers in the same way as
+           perforce.
+           """
+
         deleted = [f for f in files if f['action'] in self.delete_actions]
         to_check = set()
         for f in deleted:
@@ -3110,7 +3406,7 @@ class P4Sync(Command, P4UserMap):
                     'rev': record['headRev'],
                     'type': record['headType']})
 
-    def commit(self, details, files, branch, parent = "", allow_empty=False):
+    def commit(self, details, files, branch, parent="", allow_empty=False):
         epoch = details["time"]
         author = details["user"]
         jobs = self.extractJobsFromCommit(details)
@@ -3138,12 +3434,12 @@ class P4Sync(Command, P4UserMap):
         self.gitStream.write("commit %s\n" % branch)
         self.gitStream.write("mark :%s\n" % details["change"])
         self.committedChanges.add(int(details["change"]))
-        committer = ""
         if author not in self.users:
             self.getUserMapFromPerforceServer()
-        committer = "%s %s %s" % (self.make_email(author), epoch, self.tz)
 
-        self.gitStream.write("committer %s\n" % committer)
+        self.gitStream.write("committer ")
+        self.gitStream.write(self.make_email(author))
+        self.gitStream.write(" %s %s\n" % (epoch, self.tz))
 
         self.gitStream.write("data <<EOT\n")
         self.gitStream.write(details["desc"])
@@ -3200,8 +3496,11 @@ class P4Sync(Command, P4UserMap):
                     print("Tag %s does not match with change %s: file count is different."
                            % (labelDetails["label"], change))
 
-    # Build a dictionary of changelists and labels, for "detect-labels" option.
     def getLabels(self):
+        """Build a dictionary of changelists and labels, for "detect-labels"
+           option.
+           """
+
         self.labels = {}
 
         l = p4CmdList(["labels"] + ["%s..." % p for p in self.depotPaths])
@@ -3227,11 +3526,12 @@ class P4Sync(Command, P4UserMap):
         if self.verbose:
             print("Label changes: %s" % self.labels.keys())
 
-    # Import p4 labels as git tags. A direct mapping does not
-    # exist, so assume that if all the files are at the same revision
-    # then we can use that, or it's something more complicated we should
-    # just ignore.
     def importP4Labels(self, stream, p4Labels):
+        """Import p4 labels as git tags. A direct mapping does not exist, so
+           assume that if all the files are at the same revision then we can
+           use that, or it's something more complicated we should just ignore.
+           """
+
         if verbose:
             print("import p4 labels: " + ' '.join(p4Labels))
 
@@ -3246,7 +3546,7 @@ class P4Sync(Command, P4UserMap):
 
             if not m.match(name):
                 if verbose:
-                    print("label %s does not match regexp %s" % (name,validLabelRegexp))
+                    print("label %s does not match regexp %s" % (name, validLabelRegexp))
                 continue
 
             if name in ignoredP4Labels:
@@ -3302,7 +3602,7 @@ class P4Sync(Command, P4UserMap):
                 p = p[:-1]
             p = p[p.strip().rfind("/") + 1:]
             if not p.endswith("/"):
-               p += "/"
+                p += "/"
             return p
 
     def getBranchMapping(self):
@@ -3322,7 +3622,7 @@ class P4Sync(Command, P4UserMap):
                     continue
                 source = paths[0]
                 destination = paths[1]
-                ## HACK
+                # HACK
                 if p4PathStartsWith(source, self.depotPaths[0]) and p4PathStartsWith(destination, self.depotPaths[0]):
                     source = source[len(self.depotPaths[0]):-4]
                     destination = destination[len(self.depotPaths[0]):-4]
@@ -3351,7 +3651,7 @@ class P4Sync(Command, P4UserMap):
         configBranches = gitConfigList("git-p4.branchList")
         for branch in configBranches:
             if branch:
-                (source, destination) = branch.split(":")
+                source, destination = branch.split(":")
                 self.knownBranches[destination] = source
 
                 lostAndFoundBranches.discard(destination)
@@ -3359,7 +3659,6 @@ class P4Sync(Command, P4UserMap):
                 if source not in self.knownBranches:
                     lostAndFoundBranches.add(source)
 
-
         for branch in lostAndFoundBranches:
             self.knownBranches[branch] = branch
 
@@ -3431,27 +3730,22 @@ class P4Sync(Command, P4UserMap):
     def importNewBranch(self, branch, maxChange):
         # make fast-import flush all changes to disk and update the refs using the checkpoint
         # command so that we can try to find the branch parent in the git history
-        self.gitStream.write("checkpoint\n\n");
-        self.gitStream.flush();
+        self.gitStream.write("checkpoint\n\n")
+        self.gitStream.flush()
         branchPrefix = self.depotPaths[0] + branch + "/"
         range = "@1,%s" % maxChange
-        #print "prefix" + branchPrefix
         changes = p4ChangesForPaths([branchPrefix], range, self.changes_block_size)
         if len(changes) <= 0:
             return False
         firstChange = changes[0]
-        #print "first change in branch: %s" % firstChange
         sourceBranch = self.knownBranches[branch]
         sourceDepotPath = self.depotPaths[0] + sourceBranch
         sourceRef = self.gitRefForBranch(sourceBranch)
-        #print "source " + sourceBranch
 
         branchParentChange = int(p4Cmd(["changes", "-m", "1", "%s...@1,%s" % (sourceDepotPath, firstChange)])["change"])
-        #print "branch parent: %s" % branchParentChange
         gitParent = self.gitCommitByP4Change(sourceRef, branchParentChange)
         if len(gitParent) > 0:
             self.initialParents[self.gitRefForBranch(branch)] = gitParent
-            #print "parent git commit: %s" % gitParent
 
         self.importChanges(changes)
         return True
@@ -3486,9 +3780,9 @@ class P4Sync(Command, P4UserMap):
                 if self.detectBranches:
                     branches = self.splitFilesIntoBranches(description)
                     for branch in branches.keys():
-                        ## HACK  --hwn
+                        # HACK  --hwn
                         branchPrefix = self.depotPaths[0] + branch + "/"
-                        self.branchPrefixes = [ branchPrefix ]
+                        self.branchPrefixes = [branchPrefix]
 
                         parent = ""
 
@@ -3508,12 +3802,12 @@ class P4Sync(Command, P4UserMap):
                                 fullBranch = self.projectName + branch
                                 if fullBranch not in self.p4BranchesInGit:
                                     if not self.silent:
-                                        print("\n    Importing new branch %s" % fullBranch);
+                                        print("\n    Importing new branch %s" % fullBranch)
                                     if self.importNewBranch(branch, change - 1):
                                         parent = ""
                                         self.p4BranchesInGit.append(fullBranch)
                                     if not self.silent:
-                                        print("\n    Resuming with change %s" % change);
+                                        print("\n    Resuming with change %s" % change)
 
                                 if self.verbose:
                                     print("parent determined through known branches: %s" % parent)
@@ -3572,7 +3866,7 @@ class P4Sync(Command, P4UserMap):
         newestRevision = 0
 
         fileCnt = 0
-        fileArgs = ["%s...%s" % (p,revision) for p in self.depotPaths]
+        fileArgs = ["%s...%s" % (p, revision) for p in self.depotPaths]
 
         for info in p4CmdList(["files"] + fileArgs):
 
@@ -3581,24 +3875,21 @@ class P4Sync(Command, P4UserMap):
                                  % info['data'])
                 if info['data'].find("must refer to client") >= 0:
                     sys.stderr.write("This particular p4 error is misleading.\n")
-                    sys.stderr.write("Perhaps the depot path was misspelled.\n");
+                    sys.stderr.write("Perhaps the depot path was misspelled.\n")
                     sys.stderr.write("Depot path:  %s\n" % " ".join(self.depotPaths))
                 sys.exit(1)
             if 'p4ExitCode' in info:
                 sys.stderr.write("p4 exitcode: %s\n" % info['p4ExitCode'])
                 sys.exit(1)
 
-
             change = int(info["change"])
             if change > newestRevision:
                 newestRevision = change
 
             if info["action"] in self.delete_actions:
-                # don't increase the file cnt, otherwise details["depotFile123"] will have gaps!
-                #fileCnt = fileCnt + 1
                 continue
 
-            for prop in ["depotFile", "rev", "action", "type" ]:
+            for prop in ["depotFile", "rev", "action", "type"]:
                 details["%s%s" % (prop, fileCnt)] = info[prop]
 
             fileCnt = fileCnt + 1
@@ -3618,7 +3909,6 @@ class P4Sync(Command, P4UserMap):
             print("IO error details: {}".format(err))
             print(self.gitError.read())
 
-
     def importRevisions(self, args, branch_arg_given):
         changes = []
 
@@ -3690,7 +3980,7 @@ class P4Sync(Command, P4UserMap):
         self.importProcess = subprocess.Popen(["git", "fast-import"],
                                               stdin=subprocess.PIPE,
                                               stdout=subprocess.PIPE,
-                                              stderr=subprocess.PIPE);
+                                              stderr=subprocess.PIPE)
         self.gitOutput = self.importProcess.stdout
         self.gitStream = self.importProcess.stdin
         self.gitError = self.importProcess.stderr
@@ -3750,9 +4040,13 @@ class P4Sync(Command, P4UserMap):
 
             # restrict to just this one, disabling detect-branches
             if branch_arg_given:
-                short = self.branch.split("/")[-1]
+                short = shortP4Ref(self.branch, self.importIntoRemotes)
                 if short in branches:
-                    self.p4BranchesInGit = [ short ]
+                    self.p4BranchesInGit = [short]
+                elif self.branch.startswith('refs/') and \
+                        branchExists(self.branch) and \
+                        '[git-p4:' in extractLogMessageFromGitCommit(self.branch):
+                    self.p4BranchesInGit = [self.branch]
             else:
                 self.p4BranchesInGit = branches.keys()
 
@@ -3769,13 +4063,13 @@ class P4Sync(Command, P4UserMap):
 
             p4Change = 0
             for branch in self.p4BranchesInGit:
-                logMsg =  extractLogMessageFromGitCommit(self.refPrefix + branch)
+                logMsg = extractLogMessageFromGitCommit(fullP4Ref(branch,
+                                                        self.importIntoRemotes))
 
                 settings = extractSettingsGitLog(logMsg)
 
                 self.readOptions(settings)
-                if ('depot-paths' in settings
-                    and 'change' in settings):
+                if 'depot-paths' in settings and 'change' in settings:
                     change = int(settings['change']) + 1
                     p4Change = max(p4Change, change)
 
@@ -3792,7 +4086,7 @@ class P4Sync(Command, P4UserMap):
                                     i = i - 1
                                     break
 
-                            paths.append ("/".join(cur_list[:i + 1]))
+                            paths.append("/".join(cur_list[:i + 1]))
 
                         self.previousDepotPaths = paths
 
@@ -3802,18 +4096,7 @@ class P4Sync(Command, P4UserMap):
                 if not self.silent and not self.detectBranches:
                     print("Performing incremental import into %s git branch" % self.branch)
 
-        # accept multiple ref name abbreviations:
-        #    refs/foo/bar/branch -> use it exactly
-        #    p4/branch -> prepend refs/remotes/ or refs/heads/
-        #    branch -> prepend refs/remotes/p4/ or refs/heads/p4/
-        if not self.branch.startswith("refs/"):
-            if self.importIntoRemotes:
-                prepend = "refs/remotes/"
-            else:
-                prepend = "refs/heads/"
-            if not self.branch.startswith("p4/"):
-                prepend += "p4/"
-            self.branch = prepend + self.branch
+        self.branch = fullP4Ref(self.branch, self.importIntoRemotes)
 
         if len(args) == 0 and self.depotPaths:
             if not self.silent:
@@ -3821,8 +4104,8 @@ class P4Sync(Command, P4UserMap):
         else:
             if self.depotPaths and self.depotPaths != args:
                 print("previous import used depot path %s and now %s was specified. "
-                       "This doesn't work!" % (' '.join (self.depotPaths),
-                                               ' '.join (args)))
+                       "This doesn't work!" % (' '.join(self.depotPaths),
+                                               ' '.join(args)))
                 sys.exit(1)
 
             self.depotPaths = sorted(args)
@@ -3862,7 +4145,7 @@ class P4Sync(Command, P4UserMap):
                 if len(self.changesFile) == 0:
                     revision = "#head"
 
-            p = re.sub ("\.\.\.$", "", p)
+            p = re.sub("\.\.\.$", "", p)
             if not p.endswith("/"):
                 p += "/"
 
@@ -3876,10 +4159,10 @@ class P4Sync(Command, P4UserMap):
         self.loadUserMapFromCache()
         self.labels = {}
         if self.detectLabels:
-            self.getLabels();
+            self.getLabels()
 
         if self.detectBranches:
-            ## FIXME - what's a P4 projectName ?
+            # FIXME - what's a P4 projectName ?
             self.projectName = self.guessProjectName()
 
             if self.hasOrigin:
@@ -3892,7 +4175,7 @@ class P4Sync(Command, P4UserMap):
             for b in self.p4BranchesInGit:
                 if b != "master":
 
-                    ## FIXME
+                    # FIXME
                     b = b[len(self.projectName):]
                 self.createdBranches.add(b)
 
@@ -3942,6 +4225,7 @@ class P4Sync(Command, P4UserMap):
 
         return True
 
+
 class P4Rebase(Command):
     def __init__(self):
         Command.__init__(self)
@@ -3961,11 +4245,11 @@ class P4Rebase(Command):
 
     def rebase(self):
         if os.system("git update-index --refresh") != 0:
-            die("Some files in your working directory are modified and different than what is in your index. You can use git update-index <filename> to bring the index up to date or stash away all your changes with git stash.");
+            die("Some files in your working directory are modified and different than what is in your index. You can use git update-index <filename> to bring the index up to date or stash away all your changes with git stash.")
         if len(read_pipe(["git", "diff-index", "HEAD", "--"])) > 0:
-            die("You have uncommitted changes. Please commit them before rebasing or stash them away with git stash.");
+            die("You have uncommitted changes. Please commit them before rebasing or stash them away with git stash.")
 
-        [upstream, settings] = findUpstreamBranchPoint()
+        upstream, settings = findUpstreamBranchPoint()
         if len(upstream) == 0:
             die("Cannot find upstream branchpoint for rebase")
 
@@ -3979,6 +4263,7 @@ class P4Rebase(Command):
             "HEAD", "--"])
         return True
 
+
 class P4Clone(P4Sync):
     def __init__(self):
         P4Sync.__init__(self)
@@ -3996,7 +4281,7 @@ class P4Clone(P4Sync):
         self.cloneBare = False
 
     def defaultDestination(self, args):
-        ## TODO: use common prefix of args?
+        # TODO: use common prefix of args?
         depotPath = args[0]
         depotDir = re.sub("(@[^@]*)$", "", depotPath)
         depotDir = re.sub("(#[^#]*)$", "", depotDir)
@@ -4032,7 +4317,7 @@ class P4Clone(P4Sync):
             os.makedirs(self.cloneDestination)
         chdir(self.cloneDestination)
 
-        init_cmd = [ "git", "init" ]
+        init_cmd = ["git", "init"]
         if self.cloneBare:
             init_cmd.append("--bare")
         retcode = subprocess.call(init_cmd)
@@ -4044,19 +4329,28 @@ class P4Clone(P4Sync):
 
         # create a master branch and check out a work tree
         if gitBranchExists(self.branch):
-            system([ "git", "branch", currentGitBranch(), self.branch ])
+            system(["git", "branch", currentGitBranch(), self.branch])
             if not self.cloneBare:
-                system([ "git", "checkout", "-f" ])
+                system(["git", "checkout", "-f"])
         else:
-            print('Not checking out any branch, use ' \
+            print('Not checking out any branch, use '
                   '"git checkout -q -b master <branch>"')
 
         # auto-set this variable if invoked with --use-client-spec
         if self.useClientSpec_from_options:
             system(["git", "config", "--bool", "git-p4.useclientspec", "true"])
 
+        # persist any git-p4 encoding-handling config options passed in for clone:
+        if gitConfig('git-p4.metadataDecodingStrategy'):
+            system(["git", "config", "git-p4.metadataDecodingStrategy", gitConfig('git-p4.metadataDecodingStrategy')])
+        if gitConfig('git-p4.metadataFallbackEncoding'):
+            system(["git", "config", "git-p4.metadataFallbackEncoding", gitConfig('git-p4.metadataFallbackEncoding')])
+        if gitConfig('git-p4.pathEncoding'):
+            system(["git", "config", "git-p4.pathEncoding", gitConfig('git-p4.pathEncoding')])
+
         return True
 
+
 class P4Unshelve(Command):
     def __init__(self):
         Command.__init__(self)
@@ -4073,14 +4367,14 @@ class P4Unshelve(Command):
         self.destbranch = "refs/remotes/p4-unshelved"
 
     def renameBranch(self, branch_name):
-        """ Rename the existing branch to branch_name.N
-        """
+        """Rename the existing branch to branch_name.N ."""
 
         found = True
-        for i in range(0,1000):
+        for i in range(0, 1000):
             backup_branch_name = "{0}.{1}".format(branch_name, i)
             if not gitBranchExists(backup_branch_name):
-                gitUpdateRef(backup_branch_name, branch_name) # copy ref to backup
+                # Copy ref to backup
+                gitUpdateRef(backup_branch_name, branch_name)
                 gitDeleteRef(branch_name)
                 found = True
                 print("renamed old unshelve branch to {0}".format(backup_branch_name))
@@ -4090,9 +4384,9 @@ class P4Unshelve(Command):
             sys.exit("gave up trying to rename existing branch {0}".format(sync.branch))
 
     def findLastP4Revision(self, starting_point):
-        """ Look back from starting_point for the first commit created by git-p4
-            to find the P4 commit we are based on, and the depot-paths.
-        """
+        """Look back from starting_point for the first commit created by git-p4
+           to find the P4 commit we are based on, and the depot-paths.
+           """
 
         for parent in (range(65535)):
             log = extractLogMessageFromGitCommit("{0}~{1}".format(starting_point, parent))
@@ -4103,8 +4397,9 @@ class P4Unshelve(Command):
         sys.exit("could not find git-p4 commits in {0}".format(self.origin))
 
     def createShelveParent(self, change, branch_name, sync, origin):
-        """ Create a commit matching the parent of the shelved changelist 'change'
-        """
+        """Create a commit matching the parent of the shelved changelist
+           'change'.
+           """
         parent_description = p4_describe(change, shelved=True)
         parent_description['desc'] = 'parent for shelved changelist {}\n'.format(change)
         files = sync.extractFilesFromCommit(parent_description, shelved=False, shelved_cl=change)
@@ -4172,10 +4467,11 @@ class P4Unshelve(Command):
 
         return True
 
+
 class P4Branches(Command):
     def __init__(self):
         Command.__init__(self)
-        self.options = [ ]
+        self.options = []
         self.description = ("Shows the git branches that hold imports and their "
                             + "corresponding perforce depot paths")
         self.verbose = False
@@ -4197,6 +4493,7 @@ class P4Branches(Command):
             print("%s <= %s (%s)" % (branch, ",".join(settings["depot-paths"]), settings["change"]))
         return True
 
+
 class HelpFormatter(optparse.IndentedHelpFormatter):
     def __init__(self):
         optparse.IndentedHelpFormatter.__init__(self)
@@ -4207,6 +4504,7 @@ class HelpFormatter(optparse.IndentedHelpFormatter):
         else:
             return ""
 
+
 def printUsage(commands):
     print("usage: %s <command> [options]" % sys.argv[0])
     print("")
@@ -4215,16 +4513,18 @@ def printUsage(commands):
     print("Try %s <command> --help for command specific help." % sys.argv[0])
     print("")
 
+
 commands = {
-    "submit" : P4Submit,
-    "commit" : P4Submit,
-    "sync" : P4Sync,
-    "rebase" : P4Rebase,
-    "clone" : P4Clone,
-    "branches" : P4Branches,
-    "unshelve" : P4Unshelve,
+    "submit": P4Submit,
+    "commit": P4Submit,
+    "sync": P4Sync,
+    "rebase": P4Rebase,
+    "clone": P4Clone,
+    "branches": P4Branches,
+    "unshelve": P4Unshelve,
 }
 
+
 def main():
     if len(sys.argv[1:]) == 0:
         printUsage(commands.keys())
@@ -4251,11 +4551,11 @@ def main():
 
     parser = optparse.OptionParser(cmd.usage.replace("%prog", "%prog " + cmdName),
                                    options,
-                                   description = cmd.description,
-                                   formatter = HelpFormatter())
+                                   description=cmd.description,
+                                   formatter=HelpFormatter())
 
     try:
-        (cmd, args) = parser.parse_args(sys.argv[2:], cmd);
+        cmd, args = parser.parse_args(sys.argv[2:], cmd)
     except:
         parser.print_help()
         raise
@@ -4263,7 +4563,7 @@ def main():
     global verbose
     verbose = cmd.verbose
     if cmd.needsGit:
-        if cmd.gitdir == None:
+        if cmd.gitdir is None:
             cmd.gitdir = os.path.abspath(".git")
             if not isValidGitDir(cmd.gitdir):
                 # "rev-parse --git-dir" without arguments will try $PWD/.git
@@ -4271,7 +4571,7 @@ def main():
                 if os.path.exists(cmd.gitdir):
                     cdup = read_pipe(["git", "rev-parse", "--show-cdup"]).strip()
                     if len(cdup) > 0:
-                        chdir(cdup);
+                        chdir(cdup)
 
         if not isValidGitDir(cmd.gitdir):
             if isValidGitDir(cmd.gitdir + "/.git"):
diff --git a/git.c b/git.c
index 3d8e48cf555a5d1d56abd4d093145e6a9f77db94..5ff4f3e25b73eab27a40ea988b1e826da1462e62 100644 (file)
--- a/git.c
+++ b/git.c
@@ -25,7 +25,7 @@ struct cmd_struct {
 };
 
 const char git_usage_string[] =
-       N_("git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
+       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"
           "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
@@ -146,7 +146,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                 * commands can be written with "--" prepended
                 * to make them look like flags.
                 */
-               if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
+               if (!strcmp(cmd, "--help") || !strcmp(cmd, "-h") ||
+                   !strcmp(cmd, "--version") || !strcmp(cmd, "-v"))
                        break;
 
                /*
@@ -893,8 +894,10 @@ int cmd_main(int argc, const char **argv)
        argc--;
        handle_options(&argv, &argc, NULL);
        if (argc > 0) {
-               /* translate --help and --version into commands */
-               skip_prefix(argv[0], "--", &argv[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 {
                /* The user didn't specify a command; give them help */
                commit_pager_choice();
index 23d9dd1fe0d024c4af344c35faf01365ec8a6c58..0ae7d685904b85f97a69b243e30f010671d050e3 100755 (executable)
@@ -2955,9 +2955,9 @@ proc savestuff {w} {
 proc resizeclistpanes {win w} {
     global oldwidth oldsash use_ttk
     if {[info exists oldwidth($win)]} {
-       if {[info exists oldsash($win)]} {
-           set s0 [lindex $oldsash($win) 0]
-           set s1 [lindex $oldsash($win) 1]
+        if {[info exists oldsash($win)]} {
+            set s0 [lindex $oldsash($win) 0]
+            set s1 [lindex $oldsash($win) 1]
         } elseif {$use_ttk} {
             set s0 [$win sashpos 0]
             set s1 [$win sashpos 1]
@@ -2991,8 +2991,10 @@ proc resizeclistpanes {win w} {
         } else {
             $win sash place 0 $sash0 [lindex $s0 1]
             $win sash place 1 $sash1 [lindex $s1 1]
+            set sash0 [list $sash0 [lindex $s0 1]]
+            set sash1 [list $sash1 [lindex $s1 1]]
         }
-       set oldsash($win) [list $sash0 $sash1]
+        set oldsash($win) [list $sash0 $sash1]
     }
     set oldwidth($win) $w
 }
@@ -3000,8 +3002,8 @@ proc resizeclistpanes {win w} {
 proc resizecdetpanes {win w} {
     global oldwidth oldsash use_ttk
     if {[info exists oldwidth($win)]} {
-       if {[info exists oldsash($win)]} {
-           set s0 $oldsash($win)
+        if {[info exists oldsash($win)]} {
+            set s0 $oldsash($win)
         } elseif {$use_ttk} {
             set s0 [$win sashpos 0]
         } else {
@@ -3023,8 +3025,9 @@ proc resizecdetpanes {win w} {
             $win sashpos 0 $sash0
         } else {
             $win sash place 0 $sash0 [lindex $s0 1]
+            set sash0 [list $sash0 [lindex $s0 1]]
         }
-       set oldsash($win) $sash0
+        set oldsash($win) $sash0
     }
     set oldwidth($win) $w
 }
index 58b394cd47f3f068177c622e927532497126e14c..31bc5c7767ce865bb3fb1a89f311f7d2b03c7e6d 100644 (file)
@@ -55,7 +55,7 @@ static void fetch_single_packfile(struct object_id *packfile_hash,
        http_init(NULL, url, 0);
 
        preq = new_direct_http_pack_request(packfile_hash->hash, xstrdup(url));
-       if (preq == NULL)
+       if (!preq)
                die("couldn't create http pack request");
        preq->slot->results = &results;
        preq->index_pack_args = index_pack_args;
index f0c044dcf7661a37b2a03f59e11f9e0bcefba0ea..5f4340a36e6de404acaf4c447f6d8e60bc6f90ae 100644 (file)
@@ -253,7 +253,7 @@ static void start_fetch_loose(struct transfer_request *request)
        struct http_object_request *obj_req;
 
        obj_req = new_http_object_request(repo->url, &request->obj->oid);
-       if (obj_req == NULL) {
+       if (!obj_req) {
                request->state = ABORTED;
                return;
        }
@@ -318,7 +318,7 @@ static void start_fetch_packed(struct transfer_request *request)
        fprintf(stderr, " which contains %s\n", oid_to_hex(&request->obj->oid));
 
        preq = new_http_pack_request(target->hash, repo->url);
-       if (preq == NULL) {
+       if (!preq) {
                repo->can_update_info_refs = 0;
                return;
        }
@@ -520,7 +520,7 @@ static void finish_request(struct transfer_request *request)
        /* Keep locks active */
        check_locks();
 
-       if (request->headers != NULL)
+       if (request->headers)
                curl_slist_free_all(request->headers);
 
        /* URL is reused for MOVE after PUT and used during FETCH */
@@ -783,7 +783,7 @@ xml_start_tag(void *userData, const char *name, const char **atts)
        const char *c = strchr(name, ':');
        int old_namelen, new_len;
 
-       if (c == NULL)
+       if (!c)
                c = name;
        else
                c++;
@@ -811,7 +811,7 @@ xml_end_tag(void *userData, const char *name)
 
        ctx->userFunc(ctx, 1);
 
-       if (c == NULL)
+       if (!c)
                c = name;
        else
                c++;
@@ -1689,7 +1689,6 @@ int cmd_main(int argc, const char **argv)
        struct refspec rs = REFSPEC_INIT_PUSH;
        struct remote_lock *ref_lock = NULL;
        struct remote_lock *info_ref_lock = NULL;
-       struct rev_info revs;
        int delete_branch = 0;
        int force_delete = 0;
        int objects_to_send;
@@ -1825,6 +1824,7 @@ int cmd_main(int argc, const char **argv)
 
        new_refs = 0;
        for (ref = remote_refs; ref; ref = ref->next) {
+               struct rev_info revs;
                struct strvec commit_argv = STRVEC_INIT;
 
                if (!ref->peer_ref)
@@ -1893,7 +1893,7 @@ int cmd_main(int argc, const char **argv)
 
                /* Lock remote branch ref */
                ref_lock = lock_remote(ref->name, LOCK_TIME);
-               if (ref_lock == NULL) {
+               if (!ref_lock) {
                        fprintf(stderr, "Unable to lock remote branch %s\n",
                                ref->name);
                        if (helper_status)
@@ -1941,6 +1941,7 @@ int cmd_main(int argc, const char **argv)
                unlock_remote(ref_lock);
                check_locks();
                strvec_clear(&commit_argv);
+               release_revisions(&revs);
        }
 
        /* Update remote server info if appropriate */
index 910fae539b89e6aea2af299b61dd64ff645b3578..b8f0f98ae146999adf3770cc7338cbacbbbf8cb3 100644 (file)
@@ -59,7 +59,7 @@ static void start_object_request(struct walker *walker,
        struct http_object_request *req;
 
        req = new_http_object_request(obj_req->repo->base, &obj_req->oid);
-       if (req == NULL) {
+       if (!req) {
                obj_req->state = ABORTED;
                return;
        }
@@ -106,7 +106,7 @@ static void process_object_response(void *callback_data)
        /* Use alternates if necessary */
        if (missing_target(obj_req->req)) {
                fetch_alternates(walker, alt->base);
-               if (obj_req->repo->next != NULL) {
+               if (obj_req->repo->next) {
                        obj_req->repo =
                                obj_req->repo->next;
                        release_http_object_request(obj_req->req);
@@ -225,12 +225,12 @@ static void process_alternates_response(void *callback_data)
                                         alt_req->url->buf);
                        active_requests++;
                        slot->in_use = 1;
-                       if (slot->finished != NULL)
+                       if (slot->finished)
                                (*slot->finished) = 0;
                        if (!start_active_slot(slot)) {
                                cdata->got_alternates = -1;
                                slot->in_use = 0;
-                               if (slot->finished != NULL)
+                               if (slot->finished)
                                        (*slot->finished) = 1;
                        }
                        return;
@@ -443,7 +443,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne
        }
 
        preq = new_http_pack_request(target->hash, repo->base);
-       if (preq == NULL)
+       if (!preq)
                goto abort;
        preq->slot->results = &results;
 
@@ -489,11 +489,11 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
                if (hasheq(obj_req->oid.hash, hash))
                        break;
        }
-       if (obj_req == NULL)
+       if (!obj_req)
                return error("Couldn't find request for %s in the queue", hex);
 
        if (has_object_file(&obj_req->oid)) {
-               if (obj_req->req != NULL)
+               if (obj_req->req)
                        abort_http_object_request(obj_req->req);
                abort_object_request(obj_req);
                return 0;
diff --git a/http.c b/http.c
index 229da4d14882d9c9855ab418ad64f30fe62e485a..11c6f69facd8ec165ea50ae1dee8f7a33c7c129d 100644 (file)
--- a/http.c
+++ b/http.c
@@ -128,6 +128,8 @@ static struct curl_slist *pragma_header;
 static struct curl_slist *no_pragma_header;
 static struct string_list extra_http_headers = STRING_LIST_INIT_DUP;
 
+static struct curl_slist *host_resolutions;
+
 static struct active_request_slot *active_queue_head;
 
 static char *cached_accept_language;
@@ -197,11 +199,11 @@ static void finish_active_slot(struct active_request_slot *slot)
        closedown_active_slot(slot);
        curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);
 
-       if (slot->finished != NULL)
+       if (slot->finished)
                (*slot->finished) = 1;
 
        /* Store slot results so they can be read after the slot is reused */
-       if (slot->results != NULL) {
+       if (slot->results) {
                slot->results->curl_result = slot->curl_result;
                slot->results->http_code = slot->http_code;
                curl_easy_getinfo(slot->curl, CURLINFO_HTTPAUTH_AVAIL,
@@ -212,7 +214,7 @@ static void finish_active_slot(struct active_request_slot *slot)
        }
 
        /* Run callback if appropriate */
-       if (slot->callback_func != NULL)
+       if (slot->callback_func)
                slot->callback_func(slot->callback_data);
 }
 
@@ -234,7 +236,7 @@ static void process_curl_messages(void)
                        while (slot != NULL &&
                               slot->curl != curl_message->easy_handle)
                                slot = slot->next;
-                       if (slot != NULL) {
+                       if (slot) {
                                xmulti_remove_handle(slot);
                                slot->curl_result = curl_result;
                                finish_active_slot(slot);
@@ -393,6 +395,18 @@ static int http_options(const char *var, const char *value, void *cb)
                return 0;
        }
 
+       if (!strcmp("http.curloptresolve", var)) {
+               if (!value) {
+                       return config_error_nonbool(var);
+               } else if (!*value) {
+                       curl_slist_free_all(host_resolutions);
+                       host_resolutions = NULL;
+               } else {
+                       host_resolutions = curl_slist_append(host_resolutions, value);
+               }
+               return 0;
+       }
+
        if (!strcmp("http.followredirects", var)) {
                if (value && !strcmp(value, "initial"))
                        http_follow_config = HTTP_FOLLOW_INITIAL;
@@ -838,16 +852,16 @@ static CURL *get_curl_handle(void)
                curl_easy_setopt(result, CURLOPT_SSL_CIPHER_LIST,
                                ssl_cipherlist);
 
-       if (ssl_cert != NULL)
+       if (ssl_cert)
                curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
        if (has_cert_password())
                curl_easy_setopt(result, CURLOPT_KEYPASSWD, cert_auth.password);
-       if (ssl_key != NULL)
+       if (ssl_key)
                curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
-       if (ssl_capath != NULL)
+       if (ssl_capath)
                curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath);
 #ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
-       if (ssl_pinnedkey != NULL)
+       if (ssl_pinnedkey)
                curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
 #endif
        if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
@@ -857,10 +871,10 @@ static CURL *get_curl_handle(void)
                curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
 #endif
        } else if (ssl_cainfo != NULL || http_proxy_ssl_ca_info != NULL) {
-               if (ssl_cainfo != NULL)
+               if (ssl_cainfo)
                        curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
 #ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO
-               if (http_proxy_ssl_ca_info != NULL)
+               if (http_proxy_ssl_ca_info)
                        curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info);
 #endif
        }
@@ -1050,7 +1064,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
 
        {
                char *http_max_requests = getenv("GIT_HTTP_MAX_REQUESTS");
-               if (http_max_requests != NULL)
+               if (http_max_requests)
                        max_requests = atoi(http_max_requests);
        }
 
@@ -1069,10 +1083,10 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
        set_from_env(&user_agent, "GIT_HTTP_USER_AGENT");
 
        low_speed_limit = getenv("GIT_HTTP_LOW_SPEED_LIMIT");
-       if (low_speed_limit != NULL)
+       if (low_speed_limit)
                curl_low_speed_limit = strtol(low_speed_limit, NULL, 10);
        low_speed_time = getenv("GIT_HTTP_LOW_SPEED_TIME");
-       if (low_speed_time != NULL)
+       if (low_speed_time)
                curl_low_speed_time = strtol(low_speed_time, NULL, 10);
 
        if (curl_ssl_verify == -1)
@@ -1109,7 +1123,7 @@ void http_cleanup(void)
 
        while (slot != NULL) {
                struct active_request_slot *next = slot->next;
-               if (slot->curl != NULL) {
+               if (slot->curl) {
                        xmulti_remove_handle(slot);
                        curl_easy_cleanup(slot->curl);
                }
@@ -1131,6 +1145,9 @@ void http_cleanup(void)
        curl_slist_free_all(no_pragma_header);
        no_pragma_header = NULL;
 
+       curl_slist_free_all(host_resolutions);
+       host_resolutions = NULL;
+
        if (curl_http_proxy) {
                free((void *)curl_http_proxy);
                curl_http_proxy = NULL;
@@ -1147,13 +1164,13 @@ void http_cleanup(void)
        free((void *)http_proxy_authmethod);
        http_proxy_authmethod = NULL;
 
-       if (cert_auth.password != NULL) {
+       if (cert_auth.password) {
                memset(cert_auth.password, 0, strlen(cert_auth.password));
                FREE_AND_NULL(cert_auth.password);
        }
        ssl_cert_password_required = 0;
 
-       if (proxy_cert_auth.password != NULL) {
+       if (proxy_cert_auth.password) {
                memset(proxy_cert_auth.password, 0, strlen(proxy_cert_auth.password));
                FREE_AND_NULL(proxy_cert_auth.password);
        }
@@ -1179,14 +1196,14 @@ struct active_request_slot *get_active_slot(void)
        while (slot != NULL && slot->in_use)
                slot = slot->next;
 
-       if (slot == NULL) {
+       if (!slot) {
                newslot = xmalloc(sizeof(*newslot));
                newslot->curl = NULL;
                newslot->in_use = 0;
                newslot->next = NULL;
 
                slot = active_queue_head;
-               if (slot == NULL) {
+               if (!slot) {
                        active_queue_head = newslot;
                } else {
                        while (slot->next != NULL)
@@ -1196,7 +1213,7 @@ struct active_request_slot *get_active_slot(void)
                slot = newslot;
        }
 
-       if (slot->curl == NULL) {
+       if (!slot->curl) {
                slot->curl = curl_easy_duphandle(curl_default);
                curl_session_count++;
        }
@@ -1211,6 +1228,7 @@ struct active_request_slot *get_active_slot(void)
        if (curl_save_cookies)
                curl_easy_setopt(slot->curl, CURLOPT_COOKIEJAR, curl_cookie_file);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);
+       curl_easy_setopt(slot->curl, CURLOPT_RESOLVE, host_resolutions);
        curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr);
        curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL);
        curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, NULL);
@@ -1367,6 +1385,32 @@ void run_active_slot(struct active_request_slot *slot)
                        select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout);
                }
        }
+
+       /*
+        * The value of slot->finished we set before the loop was used
+        * to set our "finished" variable when our request completed.
+        *
+        * 1. The slot may not have been reused for another requst
+        *    yet, in which case it still has &finished.
+        *
+        * 2. The slot may already be in-use to serve another request,
+        *    which can further be divided into two cases:
+        *
+        * (a) If call run_active_slot() hasn't been called for that
+        *     other request, slot->finished would have been cleared
+        *     by get_active_slot() and has NULL.
+        *
+        * (b) If the request did call run_active_slot(), then the
+        *     call would have updated slot->finished at the beginning
+        *     of this function, and with the clearing of the member
+        *     below, we would find that slot->finished is now NULL.
+        *
+        * In all cases, slot->finished has no useful information to
+        * anybody at this point.  Some compilers warn us for
+        * attempting to smuggle a pointer that is about to become
+        * invalid, i.e. &finished.  We clear it here to assure them.
+        */
+       slot->finished = NULL;
 }
 
 static void release_active_slot(struct active_request_slot *slot)
@@ -1768,7 +1812,7 @@ static int http_request(const char *url,
        slot = get_active_slot();
        curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
 
-       if (result == NULL) {
+       if (!result) {
                curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
        } else {
                curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
@@ -1945,8 +1989,8 @@ int http_get_strbuf(const char *url,
  * If a previous interrupted download is detected (i.e. a previous temporary
  * file is still around) the download is resumed.
  */
-static int http_get_file(const char *url, const char *filename,
-                        struct http_get_options *options)
+int http_get_file(const char *url, const char *filename,
+                 struct http_get_options *options)
 {
        int ret;
        struct strbuf tmpfile = STRBUF_INIT;
@@ -2100,7 +2144,7 @@ cleanup:
 
 void release_http_pack_request(struct http_pack_request *preq)
 {
-       if (preq->packfile != NULL) {
+       if (preq->packfile) {
                fclose(preq->packfile);
                preq->packfile = NULL;
        }
@@ -2391,7 +2435,7 @@ abort:
 
 void process_http_object_request(struct http_object_request *freq)
 {
-       if (freq->slot == NULL)
+       if (!freq->slot)
                return;
        freq->curl_result = freq->slot->curl_result;
        freq->http_code = freq->slot->http_code;
@@ -2448,7 +2492,7 @@ void release_http_object_request(struct http_object_request *freq)
                freq->localfile = -1;
        }
        FREE_AND_NULL(freq->url);
-       if (freq->slot != NULL) {
+       if (freq->slot) {
                freq->slot->callback_func = NULL;
                freq->slot->callback_data = NULL;
                release_active_slot(freq->slot);
diff --git a/http.h b/http.h
index df1590e53a455787a2d4d28a7896cabf8ac15419..ba303cfb372825fb0731faebee1ccc7cb9728b29 100644 (file)
--- a/http.h
+++ b/http.h
@@ -163,6 +163,15 @@ struct http_get_options {
  */
 int http_get_strbuf(const char *url, struct strbuf *result, struct http_get_options *options);
 
+/*
+ * Downloads a URL and stores the result in the given file.
+ *
+ * If a previous interrupted download is detected (i.e. a previous temporary
+ * file is still around) the download is resumed.
+ */
+int http_get_file(const char *url, const char *filename,
+                 struct http_get_options *options);
+
 int http_fetch_ref(const char *base, struct ref *ref);
 
 /* Helpers for fetching packs */
diff --git a/kwset.c b/kwset.c
index fc439e0667f137f3449635a37a32f8418d5041f0..08aadf03117c5069116bb7e7fa4aa5ed7a9b1fb0 100644 (file)
--- a/kwset.c
+++ b/kwset.c
@@ -477,7 +477,7 @@ kwsprep (kwset_t kws)
        next[i] = NULL;
       treenext(kwset->trie->links, next);
 
-      if ((trans = kwset->trans) != NULL)
+      if ((trans = kwset->trans))
        for (i = 0; i < NCHAR; ++i)
          kwset->next[i] = next[U(trans[i])];
       else
@@ -485,7 +485,7 @@ kwsprep (kwset_t kws)
     }
 
   /* Fix things up for any translation table. */
-  if ((trans = kwset->trans) != NULL)
+  if ((trans = kwset->trans))
     for (i = 0; i < NCHAR; ++i)
       kwset->delta[i] = delta[U(trans[i])];
   else
index a937cec59a6e8cd80f2272940ed0960a08d35125..14b83620191019e465291d13be023df794ffb645 100644 (file)
@@ -207,7 +207,7 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
        dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
        dict[5].placeholder = NULL; dict[5].value = NULL;
 
-       if (fn->cmdline == NULL)
+       if (!fn->cmdline)
                die("custom merge driver %s lacks command line.", fn->name);
 
        result->ptr = NULL;
index 3a03e34c305c07533574177a7b5483d038f5290c..d0ac0a6327a18f5eeee6fc43f036c9a2618fd672 100644 (file)
@@ -88,7 +88,7 @@ static int match_ref_pattern(const char *refname,
                             const struct string_list_item *item)
 {
        int matched = 0;
-       if (item->util == NULL) {
+       if (!item->util) {
                if (!wildmatch(item->string, refname, 0))
                        matched = 1;
        } else {
index 02f6f9535783a486b09e2f22481b39dbc039c89b..9621ba62a394348a95f6e5e181aea286c6c37b56 100644 (file)
@@ -698,7 +698,7 @@ static int is_scissors_line(const char *line)
                        continue;
                }
                last_nonblank = c;
-               if (first_nonblank == NULL)
+               if (!first_nonblank)
                        first_nonblank = c;
                if (*c == '-') {
                        in_perforation = 1;
@@ -1094,7 +1094,7 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line)
                         */
                        lines = strbuf_split(line, '\n');
                        for (it = lines; (sb = *it); it++) {
-                               if (*(it + 1) == NULL) /* The last line */
+                               if (!*(it + 1)) /* The last line */
                                        if (sb->buf[sb->len - 1] != '\n') {
                                                /* Partial line, save it for later. */
                                                strbuf_addbuf(&prev, sb);
index 7befdc5e4835d533b994f75ee42709937a5d046c..da2589b08229813963347115a001d8ce6f45ae32 100644 (file)
--- a/mailmap.c
+++ b/mailmap.c
@@ -77,7 +77,7 @@ static void add_mapping(struct string_list *map,
        struct mailmap_entry *me;
        struct string_list_item *item;
 
-       if (old_email == NULL) {
+       if (!old_email) {
                old_email = new_email;
                new_email = NULL;
        }
@@ -92,7 +92,7 @@ static void add_mapping(struct string_list *map,
                item->util = me;
        }
 
-       if (old_name == NULL) {
+       if (!old_name) {
                debug_mm("mailmap: adding (simple) entry for '%s'\n", old_email);
 
                /* Replace current name and new email for simple entry */
@@ -123,9 +123,9 @@ static char *parse_name_and_email(char *buffer, char **name,
        char *left, *right, *nstart, *nend;
        *name = *email = NULL;
 
-       if ((left = strchr(buffer, '<')) == NULL)
+       if (!(left = strchr(buffer, '<')))
                return NULL;
-       if ((right = strchr(left+1, '>')) == NULL)
+       if (!(right = strchr(left + 1, '>')))
                return NULL;
        if (!allow_empty_email && (left+1 == right))
                return NULL;
@@ -153,7 +153,7 @@ static void read_mailmap_line(struct string_list *map, char *buffer)
        if (buffer[0] == '#')
                return;
 
-       if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL)
+       if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)))
                parse_name_and_email(name2, &name2, &email2, 1);
 
        if (email1)
@@ -320,7 +320,7 @@ int map_user(struct string_list *map,
                 (int)*emaillen, debug_str(*email));
 
        item = lookup_prefix(map, *email, *emaillen);
-       if (item != NULL) {
+       if (item) {
                me = (struct mailmap_entry *)item->util;
                if (me->namemap.nr) {
                        /*
@@ -334,7 +334,7 @@ int map_user(struct string_list *map,
                                item = subitem;
                }
        }
-       if (item != NULL) {
+       if (item) {
                struct mailmap_info *mi = (struct mailmap_info *)item->util;
                if (mi->name == NULL && mi->email == NULL) {
                        debug_mm("map_user:  -- (no simple mapping)\n");
index 8545354dafd0600e02eb1bb509d8f9bedd23d1c9..b5015b9afd47777ec39652f7474ee7d34b6f0cf7 100644 (file)
@@ -1594,6 +1594,7 @@ static int find_first_merges(struct repository *repo,
        }
 
        object_array_clear(&merges);
+       release_revisions(&revs);
        return result->nr;
 }
 
@@ -2068,7 +2069,7 @@ static char *handle_path_level_conflicts(struct merge_options *opt,
         * to ensure that's the case.
         */
        c_info = strmap_get(collisions, new_path);
-       if (c_info == NULL)
+       if (!c_info)
                BUG("c_info is NULL");
 
        /*
@@ -4640,7 +4641,7 @@ static void merge_ort_internal(struct merge_options *opt,
        }
 
        merged_merge_bases = pop_commit(&merge_bases);
-       if (merged_merge_bases == NULL) {
+       if (!merged_merge_bases) {
                /* if there is no common ancestor, use an empty tree */
                struct tree *tree;
 
index 1ee6364e8b16b17295258667e70b77ea1f1fffa4..b83a129b4313d9c6a4f6434fbe2002068ef7a542 100644 (file)
@@ -82,7 +82,7 @@ static struct dir_rename_entry *dir_rename_find_entry(struct hashmap *hashmap,
 {
        struct dir_rename_entry key;
 
-       if (dir == NULL)
+       if (!dir)
                return NULL;
        hashmap_entry_init(&key.ent, strhash(dir));
        key.dir = dir;
@@ -522,10 +522,10 @@ static struct stage_data *insert_stage_data(struct repository *r,
  */
 static struct string_list *get_unmerged(struct index_state *istate)
 {
-       struct string_list *unmerged = xcalloc(1, sizeof(struct string_list));
+       struct string_list *unmerged = xmalloc(sizeof(struct string_list));
        int i;
 
-       unmerged->strdup_strings = 1;
+       string_list_init_dup(unmerged);
 
        /* TODO: audit for interaction with sparse-index. */
        ensure_full_index(istate);
@@ -1160,6 +1160,7 @@ static int find_first_merges(struct repository *repo,
        }
 
        object_array_clear(&merges);
+       release_revisions(&revs);
        return result->nr;
 }
 
@@ -1990,14 +1991,14 @@ static void get_renamed_dir_portion(const char *old_path, const char *new_path,
         * renamed means the root directory can never be renamed -- because
         * the root directory always exists).
         */
-       if (end_of_old == NULL)
+       if (!end_of_old)
                return; /* Note: *old_dir and *new_dir are still NULL */
 
        /*
         * If new_path contains no directory (end_of_new is NULL), then we
         * have a rename of old_path's directory to the root directory.
         */
-       if (end_of_new == NULL) {
+       if (!end_of_new) {
                *old_dir = xstrndup(old_path, end_of_old - old_path);
                *new_dir = xstrdup("");
                return;
@@ -2116,7 +2117,7 @@ static char *handle_path_level_conflicts(struct merge_options *opt,
         * to ensure that's the case.
         */
        collision_ent = collision_find_entry(collisions, new_path);
-       if (collision_ent == NULL)
+       if (!collision_ent)
                BUG("collision_ent is NULL");
 
        /*
@@ -2996,7 +2997,7 @@ static void final_cleanup_rename(struct string_list *rename)
        const struct rename *re;
        int i;
 
-       if (rename == NULL)
+       if (!rename)
                return;
 
        for (i = 0; i < rename->nr; i++) {
@@ -3605,7 +3606,7 @@ static int merge_recursive_internal(struct merge_options *opt,
        }
 
        merged_merge_bases = pop_commit(&merge_bases);
-       if (merged_merge_bases == NULL) {
+       if (!merged_merge_bases) {
                /* if there is no common ancestor, use an empty tree */
                struct tree *tree;
 
index e2407b65b70d1e622979cdb2fe0e425ba6403ee1..eb32a7da956dc35ded8e8c129ccb7b23ab13d6a4 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" -wait -2 "$LOCAL" "$REMOTE" >/dev/null 2>&1
 }
 
+diff_cmd_help () {
+       echo "Use Araxis Merge (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -13,6 +17,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use Araxis Merge (requires a graphical session)"
+}
+
 translate_merge_tool_path() {
        echo compare
 }
index 26c19d46a5bdee5739b9a9425cc48fac3efd6bfb..2922667dddaa4ec6aa5407f7e98fd2cab23df053 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use Beyond Compare (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -13,6 +17,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use Beyond Compare (requires a graphical session)"
+}
+
 translate_merge_tool_path() {
        if type bcomp >/dev/null 2>/dev/null
        then
index 9f60e8da6527cf28dcc5ad4a3e5f7f0ca9442cb4..610963d377d66cd402cbe39e1f12a05b61fc0a02 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use Code Compare (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -13,6 +17,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use Code Compare (requires a graphical session)"
+}
+
 translate_merge_tool_path() {
        if merge_mode
        then
index ee6f374bceb8e14af5b424e64fbe9787006091e8..efae4c285ca9554d4c58ff6feb7e5ca9d2a3ff2b 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE" >/dev/null 2>&1
 }
 
+diff_cmd_help () {
+       echo "Use DeltaWalker (requires a graphical session)"
+}
+
 merge_cmd () {
        # Adding $(pwd)/ in front of $MERGED should not be necessary.
        # However without it, DeltaWalker (at least v1.9.8 on Windows)
@@ -16,6 +20,10 @@ merge_cmd () {
        fi >/dev/null 2>&1
 }
 
+merge_cmd_help () {
+       echo "Use DeltaWalker (requires a graphical session)"
+}
+
 translate_merge_tool_path () {
        echo DeltaWalker
 }
index 9b6355b98a71da2627b68c6543cea4f2515b8d54..9b5b62d1cae024e7bd6e944562ca0817c90a13b9 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE" >/dev/null 2>&1
 }
 
+diff_cmd_help () {
+       echo "Use DiffMerge (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -13,6 +17,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use DiffMerge (requires a graphical session)"
+}
+
 exit_code_trustable () {
        true
 }
index 5a3ae8b5695d3141ff0310a706495ea52037b464..ebfaba517216d85429a539177128f20719f538c7 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
 }
 
+diff_cmd_help () {
+       echo "Use Diffuse (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -13,3 +17,7 @@ merge_cmd () {
                        "$LOCAL" "$MERGED" "$REMOTE" | cat
        fi
 }
+
+merge_cmd_help () {
+       echo "Use Diffuse (requires a graphical session)"
+}
index 6c5101c4f729d49c544436e9262ca75e4ce6cddd..0d4d6098745e677f432a8c1affd793e9148f43e0 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" --default --mode=diff2 "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use ECMerge (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -12,3 +16,7 @@ merge_cmd () {
                        --default --mode=merge2 --to="$MERGED"
        fi
 }
+
+merge_cmd_help () {
+       echo "Use ECMerge (requires a graphical session)"
+}
index d1ce513ff5d3b3db14dd1270d2181099e1134c2c..fc6892cc95ed1ec480e06959bf7248f45d23371e 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" -f emerge-files-command "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use Emacs' Emerge"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -17,6 +21,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use Emacs' Emerge"
+}
+
 translate_merge_tool_path() {
        echo emacs
 }
index e72b06fc4d8ff76e06a0b972ae28df73efd4180d..6f53ca91613dc898d6247228eac98e8c23dd96fe 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE" -nh
 }
 
+diff_cmd_help () {
+       echo "Use ExamDiff Pro (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -11,6 +15,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use ExamDiff Pro (requires a graphical session)"
+}
+
 translate_merge_tool_path() {
        mergetool_find_win32_cmd "ExamDiff.com" "ExamDiff Pro"
 }
index 8b23a13c4111bdecc700a4a1a4547e15760eba58..3ed07efd16d2937939385d5777325eacccd65e2f 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use Guiffy's Diff Tool (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -13,6 +17,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use Guiffy's Diff Tool (requires a graphical session)"
+}
+
 exit_code_trustable () {
        true
 }
index 520cb914a18bd24421fe2c64daf6bac571e73975..ee8b3a0570eff25511c2d7be0cbf291faf145ee0 100644 (file)
@@ -4,6 +4,10 @@ diff_cmd () {
                "$LOCAL" "$REMOTE" >/dev/null 2>&1
 }
 
+diff_cmd_help () {
+       echo "Use KDiff3 (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -22,6 +26,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use KDiff3 (requires a graphical session)"
+}
+
 exit_code_trustable () {
        true
 }
index e8c0bfa678547258ff0f330ae756f3621e6aadc7..4ce23dbe8bbf72adf3cc06bd8928f61aa94ce020 100644 (file)
@@ -2,10 +2,18 @@ can_merge () {
        return 1
 }
 
+diff_cmd_help () {
+       echo "Use Kompare (requires a graphical session)"
+}
+
 diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+merge_cmd_help () {
+       echo "Use Kompare (requires a graphical session)"
+}
+
 exit_code_trustable () {
        true
 }
index aab4ebb9355ae946f1c7b289569f1892ea29e583..8ec0867e032bf7ed4036d5da4f2bfae7fd2b2ae4 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use Meld (requires a graphical session)"
+}
+
 merge_cmd () {
        check_meld_for_features
 
@@ -20,6 +24,10 @@ merge_cmd () {
        fi
 }
 
+merge_cmd_help () {
+       echo "Use Meld (requires a graphical session) with optional \`auto merge\` (see \`git help mergetool\`'s \`CONFIGURATION\` section)"
+}
+
 # Get meld help message
 init_meld_help_msg () {
        if test -z "$meld_help_msg"
index b608dd6de30aaab9b30729145029761330f9fb55..44adf8f95155cb4adb9a29de3ea28ca67ad579e8 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE" | cat
 }
 
+diff_cmd_help () {
+       echo "Use FileMerge (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -12,3 +16,7 @@ merge_cmd () {
                        -merge "$MERGED" | cat
        fi
 }
+
+merge_cmd_help () {
+       echo "Use FileMerge (requires a graphical session)"
+}
index 7a5b291dd28ad5b60ca0492480b800aaa9cc929e..f3cb197e5876e1a667e97189fff71fd355ccab30 100644 (file)
@@ -19,6 +19,10 @@ diff_cmd () {
        fi
 }
 
+diff_cmd_help () {
+       echo "Use HelixCore P4Merge (requires a graphical session)"
+}
+
 merge_cmd () {
        if ! $base_present
        then
@@ -34,3 +38,7 @@ create_empty_file () {
 
        printf "%s" "$empty_file"
 }
+
+merge_cmd_help () {
+       echo "Use HelixCore P4Merge (requires a graphical session)"
+}
index 9c2e6f6fd7d0a72c200b9f68f1f0f926318a27ba..5410835a6b5f6ed3d8e1220f1d98fc73d2457e64 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" mergetool "$LOCAL" "$REMOTE" -o "$MERGED"
 }
 
+diff_cmd_help () {
+       echo "Use Sublime Merge (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -10,3 +14,7 @@ merge_cmd () {
                "$merge_tool_path" mergetool "$LOCAL" "$REMOTE" -o "$MERGED"
        fi
 }
+
+merge_cmd_help () {
+       echo "Use Sublime Merge (requires a graphical session)"
+}
index eee5cb57e3ccf7f1ad7ad150c37a8b6d7ab6d436..66906a720d6079acce918b97083c0f64b95049b6 100644 (file)
@@ -2,6 +2,10 @@ diff_cmd () {
        "$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+diff_cmd_help () {
+       echo "Use TkDiff (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -14,3 +18,7 @@ merge_cmd () {
 exit_code_trustable () {
        true
 }
+
+merge_cmd_help () {
+       echo "Use TkDiff (requires a graphical session)"
+}
index d7ab666a59a2c8690861146bb6ae4874ed48e0de..507edcd444d12f4ebbc9f75b77ed89776904e401 100644 (file)
@@ -2,6 +2,10 @@ can_diff () {
        return 1
 }
 
+diff_cmd_help () {
+       echo "Use TortoiseMerge (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -30,3 +34,7 @@ translate_merge_tool_path() {
                echo tortoisemerge
        fi
 }
+
+merge_cmd_help () {
+       echo "Use TortoiseMerge (requires a graphical session)"
+}
index 96f6209a04106fbe8b66e30d5fefd0c8e92fb685..461a89b6f987972c6447a1e6d8df074aedddf814 100644 (file)
+# This script can be run in two different contexts:
+#
+#   - From git, when the user invokes the "vimdiff" merge tool. In this context
+#     this script expects the following environment variables (among others) to
+#     be defined (which is something "git" takes care of):
+#
+#       - $BASE
+#       - $LOCAL
+#       - $REMOTE
+#       - $MERGED
+#
+#     In this mode, all this script does is to run the next command:
+#
+#         vim -f -c ... $LOCAL $BASE $REMOTE $MERGED
+#
+#     ...where the "..." string depends on the value of the
+#     "mergetool.vimdiff.layout" configuration variable and is used to open vim
+#     with a certain layout of buffers, windows and tabs.
+#
+#   - From a script inside the unit tests framework folder ("t" folder) by
+#     sourcing this script and then manually calling "run_unit_tests", which
+#     will run a battery of unit tests to make sure nothing breaks.
+#     In this context this script does not expect any particular environment
+#     variable to be set.
+
+
+################################################################################
+## Internal functions (not meant to be used outside this script)
+################################################################################
+
+debug_print () {
+       # Send message to stderr if global variable GIT_MERGETOOL_VIMDIFF is set
+       # to "true"
+
+       if test -n "$GIT_MERGETOOL_VIMDIFF_DEBUG"
+       then
+               >&2 echo "$@"
+       fi
+}
+
+substring () {
+       # Return a substring of $1 containing $3 characters starting at
+       # zero-based offset $2.
+       #
+       # Examples:
+       #
+       #   substring "Hello world" 0 4  --> "Hell"
+       #   substring "Hello world" 3 4  --> "lo w"
+       #   substring "Hello world" 3 10 --> "lo world"
+
+       STRING=$1
+       START=$2
+       LEN=$3
+
+       echo "$STRING" | cut -c$(( START + 1 ))-$(( START + $LEN ))
+}
+
+gen_cmd_aux () {
+       # Auxiliary function used from "gen_cmd()".
+       # Read that other function documentation for more details.
+
+       LAYOUT=$1
+       CMD=$2  # This is a second (hidden) argument used for recursion
+
+       debug_print
+       debug_print "LAYOUT    : $LAYOUT"
+       debug_print "CMD       : $CMD"
+
+       if test -z "$CMD"
+       then
+               CMD="echo" # vim "nop" operator
+       fi
+
+       start=0
+       end=${#LAYOUT}
+
+       nested=0
+       nested_min=100
+
+
+       # Step 1:
+       #
+       # Increase/decrease "start"/"end" indices respectively to get rid of
+       # outer parenthesis.
+       #
+       # Example:
+       #
+       #   - BEFORE: (( LOCAL , BASE ) / MERGED )
+       #   - AFTER :  ( LOCAL , BASE ) / MERGED
+
+       oldIFS=$IFS
+       IFS=#
+       for c in $(echo "$LAYOUT" | sed 's:.:&#:g')
+       do
+               if test "$c" = " "
+               then
+                       continue
+               fi
+
+               if test "$c" = "("
+               then
+                       nested=$(( nested + 1 ))
+                       continue
+               fi
+
+               if test "$c" = ")"
+               then
+                       nested=$(( nested - 1 ))
+                       continue
+               fi
+
+               if test "$nested" -lt "$nested_min"
+               then
+                       nested_min=$nested
+               fi
+       done
+       IFS=$oldIFS
+
+       debug_print "NESTED MIN: $nested_min"
+
+       while test "$nested_min" -gt "0"
+       do
+               start=$(( start + 1 ))
+               end=$(( end - 1 ))
+
+               start_minus_one=$(( start - 1 ))
+
+               while ! test "$(substring "$LAYOUT" "$start_minus_one" 1)" = "("
+               do
+                       start=$(( start + 1 ))
+                       start_minus_one=$(( start_minus_one + 1 ))
+               done
+
+               while ! test "$(substring "$LAYOUT" "$end" 1)" = ")"
+               do
+                       end=$(( end - 1 ))
+               done
+
+               nested_min=$(( nested_min - 1 ))
+       done
+
+       debug_print "CLEAN     : $(substring "$LAYOUT" "$start" "$(( end - start ))")"
+
+
+       # Step 2:
+       #
+       # Search for all valid separators ("+", "/" or ",") which are *not*
+       # inside parenthesis. Save the index at which each of them makes the
+       # first appearance.
+
+       index_new_tab=""
+       index_horizontal_split=""
+       index_vertical_split=""
+
+       nested=0
+       i=$(( start - 1 ))
+
+       oldIFS=$IFS
+       IFS=#
+       for c in $(substring "$LAYOUT" "$start" "$(( end - start ))" | sed 's:.:&#:g');
+       do
+               i=$(( i + 1 ))
+
+               if test "$c" = " "
+               then
+                       continue
+               fi
+
+               if test "$c" = "("
+               then
+                       nested=$(( nested + 1 ))
+                       continue
+               fi
+
+               if test "$c" = ")"
+               then
+                       nested=$(( nested - 1 ))
+                       continue
+               fi
+
+               if test "$nested" = 0
+               then
+                       current=$c
+
+                       if test "$current" = "+"
+                       then
+                               if test -z "$index_new_tab"
+                               then
+                                       index_new_tab=$i
+                               fi
+
+                       elif test "$current" = "/"
+                       then
+                               if test -z "$index_horizontal_split"
+                               then
+                                       index_horizontal_split=$i
+                               fi
+
+                       elif test "$current" = ","
+                       then
+                               if test -z "$index_vertical_split"
+                               then
+                                       index_vertical_split=$i
+                               fi
+                       fi
+               fi
+       done
+       IFS=$oldIFS
+
+
+       # Step 3:
+       #
+       # Process the separator with the highest order of precedence
+       # (";" has the highest precedence and "|" the lowest one).
+       #
+       # By "process" I mean recursively call this function twice: the first
+       # one with the substring at the left of the separator and the second one
+       # with the one at its right.
+
+       terminate="false"
+
+       if ! test -z "$index_new_tab"
+       then
+               before="-tabnew"
+               after="tabnext"
+               index=$index_new_tab
+               terminate="true"
+
+       elif ! test -z "$index_horizontal_split"
+       then
+               before="split"
+               after="wincmd j"
+               index=$index_horizontal_split
+               terminate="true"
+
+       elif ! test -z "$index_vertical_split"
+       then
+               before="vertical split"
+               after="wincmd l"
+               index=$index_vertical_split
+               terminate="true"
+       fi
+
+       if  test "$terminate" = "true"
+       then
+               CMD="$CMD | $before"
+               CMD=$(gen_cmd_aux "$(substring "$LAYOUT" "$start" "$(( index - start ))")" "$CMD")
+               CMD="$CMD | $after"
+               CMD=$(gen_cmd_aux "$(substring "$LAYOUT" "$(( index + 1 ))" "$(( ${#LAYOUT} - index ))")" "$CMD")
+               echo "$CMD"
+               return
+       fi
+
+
+       # Step 4:
+       #
+       # If we reach this point, it means there are no separators and we just
+       # need to print the command to display the specified buffer
+
+       target=$(substring "$LAYOUT" "$start" "$(( end - start ))" | sed 's:[ @();|-]::g')
+
+       if test "$target" = "LOCAL"
+       then
+               CMD="$CMD | 1b"
+
+       elif test "$target" = "BASE"
+       then
+               CMD="$CMD | 2b"
+
+       elif test "$target" = "REMOTE"
+       then
+               CMD="$CMD | 3b"
+
+       elif test "$target" = "MERGED"
+       then
+               CMD="$CMD | 4b"
+
+       else
+               CMD="$CMD | ERROR: >$target<"
+       fi
+
+       echo "$CMD"
+       return
+}
+
+
+gen_cmd () {
+       # This function returns (in global variable FINAL_CMD) the string that
+       # you can use when invoking "vim" (as shown next) to obtain a given
+       # layout:
+       #
+       #   $ vim -f $FINAL_CMD "$LOCAL" "$BASE" "$REMOTE" "$MERGED"
+       #
+       # It takes one single argument: a string containing the desired layout
+       # definition.
+       #
+       # The syntax of the "layout definitions" is explained in "Documentation/
+       # mergetools/vimdiff.txt" but you can already intuitively understand how
+       # it works by knowing that...
+       #
+       #   * "+" means "a new vim tab"
+       #   * "/" means "a new vim horizontal split"
+       #   * "," means "a new vim vertical split"
+       #
+       # It also returns (in global variable FINAL_TARGET) the name ("LOCAL",
+       # "BASE", "REMOTE" or "MERGED") of the file that is marked with an "@",
+       # or "MERGED" if none of them is.
+       #
+       # Example:
+       #
+       #     gen_cmd "@LOCAL , REMOTE"
+       #     |
+       #     `-> FINAL_CMD    == "-c \"echo | vertical split | 1b | wincmd l | 3b | tabdo windo diffthis\" -c \"tabfirst\""
+       #         FINAL_TARGET == "LOCAL"
+
+       LAYOUT=$1
+
+
+       # Search for a "@" in one of the files identifiers ("LOCAL", "BASE",
+       # "REMOTE", "MERGED"). If not found, use "MERGE" as the default file
+       # where changes will be saved.
+
+       if echo "$LAYOUT" | grep @LOCAL >/dev/null
+       then
+               FINAL_TARGET="LOCAL"
+       elif echo "$LAYOUT" | grep @BASE >/dev/null
+       then
+               FINAL_TARGET="BASE"
+       else
+               FINAL_TARGET="MERGED"
+       fi
+
+
+       # Obtain the first part of vim "-c" option to obtain the desired layout
+
+       CMD=$(gen_cmd_aux "$LAYOUT")
+
+
+       # Adjust the just obtained script depending on whether more than one
+       # windows are visible or not
+
+       if echo "$LAYOUT" | grep ",\|/" >/dev/null
+       then
+               CMD="$CMD | tabdo windo diffthis"
+       else
+               CMD="$CMD | bufdo diffthis"
+       fi
+
+
+       # Add an extra "-c" option to move to the first tab (notice that we
+       # can't simply append the command to the previous "-c" string as
+       # explained here: https://github.com/vim/vim/issues/9076
+
+       FINAL_CMD="-c \"$CMD\" -c \"tabfirst\""
+}
+
+
+################################################################################
+## API functions (called from "git-mergetool--lib.sh")
+################################################################################
+
 diff_cmd () {
        "$merge_tool_path" -R -f -d \
                -c 'wincmd l' -c 'cd $GIT_PREFIX' "$LOCAL" "$REMOTE"
 }
 
+
+diff_cmd_help () {
+       TOOL=$1
+
+       case "$TOOL" in
+       nvimdiff*)
+               printf "Use Neovim"
+               ;;
+       gvimdiff*)
+               printf "Use gVim (requires a graphical session)"
+               ;;
+       vimdiff*)
+               printf "Use Vim"
+               ;;
+       esac
+
+       return 0
+}
+
+
 merge_cmd () {
+       layout=$(git config mergetool.vimdiff.layout)
+
        case "$1" in
        *vimdiff)
-               if $base_present
+               if test -z "$layout"
                then
-                       "$merge_tool_path" -f -d -c '4wincmd w | wincmd J' \
-                               "$LOCAL" "$BASE" "$REMOTE" "$MERGED"
-               else
-                       "$merge_tool_path" -f -d -c 'wincmd l' \
-                               "$LOCAL" "$MERGED" "$REMOTE"
+                       # Default layout when none is specified
+                       layout="(LOCAL,BASE,REMOTE)/MERGED"
                fi
                ;;
        *vimdiff1)
-               "$merge_tool_path" -f -d \
-                       -c 'echon "Resolve conflicts leftward then save. Use :cq to abort."' \
-                       "$LOCAL" "$REMOTE"
-               ret="$?"
-               if test "$ret" -eq 0
-               then
-                       cp -- "$LOCAL" "$MERGED"
-               fi
-               return "$ret"
+               layout="@LOCAL,REMOTE"
                ;;
        *vimdiff2)
-               "$merge_tool_path" -f -d -c 'wincmd l' \
-                       "$LOCAL" "$MERGED" "$REMOTE"
+               layout="LOCAL,MERGED,REMOTE"
                ;;
        *vimdiff3)
-               if $base_present
+               layout="MERGED"
+               ;;
+       esac
+
+       gen_cmd "$layout"
+
+       debug_print ""
+       debug_print "FINAL CMD : $FINAL_CMD"
+       debug_print "FINAL TAR : $FINAL_TARGET"
+
+       if $base_present
+       then
+               eval "$merge_tool_path" \
+                       -f "$FINAL_CMD" "$LOCAL" "$BASE" "$REMOTE" "$MERGED"
+       else
+               # If there is no BASE (example: a merge conflict in a new file
+               # with the same name created in both braches which didn't exist
+               # before), close all BASE windows using vim's "quit" command
+
+               FINAL_CMD=$(echo "$FINAL_CMD" | \
+                       sed -e 's:2b:quit:g' -e 's:3b:2b:g' -e 's:4b:3b:g')
+
+               eval "$merge_tool_path" \
+                       -f "$FINAL_CMD" "$LOCAL" "$REMOTE" "$MERGED"
+       fi
+
+       ret="$?"
+
+       if test "$ret" -eq 0
+       then
+               case "$FINAL_TARGET" in
+               LOCAL)
+                       source_path="$LOCAL"
+                       ;;
+               REMOTE)
+                       source_path="$REMOTE"
+                       ;;
+               MERGED|*)
+                       # Do nothing
+                       source_path=
+                       ;;
+               esac
+
+               if test -n "$source_path"
                then
-                       "$merge_tool_path" -f -d -c 'hid | hid | hid' \
-                               "$LOCAL" "$REMOTE" "$BASE" "$MERGED"
-               else
-                       "$merge_tool_path" -f -d -c 'hid | hid' \
-                               "$LOCAL" "$REMOTE" "$MERGED"
+                       cp "$source_path" "$MERGED"
                fi
+       fi
+
+       return "$ret"
+}
+
+
+merge_cmd_help () {
+       TOOL=$1
+
+       case "$TOOL" in
+       nvimdiff*)
+               printf "Use Neovim "
+               ;;
+       gvimdiff*)
+               printf "Use gVim (requires a graphical session) "
+               ;;
+       vimdiff*)
+               printf "Use Vim "
+               ;;
+       esac
+
+       case "$TOOL" in
+       *1)
+               echo "with a 2 panes layout (LOCAL and REMOTE)"
+               ;;
+       *2)
+               echo "with a 3 panes layout (LOCAL, MERGED and REMOTE)"
+               ;;
+       *3)
+               echo "where only the MERGED file is shown"
+               ;;
+       *)
+               echo "with a custom layout (see \`git help mergetool\`'s \`BACKEND SPECIFIC HINTS\` section)"
                ;;
        esac
+
+       return 0
 }
 
-translate_merge_tool_path() {
+
+translate_merge_tool_path () {
        case "$1" in
        nvimdiff*)
                echo nvim
@@ -57,14 +503,121 @@ translate_merge_tool_path() {
        esac
 }
 
+
 exit_code_trustable () {
        true
 }
 
+
 list_tool_variants () {
-       for prefix in '' g n; do
-               for suffix in '' 1 2 3; do
-                       echo "${prefix}vimdiff${suffix}"
+       if test "$TOOL_MODE" = "diff"
+       then
+               for prefix in '' g n
+               do
+                       echo "${prefix}vimdiff"
+               done
+       else
+               for prefix in '' g n
+               do
+                       for suffix in '' 1 2 3
+                       do
+                               echo "${prefix}vimdiff${suffix}"
+                       done
                done
+       fi
+}
+
+
+################################################################################
+## Unit tests (called from scripts inside the "t" folder)
+################################################################################
+
+run_unit_tests () {
+       # Function to make sure that we don't break anything when modifying this
+       # script.
+
+       NUMBER_OF_TEST_CASES=16
+
+       TEST_CASE_01="(LOCAL,BASE,REMOTE)/MERGED"   # default behaviour
+       TEST_CASE_02="@LOCAL,REMOTE"                # when using vimdiff1
+       TEST_CASE_03="LOCAL,MERGED,REMOTE"          # when using vimdiff2
+       TEST_CASE_04="MERGED"                       # when using vimdiff3
+       TEST_CASE_05="LOCAL/MERGED/REMOTE"
+       TEST_CASE_06="(LOCAL/REMOTE),MERGED"
+       TEST_CASE_07="MERGED,(LOCAL/REMOTE)"
+       TEST_CASE_08="(LOCAL,REMOTE)/MERGED"
+       TEST_CASE_09="MERGED/(LOCAL,REMOTE)"
+       TEST_CASE_10="(LOCAL/BASE/REMOTE),MERGED"
+       TEST_CASE_11="(LOCAL,BASE,REMOTE)/MERGED+BASE,LOCAL+BASE,REMOTE+(LOCAL/BASE/REMOTE),MERGED"
+       TEST_CASE_12="((LOCAL,REMOTE)/BASE),MERGED"
+       TEST_CASE_13="((LOCAL,REMOTE)/BASE),((LOCAL/REMOTE),MERGED)"
+       TEST_CASE_14="BASE,REMOTE+BASE,LOCAL"
+       TEST_CASE_15="  ((  (LOCAL , BASE , REMOTE) / MERGED))   +(BASE)   , LOCAL+ BASE , REMOTE+ (((LOCAL / BASE / REMOTE)) ,    MERGED   )  "
+       TEST_CASE_16="LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE + (LOCAL / BASE / REMOTE),MERGED"
+
+       EXPECTED_CMD_01="-c \"echo | split | vertical split | 1b | wincmd l | vertical split | 2b | wincmd l | 3b | wincmd j | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_02="-c \"echo | vertical split | 1b | wincmd l | 3b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_03="-c \"echo | vertical split | 1b | wincmd l | vertical split | 4b | wincmd l | 3b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_04="-c \"echo | 4b | bufdo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_05="-c \"echo | split | 1b | wincmd j | split | 4b | wincmd j | 3b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_06="-c \"echo | vertical split | split | 1b | wincmd j | 3b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_07="-c \"echo | vertical split | 4b | wincmd l | split | 1b | wincmd j | 3b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_08="-c \"echo | split | vertical split | 1b | wincmd l | 3b | wincmd j | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_09="-c \"echo | split | 4b | wincmd j | vertical split | 1b | wincmd l | 3b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_10="-c \"echo | vertical split | split | 1b | wincmd j | split | 2b | wincmd j | 3b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_11="-c \"echo | -tabnew | split | vertical split | 1b | wincmd l | vertical split | 2b | wincmd l | 3b | wincmd j | 4b | tabnext | -tabnew | vertical split | 2b | wincmd l | 1b | tabnext | -tabnew | vertical split | 2b | wincmd l | 3b | tabnext | vertical split | split | 1b | wincmd j | split | 2b | wincmd j | 3b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_12="-c \"echo | vertical split | split | vertical split | 1b | wincmd l | 3b | wincmd j | 2b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_13="-c \"echo | vertical split | split | vertical split | 1b | wincmd l | 3b | wincmd j | 2b | wincmd l | vertical split | split | 1b | wincmd j | 3b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_14="-c \"echo | -tabnew | vertical split | 2b | wincmd l | 3b | tabnext | vertical split | 2b | wincmd l | 1b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_15="-c \"echo | -tabnew | split | vertical split | 1b | wincmd l | vertical split | 2b | wincmd l | 3b | wincmd j | 4b | tabnext | -tabnew | vertical split | 2b | wincmd l | 1b | tabnext | -tabnew | vertical split | 2b | wincmd l | 3b | tabnext | vertical split | split | 1b | wincmd j | split | 2b | wincmd j | 3b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+       EXPECTED_CMD_16="-c \"echo | -tabnew | split | vertical split | 1b | wincmd l | vertical split | 2b | wincmd l | 3b | wincmd j | 4b | tabnext | -tabnew | vertical split | 2b | wincmd l | 1b | tabnext | -tabnew | vertical split | 2b | wincmd l | 3b | tabnext | vertical split | split | 1b | wincmd j | split | 2b | wincmd j | 3b | wincmd l | 4b | tabdo windo diffthis\" -c \"tabfirst\""
+
+       EXPECTED_TARGET_01="MERGED"
+       EXPECTED_TARGET_02="LOCAL"
+       EXPECTED_TARGET_03="MERGED"
+       EXPECTED_TARGET_04="MERGED"
+       EXPECTED_TARGET_05="MERGED"
+       EXPECTED_TARGET_06="MERGED"
+       EXPECTED_TARGET_07="MERGED"
+       EXPECTED_TARGET_08="MERGED"
+       EXPECTED_TARGET_09="MERGED"
+       EXPECTED_TARGET_10="MERGED"
+       EXPECTED_TARGET_11="MERGED"
+       EXPECTED_TARGET_12="MERGED"
+       EXPECTED_TARGET_13="MERGED"
+       EXPECTED_TARGET_14="MERGED"
+       EXPECTED_TARGET_15="MERGED"
+       EXPECTED_TARGET_16="MERGED"
+
+       at_least_one_ko="false"
+
+       for i in $(seq -w 1 99)
+       do
+               if test "$i" -gt $NUMBER_OF_TEST_CASES
+               then
+                       break
+               fi
+
+               gen_cmd "$(eval echo \${TEST_CASE_"$i"})"
+
+               if test "$FINAL_CMD" = "$(eval echo \${EXPECTED_CMD_"$i"})" \
+                       && test "$FINAL_TARGET" = "$(eval echo \${EXPECTED_TARGET_"$i"})"
+               then
+                       printf "Test Case #%02d: OK\n" "$(echo "$i" | sed 's/^0*//')"
+               else
+                       printf "Test Case #%02d: KO !!!!\n" "$(echo "$i" | sed 's/^0*//')"
+                       echo "  FINAL_CMD              : $FINAL_CMD"
+                       echo "  FINAL_CMD (expected)   : $(eval echo \${EXPECTED_CMD_"$i"})"
+                       echo "  FINAL_TARGET           : $FINAL_TARGET"
+                       echo "  FINAL_TARGET (expected): $(eval echo \${EXPECTED_TARGET_"$i"})"
+                       at_least_one_ko="true"
+               fi
        done
+
+       if test "$at_least_one_ko" = "true"
+       then
+               return 255
+       else
+               return 0
+       fi
 }
index 74d03259fdf157c9ee07eec7b2c40727f5ce49dc..36c72dde6e3ff53ed0204166343fde3ae9af9809 100644 (file)
@@ -3,6 +3,10 @@ diff_cmd () {
        return 0
 }
 
+diff_cmd_help () {
+       echo "Use WinMerge (requires a graphical session)"
+}
+
 merge_cmd () {
        # mergetool.winmerge.trustExitCode is implicitly false.
        # touch $BACKUP so that we can check_unchanged.
@@ -13,3 +17,7 @@ merge_cmd () {
 translate_merge_tool_path() {
        mergetool_find_win32_cmd "WinMergeU.exe" "WinMerge"
 }
+
+merge_cmd_help () {
+       echo "Use WinMerge (requires a graphical session)"
+}
index d5ce467995653e07be726c307fcf3b61fc5ddea4..cd205f98425dfc66a41b8b5ea536bf81b374e6c7 100644 (file)
@@ -12,6 +12,10 @@ diff_cmd () {
        fi
 }
 
+diff_cmd_help () {
+       echo "Use xxdiff (requires a graphical session)"
+}
+
 merge_cmd () {
        if $base_present
        then
@@ -28,3 +32,7 @@ merge_cmd () {
                        --merged-file "$MERGED" "$LOCAL" "$REMOTE"
        fi
 }
+
+merge_cmd_help () {
+       echo "Use xxdiff (requires a graphical session)"
+}
diff --git a/midx.c b/midx.c
index 107365d2114ce2945d4221ff853df97829b22d05..5f0dd386b0266b6549c85499ab50e964ed868f1d 100644 (file)
--- a/midx.c
+++ b/midx.c
 
 #define PACK_EXPIRED UINT_MAX
 
-static uint8_t oid_version(void)
-{
-       switch (hash_algo_by_ptr(the_hash_algo)) {
-       case GIT_HASH_SHA1:
-               return 1;
-       case GIT_HASH_SHA256:
-               return 2;
-       default:
-               die(_("invalid hash version"));
-       }
-}
-
 const unsigned char *get_midx_checksum(struct multi_pack_index *m)
 {
        return m->data + m->data_len - the_hash_algo->rawsz;
@@ -134,9 +122,9 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
                      m->version);
 
        hash_version = m->data[MIDX_BYTE_HASH_VERSION];
-       if (hash_version != oid_version()) {
+       if (hash_version != oid_version(the_hash_algo)) {
                error(_("multi-pack-index hash version %u does not match version %u"),
-                     hash_version, oid_version());
+                     hash_version, oid_version(the_hash_algo));
                goto cleanup_fail;
        }
        m->hash_len = the_hash_algo->rawsz;
@@ -420,7 +408,7 @@ static size_t write_midx_header(struct hashfile *f,
 {
        hashwrite_be32(f, MIDX_SIGNATURE);
        hashwrite_u8(f, MIDX_VERSION);
-       hashwrite_u8(f, oid_version());
+       hashwrite_u8(f, oid_version(the_hash_algo));
        hashwrite_u8(f, num_chunks);
        hashwrite_u8(f, 0); /* unused */
        hashwrite_be32(f, num_packs);
@@ -1061,6 +1049,7 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
        if (indexed_commits_nr_p)
                *indexed_commits_nr_p = cb.commits_nr;
 
+       release_revisions(&revs);
        return cb.commits;
 }
 
@@ -1132,17 +1121,26 @@ cleanup:
 static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
                                                        const char *object_dir)
 {
+       struct multi_pack_index *result = NULL;
        struct multi_pack_index *cur;
+       char *obj_dir_real = real_pathdup(object_dir, 1);
+       struct strbuf cur_path_real = STRBUF_INIT;
 
        /* Ensure the given object_dir is local, or a known alternate. */
-       find_odb(r, object_dir);
+       find_odb(r, obj_dir_real);
 
        for (cur = get_multi_pack_index(r); cur; cur = cur->next) {
-               if (!strcmp(object_dir, cur->object_dir))
-                       return cur;
+               strbuf_realpath(&cur_path_real, cur->object_dir, 1);
+               if (!strcmp(obj_dir_real, cur_path_real.buf)) {
+                       result = cur;
+                       goto cleanup;
+               }
        }
 
-       return NULL;
+cleanup:
+       free(obj_dir_real);
+       strbuf_release(&cur_path_real);
+       return result;
 }
 
 static int write_midx_internal(const char *object_dir,
index 5ffbf3d4fd46de4242bd1ce00c6b3c2dad17322f..79eb8339b60710b106748792d3faab59b374b62a 100644 (file)
@@ -997,7 +997,7 @@ int has_loose_object_nonlocal(const struct object_id *oid)
        return check_and_freshen_nonlocal(oid, 0);
 }
 
-static int has_loose_object(const struct object_id *oid)
+int has_loose_object(const struct object_id *oid)
 {
        return check_and_freshen(oid, 0);
 }
@@ -1728,7 +1728,7 @@ void *read_object_file_extended(struct repository *r,
                die(_("loose object %s (stored in %s) is corrupt"),
                    oid_to_hex(repl), path);
 
-       if ((p = has_packed_and_bad(r, repl)) != NULL)
+       if ((p = has_packed_and_bad(r, repl)))
                die(_("packed object %s (stored in %s) is corrupt"),
                    oid_to_hex(repl), p->pack_name);
        obj_read_unlock();
@@ -1893,7 +1893,9 @@ static void close_loose_object(int fd, const char *filename)
        if (the_repository->objects->odb->will_destroy)
                goto out;
 
-       if (fsync_object_files > 0)
+       if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
+               fsync_loose_object_bulk_checkin(fd, filename);
+       else if (fsync_object_files > 0)
                fsync_or_die(fd, filename);
        else
                fsync_component_or_die(FSYNC_COMPONENT_LOOSE_OBJECT, fd,
@@ -1961,6 +1963,9 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
        static struct strbuf tmp_file = STRBUF_INIT;
        static struct strbuf filename = STRBUF_INIT;
 
+       if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT))
+               prepare_loose_object_bulk_checkin();
+
        loose_object_path(the_repository, &filename, oid);
 
        fd = create_tmpfile(&tmp_file, filename.buf);
@@ -2035,6 +2040,8 @@ static int freshen_packed_object(const struct object_id *oid)
        struct pack_entry e;
        if (!find_pack_entry(the_repository, oid, &e))
                return 0;
+       if (e.p->is_cruft)
+               return 0;
        if (e.p->freshened)
                return 1;
        if (!freshen_file(e.p->pack_name))
@@ -2624,7 +2631,7 @@ int read_loose_object(const char *path,
        }
 
        if (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr),
-                               NULL) < 0) {
+                               NULL) != ULHR_OK) {
                error(_("unable to unpack header of %s"), path);
                goto out;
        }
index f0e327f91f57ac9dabaec840cd1eb77a4b4293ec..4d2746574cde0b813a73772c13d71a30db696128 100644 (file)
@@ -1832,7 +1832,8 @@ static void diagnose_invalid_index_path(struct repository *r,
                pos = -pos - 1;
        if (pos < istate->cache_nr) {
                ce = istate->cache[pos];
-               if (ce_namelen(ce) == namelen &&
+               if (!S_ISSPARSEDIR(ce->ce_mode) &&
+                   ce_namelen(ce) == namelen &&
                    !memcmp(ce->name, filename, namelen))
                        die(_("path '%s' is in the index, but not at stage %d\n"
                            "hint: Did you mean ':%d:%s'?"),
@@ -1848,7 +1849,8 @@ static void diagnose_invalid_index_path(struct repository *r,
                pos = -pos - 1;
        if (pos < istate->cache_nr) {
                ce = istate->cache[pos];
-               if (ce_namelen(ce) == fullname.len &&
+               if (!S_ISSPARSEDIR(ce->ce_mode) &&
+                   ce_namelen(ce) == fullname.len &&
                    !memcmp(ce->name, fullname.buf, fullname.len))
                        die(_("path '%s' is in the index, but not '%s'\n"
                            "hint: Did you mean ':%d:%s' aka ':%d:./%s'?"),
@@ -1881,6 +1883,20 @@ static char *resolve_relative_path(struct repository *r, const char *rel)
                           rel);
 }
 
+static int reject_tree_in_index(struct repository *repo,
+                               int only_to_die,
+                               const struct cache_entry *ce,
+                               int stage,
+                               const char *prefix,
+                               const char *cp)
+{
+       if (!S_ISSPARSEDIR(ce->ce_mode))
+               return 0;
+       if (only_to_die)
+               diagnose_invalid_index_path(repo, stage, prefix, cp);
+       return -1;
+}
+
 static enum get_oid_result get_oid_with_context_1(struct repository *repo,
                                  const char *name,
                                  unsigned flags,
@@ -1955,9 +1971,12 @@ static enum get_oid_result get_oid_with_context_1(struct repository *repo,
                            memcmp(ce->name, cp, namelen))
                                break;
                        if (ce_stage(ce) == stage) {
+                               free(new_path);
+                               if (reject_tree_in_index(repo, only_to_die, ce,
+                                                        stage, prefix, cp))
+                                       return -1;
                                oidcpy(oid, &ce->oid);
                                oc->mode = ce->ce_mode;
-                               free(new_path);
                                return 0;
                        }
                        pos++;
index bd2322ed8ce3368d8b06ab570f2f1f4c2217d757..539ea439046dc18625917769040c7f824c490c24 100644 (file)
@@ -115,12 +115,20 @@ struct packed_git {
                 freshened:1,
                 do_not_close:1,
                 pack_promisor:1,
-                multi_pack_index:1;
+                multi_pack_index:1,
+                is_cruft:1;
        unsigned char hash[GIT_MAX_RAWSZ];
        struct revindex_entry *revindex;
        const uint32_t *revindex_data;
        const uint32_t *revindex_map;
        size_t revindex_size;
+       /*
+        * mtimes_map points at the beginning of the memory mapped region of
+        * this pack's corresponding .mtimes file, and mtimes_size is the size
+        * of that .mtimes file
+        */
+       const uint32_t *mtimes_map;
+       size_t mtimes_size;
        /* something like ".git/objects/pack/xxxxx.pack" */
        char pack_name[FLEX_ARRAY]; /* more */
 };
@@ -312,10 +320,6 @@ int has_object(struct repository *r, const struct object_id *oid,
  * These functions can be removed once all callers have migrated to
  * has_object() and/or oid_object_info_extended().
  */
-#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
-#define has_sha1_file_with_flags(sha1, flags) repo_has_sha1_file_with_flags(the_repository, sha1, flags)
-#define has_sha1_file(sha1) repo_has_sha1_file(the_repository, sha1)
-#endif
 int repo_has_object_file(struct repository *r, const struct object_id *oid);
 int repo_has_object_file_with_flags(struct repository *r,
                                    const struct object_id *oid, int flags);
@@ -331,6 +335,8 @@ int repo_has_object_file_with_flags(struct repository *r,
  */
 int has_loose_object_nonlocal(const struct object_id *);
 
+int has_loose_object(const struct object_id *);
+
 /**
  * format_object_header() is a thin wrapper around s xsnprintf() that
  * writes the initial "<type> <obj-len>" part of the loose object
index cf681547f2e626b324fd5bcc9c33fbec8f449d81..c43375bd344f22473adcd7cac09c9f1572e27079 100644 (file)
@@ -326,6 +326,7 @@ next:
        trace2_data_intmax("pack-bitmap-write", the_repository,
                           "num_maximal_commits", num_maximal);
 
+       release_revisions(&revs);
        free_commit_list(reusable);
 }
 
index 97909d48da381f81622d36fb5889fd5d7013b04a..36134222d7a00acc1ebf5d52b3c3d817c10af8e9 100644 (file)
@@ -111,7 +111,7 @@ static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
        struct ewah_bitmap *parent;
        struct ewah_bitmap *composed;
 
-       if (st->xor == NULL)
+       if (!st->xor)
                return st->root;
 
        composed = ewah_pool_new();
@@ -279,7 +279,7 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
                if (xor_offset > 0) {
                        xor_bitmap = recent_bitmaps[(i - xor_offset) % MAX_XOR_OFFSET];
 
-                       if (xor_bitmap == NULL)
+                       if (!xor_bitmap)
                                return error("Invalid XOR offset in bitmap pack index");
                }
 
@@ -315,6 +315,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
        struct stat st;
        char *idx_name = midx_bitmap_filename(midx);
        int fd = git_open(idx_name);
+       uint32_t i;
+       struct packed_git *preferred;
 
        free(idx_name);
 
@@ -353,6 +355,20 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
                warning(_("multi-pack bitmap is missing required reverse index"));
                goto cleanup;
        }
+
+       for (i = 0; i < bitmap_git->midx->num_packs; i++) {
+               if (prepare_midx_pack(the_repository, bitmap_git->midx, i))
+                       die(_("could not open pack %s"),
+                           bitmap_git->midx->pack_names[i]);
+       }
+
+       preferred = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)];
+       if (!is_pack_valid(preferred)) {
+               warning(_("preferred pack (%s) is invalid"),
+                       preferred->pack_name);
+               goto cleanup;
+       }
+
        return 0;
 
 cleanup:
@@ -429,8 +445,6 @@ static int load_reverse_index(struct bitmap_index *bitmap_git)
                 * since we will need to make use of them in pack-objects.
                 */
                for (i = 0; i < bitmap_git->midx->num_packs; i++) {
-                       if (prepare_midx_pack(the_repository, bitmap_git->midx, i))
-                               die(_("load_reverse_index: could not open pack"));
                        ret = load_pack_revindex(bitmap_git->midx->packs[i]);
                        if (ret)
                                return ret;
@@ -728,7 +742,7 @@ static int add_commit_to_bitmap(struct bitmap_index *bitmap_git,
        if (!or_with)
                return 0;
 
-       if (*base == NULL)
+       if (!*base)
                *base = ewah_to_bitmap(or_with);
        else
                bitmap_or_ewah(*base, or_with);
@@ -771,7 +785,7 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
         * Best case scenario: We found bitmaps for all the roots,
         * so the resulting `or` bitmap has the full reachability analysis
         */
-       if (not_mapped == NULL)
+       if (!not_mapped)
                return base;
 
        roots = not_mapped;
@@ -805,7 +819,7 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
                struct include_data incdata;
                struct bitmap_show_data show_data;
 
-               if (base == NULL)
+               if (!base)
                        base = bitmap_new();
 
                incdata.bitmap_git = bitmap_git;
@@ -1299,7 +1313,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
                reset_revision_walk();
                revs->ignore_missing_links = 0;
 
-               if (haves_bitmap == NULL)
+               if (!haves_bitmap)
                        BUG("failed to perform bitmap walk");
        }
 
@@ -1698,7 +1712,7 @@ void test_bitmap_walk(struct rev_info *revs)
                result = ewah_to_bitmap(bm);
        }
 
-       if (result == NULL)
+       if (!result)
                die("Commit %s doesn't have an indexed bitmap", oid_to_hex(&root->oid));
 
        revs->tag_objects = 1;
diff --git a/pack-mtimes.c b/pack-mtimes.c
new file mode 100644 (file)
index 0000000..0e0aafd
--- /dev/null
@@ -0,0 +1,129 @@
+#include "git-compat-util.h"
+#include "pack-mtimes.h"
+#include "object-store.h"
+#include "packfile.h"
+
+static char *pack_mtimes_filename(struct packed_git *p)
+{
+       size_t len;
+       if (!strip_suffix(p->pack_name, ".pack", &len))
+               BUG("pack_name does not end in .pack");
+       return xstrfmt("%.*s.mtimes", (int)len, p->pack_name);
+}
+
+#define MTIMES_HEADER_SIZE (12)
+
+struct mtimes_header {
+       uint32_t signature;
+       uint32_t version;
+       uint32_t hash_id;
+};
+
+static int load_pack_mtimes_file(char *mtimes_file,
+                                uint32_t num_objects,
+                                const uint32_t **data_p, size_t *len_p)
+{
+       int fd, ret = 0;
+       struct stat st;
+       uint32_t *data = NULL;
+       size_t mtimes_size, expected_size;
+       struct mtimes_header header;
+
+       fd = git_open(mtimes_file);
+
+       if (fd < 0) {
+               ret = -1;
+               goto cleanup;
+       }
+       if (fstat(fd, &st)) {
+               ret = error_errno(_("failed to read %s"), mtimes_file);
+               goto cleanup;
+       }
+
+       mtimes_size = xsize_t(st.st_size);
+
+       if (mtimes_size < MTIMES_HEADER_SIZE) {
+               ret = error(_("mtimes file %s is too small"), mtimes_file);
+               goto cleanup;
+       }
+
+       data = xmmap(NULL, mtimes_size, PROT_READ, MAP_PRIVATE, fd, 0);
+
+       header.signature = ntohl(data[0]);
+       header.version = ntohl(data[1]);
+       header.hash_id = ntohl(data[2]);
+
+       if (header.signature != MTIMES_SIGNATURE) {
+               ret = error(_("mtimes file %s has unknown signature"), mtimes_file);
+               goto cleanup;
+       }
+
+       if (header.version != 1) {
+               ret = error(_("mtimes file %s has unsupported version %"PRIu32),
+                           mtimes_file, header.version);
+               goto cleanup;
+       }
+
+       if (!(header.hash_id == 1 || header.hash_id == 2)) {
+               ret = error(_("mtimes file %s has unsupported hash id %"PRIu32),
+                           mtimes_file, header.hash_id);
+               goto cleanup;
+       }
+
+
+       expected_size = MTIMES_HEADER_SIZE;
+       expected_size = st_add(expected_size, st_mult(sizeof(uint32_t), num_objects));
+       expected_size = st_add(expected_size, 2 * (header.hash_id == 1 ? GIT_SHA1_RAWSZ : GIT_SHA256_RAWSZ));
+
+       if (mtimes_size != expected_size) {
+               ret = error(_("mtimes file %s is corrupt"), mtimes_file);
+               goto cleanup;
+       }
+
+cleanup:
+       if (ret) {
+               if (data)
+                       munmap(data, mtimes_size);
+       } else {
+               *len_p = mtimes_size;
+               *data_p = data;
+       }
+
+       close(fd);
+       return ret;
+}
+
+int load_pack_mtimes(struct packed_git *p)
+{
+       char *mtimes_name = NULL;
+       int ret = 0;
+
+       if (!p->is_cruft)
+               return ret; /* not a cruft pack */
+       if (p->mtimes_map)
+               return ret; /* already loaded */
+
+       ret = open_pack_index(p);
+       if (ret < 0)
+               goto cleanup;
+
+       mtimes_name = pack_mtimes_filename(p);
+       ret = load_pack_mtimes_file(mtimes_name,
+                                   p->num_objects,
+                                   &p->mtimes_map,
+                                   &p->mtimes_size);
+cleanup:
+       free(mtimes_name);
+       return ret;
+}
+
+uint32_t nth_packed_mtime(struct packed_git *p, uint32_t pos)
+{
+       if (!p->mtimes_map)
+               BUG("pack .mtimes file not loaded for %s", p->pack_name);
+       if (p->num_objects <= pos)
+               BUG("pack .mtimes out-of-bounds (%"PRIu32" vs %"PRIu32")",
+                   pos, p->num_objects);
+
+       return get_be32(p->mtimes_map + pos + 3);
+}
diff --git a/pack-mtimes.h b/pack-mtimes.h
new file mode 100644 (file)
index 0000000..cc957b3
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef PACK_MTIMES_H
+#define PACK_MTIMES_H
+
+#include "git-compat-util.h"
+
+#define MTIMES_SIGNATURE 0x4d544d45 /* "MTME" */
+#define MTIMES_VERSION 1
+
+struct packed_git;
+
+/*
+ * Loads the .mtimes file corresponding to "p", if any, returning zero
+ * on success.
+ */
+int load_pack_mtimes(struct packed_git *p);
+
+/* Returns the mtime associated with the object at position "pos" (in
+ * lexicographic/index order) in pack "p".
+ *
+ * Note that it is a BUG() to call this function if either (a) "p" does
+ * not have a corresponding .mtimes file, or (b) it does, but it hasn't
+ * been loaded
+ */
+uint32_t nth_packed_mtime(struct packed_git *p, uint32_t pos);
+
+#endif
index fe2a4eace9910b487aae56447b7fc6bd93fe1392..272e8d451739e8466a35df155520c9c54d85e75c 100644 (file)
@@ -170,6 +170,9 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
 
                if (pdata->layer)
                        REALLOC_ARRAY(pdata->layer, pdata->nr_alloc);
+
+               if (pdata->cruft_mtime)
+                       REALLOC_ARRAY(pdata->cruft_mtime, pdata->nr_alloc);
        }
 
        new_entry = pdata->objects + pdata->nr_objects++;
@@ -198,6 +201,9 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
        if (pdata->layer)
                pdata->layer[pdata->nr_objects - 1] = 0;
 
+       if (pdata->cruft_mtime)
+               pdata->cruft_mtime[pdata->nr_objects - 1] = 0;
+
        return new_entry;
 }
 
index dca2351ef94ecf4e8d4aa51cd81b38cb03eb8b4f..393b9db546433d71de6f821a58d2a58a9ebc5ecb 100644 (file)
@@ -168,6 +168,14 @@ struct packing_data {
        /* delta islands */
        unsigned int *tree_depth;
        unsigned char *layer;
+
+       /*
+        * Used when writing cruft packs.
+        *
+        * Object mtimes are stored in pack order when writing, but
+        * written out in lexicographic (index) order.
+        */
+       uint32_t *cruft_mtime;
 };
 
 void prepare_packing_data(struct repository *r, struct packing_data *pdata);
@@ -289,4 +297,21 @@ static inline void oe_set_layer(struct packing_data *pack,
        pack->layer[e - pack->objects] = layer;
 }
 
+static inline uint32_t oe_cruft_mtime(struct packing_data *pack,
+                                     struct object_entry *e)
+{
+       if (!pack->cruft_mtime)
+               return 0;
+       return pack->cruft_mtime[e - pack->objects];
+}
+
+static inline void oe_set_cruft_mtime(struct packing_data *pack,
+                                     struct object_entry *e,
+                                     uint32_t mtime)
+{
+       if (!pack->cruft_mtime)
+               CALLOC_ARRAY(pack->cruft_mtime, pack->nr_alloc);
+       pack->cruft_mtime[e - pack->objects] = mtime;
+}
+
 #endif
index 51812cb1299222cbcbc976ef2b8304f7e25bfbff..23c0342018fa1f76831b0d83fe1e7249d18090bf 100644 (file)
@@ -2,6 +2,11 @@
 #include "pack.h"
 #include "csum-file.h"
 #include "remote.h"
+#include "chunk-format.h"
+#include "pack-mtimes.h"
+#include "oidmap.h"
+#include "chunk-format.h"
+#include "pack-objects.h"
 
 void reset_pack_idx_option(struct pack_idx_option *opts)
 {
@@ -181,21 +186,9 @@ static int pack_order_cmp(const void *va, const void *vb, void *ctx)
 
 static void write_rev_header(struct hashfile *f)
 {
-       uint32_t oid_version;
-       switch (hash_algo_by_ptr(the_hash_algo)) {
-       case GIT_HASH_SHA1:
-               oid_version = 1;
-               break;
-       case GIT_HASH_SHA256:
-               oid_version = 2;
-               break;
-       default:
-               die("write_rev_header: unknown hash version");
-       }
-
        hashwrite_be32(f, RIDX_SIGNATURE);
        hashwrite_be32(f, RIDX_VERSION);
-       hashwrite_be32(f, oid_version);
+       hashwrite_be32(f, oid_version(the_hash_algo));
 }
 
 static void write_rev_index_positions(struct hashfile *f,
@@ -288,6 +281,70 @@ const char *write_rev_file_order(const char *rev_name,
        return rev_name;
 }
 
+static void write_mtimes_header(struct hashfile *f)
+{
+       hashwrite_be32(f, MTIMES_SIGNATURE);
+       hashwrite_be32(f, MTIMES_VERSION);
+       hashwrite_be32(f, oid_version(the_hash_algo));
+}
+
+/*
+ * Writes the object mtimes of "objects" for use in a .mtimes file.
+ * Note that objects must be in lexicographic (index) order, which is
+ * the expected ordering of these values in the .mtimes file.
+ */
+static void write_mtimes_objects(struct hashfile *f,
+                                struct packing_data *to_pack,
+                                struct pack_idx_entry **objects,
+                                uint32_t nr_objects)
+{
+       uint32_t i;
+       for (i = 0; i < nr_objects; i++) {
+               struct object_entry *e = (struct object_entry*)objects[i];
+               hashwrite_be32(f, oe_cruft_mtime(to_pack, e));
+       }
+}
+
+static void write_mtimes_trailer(struct hashfile *f, const unsigned char *hash)
+{
+       hashwrite(f, hash, the_hash_algo->rawsz);
+}
+
+static const char *write_mtimes_file(const char *mtimes_name,
+                                    struct packing_data *to_pack,
+                                    struct pack_idx_entry **objects,
+                                    uint32_t nr_objects,
+                                    const unsigned char *hash)
+{
+       struct hashfile *f;
+       int fd;
+
+       if (!to_pack)
+               BUG("cannot call write_mtimes_file with NULL packing_data");
+
+       if (!mtimes_name) {
+               struct strbuf tmp_file = STRBUF_INIT;
+               fd = odb_mkstemp(&tmp_file, "pack/tmp_mtimes_XXXXXX");
+               mtimes_name = strbuf_detach(&tmp_file, NULL);
+       } else {
+               unlink(mtimes_name);
+               fd = xopen(mtimes_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
+       }
+       f = hashfd(fd, mtimes_name);
+
+       write_mtimes_header(f);
+       write_mtimes_objects(f, to_pack, objects, nr_objects);
+       write_mtimes_trailer(f, hash);
+
+       if (adjust_shared_perm(mtimes_name) < 0)
+               die(_("failed to make %s readable"), mtimes_name);
+
+       finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
+                         CSUM_HASH_IN_STREAM | CSUM_CLOSE | CSUM_FSYNC);
+
+       return mtimes_name;
+}
+
 off_t write_pack_header(struct hashfile *f, uint32_t nr_entries)
 {
        struct pack_header hdr;
@@ -484,11 +541,13 @@ void stage_tmp_packfiles(struct strbuf *name_buffer,
                         const char *pack_tmp_name,
                         struct pack_idx_entry **written_list,
                         uint32_t nr_written,
+                        struct packing_data *to_pack,
                         struct pack_idx_option *pack_idx_opts,
                         unsigned char hash[],
                         char **idx_tmp_name)
 {
        const char *rev_tmp_name = NULL;
+       const char *mtimes_tmp_name = NULL;
 
        if (adjust_shared_perm(pack_tmp_name))
                die_errno("unable to make temporary pack file readable");
@@ -501,9 +560,17 @@ void stage_tmp_packfiles(struct strbuf *name_buffer,
        rev_tmp_name = write_rev_file(NULL, written_list, nr_written, hash,
                                      pack_idx_opts->flags);
 
+       if (pack_idx_opts->flags & WRITE_MTIMES) {
+               mtimes_tmp_name = write_mtimes_file(NULL, to_pack, written_list,
+                                                   nr_written,
+                                                   hash);
+       }
+
        rename_tmp_packfile(name_buffer, pack_tmp_name, "pack");
        if (rev_tmp_name)
                rename_tmp_packfile(name_buffer, rev_tmp_name, "rev");
+       if (mtimes_tmp_name)
+               rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes");
 }
 
 void write_promisor_file(const char *promisor_name, struct ref **sought, int nr_sought)
diff --git a/pack.h b/pack.h
index b22bfc4a18e8543be54d6328c4e3cae6270c0aa7..01d385903adcba22f46633aec3f7c2fff78776f3 100644 (file)
--- a/pack.h
+++ b/pack.h
@@ -44,6 +44,7 @@ struct pack_idx_option {
 #define WRITE_IDX_STRICT 02
 #define WRITE_REV 04
 #define WRITE_REV_VERIFY 010
+#define WRITE_MTIMES 020
 
        uint32_t version;
        uint32_t off32_limit;
@@ -109,11 +110,14 @@ int encode_in_pack_object_header(unsigned char *hdr, int hdr_len,
 #define PH_ERROR_PROTOCOL      (-3)
 int read_pack_header(int fd, struct pack_header *);
 
+struct packing_data;
+
 struct hashfile *create_tmp_packfile(char **pack_tmp_name);
 void stage_tmp_packfiles(struct strbuf *name_buffer,
                         const char *pack_tmp_name,
                         struct pack_idx_entry **written_list,
                         uint32_t nr_written,
+                        struct packing_data *to_pack,
                         struct pack_idx_option *pack_idx_opts,
                         unsigned char hash[],
                         char **idx_tmp_name);
index 835b2d271645ce08b7f98214748d3ffe4296edb8..8e812a84a3c3395de964bae782d9fe74ae169737 100644 (file)
@@ -116,7 +116,7 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
 
        if (idx_size < 4 * 256 + hashsz + hashsz)
                return error("index file %s is too small", path);
-       if (idx_map == NULL)
+       if (!idx_map)
                return error("empty data");
 
        if (hdr->idx_signature == htonl(PACK_IDX_SIGNATURE)) {
@@ -334,12 +334,22 @@ static void close_pack_revindex(struct packed_git *p)
        p->revindex_data = NULL;
 }
 
+static void close_pack_mtimes(struct packed_git *p)
+{
+       if (!p->mtimes_map)
+               return;
+
+       munmap((void *)p->mtimes_map, p->mtimes_size);
+       p->mtimes_map = NULL;
+}
+
 void close_pack(struct packed_git *p)
 {
        close_pack_windows(p);
        close_pack_fd(p);
        close_pack_index(p);
        close_pack_revindex(p);
+       close_pack_mtimes(p);
        oidset_clear(&p->bad_objects);
 }
 
@@ -363,7 +373,7 @@ void close_object_store(struct raw_object_store *o)
 
 void unlink_pack_path(const char *pack_name, int force_delete)
 {
-       static const char *exts[] = {".pack", ".idx", ".rev", ".keep", ".bitmap", ".promisor"};
+       static const char *exts[] = {".pack", ".idx", ".rev", ".keep", ".bitmap", ".promisor", ".mtimes"};
        int i;
        struct strbuf buf = STRBUF_INIT;
        size_t plen;
@@ -718,6 +728,10 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
        if (!access(p->pack_name, F_OK))
                p->pack_promisor = 1;
 
+       xsnprintf(p->pack_name + path_len, alloc - path_len, ".mtimes");
+       if (!access(p->pack_name, F_OK))
+               p->is_cruft = 1;
+
        xsnprintf(p->pack_name + path_len, alloc - path_len, ".pack");
        if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
                free(p);
@@ -869,7 +883,8 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
            ends_with(file_name, ".pack") ||
            ends_with(file_name, ".bitmap") ||
            ends_with(file_name, ".keep") ||
-           ends_with(file_name, ".promisor"))
+           ends_with(file_name, ".promisor") ||
+           ends_with(file_name, ".mtimes"))
                string_list_append(data->garbage, full_name);
        else
                report_garbage(PACKDIR_FILE_GARBAGE, full_name);
diff --git a/path.c b/path.c
index d73146b6cd266a9d051c334ae63bb91426da0a33..a3cfcd8a6e95b3d018c55529d0e532a9d48da0ef 100644 (file)
--- a/path.c
+++ b/path.c
@@ -733,7 +733,7 @@ char *interpolate_path(const char *path, int real_home)
        struct strbuf user_path = STRBUF_INIT;
        const char *to_copy = path;
 
-       if (path == NULL)
+       if (!path)
                goto return_null;
 
        if (skip_prefix(path, "%(prefix)/", &path))
@@ -1413,7 +1413,7 @@ int is_ntfs_dotgit(const char *name)
 
        for (;;) {
                c = *(name++);
-               if (!c || c == '\\' || c == '/' || c == ':')
+               if (!c || is_xplatform_dir_sep(c) || c == ':')
                        return 1;
                if (c != '.' && c != ' ')
                        return 0;
index 796b96d1c402326528b4ba3c12ee9d92d0e212e9..ff0e5176a65dbd4d82ec9d5bf282afabf1704ea2 100644 (file)
@@ -1 +1,3 @@
 /build
+/git.pot
+/git-core.pot
index 19fabb4acf47dbb4fe0b23d25ce6a11bf3149ab7..74856ca5bf2eca27132168bb49daf07218bb8908 100644 (file)
@@ -9,8 +9,14 @@ coordinates our localization effort in the l10 coordinator repository:
 
     https://github.com/git-l10n/git-po/
 
-The two character language translation codes are defined by ISO\_639-1, as
-stated in the gettext(1) full manual, appendix A.1, Usual Language Codes.
+We will use XX as an alias to refer to the language translation code in
+the following paragraphs, for example we use "po/XX.po" to refer to the
+translation file for a specific language. But this doesn't mean that
+the language code has only two letters. The language code can be in one
+of two forms: "ll" or "ll\_CC". Here "ll" is the ISO 639 two-letter
+language code and "CC" is the ISO 3166 two-letter code for country names
+and subdivisions. For example: "de" for German language code, "zh\_CN"
+for Simplified Chinese language code.
 
 
 ## Contributing to an existing translation
@@ -39,72 +45,74 @@ language, so that the l10n coordinator only needs to interact with one
 person per language.
 
 
-## Core translation
+## Translation Process Flow
 
-The core translation is the smallest set of work that must be completed
-for a new language translation. Because there are more than 5000 messages
-in the template message file "po/git.pot" that need to be translated,
-this is not a piece of cake for the contributor for a new language.
+The overall data-flow looks like this:
 
-The core template message file which contains a small set of messages
-will be generated in "po-core/core.pot" automatically by running a helper
-program named "git-po-helper" (described later).
+    +-------------------+             +------------------+
+    | Git source code   | ----(2)---> | L10n coordinator |
+    | repository        | <---(5)---- | repository       |
+    +-------------------+             +------------------+
+                    |                     |    ^
+                   (1)                   (3)  (4)
+                    V                     v    |
+               +----------------------------------+
+               |        Language Team XX          |
+               +----------------------------------+
 
-```shell
-git-po-helper init --core XX.po
-```
+- Translatable strings are marked in the source file.
+- Language teams can start translation iterations at any time, even
+  before the l10n window opens:
 
-After translating the generated "po-core/XX.po", you can merge it to
-"po/XX.po" using the following commands:
+  + Pull from the master branch of the source (1)
+  + Update the message file by running "make po-update PO\_FILE=po/XX.po"
+  + Translate the message file "po/XX.po"
 
-```shell
-msgcat po-core/XX.po po/XX.po -s -o /tmp/XX.po
-mv /tmp/XX.po po/XX.po
-git-po-helper update XX.po
-```
+- The L10n coordinator pulls from source and announces the l10n window
+  open (2)
+- Language team pulls from the l10n coordinator, starts another
+  translation iteration against the l10n coordinator's tree (3)
 
-Edit "po/XX.po" by hand to fix "fuzzy" messages, which may have misplaced
-translated messages and duplicate messages.
+  + Run "git pull --rebase" from the l10n coordinator
+  + Update the message file by running "make po-update PO\_FILE=po/XX.po"
+  + Translate the message file "po/XX.po"
+  + Squash trivial l10n git commits using "git rebase -i"
 
+- Language team sends pull request to the l10n coordinator (4)
+- L10n coordinator checks and merges
+- L10n coordinator asks the result to be pulled (5).
 
-## Translation Process Flow
 
-The overall data-flow looks like this:
+## Dynamically generated POT files
 
-    +-------------------+            +------------------+
-    | Git source code   | ---(1)---> | L10n coordinator |
-    | repository        | <---(4)--- | repository       |
-    +-------------------+            +------------------+
-                                          |      ^
-                                         (2)    (3)
-                                          V      |
-                                     +------------------+
-                                     | Language Team XX |
-                                     +------------------+
+POT files are templates for l10n contributors to create or update their
+translation files. We used to have the "po/git.pot" file which was
+generated by the l10n coordinator, but this file had been removed from
+the tree.
 
-- Translatable strings are marked in the source file.
-- L10n coordinator pulls from the source (1)
-- L10n coordinator updates the message template "po/git.pot"
-- Language team pulls from L10n coordinator (2)
-- Language team updates the message file "po/XX.po"
-- L10n coordinator pulls from Language team (3)
-- L10n coordinator asks the result to be pulled (4).
+The two POT files "po/git.pot" and "po/git-core.pot" can be created
+dynamically when necessary.
 
+L10n contributors use "po/git.pot" to prepare translations for their
+languages, but they are not expected to modify it. The "po/git.pot" file
+can be generated manually with the following command:
 
-## Maintaining the "po/git.pot" file
+```shell
+make po/git.pot
+```
 
-(This is done by the l10n coordinator).
+The "po/git-core.pot" file is the template for core translations. A core
+translation is the minimum set of work necessary to complete a
+translation of a new language. Since there are more than 5000 messages
+in the full set of template message file "po/git.pot" that need to be
+translated, this is not a piece of cake for new language contributors.
 
-The "po/git.pot" file contains a message catalog extracted from Git's
-sources. The l10n coordinator maintains it by adding new translations with
-msginit(1), or update existing ones with msgmerge(1).  In order to update
-the Git sources to extract the messages from, the l10n coordinator is
-expected to pull from the main git repository at strategic point in
-history (e.g. when a major release and release candidates are tagged),
-and then run "make pot" at the top-level directory.
+The "core" template file "po/git-core.pot" can be generated manually
+by running:
 
-Language contributors use this file to prepare translations for their
-language, but they are not expected to modify it.
+```shell
+make po/git-core.pot
+```
 
 
 ## Initializing a "XX.po" file
@@ -115,32 +123,14 @@ If your language XX does not have translated message file "po/XX.po" yet,
 you add a translation for the first time by running:
 
 ```shell
-msginit --locale=XX
+make po-init PO_FILE=po/XX.po
 ```
 
-in the "po/" directory, where XX is the locale, e.g. "de", "is", "pt\_BR",
-"zh\_CN", etc.
-
-Then edit the automatically generated copyright info in your new "XX.po"
-to be correct, e.g. for Icelandic:
-
-```diff
-@@ -1,6 +1,6 @@
--# Icelandic translations for PACKAGE package.
--# Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER
--# This file is distributed under the same license as the PACKAGE package.
-+# Icelandic translations for Git.
-+# Copyright (C) 2010 Ã†var Arnfjörð Bjarmason <avarab@gmail.com>
-+# This file is distributed under the same license as the Git package.
- # Ã†var Arnfjörð Bjarmason <avarab@gmail.com>, 2010.
-```
-
-And change references to PACKAGE VERSION in the PO Header Entry to
-just "Git":
+where XX is the locale, e.g. "de", "is", "pt\_BR", "zh\_CN", etc.
 
-```shell
-perl -pi -e 's/(?<="Project-Id-Version: )PACKAGE VERSION/Git/' XX.po
-```
+The newly generated message file "po/XX.po" is based on the core pot
+file "po/git-core.pot", so it contains only a minimal set of messages
+and it's a good start for a new language contribution.
 
 Once you are done testing the translation (see below), commit the result
 and ask the l10n coordinator to pull from you.
@@ -153,19 +143,53 @@ and ask the l10n coordinator to pull from you.
 If you are replacing translation strings in an existing "XX.po" file to
 improve the translation, just edit the file.
 
-If there's an existing "XX.po" file for your language, but the repository
-of the l10n coordinator has newer "po/git.pot" file, you would need to first
-pull from the l10n coordinator (see the beginning of this document for its
-URL), and then update the existing translation by running:
+If you want to find new translatable strings in source files of upstream
+repository and propagate them to your "po/XX.po", run command:
 
 ```shell
-msgmerge --add-location --backup=off -U XX.po git.pot
+make po-update PO_FILE=po/XX.po
 ```
 
-in the "po/" directory, where "XX.po" is the file you want to update.
+It will:
 
-Once you are done testing the translation (see below), commit the result
-and ask the l10n coordinator to pull from you.
+- Call "make po/git.pot" to generate new "po/git.pot" file
+- Call "msgmerge --add-location --backup=off -U po/XX.po po/git.pot"
+  to update your "po/XX.po"
+- The "--add-location" option for msgmerge will add location lines,
+  and these location lines will help translation tools to locate
+  translation context easily.
+
+Once you are done testing the translation (see below), it's better
+to commit a location-less "po/XX.po" file to save repository space
+and make a user-friendly patch for review.
+
+To save a location-less "po/XX.po" automatically in repository, you
+can:
+
+First define a new attribute for "po/XX.po" by appending the following
+line in ".git/info/attributes":
+
+```
+/po/XX.po filter=gettext-no-location
+```
+
+Then define the driver for the "gettext-no-location" clean filter to
+strip out both filenames and locations from the contents as follows:
+
+```shell
+git config --global filter.gettext-no-location.clean \
+           "msgcat --no-location -"
+```
+
+For users who have gettext version 0.20 or higher, it is also possible
+to define a clean filter to preserve filenames but not locations:
+
+```shell
+git config --global filter.gettext-no-location.clean \
+           "msgcat --add-location=file -"
+```
+
+You're now ready to ask the l10n coordinator to pull from you.
 
 
 ## Fuzzy translation
@@ -196,6 +220,14 @@ common errors, e.g. missing printf format strings, or translated
 messages that deviate from the originals in whether they begin/end
 with a newline or not.
 
+L10n coordinator will check your contributions using a helper program
+(see "PO helper" section below):
+
+```shell
+git-po-helper check-po po/XX.po
+git-po-helper check-commits <rev-list-opts>
+```
+
 
 ## Marking strings for translation
 
@@ -370,29 +402,6 @@ l10n workflow.
 To build and install the helper program from source, see
 [git-po-helper/README][].
 
-Usage for git-po-helper:
-
-- To start a new language translation:
-
-  ```shell
-  git-po-helper init XX.po
-  ```
-
-- To update your "XX.po" file:
-
-  ```shell
-  git-po-helper update XX.po
-  ```
-
-- To check commit log and syntax of "XX.po":
-
-  ```shell
-  git-po-helper check-po XX.po
-  git-po-helper check-commits
-  ```
-
-Run "git-po-helper" without arguments to show usage.
-
 
 ## Conventions
 
@@ -436,13 +445,8 @@ additional conventions:
 - Initialize proper filename of the "XX.po" file conforming to
   iso-639 and iso-3166.
 
-- Must complete a minimal translation based on the "po-core/core.pot"
-  template. Using the following command to initialize the minimal
-  "po-core/XX.po" file:
-
-  ```shell
-  git-po-helper init --core <your-language>
-  ```
+- Must complete a minimal translation based on the "Core
+  translation". See that section above.
 
 - Add a new entry in the "po/TEAMS" file with proper format, and check
   the syntax of "po/TEAMS" by running the following command:
diff --git a/po/git.pot b/po/git.pot
deleted file mode 100644 (file)
index 054cb99..0000000
+++ /dev/null
@@ -1,25151 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-04-13 14:52+0800\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-
-#: add-interactive.c:382
-#, c-format
-msgid "Huh (%s)?"
-msgstr ""
-
-#: add-interactive.c:535 add-interactive.c:836 reset.c:136 sequencer.c:3505
-#: sequencer.c:3970 sequencer.c:4127 builtin/rebase.c:1261
-#: builtin/rebase.c:1671
-msgid "could not read index"
-msgstr ""
-
-#: add-interactive.c:590 git-add--interactive.perl:269
-#: git-add--interactive.perl:294
-msgid "binary"
-msgstr ""
-
-#: add-interactive.c:648 git-add--interactive.perl:278
-#: git-add--interactive.perl:332
-msgid "nothing"
-msgstr ""
-
-#: add-interactive.c:649 git-add--interactive.perl:314
-#: git-add--interactive.perl:329
-msgid "unchanged"
-msgstr ""
-
-#: add-interactive.c:686 git-add--interactive.perl:641
-msgid "Update"
-msgstr ""
-
-#: add-interactive.c:703 add-interactive.c:891
-#, c-format
-msgid "could not stage '%s'"
-msgstr ""
-
-#: add-interactive.c:709 add-interactive.c:898 reset.c:160 sequencer.c:3709
-msgid "could not write index"
-msgstr ""
-
-#: add-interactive.c:712 git-add--interactive.perl:626
-#, c-format, perl-format
-msgid "updated %d path\n"
-msgid_plural "updated %d paths\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: add-interactive.c:730 git-add--interactive.perl:676
-#, c-format, perl-format
-msgid "note: %s is untracked now.\n"
-msgstr ""
-
-#: add-interactive.c:735 apply.c:4133 builtin/checkout.c:311
-#: builtin/reset.c:167
-#, c-format
-msgid "make_cache_entry failed for path '%s'"
-msgstr ""
-
-#: add-interactive.c:765 git-add--interactive.perl:653
-msgid "Revert"
-msgstr ""
-
-#: add-interactive.c:781
-msgid "Could not parse HEAD^{tree}"
-msgstr ""
-
-#: add-interactive.c:819 git-add--interactive.perl:629
-#, c-format, perl-format
-msgid "reverted %d path\n"
-msgid_plural "reverted %d paths\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: add-interactive.c:870 git-add--interactive.perl:693
-#, c-format
-msgid "No untracked files.\n"
-msgstr ""
-
-#: add-interactive.c:874 git-add--interactive.perl:687
-msgid "Add untracked"
-msgstr ""
-
-#: add-interactive.c:901 git-add--interactive.perl:623
-#, c-format, perl-format
-msgid "added %d path\n"
-msgid_plural "added %d paths\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: add-interactive.c:931
-#, c-format
-msgid "ignoring unmerged: %s"
-msgstr ""
-
-#: add-interactive.c:943 add-patch.c:1758 git-add--interactive.perl:1371
-#, c-format
-msgid "Only binary files changed.\n"
-msgstr ""
-
-#: add-interactive.c:945 add-patch.c:1756 git-add--interactive.perl:1373
-#, c-format
-msgid "No changes.\n"
-msgstr ""
-
-#: add-interactive.c:949 git-add--interactive.perl:1381
-msgid "Patch update"
-msgstr ""
-
-#: add-interactive.c:988 git-add--interactive.perl:1794
-msgid "Review diff"
-msgstr ""
-
-#: add-interactive.c:1016
-msgid "show paths with changes"
-msgstr ""
-
-#: add-interactive.c:1018
-msgid "add working tree state to the staged set of changes"
-msgstr ""
-
-#: add-interactive.c:1020
-msgid "revert staged set of changes back to the HEAD version"
-msgstr ""
-
-#: add-interactive.c:1022
-msgid "pick hunks and update selectively"
-msgstr ""
-
-#: add-interactive.c:1024
-msgid "view diff between HEAD and index"
-msgstr ""
-
-#: add-interactive.c:1026
-msgid "add contents of untracked files to the staged set of changes"
-msgstr ""
-
-#: add-interactive.c:1034 add-interactive.c:1083
-msgid "Prompt help:"
-msgstr ""
-
-#: add-interactive.c:1036
-msgid "select a single item"
-msgstr ""
-
-#: add-interactive.c:1038
-msgid "select a range of items"
-msgstr ""
-
-#: add-interactive.c:1040
-msgid "select multiple ranges"
-msgstr ""
-
-#: add-interactive.c:1042 add-interactive.c:1087
-msgid "select item based on unique prefix"
-msgstr ""
-
-#: add-interactive.c:1044
-msgid "unselect specified items"
-msgstr ""
-
-#: add-interactive.c:1046
-msgid "choose all items"
-msgstr ""
-
-#: add-interactive.c:1048
-msgid "(empty) finish selecting"
-msgstr ""
-
-#: add-interactive.c:1085
-msgid "select a numbered item"
-msgstr ""
-
-#: add-interactive.c:1089
-msgid "(empty) select nothing"
-msgstr ""
-
-#: add-interactive.c:1097 builtin/clean.c:839 git-add--interactive.perl:1898
-msgid "*** Commands ***"
-msgstr ""
-
-#: add-interactive.c:1098 builtin/clean.c:840 git-add--interactive.perl:1895
-msgid "What now"
-msgstr ""
-
-#: add-interactive.c:1150 git-add--interactive.perl:213
-msgid "staged"
-msgstr ""
-
-#: add-interactive.c:1150 git-add--interactive.perl:213
-msgid "unstaged"
-msgstr ""
-
-#: add-interactive.c:1150 apply.c:5002 apply.c:5005 builtin/am.c:2370
-#: builtin/am.c:2373 builtin/bugreport.c:107 builtin/clone.c:132
-#: builtin/fetch.c:154 builtin/merge.c:287 builtin/pull.c:194
-#: builtin/submodule--helper.c:412 builtin/submodule--helper.c:1872
-#: builtin/submodule--helper.c:1875 builtin/submodule--helper.c:2709
-#: builtin/submodule--helper.c:2712 builtin/submodule--helper.c:2891
-#: git-add--interactive.perl:213
-msgid "path"
-msgstr ""
-
-#: add-interactive.c:1157
-msgid "could not refresh index"
-msgstr ""
-
-#: add-interactive.c:1171 builtin/clean.c:804 git-add--interactive.perl:1805
-#, c-format
-msgid "Bye.\n"
-msgstr ""
-
-#: add-patch.c:34 git-add--interactive.perl:1433
-#, c-format, perl-format
-msgid "Stage mode change [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:35 git-add--interactive.perl:1434
-#, c-format, perl-format
-msgid "Stage deletion [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:36 git-add--interactive.perl:1435
-#, c-format, perl-format
-msgid "Stage addition [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:37 git-add--interactive.perl:1436
-#, c-format, perl-format
-msgid "Stage this hunk [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:39
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be marked for "
-"staging."
-msgstr ""
-
-#: add-patch.c:42
-msgid ""
-"y - stage this hunk\n"
-"n - do not stage this hunk\n"
-"q - quit; do not stage this hunk or any of the remaining ones\n"
-"a - stage this hunk and all later hunks in the file\n"
-"d - do not stage this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:56 git-add--interactive.perl:1439
-#, c-format, perl-format
-msgid "Stash mode change [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:57 git-add--interactive.perl:1440
-#, c-format, perl-format
-msgid "Stash deletion [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:58 git-add--interactive.perl:1441
-#, c-format, perl-format
-msgid "Stash addition [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:59 git-add--interactive.perl:1442
-#, c-format, perl-format
-msgid "Stash this hunk [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:61
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be marked for "
-"stashing."
-msgstr ""
-
-#: add-patch.c:64
-msgid ""
-"y - stash this hunk\n"
-"n - do not stash this hunk\n"
-"q - quit; do not stash this hunk or any of the remaining ones\n"
-"a - stash this hunk and all later hunks in the file\n"
-"d - do not stash this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:80 git-add--interactive.perl:1445
-#, c-format, perl-format
-msgid "Unstage mode change [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:81 git-add--interactive.perl:1446
-#, c-format, perl-format
-msgid "Unstage deletion [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:82 git-add--interactive.perl:1447
-#, c-format, perl-format
-msgid "Unstage addition [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:83 git-add--interactive.perl:1448
-#, c-format, perl-format
-msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:85
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be marked for "
-"unstaging."
-msgstr ""
-
-#: add-patch.c:88
-msgid ""
-"y - unstage this hunk\n"
-"n - do not unstage this hunk\n"
-"q - quit; do not unstage this hunk or any of the remaining ones\n"
-"a - unstage this hunk and all later hunks in the file\n"
-"d - do not unstage this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:103 git-add--interactive.perl:1451
-#, c-format, perl-format
-msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:104 git-add--interactive.perl:1452
-#, c-format, perl-format
-msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:105 git-add--interactive.perl:1453
-#, c-format, perl-format
-msgid "Apply addition to index [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:106 git-add--interactive.perl:1454
-#, c-format, perl-format
-msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:108 add-patch.c:176 add-patch.c:221
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be marked for "
-"applying."
-msgstr ""
-
-#: add-patch.c:111
-msgid ""
-"y - apply this hunk to index\n"
-"n - do not apply this hunk to index\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:126 git-add--interactive.perl:1457
-#: git-add--interactive.perl:1475
-#, c-format, perl-format
-msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:127 git-add--interactive.perl:1458
-#: git-add--interactive.perl:1476
-#, c-format, perl-format
-msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:128 git-add--interactive.perl:1459
-#: git-add--interactive.perl:1477
-#, c-format, perl-format
-msgid "Discard addition from worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:129 git-add--interactive.perl:1460
-#: git-add--interactive.perl:1478
-#, c-format, perl-format
-msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:131 add-patch.c:154 add-patch.c:199
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be marked for "
-"discarding."
-msgstr ""
-
-#: add-patch.c:134 add-patch.c:202
-msgid ""
-"y - discard this hunk from worktree\n"
-"n - do not discard this hunk from worktree\n"
-"q - quit; do not discard this hunk or any of the remaining ones\n"
-"a - discard this hunk and all later hunks in the file\n"
-"d - do not discard this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:149 add-patch.c:194 git-add--interactive.perl:1463
-#, c-format, perl-format
-msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:150 add-patch.c:195 git-add--interactive.perl:1464
-#, c-format, perl-format
-msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:151 add-patch.c:196 git-add--interactive.perl:1465
-#, c-format, perl-format
-msgid "Discard addition from index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:152 add-patch.c:197 git-add--interactive.perl:1466
-#, c-format, perl-format
-msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:157
-msgid ""
-"y - discard this hunk from index and worktree\n"
-"n - do not discard this hunk from index and worktree\n"
-"q - quit; do not discard this hunk or any of the remaining ones\n"
-"a - discard this hunk and all later hunks in the file\n"
-"d - do not discard this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:171 add-patch.c:216 git-add--interactive.perl:1469
-#, c-format, perl-format
-msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:172 add-patch.c:217 git-add--interactive.perl:1470
-#, c-format, perl-format
-msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:173 add-patch.c:218 git-add--interactive.perl:1471
-#, c-format, perl-format
-msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:174 add-patch.c:219 git-add--interactive.perl:1472
-#, c-format, perl-format
-msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: add-patch.c:179
-msgid ""
-"y - apply this hunk to index and worktree\n"
-"n - do not apply this hunk to index and worktree\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:224
-msgid ""
-"y - apply this hunk to worktree\n"
-"n - do not apply this hunk to worktree\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file\n"
-msgstr ""
-
-#: add-patch.c:343
-#, c-format
-msgid "could not parse hunk header '%.*s'"
-msgstr ""
-
-#: add-patch.c:362 add-patch.c:366
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr ""
-
-#: add-patch.c:431
-msgid "could not parse diff"
-msgstr ""
-
-#: add-patch.c:450
-msgid "could not parse colored diff"
-msgstr ""
-
-#: add-patch.c:464
-#, c-format
-msgid "failed to run '%s'"
-msgstr ""
-
-#: add-patch.c:618
-msgid "mismatched output from interactive.diffFilter"
-msgstr ""
-
-#: add-patch.c:619
-msgid ""
-"Your filter must maintain a one-to-one correspondence\n"
-"between its input and output lines."
-msgstr ""
-
-#: add-patch.c:797
-#, c-format
-msgid ""
-"expected context line #%d in\n"
-"%.*s"
-msgstr ""
-
-#: add-patch.c:812
-#, c-format
-msgid ""
-"hunks do not overlap:\n"
-"%.*s\n"
-"\tdoes not end with:\n"
-"%.*s"
-msgstr ""
-
-#: add-patch.c:1088 git-add--interactive.perl:1115
-msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
-msgstr ""
-
-#: add-patch.c:1092
-#, c-format
-msgid ""
-"---\n"
-"To remove '%c' lines, make them ' ' lines (context).\n"
-"To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
-msgstr ""
-
-#. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: add-patch.c:1106 git-add--interactive.perl:1129
-msgid ""
-"If it does not apply cleanly, you will be given an opportunity to\n"
-"edit again.  If all lines of the hunk are removed, then the edit is\n"
-"aborted and the hunk is left unchanged.\n"
-msgstr ""
-
-#: add-patch.c:1139
-msgid "could not parse hunk header"
-msgstr ""
-
-#: add-patch.c:1184
-msgid "'git apply --cached' failed"
-msgstr ""
-
-#. 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.
-#.
-#. 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.
-#: add-patch.c:1253 git-add--interactive.perl:1244
-msgid ""
-"Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
-msgstr ""
-
-#: add-patch.c:1296
-msgid "The selected hunks do not apply to the index!"
-msgstr ""
-
-#: add-patch.c:1297 git-add--interactive.perl:1348
-msgid "Apply them to the worktree anyway? "
-msgstr ""
-
-#: add-patch.c:1304 git-add--interactive.perl:1351
-msgid "Nothing was applied.\n"
-msgstr ""
-
-#: add-patch.c:1361
-msgid ""
-"j - leave this hunk undecided, see next undecided hunk\n"
-"J - leave this hunk undecided, see next hunk\n"
-"k - leave this hunk undecided, see previous undecided hunk\n"
-"K - leave this hunk undecided, see previous hunk\n"
-"g - select a hunk to go to\n"
-"/ - search for a hunk matching the given regex\n"
-"s - split the current hunk into smaller hunks\n"
-"e - manually edit the current hunk\n"
-"? - print help\n"
-msgstr ""
-
-#: add-patch.c:1523 add-patch.c:1533
-msgid "No previous hunk"
-msgstr ""
-
-#: add-patch.c:1528 add-patch.c:1538
-msgid "No next hunk"
-msgstr ""
-
-#: add-patch.c:1544
-msgid "No other hunks to goto"
-msgstr ""
-
-#: add-patch.c:1555 git-add--interactive.perl:1608
-msgid "go to which hunk (<ret> to see more)? "
-msgstr ""
-
-#: add-patch.c:1556 git-add--interactive.perl:1610
-msgid "go to which hunk? "
-msgstr ""
-
-#: add-patch.c:1567
-#, c-format
-msgid "Invalid number: '%s'"
-msgstr ""
-
-#: add-patch.c:1572
-#, c-format
-msgid "Sorry, only %d hunk available."
-msgid_plural "Sorry, only %d hunks available."
-msgstr[0] ""
-msgstr[1] ""
-
-#: add-patch.c:1581
-msgid "No other hunks to search"
-msgstr ""
-
-#: add-patch.c:1587 git-add--interactive.perl:1663
-msgid "search for regex? "
-msgstr ""
-
-#: add-patch.c:1602
-#, c-format
-msgid "Malformed search regexp %s: %s"
-msgstr ""
-
-#: add-patch.c:1619
-msgid "No hunk matches the given pattern"
-msgstr ""
-
-#: add-patch.c:1626
-msgid "Sorry, cannot split this hunk"
-msgstr ""
-
-#: add-patch.c:1630
-#, c-format
-msgid "Split into %d hunks."
-msgstr ""
-
-#: add-patch.c:1634
-msgid "Sorry, cannot edit this hunk"
-msgstr ""
-
-#: add-patch.c:1686
-msgid "'git apply' failed"
-msgstr ""
-
-#: advice.c:81
-#, c-format
-msgid ""
-"\n"
-"Disable this message with \"git config advice.%s false\""
-msgstr ""
-
-#: advice.c:97
-#, c-format
-msgid "%shint: %.*s%s\n"
-msgstr ""
-
-#: advice.c:181
-msgid "Cherry-picking is not possible because you have unmerged files."
-msgstr ""
-
-#: advice.c:183
-msgid "Committing is not possible because you have unmerged files."
-msgstr ""
-
-#: advice.c:185
-msgid "Merging is not possible because you have unmerged files."
-msgstr ""
-
-#: advice.c:187
-msgid "Pulling is not possible because you have unmerged files."
-msgstr ""
-
-#: advice.c:189
-msgid "Reverting is not possible because you have unmerged files."
-msgstr ""
-
-#: advice.c:191
-#, c-format
-msgid "It is not possible to %s because you have unmerged files."
-msgstr ""
-
-#: advice.c:199
-msgid ""
-"Fix them up in the work tree, and then use 'git add/rm <file>'\n"
-"as appropriate to mark resolution and make a commit."
-msgstr ""
-
-#: advice.c:207
-msgid "Exiting because of an unresolved conflict."
-msgstr ""
-
-#: advice.c:212 builtin/merge.c:1388
-msgid "You have not concluded your merge (MERGE_HEAD exists)."
-msgstr ""
-
-#: advice.c:214
-msgid "Please, commit your changes before merging."
-msgstr ""
-
-#: advice.c:215
-msgid "Exiting because of unfinished merge."
-msgstr ""
-
-#: advice.c:220
-msgid "Not possible to fast-forward, aborting."
-msgstr ""
-
-#: advice.c:230
-#, c-format
-msgid ""
-"The following paths and/or pathspecs matched paths that exist\n"
-"outside of your sparse-checkout definition, so will not be\n"
-"updated in the index:\n"
-msgstr ""
-
-#: advice.c:237
-msgid ""
-"If you intend to update such entries, try one of the following:\n"
-"* Use the --sparse option.\n"
-"* Disable or modify the sparsity rules."
-msgstr ""
-
-#: advice.c:245
-#, c-format
-msgid ""
-"Note: switching to '%s'.\n"
-"\n"
-"You are in 'detached HEAD' state. You can look around, make experimental\n"
-"changes and commit them, and you can discard any commits you make in this\n"
-"state without impacting any branches by switching back to a branch.\n"
-"\n"
-"If you want to create a new branch to retain commits you create, you may\n"
-"do so (now or later) by using -c with the switch command. Example:\n"
-"\n"
-"  git switch -c <new-branch-name>\n"
-"\n"
-"Or undo this operation with:\n"
-"\n"
-"  git switch -\n"
-"\n"
-"Turn off this advice by setting config variable advice.detachedHead to "
-"false\n"
-"\n"
-msgstr ""
-
-#: alias.c:50
-msgid "cmdline ends with \\"
-msgstr ""
-
-#: alias.c:51
-msgid "unclosed quote"
-msgstr ""
-
-#: apply.c:70
-#, c-format
-msgid "unrecognized whitespace option '%s'"
-msgstr ""
-
-#: apply.c:86
-#, c-format
-msgid "unrecognized whitespace ignore option '%s'"
-msgstr ""
-
-#: apply.c:138 archive.c:584 parse-options.c:1122 range-diff.c:555
-#: revision.c:2314 revision.c:2318 revision.c:2327 revision.c:2332
-#: revision.c:2560 revision.c:2895 revision.c:2899 revision.c:2907
-#: revision.c:2910 revision.c:2912 builtin/add.c:507 builtin/add.c:509
-#: builtin/add.c:515 builtin/add.c:527 builtin/branch.c:755
-#: builtin/checkout.c:472 builtin/checkout.c:475 builtin/checkout.c:1663
-#: builtin/checkout.c:1773 builtin/checkout.c:1776 builtin/clone.c:921
-#: builtin/commit.c:359 builtin/commit.c:362 builtin/commit.c:1200
-#: builtin/commit.c:1256 builtin/commit.c:1273 builtin/describe.c:593
-#: builtin/diff-tree.c:155 builtin/difftool.c:733 builtin/fast-export.c:1245
-#: builtin/fetch.c:2141 builtin/fetch.c:2162 builtin/fetch.c:2167
-#: builtin/help.c:602 builtin/index-pack.c:1858 builtin/init-db.c:560
-#: builtin/log.c:1968 builtin/log.c:1970 builtin/ls-files.c:778
-#: builtin/merge-base.c:163 builtin/merge-base.c:169 builtin/merge.c:1409
-#: builtin/merge.c:1411 builtin/pack-objects.c:4098 builtin/push.c:592
-#: builtin/push.c:630 builtin/push.c:636 builtin/push.c:641
-#: builtin/rebase.c:1221 builtin/rebase.c:1223 builtin/rebase.c:1227
-#: builtin/repack.c:688 builtin/repack.c:719 builtin/reset.c:433
-#: builtin/reset.c:469 builtin/rev-list.c:537 builtin/show-branch.c:711
-#: builtin/stash.c:1696 builtin/stash.c:1699 builtin/submodule--helper.c:1328
-#: builtin/submodule--helper.c:3054 builtin/tag.c:527 builtin/tag.c:573
-#: builtin/worktree.c:779
-#, c-format
-msgid "options '%s' and '%s' cannot be used together"
-msgstr ""
-
-#: apply.c:141 apply.c:152 apply.c:155
-#, c-format
-msgid "'%s' outside a repository"
-msgstr ""
-
-#: apply.c:807
-#, c-format
-msgid "Cannot prepare timestamp regexp %s"
-msgstr ""
-
-#: apply.c:816
-#, c-format
-msgid "regexec returned %d for input: %s"
-msgstr ""
-
-#: apply.c:890
-#, c-format
-msgid "unable to find filename in patch at line %d"
-msgstr ""
-
-#: apply.c:928
-#, c-format
-msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
-msgstr ""
-
-#: apply.c:934
-#, c-format
-msgid "git apply: bad git-diff - inconsistent new filename on line %d"
-msgstr ""
-
-#: apply.c:935
-#, c-format
-msgid "git apply: bad git-diff - inconsistent old filename on line %d"
-msgstr ""
-
-#: apply.c:940
-#, c-format
-msgid "git apply: bad git-diff - expected /dev/null on line %d"
-msgstr ""
-
-#: apply.c:969
-#, c-format
-msgid "invalid mode on line %d: %s"
-msgstr ""
-
-#: apply.c:1288
-#, c-format
-msgid "inconsistent header lines %d and %d"
-msgstr ""
-
-#: apply.c:1378
-#, c-format
-msgid ""
-"git diff header lacks filename information when removing %d leading pathname "
-"component (line %d)"
-msgid_plural ""
-"git diff header lacks filename information when removing %d leading pathname "
-"components (line %d)"
-msgstr[0] ""
-msgstr[1] ""
-
-#: apply.c:1391
-#, c-format
-msgid "git diff header lacks filename information (line %d)"
-msgstr ""
-
-#: apply.c:1487
-#, c-format
-msgid "recount: unexpected line: %.*s"
-msgstr ""
-
-#: apply.c:1556
-#, c-format
-msgid "patch fragment without header at line %d: %.*s"
-msgstr ""
-
-#: apply.c:1759
-msgid "new file depends on old contents"
-msgstr ""
-
-#: apply.c:1761
-msgid "deleted file still has contents"
-msgstr ""
-
-#: apply.c:1795
-#, c-format
-msgid "corrupt patch at line %d"
-msgstr ""
-
-#: apply.c:1832
-#, c-format
-msgid "new file %s depends on old contents"
-msgstr ""
-
-#: apply.c:1834
-#, c-format
-msgid "deleted file %s still has contents"
-msgstr ""
-
-#: apply.c:1837
-#, c-format
-msgid "** warning: file %s becomes empty but is not deleted"
-msgstr ""
-
-#: apply.c:1985
-#, c-format
-msgid "corrupt binary patch at line %d: %.*s"
-msgstr ""
-
-#: apply.c:2022
-#, c-format
-msgid "unrecognized binary patch at line %d"
-msgstr ""
-
-#: apply.c:2184
-#, c-format
-msgid "patch with only garbage at line %d"
-msgstr ""
-
-#: apply.c:2270
-#, c-format
-msgid "unable to read symlink %s"
-msgstr ""
-
-#: apply.c:2274
-#, c-format
-msgid "unable to open or read %s"
-msgstr ""
-
-#: apply.c:2943
-#, c-format
-msgid "invalid start of line: '%c'"
-msgstr ""
-
-#: apply.c:3064
-#, c-format
-msgid "Hunk #%d succeeded at %d (offset %d line)."
-msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
-msgstr[0] ""
-msgstr[1] ""
-
-#: apply.c:3076
-#, c-format
-msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
-msgstr ""
-
-#: apply.c:3082
-#, c-format
-msgid ""
-"while searching for:\n"
-"%.*s"
-msgstr ""
-
-#: apply.c:3104
-#, c-format
-msgid "missing binary patch data for '%s'"
-msgstr ""
-
-#: apply.c:3112
-#, c-format
-msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'"
-msgstr ""
-
-#: apply.c:3159
-#, c-format
-msgid "cannot apply binary patch to '%s' without full index line"
-msgstr ""
-
-#: apply.c:3170
-#, c-format
-msgid ""
-"the patch applies to '%s' (%s), which does not match the current contents."
-msgstr ""
-
-#: apply.c:3178
-#, c-format
-msgid "the patch applies to an empty '%s' but it is not empty"
-msgstr ""
-
-#: apply.c:3196
-#, c-format
-msgid "the necessary postimage %s for '%s' cannot be read"
-msgstr ""
-
-#: apply.c:3209
-#, c-format
-msgid "binary patch does not apply to '%s'"
-msgstr ""
-
-#: apply.c:3216
-#, c-format
-msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
-msgstr ""
-
-#: apply.c:3237
-#, c-format
-msgid "patch failed: %s:%ld"
-msgstr ""
-
-#: apply.c:3360
-#, c-format
-msgid "cannot checkout %s"
-msgstr ""
-
-#: apply.c:3412 apply.c:3423 apply.c:3469 midx.c:105 pack-revindex.c:214
-#: setup.c:310
-#, c-format
-msgid "failed to read %s"
-msgstr ""
-
-#: apply.c:3420
-#, c-format
-msgid "reading from '%s' beyond a symbolic link"
-msgstr ""
-
-#: apply.c:3449 apply.c:3721
-#, c-format
-msgid "path %s has been renamed/deleted"
-msgstr ""
-
-#: apply.c:3559 apply.c:3736
-#, c-format
-msgid "%s: does not exist in index"
-msgstr ""
-
-#: apply.c:3568 apply.c:3744 apply.c:3960
-#, c-format
-msgid "%s: does not match index"
-msgstr ""
-
-#: apply.c:3605
-msgid "repository lacks the necessary blob to perform 3-way merge."
-msgstr ""
-
-#: apply.c:3608
-#, c-format
-msgid "Performing three-way merge...\n"
-msgstr ""
-
-#: apply.c:3624 apply.c:3628
-#, c-format
-msgid "cannot read the current contents of '%s'"
-msgstr ""
-
-#: apply.c:3640
-#, c-format
-msgid "Failed to perform three-way merge...\n"
-msgstr ""
-
-#: apply.c:3654
-#, c-format
-msgid "Applied patch to '%s' with conflicts.\n"
-msgstr ""
-
-#: apply.c:3659
-#, c-format
-msgid "Applied patch to '%s' cleanly.\n"
-msgstr ""
-
-#: apply.c:3676
-#, c-format
-msgid "Falling back to direct application...\n"
-msgstr ""
-
-#: apply.c:3688
-msgid "removal patch leaves file contents"
-msgstr ""
-
-#: apply.c:3761
-#, c-format
-msgid "%s: wrong type"
-msgstr ""
-
-#: apply.c:3763
-#, c-format
-msgid "%s has type %o, expected %o"
-msgstr ""
-
-#: apply.c:3900 apply.c:3902 read-cache.c:903 read-cache.c:932
-#: read-cache.c:1399
-#, c-format
-msgid "invalid path '%s'"
-msgstr ""
-
-#: apply.c:3958
-#, c-format
-msgid "%s: already exists in index"
-msgstr ""
-
-#: apply.c:3962
-#, c-format
-msgid "%s: already exists in working directory"
-msgstr ""
-
-#: apply.c:3982
-#, c-format
-msgid "new mode (%o) of %s does not match old mode (%o)"
-msgstr ""
-
-#: apply.c:3987
-#, c-format
-msgid "new mode (%o) of %s does not match old mode (%o) of %s"
-msgstr ""
-
-#: apply.c:4007
-#, c-format
-msgid "affected file '%s' is beyond a symbolic link"
-msgstr ""
-
-#: apply.c:4011
-#, c-format
-msgid "%s: patch does not apply"
-msgstr ""
-
-#: apply.c:4026
-#, c-format
-msgid "Checking patch %s..."
-msgstr ""
-
-#: apply.c:4118
-#, c-format
-msgid "sha1 information is lacking or useless for submodule %s"
-msgstr ""
-
-#: apply.c:4125
-#, c-format
-msgid "mode change for %s, which is not in current HEAD"
-msgstr ""
-
-#: apply.c:4128
-#, c-format
-msgid "sha1 information is lacking or useless (%s)."
-msgstr ""
-
-#: apply.c:4137
-#, c-format
-msgid "could not add %s to temporary index"
-msgstr ""
-
-#: apply.c:4147
-#, c-format
-msgid "could not write temporary index to %s"
-msgstr ""
-
-#: apply.c:4285
-#, c-format
-msgid "unable to remove %s from index"
-msgstr ""
-
-#: apply.c:4319
-#, c-format
-msgid "corrupt patch for submodule %s"
-msgstr ""
-
-#: apply.c:4325
-#, c-format
-msgid "unable to stat newly created file '%s'"
-msgstr ""
-
-#: apply.c:4333
-#, c-format
-msgid "unable to create backing store for newly created file %s"
-msgstr ""
-
-#: apply.c:4339 apply.c:4484
-#, c-format
-msgid "unable to add cache entry for %s"
-msgstr ""
-
-#: apply.c:4382 builtin/bisect--helper.c:540 builtin/gc.c:2258
-#: builtin/gc.c:2293
-#, c-format
-msgid "failed to write to '%s'"
-msgstr ""
-
-#: apply.c:4386
-#, c-format
-msgid "closing file '%s'"
-msgstr ""
-
-#: apply.c:4456
-#, c-format
-msgid "unable to write file '%s' mode %o"
-msgstr ""
-
-#: apply.c:4554
-#, c-format
-msgid "Applied patch %s cleanly."
-msgstr ""
-
-#: apply.c:4562
-msgid "internal error"
-msgstr ""
-
-#: apply.c:4565
-#, c-format
-msgid "Applying patch %%s with %d reject..."
-msgid_plural "Applying patch %%s with %d rejects..."
-msgstr[0] ""
-msgstr[1] ""
-
-#: apply.c:4576
-#, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr ""
-
-#: apply.c:4584
-#, c-format
-msgid "cannot open %s"
-msgstr ""
-
-#: apply.c:4598
-#, c-format
-msgid "Hunk #%d applied cleanly."
-msgstr ""
-
-#: apply.c:4602
-#, c-format
-msgid "Rejected hunk #%d."
-msgstr ""
-
-#: apply.c:4731
-#, c-format
-msgid "Skipped patch '%s'."
-msgstr ""
-
-#: apply.c:4740
-msgid "No valid patches in input (allow with \"--allow-empty\")"
-msgstr ""
-
-#: apply.c:4761
-msgid "unable to read index file"
-msgstr ""
-
-#: apply.c:4918
-#, c-format
-msgid "can't open patch '%s': %s"
-msgstr ""
-
-#: apply.c:4945
-#, c-format
-msgid "squelched %d whitespace error"
-msgid_plural "squelched %d whitespace errors"
-msgstr[0] ""
-msgstr[1] ""
-
-#: apply.c:4951 apply.c:4966
-#, c-format
-msgid "%d line adds whitespace errors."
-msgid_plural "%d lines add whitespace errors."
-msgstr[0] ""
-msgstr[1] ""
-
-#: apply.c:4959
-#, c-format
-msgid "%d line applied after fixing whitespace errors."
-msgid_plural "%d lines applied after fixing whitespace errors."
-msgstr[0] ""
-msgstr[1] ""
-
-#: apply.c:4975 builtin/add.c:690 builtin/mv.c:338 builtin/rm.c:430
-msgid "Unable to write new index file"
-msgstr ""
-
-#: apply.c:5003
-msgid "don't apply changes matching the given path"
-msgstr ""
-
-#: apply.c:5006
-msgid "apply changes matching the given path"
-msgstr ""
-
-#: apply.c:5008 builtin/am.c:2379
-msgid "num"
-msgstr ""
-
-#: apply.c:5009
-msgid "remove <num> leading slashes from traditional diff paths"
-msgstr ""
-
-#: apply.c:5012
-msgid "ignore additions made by the patch"
-msgstr ""
-
-#: apply.c:5014
-msgid "instead of applying the patch, output diffstat for the input"
-msgstr ""
-
-#: apply.c:5018
-msgid "show number of added and deleted lines in decimal notation"
-msgstr ""
-
-#: apply.c:5020
-msgid "instead of applying the patch, output a summary for the input"
-msgstr ""
-
-#: apply.c:5022
-msgid "instead of applying the patch, see if the patch is applicable"
-msgstr ""
-
-#: apply.c:5024
-msgid "make sure the patch is applicable to the current index"
-msgstr ""
-
-#: apply.c:5026
-msgid "mark new files with `git add --intent-to-add`"
-msgstr ""
-
-#: apply.c:5028
-msgid "apply a patch without touching the working tree"
-msgstr ""
-
-#: apply.c:5030
-msgid "accept a patch that touches outside the working area"
-msgstr ""
-
-#: apply.c:5033
-msgid "also apply the patch (use with --stat/--summary/--check)"
-msgstr ""
-
-#: apply.c:5035
-msgid "attempt three-way merge, fall back on normal patch if that fails"
-msgstr ""
-
-#: apply.c:5037
-msgid "build a temporary index based on embedded index information"
-msgstr ""
-
-#: apply.c:5040 builtin/checkout-index.c:230
-msgid "paths are separated with NUL character"
-msgstr ""
-
-#: apply.c:5042
-msgid "ensure at least <n> lines of context match"
-msgstr ""
-
-#: apply.c:5043 builtin/am.c:2355 builtin/am.c:2358
-#: builtin/interpret-trailers.c:98 builtin/interpret-trailers.c:100
-#: builtin/interpret-trailers.c:102 builtin/pack-objects.c:3983
-#: builtin/rebase.c:1079
-msgid "action"
-msgstr ""
-
-#: apply.c:5044
-msgid "detect new or modified lines that have whitespace errors"
-msgstr ""
-
-#: apply.c:5047 apply.c:5050
-msgid "ignore changes in whitespace when finding context"
-msgstr ""
-
-#: apply.c:5053
-msgid "apply the patch in reverse"
-msgstr ""
-
-#: apply.c:5055
-msgid "don't expect at least one line of context"
-msgstr ""
-
-#: apply.c:5057
-msgid "leave the rejected hunks in corresponding *.rej files"
-msgstr ""
-
-#: apply.c:5059
-msgid "allow overlapping hunks"
-msgstr ""
-
-#: apply.c:5062
-msgid "tolerate incorrectly detected missing new-line at the end of file"
-msgstr ""
-
-#: apply.c:5065
-msgid "do not trust the line counts in the hunk headers"
-msgstr ""
-
-#: apply.c:5067 builtin/am.c:2367
-msgid "root"
-msgstr ""
-
-#: apply.c:5068
-msgid "prepend <root> to all filenames"
-msgstr ""
-
-#: apply.c:5071
-msgid "don't return error for empty patches"
-msgstr ""
-
-#: archive-tar.c:125 archive-zip.c:346
-#, c-format
-msgid "cannot stream blob %s"
-msgstr ""
-
-#: archive-tar.c:265 archive-zip.c:359
-#, c-format
-msgid "unsupported file mode: 0%o (SHA1: %s)"
-msgstr ""
-
-#: archive-tar.c:447
-#, c-format
-msgid "unable to start '%s' filter"
-msgstr ""
-
-#: archive-tar.c:450
-msgid "unable to redirect descriptor"
-msgstr ""
-
-#: archive-tar.c:457
-#, c-format
-msgid "'%s' filter reported error"
-msgstr ""
-
-#: archive-zip.c:319
-#, c-format
-msgid "path is not valid UTF-8: %s"
-msgstr ""
-
-#: archive-zip.c:323
-#, c-format
-msgid "path too long (%d chars, SHA1: %s): %s"
-msgstr ""
-
-#: archive-zip.c:470 builtin/pack-objects.c:363 builtin/pack-objects.c:366
-#, c-format
-msgid "deflate error (%d)"
-msgstr ""
-
-#: archive-zip.c:604
-#, c-format
-msgid "timestamp too large for this system: %<PRIuMAX>"
-msgstr ""
-
-#: archive.c:14
-msgid "git archive [<options>] <tree-ish> [<path>...]"
-msgstr ""
-
-#: archive.c:16
-msgid ""
-"git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]"
-msgstr ""
-
-#: archive.c:17
-msgid "git archive --remote <repo> [--exec <cmd>] --list"
-msgstr ""
-
-#: archive.c:188 archive.c:341 builtin/gc.c:497 builtin/notes.c:238
-#: builtin/tag.c:579
-#, c-format
-msgid "cannot read '%s'"
-msgstr ""
-
-#: archive.c:426 builtin/add.c:214 builtin/add.c:657 builtin/rm.c:334
-#, c-format
-msgid "pathspec '%s' did not match any files"
-msgstr ""
-
-#: archive.c:450
-#, c-format
-msgid "no such ref: %.*s"
-msgstr ""
-
-#: archive.c:456
-#, c-format
-msgid "not a valid object name: %s"
-msgstr ""
-
-#: archive.c:469
-#, c-format
-msgid "not a tree object: %s"
-msgstr ""
-
-#: archive.c:481
-msgid "current working directory is untracked"
-msgstr ""
-
-#: archive.c:522
-#, c-format
-msgid "File not found: %s"
-msgstr ""
-
-#: archive.c:524
-#, c-format
-msgid "Not a regular file: %s"
-msgstr ""
-
-#: archive.c:551
-msgid "fmt"
-msgstr ""
-
-#: archive.c:551
-msgid "archive format"
-msgstr ""
-
-#: archive.c:552 builtin/log.c:1809
-msgid "prefix"
-msgstr ""
-
-#: archive.c:553
-msgid "prepend prefix to each pathname in the archive"
-msgstr ""
-
-#: archive.c:554 archive.c:557 builtin/blame.c:881 builtin/blame.c:885
-#: builtin/blame.c:886 builtin/commit-tree.c:115 builtin/config.c:135
-#: builtin/fast-export.c:1181 builtin/fast-export.c:1183
-#: builtin/fast-export.c:1187 builtin/grep.c:936 builtin/hash-object.c:104
-#: builtin/ls-files.c:654 builtin/ls-files.c:657 builtin/notes.c:410
-#: builtin/notes.c:576 builtin/read-tree.c:115 parse-options.h:195
-msgid "file"
-msgstr ""
-
-#: archive.c:555
-msgid "add untracked file to archive"
-msgstr ""
-
-#: archive.c:558 builtin/archive.c:88
-msgid "write the archive to this file"
-msgstr ""
-
-#: archive.c:560
-msgid "read .gitattributes in working directory"
-msgstr ""
-
-#: archive.c:561
-msgid "report archived files on stderr"
-msgstr ""
-
-#: archive.c:563
-msgid "set compression level"
-msgstr ""
-
-#: archive.c:566
-msgid "list supported archive formats"
-msgstr ""
-
-#: archive.c:568 builtin/archive.c:89 builtin/clone.c:122 builtin/clone.c:125
-#: builtin/submodule--helper.c:1884 builtin/submodule--helper.c:2718
-msgid "repo"
-msgstr ""
-
-#: archive.c:569 builtin/archive.c:90
-msgid "retrieve the archive from remote repository <repo>"
-msgstr ""
-
-#: archive.c:570 builtin/archive.c:91 builtin/difftool.c:708
-#: builtin/notes.c:496
-msgid "command"
-msgstr ""
-
-#: archive.c:571 builtin/archive.c:92
-msgid "path to the remote git-upload-archive command"
-msgstr ""
-
-#: archive.c:578
-msgid "Unexpected option --remote"
-msgstr ""
-
-#: archive.c:580 fetch-pack.c:300 revision.c:2914 builtin/add.c:530
-#: builtin/add.c:562 builtin/checkout.c:1782 builtin/clone.c:1099
-#: builtin/clone.c:1102 builtin/commit.c:371 builtin/fast-export.c:1230
-#: builtin/index-pack.c:1854 builtin/log.c:2140 builtin/reset.c:442
-#: builtin/reset.c:500 builtin/rm.c:281 builtin/stash.c:1708
-#: builtin/worktree.c:580 builtin/worktree.c:781 http-fetch.c:144
-#: http-fetch.c:153
-#, c-format
-msgid "the option '%s' requires '%s'"
-msgstr ""
-
-#: archive.c:582
-msgid "Unexpected option --output"
-msgstr ""
-
-#: archive.c:606
-#, c-format
-msgid "Unknown archive format '%s'"
-msgstr ""
-
-#: archive.c:615
-#, c-format
-msgid "Argument not supported for format '%s': -%d"
-msgstr ""
-
-#: attr.c:202
-#, c-format
-msgid "%.*s is not a valid attribute name"
-msgstr ""
-
-#: attr.c:363
-#, c-format
-msgid "%s not allowed: %s:%d"
-msgstr ""
-
-#: attr.c:403
-msgid ""
-"Negative patterns are ignored in git attributes\n"
-"Use '\\!' for literal leading exclamation."
-msgstr ""
-
-#: bisect.c:488
-#, c-format
-msgid "Badly quoted content in file '%s': %s"
-msgstr ""
-
-#: bisect.c:698
-#, c-format
-msgid "We cannot bisect more!\n"
-msgstr ""
-
-#: bisect.c:765
-#, c-format
-msgid "Not a valid commit name %s"
-msgstr ""
-
-#: bisect.c:790
-#, c-format
-msgid ""
-"The merge base %s is bad.\n"
-"This means the bug has been fixed between %s and [%s].\n"
-msgstr ""
-
-#: bisect.c:795
-#, c-format
-msgid ""
-"The merge base %s is new.\n"
-"The property has changed between %s and [%s].\n"
-msgstr ""
-
-#: bisect.c:800
-#, c-format
-msgid ""
-"The merge base %s is %s.\n"
-"This means the first '%s' commit is between %s and [%s].\n"
-msgstr ""
-
-#: bisect.c:808
-#, c-format
-msgid ""
-"Some %s revs are not ancestors of the %s rev.\n"
-"git bisect cannot work properly in this case.\n"
-"Maybe you mistook %s and %s revs?\n"
-msgstr ""
-
-#: bisect.c:821
-#, c-format
-msgid ""
-"the merge base between %s and [%s] must be skipped.\n"
-"So we cannot be sure the first %s commit is between %s and %s.\n"
-"We continue anyway."
-msgstr ""
-
-#: bisect.c:860
-#, c-format
-msgid "Bisecting: a merge base must be tested\n"
-msgstr ""
-
-#: bisect.c:910
-#, c-format
-msgid "a %s revision is needed"
-msgstr ""
-
-#: bisect.c:940
-#, c-format
-msgid "could not create file '%s'"
-msgstr ""
-
-#: bisect.c:986 builtin/merge.c:155
-#, c-format
-msgid "could not read file '%s'"
-msgstr ""
-
-#: bisect.c:1026
-msgid "reading bisect refs failed"
-msgstr ""
-
-#: bisect.c:1056
-#, c-format
-msgid "%s was both %s and %s\n"
-msgstr ""
-
-#: bisect.c:1065
-#, c-format
-msgid ""
-"No testable commit found.\n"
-"Maybe you started with bad path arguments?\n"
-msgstr ""
-
-#: bisect.c:1094
-#, c-format
-msgid "(roughly %d step)"
-msgid_plural "(roughly %d steps)"
-msgstr[0] ""
-msgstr[1] ""
-
-#. TRANSLATORS: the last %s will be replaced with "(roughly %d
-#. steps)" translation.
-#.
-#: bisect.c:1100
-#, c-format
-msgid "Bisecting: %d revision left to test after this %s\n"
-msgid_plural "Bisecting: %d revisions left to test after this %s\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: blame.c:2773
-msgid "--contents and --reverse do not blend well."
-msgstr ""
-
-#: blame.c:2787
-msgid "cannot use --contents with final commit object name"
-msgstr ""
-
-#: blame.c:2808
-msgid "--reverse and --first-parent together require specified latest commit"
-msgstr ""
-
-#: blame.c:2817 bundle.c:231 midx.c:1058 ref-filter.c:2371 remote.c:2157
-#: sequencer.c:2348 sequencer.c:4872 submodule.c:913 builtin/commit.c:1118
-#: builtin/log.c:437 builtin/log.c:1055 builtin/log.c:1663 builtin/log.c:2096
-#: builtin/log.c:2387 builtin/merge.c:431 builtin/pack-objects.c:3381
-#: builtin/pack-objects.c:3781 builtin/pack-objects.c:3796
-#: builtin/shortlog.c:255
-msgid "revision walk setup failed"
-msgstr ""
-
-#: blame.c:2835
-msgid ""
-"--reverse --first-parent together require range along first-parent chain"
-msgstr ""
-
-#: blame.c:2846
-#, c-format
-msgid "no such path %s in %s"
-msgstr ""
-
-#: blame.c:2857
-#, c-format
-msgid "cannot read blob %s for path %s"
-msgstr ""
-
-#: branch.c:93
-msgid ""
-"cannot inherit upstream tracking configuration of multiple refs when "
-"rebasing is requested"
-msgstr ""
-
-#: branch.c:104
-#, c-format
-msgid "not setting branch '%s' as its own upstream"
-msgstr ""
-
-#: branch.c:160
-#, c-format
-msgid "branch '%s' set up to track '%s' by rebasing."
-msgstr ""
-
-#: branch.c:161
-#, c-format
-msgid "branch '%s' set up to track '%s'."
-msgstr ""
-
-#: branch.c:164
-#, c-format
-msgid "branch '%s' set up to track:"
-msgstr ""
-
-#: branch.c:176
-msgid "unable to write upstream branch configuration"
-msgstr ""
-
-#: branch.c:178
-msgid ""
-"\n"
-"After fixing the error cause you may try to fix up\n"
-"the remote tracking information by invoking:"
-msgstr ""
-
-#: branch.c:219
-#, c-format
-msgid "asked to inherit tracking from '%s', but no remote is set"
-msgstr ""
-
-#: branch.c:225
-#, c-format
-msgid "asked to inherit tracking from '%s', but no merge configuration is set"
-msgstr ""
-
-#: branch.c:277
-#, c-format
-msgid "not tracking: ambiguous information for ref '%s'"
-msgstr ""
-
-#. 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.
-#.
-#. 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.
-#.
-#: branch.c:289 object-name.c:464
-#, c-format
-msgid "  %s\n"
-msgstr ""
-
-#. TRANSLATORS: The second argument is a \n-delimited list of
-#. duplicate refspecs, composed above.
-#.
-#: branch.c:295
-#, c-format
-msgid ""
-"There are multiple remotes whose fetch refspecs map to the remote\n"
-"tracking ref '%s':\n"
-"%s\n"
-"This is typically a configuration error.\n"
-"\n"
-"To support setting up tracking branches, ensure that\n"
-"different remotes' fetch refspecs map into different\n"
-"tracking namespaces."
-msgstr ""
-
-#: branch.c:344
-#, c-format
-msgid "'%s' is not a valid branch name"
-msgstr ""
-
-#: branch.c:364
-#, c-format
-msgid "a branch named '%s' already exists"
-msgstr ""
-
-#: branch.c:370
-#, c-format
-msgid "cannot force update the branch '%s' checked out at '%s'"
-msgstr ""
-
-#: branch.c:393
-#, c-format
-msgid "cannot set up tracking information; starting point '%s' is not a branch"
-msgstr ""
-
-#: branch.c:395
-#, c-format
-msgid "the requested upstream branch '%s' does not exist"
-msgstr ""
-
-#: branch.c:397
-msgid ""
-"\n"
-"If you are planning on basing your work on an upstream\n"
-"branch that already exists at the remote, you may need to\n"
-"run \"git fetch\" to retrieve it.\n"
-"\n"
-"If you are planning to push out a new local branch that\n"
-"will track its remote counterpart, you may want to use\n"
-"\"git push -u\" to set the upstream config as you push."
-msgstr ""
-
-#: branch.c:445 builtin/replace.c:321 builtin/replace.c:377
-#: builtin/replace.c:423 builtin/replace.c:453
-#, c-format
-msgid "not a valid object name: '%s'"
-msgstr ""
-
-#: branch.c:465
-#, c-format
-msgid "ambiguous object name: '%s'"
-msgstr ""
-
-#: branch.c:470
-#, c-format
-msgid "not a valid branch point: '%s'"
-msgstr ""
-
-#: branch.c:658
-#, c-format
-msgid "submodule '%s': unable to find submodule"
-msgstr ""
-
-#: branch.c:661
-#, c-format
-msgid ""
-"You may try updating the submodules using 'git checkout %s && git submodule "
-"update --init'"
-msgstr ""
-
-#: branch.c:672 branch.c:698
-#, c-format
-msgid "submodule '%s': cannot create branch '%s'"
-msgstr ""
-
-#: branch.c:730
-#, c-format
-msgid "'%s' is already checked out at '%s'"
-msgstr ""
-
-#: branch.c:755
-#, c-format
-msgid "HEAD of working tree %s is not updated"
-msgstr ""
-
-#: bundle.c:45
-#, c-format
-msgid "unrecognized bundle hash algorithm: %s"
-msgstr ""
-
-#: bundle.c:53
-#, c-format
-msgid "unknown capability '%s'"
-msgstr ""
-
-#: bundle.c:79
-#, c-format
-msgid "'%s' does not look like a v2 or v3 bundle file"
-msgstr ""
-
-#: bundle.c:118
-#, c-format
-msgid "unrecognized header: %s%s (%d)"
-msgstr ""
-
-#: bundle.c:145 rerere.c:464 rerere.c:675 sequencer.c:2616 sequencer.c:3402
-#: builtin/commit.c:865
-#, c-format
-msgid "could not open '%s'"
-msgstr ""
-
-#: bundle.c:203
-msgid "Repository lacks these prerequisite commits:"
-msgstr ""
-
-#: bundle.c:206
-msgid "need a repository to verify a bundle"
-msgstr ""
-
-#: bundle.c:264
-#, c-format
-msgid "The bundle contains this ref:"
-msgid_plural "The bundle contains these %<PRIuMAX> refs:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: bundle.c:272
-msgid "The bundle records a complete history."
-msgstr ""
-
-#: bundle.c:274
-#, c-format
-msgid "The bundle requires this ref:"
-msgid_plural "The bundle requires these %<PRIuMAX> refs:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: bundle.c:350
-msgid "unable to dup bundle descriptor"
-msgstr ""
-
-#: bundle.c:357
-msgid "Could not spawn pack-objects"
-msgstr ""
-
-#: bundle.c:368
-msgid "pack-objects died"
-msgstr ""
-
-#: bundle.c:417
-#, c-format
-msgid "ref '%s' is excluded by the rev-list options"
-msgstr ""
-
-#: bundle.c:533 builtin/log.c:211 builtin/log.c:1975 builtin/shortlog.c:400
-#, c-format
-msgid "unrecognized argument: %s"
-msgstr ""
-
-#: bundle.c:548
-#, c-format
-msgid "unsupported bundle version %d"
-msgstr ""
-
-#: bundle.c:550
-#, c-format
-msgid "cannot write bundle version %d with algorithm %s"
-msgstr ""
-
-#: bundle.c:600
-msgid "Refusing to create empty bundle."
-msgstr ""
-
-#: bundle.c:610
-#, c-format
-msgid "cannot create '%s'"
-msgstr ""
-
-#: bundle.c:639
-msgid "index-pack died"
-msgstr ""
-
-#: chunk-format.c:117
-msgid "terminating chunk id appears earlier than expected"
-msgstr ""
-
-#: chunk-format.c:126
-#, c-format
-msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>"
-msgstr ""
-
-#: chunk-format.c:133
-#, c-format
-msgid "duplicate chunk ID %<PRIx32> found"
-msgstr ""
-
-#: chunk-format.c:147
-#, c-format
-msgid "final chunk has non-zero id %<PRIx32>"
-msgstr ""
-
-#: color.c:354
-#, c-format
-msgid "invalid color value: %.*s"
-msgstr ""
-
-#: commit-graph.c:204 midx.c:52
-msgid "invalid hash version"
-msgstr ""
-
-#: commit-graph.c:262
-msgid "commit-graph file is too small"
-msgstr ""
-
-#: commit-graph.c:355
-#, c-format
-msgid "commit-graph signature %X does not match signature %X"
-msgstr ""
-
-#: commit-graph.c:362
-#, c-format
-msgid "commit-graph version %X does not match version %X"
-msgstr ""
-
-#: commit-graph.c:369
-#, c-format
-msgid "commit-graph hash version %X does not match version %X"
-msgstr ""
-
-#: commit-graph.c:386
-#, c-format
-msgid "commit-graph file is too small to hold %u chunks"
-msgstr ""
-
-#: commit-graph.c:485
-msgid "commit-graph has no base graphs chunk"
-msgstr ""
-
-#: commit-graph.c:495
-msgid "commit-graph chain does not match"
-msgstr ""
-
-#: commit-graph.c:543
-#, c-format
-msgid "invalid commit-graph chain: line '%s' not a hash"
-msgstr ""
-
-#: commit-graph.c:567
-msgid "unable to find all commit-graph files"
-msgstr ""
-
-#: commit-graph.c:752 commit-graph.c:789
-msgid "invalid commit position. commit-graph is likely corrupt"
-msgstr ""
-
-#: commit-graph.c:773
-#, c-format
-msgid "could not find commit %s"
-msgstr ""
-
-#: commit-graph.c:806
-msgid "commit-graph requires overflow generation data but has none"
-msgstr ""
-
-#: commit-graph.c:1111 builtin/am.c:1370 builtin/checkout.c:775
-#: builtin/clone.c:705
-#, c-format
-msgid "unable to parse commit %s"
-msgstr ""
-
-#: commit-graph.c:1373 builtin/pack-objects.c:3078
-#, c-format
-msgid "unable to get type of object %s"
-msgstr ""
-
-#: commit-graph.c:1404
-msgid "Loading known commits in commit graph"
-msgstr ""
-
-#: commit-graph.c:1421
-msgid "Expanding reachable commits in commit graph"
-msgstr ""
-
-#: commit-graph.c:1441
-msgid "Clearing commit marks in commit graph"
-msgstr ""
-
-#: commit-graph.c:1460
-msgid "Computing commit graph topological levels"
-msgstr ""
-
-#: commit-graph.c:1513
-msgid "Computing commit graph generation numbers"
-msgstr ""
-
-#: commit-graph.c:1598
-msgid "Computing commit changed paths Bloom filters"
-msgstr ""
-
-#: commit-graph.c:1675
-msgid "Collecting referenced commits"
-msgstr ""
-
-#: commit-graph.c:1701
-#, 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] ""
-
-#: commit-graph.c:1714
-#, c-format
-msgid "error adding pack %s"
-msgstr ""
-
-#: commit-graph.c:1718
-#, c-format
-msgid "error opening index for %s"
-msgstr ""
-
-#: commit-graph.c:1756
-msgid "Finding commits for commit graph among packed objects"
-msgstr ""
-
-#: commit-graph.c:1774
-msgid "Finding extra edges in commit graph"
-msgstr ""
-
-#: commit-graph.c:1823
-msgid "failed to write correct number of base graph ids"
-msgstr ""
-
-#: commit-graph.c:1854 midx.c:1168 builtin/sparse-checkout.c:475
-#, c-format
-msgid "unable to create leading directories of %s"
-msgstr ""
-
-#: commit-graph.c:1868
-msgid "unable to create temporary graph layer"
-msgstr ""
-
-#: commit-graph.c:1873
-#, c-format
-msgid "unable to adjust shared permissions for '%s'"
-msgstr ""
-
-#: commit-graph.c:1930
-#, c-format
-msgid "Writing out commit graph in %d pass"
-msgid_plural "Writing out commit graph in %d passes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: commit-graph.c:1967
-msgid "unable to open commit-graph chain file"
-msgstr ""
-
-#: commit-graph.c:1983
-msgid "failed to rename base commit-graph file"
-msgstr ""
-
-#: commit-graph.c:2004
-msgid "failed to rename temporary commit-graph file"
-msgstr ""
-
-#: commit-graph.c:2137
-msgid "Scanning merged commits"
-msgstr ""
-
-#: commit-graph.c:2181
-msgid "Merging commit-graph"
-msgstr ""
-
-#: commit-graph.c:2289
-msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
-msgstr ""
-
-#: commit-graph.c:2396
-msgid "too many commits to write graph"
-msgstr ""
-
-#: commit-graph.c:2494
-msgid "the commit-graph file has incorrect checksum and is likely corrupt"
-msgstr ""
-
-#: commit-graph.c:2504
-#, c-format
-msgid "commit-graph has incorrect OID order: %s then %s"
-msgstr ""
-
-#: commit-graph.c:2514 commit-graph.c:2529
-#, c-format
-msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u"
-msgstr ""
-
-#: commit-graph.c:2521
-#, c-format
-msgid "failed to parse commit %s from commit-graph"
-msgstr ""
-
-#: commit-graph.c:2539
-msgid "Verifying commits in commit graph"
-msgstr ""
-
-#: commit-graph.c:2554
-#, c-format
-msgid "failed to parse commit %s from object database for commit-graph"
-msgstr ""
-
-#: commit-graph.c:2561
-#, c-format
-msgid "root tree OID for commit %s in commit-graph is %s != %s"
-msgstr ""
-
-#: commit-graph.c:2571
-#, c-format
-msgid "commit-graph parent list for commit %s is too long"
-msgstr ""
-
-#: commit-graph.c:2580
-#, c-format
-msgid "commit-graph parent for %s is %s != %s"
-msgstr ""
-
-#: commit-graph.c:2594
-#, c-format
-msgid "commit-graph parent list for commit %s terminates early"
-msgstr ""
-
-#: commit-graph.c:2599
-#, c-format
-msgid ""
-"commit-graph has generation number zero for commit %s, but non-zero elsewhere"
-msgstr ""
-
-#: commit-graph.c:2603
-#, c-format
-msgid ""
-"commit-graph has non-zero generation number for commit %s, but zero elsewhere"
-msgstr ""
-
-#: commit-graph.c:2620
-#, c-format
-msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>"
-msgstr ""
-
-#: commit-graph.c:2626
-#, c-format
-msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>"
-msgstr ""
-
-#: commit.c:54 sequencer.c:3105 builtin/am.c:400 builtin/am.c:445
-#: builtin/am.c:450 builtin/am.c:1449 builtin/am.c:2124 builtin/replace.c:456
-#, c-format
-msgid "could not parse %s"
-msgstr ""
-
-#: commit.c:56
-#, c-format
-msgid "%s %s is not a commit!"
-msgstr ""
-
-#: commit.c:197
-msgid ""
-"Support for <GIT_DIR>/info/grafts is deprecated\n"
-"and will be removed in a future Git version.\n"
-"\n"
-"Please use \"git replace --convert-graft-file\"\n"
-"to convert the grafts into replace refs.\n"
-"\n"
-"Turn this message off by running\n"
-"\"git config advice.graftFileDeprecated false\""
-msgstr ""
-
-#: commit.c:1252
-#, c-format
-msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
-msgstr ""
-
-#: commit.c:1256
-#, c-format
-msgid "Commit %s has a bad GPG signature allegedly by %s."
-msgstr ""
-
-#: commit.c:1259
-#, c-format
-msgid "Commit %s does not have a GPG signature."
-msgstr ""
-
-#: commit.c:1262
-#, c-format
-msgid "Commit %s has a good GPG signature by %s\n"
-msgstr ""
-
-#: commit.c:1516
-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 ""
-
-#: compat/obstack.c:406 compat/obstack.c:408
-msgid "memory exhausted"
-msgstr ""
-
-#: compat/terminal.c:167
-msgid "cannot resume in the background, please use 'fg' to resume"
-msgstr ""
-
-#: compat/terminal.c:168
-msgid "cannot restore terminal settings"
-msgstr ""
-
-#: config.c:143
-#, c-format
-msgid ""
-"exceeded maximum include depth (%d) while including\n"
-"\t%s\n"
-"from\n"
-"\t%s\n"
-"This might be due to circular includes."
-msgstr ""
-
-#: config.c:159
-#, c-format
-msgid "could not expand include path '%s'"
-msgstr ""
-
-#: config.c:170
-msgid "relative config includes must come from files"
-msgstr ""
-
-#: config.c:219
-msgid "relative config include conditionals must come from files"
-msgstr ""
-
-#: config.c:364
-msgid ""
-"remote URLs cannot be configured in file directly or indirectly included by "
-"includeIf.hasconfig:remote.*.url"
-msgstr ""
-
-#: config.c:508
-#, c-format
-msgid "invalid config format: %s"
-msgstr ""
-
-#: config.c:512
-#, c-format
-msgid "missing environment variable name for configuration '%.*s'"
-msgstr ""
-
-#: config.c:517
-#, c-format
-msgid "missing environment variable '%s' for configuration '%.*s'"
-msgstr ""
-
-#: config.c:553
-#, c-format
-msgid "key does not contain a section: %s"
-msgstr ""
-
-#: config.c:558
-#, c-format
-msgid "key does not contain variable name: %s"
-msgstr ""
-
-#: config.c:580 sequencer.c:2802
-#, c-format
-msgid "invalid key: %s"
-msgstr ""
-
-#: config.c:585
-#, c-format
-msgid "invalid key (newline): %s"
-msgstr ""
-
-#: config.c:605
-msgid "empty config key"
-msgstr ""
-
-#: config.c:623 config.c:635
-#, c-format
-msgid "bogus config parameter: %s"
-msgstr ""
-
-#: config.c:649 config.c:666 config.c:673 config.c:682
-#, c-format
-msgid "bogus format in %s"
-msgstr ""
-
-#: config.c:716
-#, c-format
-msgid "bogus count in %s"
-msgstr ""
-
-#: config.c:720
-#, c-format
-msgid "too many entries in %s"
-msgstr ""
-
-#: config.c:730
-#, c-format
-msgid "missing config key %s"
-msgstr ""
-
-#: config.c:738
-#, c-format
-msgid "missing config value %s"
-msgstr ""
-
-#: config.c:1089
-#, c-format
-msgid "bad config line %d in blob %s"
-msgstr ""
-
-#: config.c:1093
-#, c-format
-msgid "bad config line %d in file %s"
-msgstr ""
-
-#: config.c:1097
-#, c-format
-msgid "bad config line %d in standard input"
-msgstr ""
-
-#: config.c:1101
-#, c-format
-msgid "bad config line %d in submodule-blob %s"
-msgstr ""
-
-#: config.c:1105
-#, c-format
-msgid "bad config line %d in command line %s"
-msgstr ""
-
-#: config.c:1109
-#, c-format
-msgid "bad config line %d in %s"
-msgstr ""
-
-#: config.c:1246
-msgid "out of range"
-msgstr ""
-
-#: config.c:1246
-msgid "invalid unit"
-msgstr ""
-
-#: config.c:1247
-#, c-format
-msgid "bad numeric config value '%s' for '%s': %s"
-msgstr ""
-
-#: config.c:1257
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
-msgstr ""
-
-#: config.c:1260
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in file %s: %s"
-msgstr ""
-
-#: config.c:1263
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in standard input: %s"
-msgstr ""
-
-#: config.c:1266
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
-msgstr ""
-
-#: config.c:1269
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
-msgstr ""
-
-#: config.c:1272
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in %s: %s"
-msgstr ""
-
-#: config.c:1368
-#, c-format
-msgid "invalid value for variable %s"
-msgstr ""
-
-#: config.c:1389
-#, c-format
-msgid "ignoring unknown core.fsync component '%s'"
-msgstr ""
-
-#: config.c:1425
-#, c-format
-msgid "bad boolean config value '%s' for '%s'"
-msgstr ""
-
-#: config.c:1443
-#, c-format
-msgid "failed to expand user dir in: '%s'"
-msgstr ""
-
-#: config.c:1452
-#, c-format
-msgid "'%s' for '%s' is not a valid timestamp"
-msgstr ""
-
-#: config.c:1545
-#, c-format
-msgid "abbrev length out of range: %d"
-msgstr ""
-
-#: config.c:1559 config.c:1570
-#, c-format
-msgid "bad zlib compression level %d"
-msgstr ""
-
-#: config.c:1660
-msgid "core.commentChar should only be one character"
-msgstr ""
-
-#: config.c:1692
-#, c-format
-msgid "ignoring unknown core.fsyncMethod value '%s'"
-msgstr ""
-
-#: config.c:1698
-msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead"
-msgstr ""
-
-#: config.c:1714
-#, c-format
-msgid "invalid mode for object creation: %s"
-msgstr ""
-
-#: config.c:1800
-#, c-format
-msgid "malformed value for %s"
-msgstr ""
-
-#: config.c:1826
-#, c-format
-msgid "malformed value for %s: %s"
-msgstr ""
-
-#: config.c:1827
-msgid "must be one of nothing, matching, simple, upstream or current"
-msgstr ""
-
-#: config.c:1888 builtin/pack-objects.c:4078
-#, c-format
-msgid "bad pack compression level %d"
-msgstr ""
-
-#: config.c:2014
-#, c-format
-msgid "unable to load config blob object '%s'"
-msgstr ""
-
-#: config.c:2017
-#, c-format
-msgid "reference '%s' does not point to a blob"
-msgstr ""
-
-#: config.c:2035
-#, c-format
-msgid "unable to resolve config blob '%s'"
-msgstr ""
-
-#: config.c:2080
-#, c-format
-msgid "failed to parse %s"
-msgstr ""
-
-#: config.c:2136
-msgid "unable to parse command-line config"
-msgstr ""
-
-#: config.c:2512
-msgid "unknown error occurred while reading the configuration files"
-msgstr ""
-
-#: config.c:2686
-#, c-format
-msgid "Invalid %s: '%s'"
-msgstr ""
-
-#: config.c:2731
-#, c-format
-msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
-msgstr ""
-
-#: config.c:2763
-#, c-format
-msgid "unable to parse '%s' from command-line config"
-msgstr ""
-
-#: config.c:2765
-#, c-format
-msgid "bad config variable '%s' in file '%s' at line %d"
-msgstr ""
-
-#: config.c:2850
-#, c-format
-msgid "invalid section name '%s'"
-msgstr ""
-
-#: config.c:2882
-#, c-format
-msgid "%s has multiple values"
-msgstr ""
-
-#: config.c:2911
-#, c-format
-msgid "failed to write new configuration file %s"
-msgstr ""
-
-#: config.c:3177 config.c:3518
-#, c-format
-msgid "could not lock config file %s"
-msgstr ""
-
-#: config.c:3188
-#, c-format
-msgid "opening %s"
-msgstr ""
-
-#: config.c:3225 builtin/config.c:361
-#, c-format
-msgid "invalid pattern: %s"
-msgstr ""
-
-#: config.c:3250
-#, c-format
-msgid "invalid config file %s"
-msgstr ""
-
-#: config.c:3263 config.c:3531
-#, c-format
-msgid "fstat on %s failed"
-msgstr ""
-
-#: config.c:3274
-#, c-format
-msgid "unable to mmap '%s'%s"
-msgstr ""
-
-#: config.c:3284 config.c:3536
-#, c-format
-msgid "chmod on %s failed"
-msgstr ""
-
-#: config.c:3369 config.c:3633
-#, c-format
-msgid "could not write config file %s"
-msgstr ""
-
-#: config.c:3403
-#, c-format
-msgid "could not set '%s' to '%s'"
-msgstr ""
-
-#: config.c:3405 builtin/remote.c:666 builtin/remote.c:885 builtin/remote.c:893
-#, c-format
-msgid "could not unset '%s'"
-msgstr ""
-
-#: config.c:3509
-#, c-format
-msgid "invalid section name: %s"
-msgstr ""
-
-#: config.c:3676
-#, c-format
-msgid "missing value for '%s'"
-msgstr ""
-
-#: connect.c:61
-msgid "the remote end hung up upon initial contact"
-msgstr ""
-
-#: connect.c:63
-msgid ""
-"Could not read from remote repository.\n"
-"\n"
-"Please make sure you have the correct access rights\n"
-"and the repository exists."
-msgstr ""
-
-#: connect.c:81
-#, c-format
-msgid "server doesn't support '%s'"
-msgstr ""
-
-#: connect.c:118
-#, c-format
-msgid "server doesn't support feature '%s'"
-msgstr ""
-
-#: connect.c:129
-msgid "expected flush after capabilities"
-msgstr ""
-
-#: connect.c:265
-#, c-format
-msgid "ignoring capabilities after first line '%s'"
-msgstr ""
-
-#: connect.c:286
-msgid "protocol error: unexpected capabilities^{}"
-msgstr ""
-
-#: connect.c:308
-#, c-format
-msgid "protocol error: expected shallow sha-1, got '%s'"
-msgstr ""
-
-#: connect.c:310
-msgid "repository on the other end cannot be shallow"
-msgstr ""
-
-#: connect.c:349
-msgid "invalid packet"
-msgstr ""
-
-#: connect.c:369
-#, c-format
-msgid "protocol error: unexpected '%s'"
-msgstr ""
-
-#: connect.c:499
-#, c-format
-msgid "unknown object format '%s' specified by server"
-msgstr ""
-
-#: connect.c:528
-#, c-format
-msgid "invalid ls-refs response: %s"
-msgstr ""
-
-#: connect.c:532
-msgid "expected flush after ref listing"
-msgstr ""
-
-#: connect.c:535
-msgid "expected response end packet after ref listing"
-msgstr ""
-
-#: connect.c:670
-#, c-format
-msgid "protocol '%s' is not supported"
-msgstr ""
-
-#: connect.c:721
-msgid "unable to set SO_KEEPALIVE on socket"
-msgstr ""
-
-#: connect.c:761 connect.c:824
-#, c-format
-msgid "Looking up %s ... "
-msgstr ""
-
-#: connect.c:765
-#, c-format
-msgid "unable to look up %s (port %s) (%s)"
-msgstr ""
-
-#. TRANSLATORS: this is the end of "Looking up %s ... "
-#: connect.c:769 connect.c:840
-#, c-format
-msgid ""
-"done.\n"
-"Connecting to %s (port %s) ... "
-msgstr ""
-
-#: connect.c:791 connect.c:868
-#, c-format
-msgid ""
-"unable to connect to %s:\n"
-"%s"
-msgstr ""
-
-#. TRANSLATORS: this is the end of "Connecting to %s (port %s) ... "
-#: connect.c:797 connect.c:874
-msgid "done."
-msgstr ""
-
-#: connect.c:828
-#, c-format
-msgid "unable to look up %s (%s)"
-msgstr ""
-
-#: connect.c:834
-#, c-format
-msgid "unknown port %s"
-msgstr ""
-
-#: connect.c:971 connect.c:1303
-#, c-format
-msgid "strange hostname '%s' blocked"
-msgstr ""
-
-#: connect.c:973
-#, c-format
-msgid "strange port '%s' blocked"
-msgstr ""
-
-#: connect.c:983
-#, c-format
-msgid "cannot start proxy %s"
-msgstr ""
-
-#: connect.c:1054
-msgid "no path specified; see 'git help pull' for valid url syntax"
-msgstr ""
-
-#: connect.c:1194
-msgid "newline is forbidden in git:// hosts and repo paths"
-msgstr ""
-
-#: connect.c:1251
-msgid "ssh variant 'simple' does not support -4"
-msgstr ""
-
-#: connect.c:1263
-msgid "ssh variant 'simple' does not support -6"
-msgstr ""
-
-#: connect.c:1280
-msgid "ssh variant 'simple' does not support setting port"
-msgstr ""
-
-#: connect.c:1392
-#, c-format
-msgid "strange pathname '%s' blocked"
-msgstr ""
-
-#: connect.c:1440
-msgid "unable to fork"
-msgstr ""
-
-#: connected.c:109 builtin/fsck.c:189 builtin/prune.c:57
-msgid "Checking connectivity"
-msgstr ""
-
-#: connected.c:122
-msgid "Could not run 'git rev-list'"
-msgstr ""
-
-#: connected.c:146
-msgid "failed write to rev-list"
-msgstr ""
-
-#: connected.c:151
-msgid "failed to close rev-list's stdin"
-msgstr ""
-
-#: convert.c:183
-#, c-format
-msgid "illegal crlf_action %d"
-msgstr ""
-
-#: convert.c:196
-#, c-format
-msgid "CRLF would be replaced by LF in %s"
-msgstr ""
-
-#: convert.c:198
-#, 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 ""
-
-#: convert.c:206
-#, c-format
-msgid "LF would be replaced by CRLF in %s"
-msgstr ""
-
-#: convert.c:208
-#, 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 ""
-
-#: convert.c:273
-#, c-format
-msgid "BOM is prohibited in '%s' if encoded as %s"
-msgstr ""
-
-#: convert.c:280
-#, c-format
-msgid ""
-"The file '%s' contains a byte order mark (BOM). Please use UTF-%.*s as "
-"working-tree-encoding."
-msgstr ""
-
-#: convert.c:293
-#, c-format
-msgid "BOM is required in '%s' if encoded as %s"
-msgstr ""
-
-#: convert.c:295
-#, c-format
-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 ""
-
-#: convert.c:408 convert.c:479
-#, c-format
-msgid "failed to encode '%s' from %s to %s"
-msgstr ""
-
-#: convert.c:451
-#, c-format
-msgid "encoding '%s' from %s to %s and back is not the same"
-msgstr ""
-
-#: convert.c:654
-#, c-format
-msgid "cannot fork to run external filter '%s'"
-msgstr ""
-
-#: convert.c:674
-#, c-format
-msgid "cannot feed the input to external filter '%s'"
-msgstr ""
-
-#: convert.c:681
-#, c-format
-msgid "external filter '%s' failed %d"
-msgstr ""
-
-#: convert.c:716 convert.c:719
-#, c-format
-msgid "read from external filter '%s' failed"
-msgstr ""
-
-#: convert.c:722 convert.c:777
-#, c-format
-msgid "external filter '%s' failed"
-msgstr ""
-
-#: convert.c:826
-msgid "unexpected filter type"
-msgstr ""
-
-#: convert.c:837
-msgid "path name too long for external filter"
-msgstr ""
-
-#: convert.c:935
-#, c-format
-msgid ""
-"external filter '%s' is not available anymore although not all paths have "
-"been filtered"
-msgstr ""
-
-#: convert.c:1236
-msgid "true/false are no valid working-tree-encodings"
-msgstr ""
-
-#: convert.c:1416 convert.c:1449
-#, c-format
-msgid "%s: clean filter '%s' failed"
-msgstr ""
-
-#: convert.c:1492
-#, c-format
-msgid "%s: smudge filter %s failed"
-msgstr ""
-
-#: credential.c:96
-#, c-format
-msgid "skipping credential lookup for key: credential.%s"
-msgstr ""
-
-#: credential.c:112
-msgid "refusing to work with credential missing host field"
-msgstr ""
-
-#: credential.c:114
-msgid "refusing to work with credential missing protocol field"
-msgstr ""
-
-#: credential.c:396
-#, c-format
-msgid "url contains a newline in its %s component: %s"
-msgstr ""
-
-#: credential.c:440
-#, c-format
-msgid "url has no scheme: %s"
-msgstr ""
-
-#: credential.c:513
-#, c-format
-msgid "credential url cannot be parsed: %s"
-msgstr ""
-
-#: date.c:139
-msgid "in the future"
-msgstr ""
-
-#: date.c:145
-#, c-format
-msgid "%<PRIuMAX> second ago"
-msgid_plural "%<PRIuMAX> seconds ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:152
-#, c-format
-msgid "%<PRIuMAX> minute ago"
-msgid_plural "%<PRIuMAX> minutes ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:159
-#, c-format
-msgid "%<PRIuMAX> hour ago"
-msgid_plural "%<PRIuMAX> hours ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:166
-#, c-format
-msgid "%<PRIuMAX> day ago"
-msgid_plural "%<PRIuMAX> days ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:172
-#, c-format
-msgid "%<PRIuMAX> week ago"
-msgid_plural "%<PRIuMAX> weeks ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:179
-#, c-format
-msgid "%<PRIuMAX> month ago"
-msgid_plural "%<PRIuMAX> months ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:190
-#, c-format
-msgid "%<PRIuMAX> year"
-msgid_plural "%<PRIuMAX> years"
-msgstr[0] ""
-msgstr[1] ""
-
-#. TRANSLATORS: "%s" is "<n> years"
-#: date.c:193
-#, c-format
-msgid "%s, %<PRIuMAX> month ago"
-msgid_plural "%s, %<PRIuMAX> months ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: date.c:198 date.c:203
-#, c-format
-msgid "%<PRIuMAX> year ago"
-msgid_plural "%<PRIuMAX> years ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: delta-islands.c:272
-msgid "Propagating island marks"
-msgstr ""
-
-#: delta-islands.c:290
-#, c-format
-msgid "bad tree object %s"
-msgstr ""
-
-#: delta-islands.c:334
-#, c-format
-msgid "failed to load island regex for '%s': %s"
-msgstr ""
-
-#: delta-islands.c:390
-#, c-format
-msgid "island regex from config has too many capture groups (max=%d)"
-msgstr ""
-
-#: delta-islands.c:467
-#, c-format
-msgid "Marked %d islands, done.\n"
-msgstr ""
-
-#: diff-merges.c:81 gpg-interface.c:719 gpg-interface.c:734 ls-refs.c:37
-#: parallel-checkout.c:42 sequencer.c:2805 setup.c:563 builtin/am.c:203
-#: builtin/am.c:2243 builtin/am.c:2287 builtin/blame.c:724 builtin/blame.c:742
-#: builtin/fetch.c:792 builtin/pack-objects.c:3515 builtin/pull.c:45
-#: builtin/pull.c:47 builtin/pull.c:321
-#, c-format
-msgid "invalid value for '%s': '%s'"
-msgstr ""
-
-#: diff-lib.c:561
-msgid "--merge-base does not work with ranges"
-msgstr ""
-
-#: diff-lib.c:563
-msgid "--merge-base only works with commits"
-msgstr ""
-
-#: diff-lib.c:580
-msgid "unable to get HEAD"
-msgstr ""
-
-#: diff-lib.c:587
-msgid "no merge base found"
-msgstr ""
-
-#: diff-lib.c:589
-msgid "multiple merge bases found"
-msgstr ""
-
-#: diff-no-index.c:237
-msgid "git diff --no-index [<options>] <path> <path>"
-msgstr ""
-
-#: diff-no-index.c:262
-msgid ""
-"Not a git repository. Use --no-index to compare two paths outside a working "
-"tree"
-msgstr ""
-
-#: diff.c:159
-#, c-format
-msgid "  Failed to parse dirstat cut-off percentage '%s'\n"
-msgstr ""
-
-#: diff.c:164
-#, c-format
-msgid "  Unknown dirstat parameter '%s'\n"
-msgstr ""
-
-#: diff.c:300
-msgid ""
-"color moved setting must be one of 'no', 'default', 'blocks', 'zebra', "
-"'dimmed-zebra', 'plain'"
-msgstr ""
-
-#: diff.c:328
-#, c-format
-msgid ""
-"unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', "
-"'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'"
-msgstr ""
-
-#: diff.c:336
-msgid ""
-"color-moved-ws: allow-indentation-change cannot be combined with other "
-"whitespace modes"
-msgstr ""
-
-#: diff.c:413
-#, c-format
-msgid "Unknown value for 'diff.submodule' config variable: '%s'"
-msgstr ""
-
-#: diff.c:473
-#, c-format
-msgid ""
-"Found errors in 'diff.dirstat' config variable:\n"
-"%s"
-msgstr ""
-
-#: diff.c:4282
-#, c-format
-msgid "external diff died, stopping at %s"
-msgstr ""
-
-#: diff.c:4677 parse-options.c:1114
-#, c-format
-msgid "options '%s', '%s', '%s', and '%s' cannot be used together"
-msgstr ""
-
-#: diff.c:4681 parse-options.c:1118 builtin/worktree.c:578
-#, c-format
-msgid "options '%s', '%s', and '%s' cannot be used together"
-msgstr ""
-
-#: diff.c:4685
-#, c-format
-msgid "options '%s' and '%s' cannot be used together, use '%s' with '%s'"
-msgstr ""
-
-#: diff.c:4689
-#, c-format
-msgid ""
-"options '%s' and '%s' cannot be used together, use '%s' with '%s' and '%s'"
-msgstr ""
-
-#: diff.c:4769
-msgid "--follow requires exactly one pathspec"
-msgstr ""
-
-#: diff.c:4823
-#, c-format
-msgid "invalid --stat value: %s"
-msgstr ""
-
-#: diff.c:4828 diff.c:4833 diff.c:4838 diff.c:4843 diff.c:5319
-#: parse-options.c:217 parse-options.c:221
-#, c-format
-msgid "%s expects a numerical value"
-msgstr ""
-
-#: diff.c:4860
-#, c-format
-msgid ""
-"Failed to parse --dirstat/-X option parameter:\n"
-"%s"
-msgstr ""
-
-#: diff.c:4893
-#, c-format
-msgid "unknown change class '%c' in --diff-filter=%s"
-msgstr ""
-
-#: diff.c:4917
-#, c-format
-msgid "unknown value after ws-error-highlight=%.*s"
-msgstr ""
-
-#: diff.c:4931
-#, c-format
-msgid "unable to resolve '%s'"
-msgstr ""
-
-#: diff.c:4981 diff.c:4987
-#, c-format
-msgid "%s expects <n>/<m> form"
-msgstr ""
-
-#: diff.c:4999
-#, c-format
-msgid "%s expects a character, got '%s'"
-msgstr ""
-
-#: diff.c:5020
-#, c-format
-msgid "bad --color-moved argument: %s"
-msgstr ""
-
-#: diff.c:5039
-#, c-format
-msgid "invalid mode '%s' in --color-moved-ws"
-msgstr ""
-
-#: diff.c:5079
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-
-#: diff.c:5115 diff.c:5135
-#, c-format
-msgid "invalid argument to %s"
-msgstr ""
-
-#: diff.c:5239
-#, c-format
-msgid "invalid regex given to -I: '%s'"
-msgstr ""
-
-#: diff.c:5288
-#, c-format
-msgid "failed to parse --submodule option parameter: '%s'"
-msgstr ""
-
-#: diff.c:5344
-#, c-format
-msgid "bad --word-diff argument: %s"
-msgstr ""
-
-#: diff.c:5380
-msgid "Diff output format options"
-msgstr ""
-
-#: diff.c:5382 diff.c:5388
-msgid "generate patch"
-msgstr ""
-
-#: diff.c:5385 builtin/log.c:180
-msgid "suppress diff output"
-msgstr ""
-
-#: diff.c:5390 diff.c:5504 diff.c:5511
-msgid "<n>"
-msgstr ""
-
-#: diff.c:5391 diff.c:5394
-msgid "generate diffs with <n> lines context"
-msgstr ""
-
-#: diff.c:5396
-msgid "generate the diff in raw format"
-msgstr ""
-
-#: diff.c:5399
-msgid "synonym for '-p --raw'"
-msgstr ""
-
-#: diff.c:5403
-msgid "synonym for '-p --stat'"
-msgstr ""
-
-#: diff.c:5407
-msgid "machine friendly --stat"
-msgstr ""
-
-#: diff.c:5410
-msgid "output only the last line of --stat"
-msgstr ""
-
-#: diff.c:5412 diff.c:5420
-msgid "<param1,param2>..."
-msgstr ""
-
-#: diff.c:5413
-msgid ""
-"output the distribution of relative amount of changes for each sub-directory"
-msgstr ""
-
-#: diff.c:5417
-msgid "synonym for --dirstat=cumulative"
-msgstr ""
-
-#: diff.c:5421
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr ""
-
-#: diff.c:5425
-msgid "warn if changes introduce conflict markers or whitespace errors"
-msgstr ""
-
-#: diff.c:5428
-msgid "condensed summary such as creations, renames and mode changes"
-msgstr ""
-
-#: diff.c:5431
-msgid "show only names of changed files"
-msgstr ""
-
-#: diff.c:5434
-msgid "show only names and status of changed files"
-msgstr ""
-
-#: diff.c:5436
-msgid "<width>[,<name-width>[,<count>]]"
-msgstr ""
-
-#: diff.c:5437
-msgid "generate diffstat"
-msgstr ""
-
-#: diff.c:5439 diff.c:5442 diff.c:5445
-msgid "<width>"
-msgstr ""
-
-#: diff.c:5440
-msgid "generate diffstat with a given width"
-msgstr ""
-
-#: diff.c:5443
-msgid "generate diffstat with a given name width"
-msgstr ""
-
-#: diff.c:5446
-msgid "generate diffstat with a given graph width"
-msgstr ""
-
-#: diff.c:5448
-msgid "<count>"
-msgstr ""
-
-#: diff.c:5449
-msgid "generate diffstat with limited lines"
-msgstr ""
-
-#: diff.c:5452
-msgid "generate compact summary in diffstat"
-msgstr ""
-
-#: diff.c:5455
-msgid "output a binary diff that can be applied"
-msgstr ""
-
-#: diff.c:5458
-msgid "show full pre- and post-image object names on the \"index\" lines"
-msgstr ""
-
-#: diff.c:5460
-msgid "show colored diff"
-msgstr ""
-
-#: diff.c:5461
-msgid "<kind>"
-msgstr ""
-
-#: diff.c:5462
-msgid ""
-"highlight whitespace errors in the 'context', 'old' or 'new' lines in the "
-"diff"
-msgstr ""
-
-#: diff.c:5465
-msgid ""
-"do not munge pathnames and use NULs as output field terminators in --raw or "
-"--numstat"
-msgstr ""
-
-#: diff.c:5468 diff.c:5471 diff.c:5474 diff.c:5583
-msgid "<prefix>"
-msgstr ""
-
-#: diff.c:5469
-msgid "show the given source prefix instead of \"a/\""
-msgstr ""
-
-#: diff.c:5472
-msgid "show the given destination prefix instead of \"b/\""
-msgstr ""
-
-#: diff.c:5475
-msgid "prepend an additional prefix to every line of output"
-msgstr ""
-
-#: diff.c:5478
-msgid "do not show any source or destination prefix"
-msgstr ""
-
-#: diff.c:5481
-msgid "show context between diff hunks up to the specified number of lines"
-msgstr ""
-
-#: diff.c:5485 diff.c:5490 diff.c:5495
-msgid "<char>"
-msgstr ""
-
-#: diff.c:5486
-msgid "specify the character to indicate a new line instead of '+'"
-msgstr ""
-
-#: diff.c:5491
-msgid "specify the character to indicate an old line instead of '-'"
-msgstr ""
-
-#: diff.c:5496
-msgid "specify the character to indicate a context instead of ' '"
-msgstr ""
-
-#: diff.c:5499
-msgid "Diff rename options"
-msgstr ""
-
-#: diff.c:5500
-msgid "<n>[/<m>]"
-msgstr ""
-
-#: diff.c:5501
-msgid "break complete rewrite changes into pairs of delete and create"
-msgstr ""
-
-#: diff.c:5505
-msgid "detect renames"
-msgstr ""
-
-#: diff.c:5509
-msgid "omit the preimage for deletes"
-msgstr ""
-
-#: diff.c:5512
-msgid "detect copies"
-msgstr ""
-
-#: diff.c:5516
-msgid "use unmodified files as source to find copies"
-msgstr ""
-
-#: diff.c:5518
-msgid "disable rename detection"
-msgstr ""
-
-#: diff.c:5521
-msgid "use empty blobs as rename source"
-msgstr ""
-
-#: diff.c:5523
-msgid "continue listing the history of a file beyond renames"
-msgstr ""
-
-#: diff.c:5526
-msgid ""
-"prevent rename/copy detection if the number of rename/copy targets exceeds "
-"given limit"
-msgstr ""
-
-#: diff.c:5528
-msgid "Diff algorithm options"
-msgstr ""
-
-#: diff.c:5530
-msgid "produce the smallest possible diff"
-msgstr ""
-
-#: diff.c:5533
-msgid "ignore whitespace when comparing lines"
-msgstr ""
-
-#: diff.c:5536
-msgid "ignore changes in amount of whitespace"
-msgstr ""
-
-#: diff.c:5539
-msgid "ignore changes in whitespace at EOL"
-msgstr ""
-
-#: diff.c:5542
-msgid "ignore carrier-return at the end of line"
-msgstr ""
-
-#: diff.c:5545
-msgid "ignore changes whose lines are all blank"
-msgstr ""
-
-#: diff.c:5547 diff.c:5569 diff.c:5572 diff.c:5617
-msgid "<regex>"
-msgstr ""
-
-#: diff.c:5548
-msgid "ignore changes whose all lines match <regex>"
-msgstr ""
-
-#: diff.c:5551
-msgid "heuristic to shift diff hunk boundaries for easy reading"
-msgstr ""
-
-#: diff.c:5554
-msgid "generate diff using the \"patience diff\" algorithm"
-msgstr ""
-
-#: diff.c:5558
-msgid "generate diff using the \"histogram diff\" algorithm"
-msgstr ""
-
-#: diff.c:5560
-msgid "<algorithm>"
-msgstr ""
-
-#: diff.c:5561
-msgid "choose a diff algorithm"
-msgstr ""
-
-#: diff.c:5563
-msgid "<text>"
-msgstr ""
-
-#: diff.c:5564
-msgid "generate diff using the \"anchored diff\" algorithm"
-msgstr ""
-
-#: diff.c:5566 diff.c:5575 diff.c:5578
-msgid "<mode>"
-msgstr ""
-
-#: diff.c:5567
-msgid "show word diff, using <mode> to delimit changed words"
-msgstr ""
-
-#: diff.c:5570
-msgid "use <regex> to decide what a word is"
-msgstr ""
-
-#: diff.c:5573
-msgid "equivalent to --word-diff=color --word-diff-regex=<regex>"
-msgstr ""
-
-#: diff.c:5576
-msgid "moved lines of code are colored differently"
-msgstr ""
-
-#: diff.c:5579
-msgid "how white spaces are ignored in --color-moved"
-msgstr ""
-
-#: diff.c:5582
-msgid "Other diff options"
-msgstr ""
-
-#: diff.c:5584
-msgid "when run from subdir, exclude changes outside and show relative paths"
-msgstr ""
-
-#: diff.c:5588
-msgid "treat all files as text"
-msgstr ""
-
-#: diff.c:5590
-msgid "swap two inputs, reverse the diff"
-msgstr ""
-
-#: diff.c:5592
-msgid "exit with 1 if there were differences, 0 otherwise"
-msgstr ""
-
-#: diff.c:5594
-msgid "disable all output of the program"
-msgstr ""
-
-#: diff.c:5596
-msgid "allow an external diff helper to be executed"
-msgstr ""
-
-#: diff.c:5598
-msgid "run external text conversion filters when comparing binary files"
-msgstr ""
-
-#: diff.c:5600
-msgid "<when>"
-msgstr ""
-
-#: diff.c:5601
-msgid "ignore changes to submodules in the diff generation"
-msgstr ""
-
-#: diff.c:5604
-msgid "<format>"
-msgstr ""
-
-#: diff.c:5605
-msgid "specify how differences in submodules are shown"
-msgstr ""
-
-#: diff.c:5609
-msgid "hide 'git add -N' entries from the index"
-msgstr ""
-
-#: diff.c:5612
-msgid "treat 'git add -N' entries as real in the index"
-msgstr ""
-
-#: diff.c:5614
-msgid "<string>"
-msgstr ""
-
-#: diff.c:5615
-msgid ""
-"look for differences that change the number of occurrences of the specified "
-"string"
-msgstr ""
-
-#: diff.c:5618
-msgid ""
-"look for differences that change the number of occurrences of the specified "
-"regex"
-msgstr ""
-
-#: diff.c:5621
-msgid "show all changes in the changeset with -S or -G"
-msgstr ""
-
-#: diff.c:5624
-msgid "treat <string> in -S as extended POSIX regular expression"
-msgstr ""
-
-#: diff.c:5627
-msgid "control the order in which files appear in the output"
-msgstr ""
-
-#: diff.c:5628 diff.c:5631
-msgid "<path>"
-msgstr ""
-
-#: diff.c:5629
-msgid "show the change in the specified path first"
-msgstr ""
-
-#: diff.c:5632
-msgid "skip the output to the specified path"
-msgstr ""
-
-#: diff.c:5634
-msgid "<object-id>"
-msgstr ""
-
-#: diff.c:5635
-msgid ""
-"look for differences that change the number of occurrences of the specified "
-"object"
-msgstr ""
-
-#: diff.c:5637
-msgid "[(A|C|D|M|R|T|U|X|B)...[*]]"
-msgstr ""
-
-#: diff.c:5638
-msgid "select files by diff type"
-msgstr ""
-
-#: diff.c:5640
-msgid "<file>"
-msgstr ""
-
-#: diff.c:5641
-msgid "output to a specific file"
-msgstr ""
-
-#: diff.c:6321
-msgid "exhaustive rename detection was skipped due to too many files."
-msgstr ""
-
-#: diff.c:6324
-msgid "only found copies from modified paths due to too many files."
-msgstr ""
-
-#: diff.c:6327
-#, c-format
-msgid ""
-"you may want to set your %s variable to at least %d and retry the command."
-msgstr ""
-
-#: diffcore-order.c:24
-#, c-format
-msgid "failed to read orderfile '%s'"
-msgstr ""
-
-#: diffcore-rename.c:1564
-msgid "Performing inexact rename detection"
-msgstr ""
-
-#: diffcore-rotate.c:29
-#, c-format
-msgid "No such path '%s' in the diff"
-msgstr ""
-
-#: dir.c:593
-#, c-format
-msgid "pathspec '%s' did not match any file(s) known to git"
-msgstr ""
-
-#: dir.c:733 dir.c:762 dir.c:775
-#, c-format
-msgid "unrecognized pattern: '%s'"
-msgstr ""
-
-#: dir.c:790 dir.c:804
-#, c-format
-msgid "unrecognized negative pattern: '%s'"
-msgstr ""
-
-#: dir.c:820
-#, c-format
-msgid "your sparse-checkout file may have issues: pattern '%s' is repeated"
-msgstr ""
-
-#: dir.c:828
-msgid "disabling cone pattern matching"
-msgstr ""
-
-#: dir.c:1212
-#, c-format
-msgid "cannot use %s as an exclude file"
-msgstr ""
-
-#: dir.c:2419
-#, c-format
-msgid "could not open directory '%s'"
-msgstr ""
-
-#: dir.c:2721
-msgid "failed to get kernel name and information"
-msgstr ""
-
-#: dir.c:2846
-msgid "untracked cache is disabled on this system or location"
-msgstr ""
-
-#: dir.c:3119
-msgid ""
-"No directory name could be guessed.\n"
-"Please specify a directory on the command line"
-msgstr ""
-
-#: dir.c:3807
-#, c-format
-msgid "index file corrupt in repo %s"
-msgstr ""
-
-#: dir.c:3854 dir.c:3859
-#, c-format
-msgid "could not create directories for %s"
-msgstr ""
-
-#: dir.c:3888
-#, c-format
-msgid "could not migrate git directory from '%s' to '%s'"
-msgstr ""
-
-#: editor.c:74
-#, c-format
-msgid "hint: Waiting for your editor to close the file...%c"
-msgstr ""
-
-#: entry.c:179
-msgid "Filtering content"
-msgstr ""
-
-#: entry.c:500
-#, c-format
-msgid "could not stat file '%s'"
-msgstr ""
-
-#: environment.c:147
-#, c-format
-msgid "bad git namespace path \"%s\""
-msgstr ""
-
-#: exec-cmd.c:363
-#, c-format
-msgid "too many args to run %s"
-msgstr ""
-
-#: fetch-pack.c:194
-msgid "git fetch-pack: expected shallow list"
-msgstr ""
-
-#: fetch-pack.c:197
-msgid "git fetch-pack: expected a flush packet after shallow list"
-msgstr ""
-
-#: fetch-pack.c:208
-msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
-msgstr ""
-
-#: fetch-pack.c:228
-#, c-format
-msgid "git fetch-pack: expected ACK/NAK, got '%s'"
-msgstr ""
-
-#: fetch-pack.c:239
-msgid "unable to write to remote"
-msgstr ""
-
-#: fetch-pack.c:397 fetch-pack.c:1460
-#, c-format
-msgid "invalid shallow line: %s"
-msgstr ""
-
-#: fetch-pack.c:403 fetch-pack.c:1466
-#, c-format
-msgid "invalid unshallow line: %s"
-msgstr ""
-
-#: fetch-pack.c:405 fetch-pack.c:1468
-#, c-format
-msgid "object not found: %s"
-msgstr ""
-
-#: fetch-pack.c:408 fetch-pack.c:1471
-#, c-format
-msgid "error in object: %s"
-msgstr ""
-
-#: fetch-pack.c:410 fetch-pack.c:1473
-#, c-format
-msgid "no shallow found: %s"
-msgstr ""
-
-#: fetch-pack.c:413 fetch-pack.c:1477
-#, c-format
-msgid "expected shallow/unshallow, got %s"
-msgstr ""
-
-#: fetch-pack.c:453
-#, c-format
-msgid "got %s %d %s"
-msgstr ""
-
-#: fetch-pack.c:470
-#, c-format
-msgid "invalid commit %s"
-msgstr ""
-
-#: fetch-pack.c:501
-msgid "giving up"
-msgstr ""
-
-#: fetch-pack.c:514 progress.h:25
-msgid "done"
-msgstr ""
-
-#: fetch-pack.c:526
-#, c-format
-msgid "got %s (%d) %s"
-msgstr ""
-
-#: fetch-pack.c:562
-#, c-format
-msgid "Marking %s as complete"
-msgstr ""
-
-#: fetch-pack.c:784
-#, c-format
-msgid "already have %s (%s)"
-msgstr ""
-
-#: fetch-pack.c:870
-msgid "fetch-pack: unable to fork off sideband demultiplexer"
-msgstr ""
-
-#: fetch-pack.c:878
-msgid "protocol error: bad pack header"
-msgstr ""
-
-#: fetch-pack.c:974
-#, c-format
-msgid "fetch-pack: unable to fork off %s"
-msgstr ""
-
-#: fetch-pack.c:980
-msgid "fetch-pack: invalid index-pack output"
-msgstr ""
-
-#: fetch-pack.c:997
-#, c-format
-msgid "%s failed"
-msgstr ""
-
-#: fetch-pack.c:999
-msgid "error in sideband demultiplexer"
-msgstr ""
-
-#: fetch-pack.c:1048
-#, c-format
-msgid "Server version is %.*s"
-msgstr ""
-
-#: fetch-pack.c:1056 fetch-pack.c:1062 fetch-pack.c:1065 fetch-pack.c:1071
-#: fetch-pack.c:1075 fetch-pack.c:1079 fetch-pack.c:1083 fetch-pack.c:1087
-#: fetch-pack.c:1091 fetch-pack.c:1095 fetch-pack.c:1099 fetch-pack.c:1103
-#: fetch-pack.c:1109 fetch-pack.c:1115 fetch-pack.c:1120 fetch-pack.c:1125
-#, c-format
-msgid "Server supports %s"
-msgstr ""
-
-#: fetch-pack.c:1058
-msgid "Server does not support shallow clients"
-msgstr ""
-
-#: fetch-pack.c:1118
-msgid "Server does not support --shallow-since"
-msgstr ""
-
-#: fetch-pack.c:1123
-msgid "Server does not support --shallow-exclude"
-msgstr ""
-
-#: fetch-pack.c:1127
-msgid "Server does not support --deepen"
-msgstr ""
-
-#: fetch-pack.c:1129
-msgid "Server does not support this repository's object format"
-msgstr ""
-
-#: fetch-pack.c:1142
-msgid "no common commits"
-msgstr ""
-
-#: fetch-pack.c:1151 fetch-pack.c:1506 builtin/clone.c:1166
-msgid "source repository is shallow, reject to clone."
-msgstr ""
-
-#: fetch-pack.c:1157 fetch-pack.c:1705
-msgid "git fetch-pack: fetch failed."
-msgstr ""
-
-#: fetch-pack.c:1271
-#, c-format
-msgid "mismatched algorithms: client %s; server %s"
-msgstr ""
-
-#: fetch-pack.c:1275
-#, c-format
-msgid "the server does not support algorithm '%s'"
-msgstr ""
-
-#: fetch-pack.c:1308
-msgid "Server does not support shallow requests"
-msgstr ""
-
-#: fetch-pack.c:1315
-msgid "Server supports filter"
-msgstr ""
-
-#: fetch-pack.c:1358 fetch-pack.c:2087
-msgid "unable to write request to remote"
-msgstr ""
-
-#: fetch-pack.c:1376
-#, c-format
-msgid "error reading section header '%s'"
-msgstr ""
-
-#: fetch-pack.c:1382
-#, c-format
-msgid "expected '%s', received '%s'"
-msgstr ""
-
-#: fetch-pack.c:1416
-#, c-format
-msgid "unexpected acknowledgment line: '%s'"
-msgstr ""
-
-#: fetch-pack.c:1421
-#, c-format
-msgid "error processing acks: %d"
-msgstr ""
-
-#. TRANSLATORS: The parameter will be 'ready', a protocol
-#. keyword.
-#.
-#: fetch-pack.c:1435
-#, c-format
-msgid "expected packfile to be sent after '%s'"
-msgstr ""
-
-#. TRANSLATORS: The parameter will be 'ready', a protocol
-#. keyword.
-#.
-#: fetch-pack.c:1441
-#, c-format
-msgid "expected no other sections to be sent after no '%s'"
-msgstr ""
-
-#: fetch-pack.c:1482
-#, c-format
-msgid "error processing shallow info: %d"
-msgstr ""
-
-#: fetch-pack.c:1531
-#, c-format
-msgid "expected wanted-ref, got '%s'"
-msgstr ""
-
-#: fetch-pack.c:1536
-#, c-format
-msgid "unexpected wanted-ref: '%s'"
-msgstr ""
-
-#: fetch-pack.c:1541
-#, c-format
-msgid "error processing wanted refs: %d"
-msgstr ""
-
-#: fetch-pack.c:1571
-msgid "git fetch-pack: expected response end packet"
-msgstr ""
-
-#: fetch-pack.c:1983
-msgid "no matching remote head"
-msgstr ""
-
-#: fetch-pack.c:2006 builtin/clone.c:587
-msgid "remote did not send all necessary objects"
-msgstr ""
-
-#: fetch-pack.c:2109
-msgid "unexpected 'ready' from remote"
-msgstr ""
-
-#: fetch-pack.c:2132
-#, c-format
-msgid "no such remote ref %s"
-msgstr ""
-
-#: fetch-pack.c:2135
-#, c-format
-msgid "Server does not allow request for unadvertised object %s"
-msgstr ""
-
-#: fsmonitor-ipc.c:119
-#, c-format
-msgid "fsmonitor_ipc__send_query: invalid path '%s'"
-msgstr ""
-
-#: fsmonitor-ipc.c:125
-#, c-format
-msgid "fsmonitor_ipc__send_query: unspecified error on '%s'"
-msgstr ""
-
-#: fsmonitor-ipc.c:155
-msgid "fsmonitor--daemon is not running"
-msgstr ""
-
-#: fsmonitor-ipc.c:164
-#, c-format
-msgid "could not send '%s' command to fsmonitor--daemon"
-msgstr ""
-
-#: gpg-interface.c:329 gpg-interface.c:456 gpg-interface.c:995
-#: gpg-interface.c:1011
-msgid "could not create temporary file"
-msgstr ""
-
-#: gpg-interface.c:332 gpg-interface.c:459
-#, c-format
-msgid "failed writing detached signature to '%s'"
-msgstr ""
-
-#: gpg-interface.c:450
-msgid ""
-"gpg.ssh.allowedSignersFile needs to be configured and exist for ssh "
-"signature verification"
-msgstr ""
-
-#: gpg-interface.c:479
-msgid ""
-"ssh-keygen -Y find-principals/verify is needed for ssh signature "
-"verification (available in openssh version 8.2p1+)"
-msgstr ""
-
-#: gpg-interface.c:550
-#, c-format
-msgid "ssh signing revocation file configured but not found: %s"
-msgstr ""
-
-#: gpg-interface.c:638
-#, c-format
-msgid "bad/incompatible signature '%s'"
-msgstr ""
-
-#: gpg-interface.c:815 gpg-interface.c:820
-#, c-format
-msgid "failed to get the ssh fingerprint for key '%s'"
-msgstr ""
-
-#: gpg-interface.c:843
-msgid ""
-"either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured"
-msgstr ""
-
-#: gpg-interface.c:865
-#, c-format
-msgid "gpg.ssh.defaultKeyCommand succeeded but returned no keys: %s %s"
-msgstr ""
-
-#: gpg-interface.c:871
-#, c-format
-msgid "gpg.ssh.defaultKeyCommand failed: %s %s"
-msgstr ""
-
-#: gpg-interface.c:966
-msgid "gpg failed to sign the data"
-msgstr ""
-
-#: gpg-interface.c:988
-msgid "user.signingkey needs to be set for ssh signing"
-msgstr ""
-
-#: gpg-interface.c:999
-#, c-format
-msgid "failed writing ssh signing key to '%s'"
-msgstr ""
-
-#: gpg-interface.c:1017
-#, c-format
-msgid "failed writing ssh signing key buffer to '%s'"
-msgstr ""
-
-#: gpg-interface.c:1035
-msgid ""
-"ssh-keygen -Y sign is needed for ssh signing (available in openssh version "
-"8.2p1+)"
-msgstr ""
-
-#: gpg-interface.c:1047
-#, c-format
-msgid "failed reading ssh signing data buffer from '%s'"
-msgstr ""
-
-#: graph.c:98
-#, c-format
-msgid "ignored invalid color '%.*s' in log.graphColors"
-msgstr ""
-
-#: grep.c:446
-msgid ""
-"given pattern contains NULL byte (via -f <file>). This is only supported "
-"with -P under PCRE v2"
-msgstr ""
-
-#: grep.c:1859
-#, c-format
-msgid "'%s': unable to read %s"
-msgstr ""
-
-#: grep.c:1876 setup.c:178 builtin/clone.c:308 builtin/diff.c:90
-#: builtin/rm.c:136
-#, c-format
-msgid "failed to stat '%s'"
-msgstr ""
-
-#: grep.c:1887
-#, c-format
-msgid "'%s': short read"
-msgstr ""
-
-#: help.c:25
-msgid "start a working area (see also: git help tutorial)"
-msgstr ""
-
-#: help.c:26
-msgid "work on the current change (see also: git help everyday)"
-msgstr ""
-
-#: help.c:27
-msgid "examine the history and state (see also: git help revisions)"
-msgstr ""
-
-#: help.c:28
-msgid "grow, mark and tweak your common history"
-msgstr ""
-
-#: help.c:29
-msgid "collaborate (see also: git help workflows)"
-msgstr ""
-
-#: help.c:33
-msgid "Main Porcelain Commands"
-msgstr ""
-
-#: help.c:34
-msgid "Ancillary Commands / Manipulators"
-msgstr ""
-
-#: help.c:35
-msgid "Ancillary Commands / Interrogators"
-msgstr ""
-
-#: help.c:36
-msgid "Interacting with Others"
-msgstr ""
-
-#: help.c:37
-msgid "Low-level Commands / Manipulators"
-msgstr ""
-
-#: help.c:38
-msgid "Low-level Commands / Interrogators"
-msgstr ""
-
-#: help.c:39
-msgid "Low-level Commands / Syncing Repositories"
-msgstr ""
-
-#: help.c:40
-msgid "Low-level Commands / Internal Helpers"
-msgstr ""
-
-#: help.c:316
-#, c-format
-msgid "available git commands in '%s'"
-msgstr ""
-
-#: help.c:323
-msgid "git commands available from elsewhere on your $PATH"
-msgstr ""
-
-#: help.c:332
-msgid "These are common Git commands used in various situations:"
-msgstr ""
-
-#: help.c:382 git.c:100
-#, c-format
-msgid "unsupported command listing type '%s'"
-msgstr ""
-
-#: help.c:422
-msgid "The Git concept guides are:"
-msgstr ""
-
-#: help.c:446
-msgid "External commands"
-msgstr ""
-
-#: help.c:468
-msgid "Command aliases"
-msgstr ""
-
-#: help.c:486
-msgid "See 'git help <command>' to read about a specific subcommand"
-msgstr ""
-
-#: help.c:563
-#, c-format
-msgid ""
-"'%s' appears to be a git command, but we were not\n"
-"able to execute it. Maybe git-%s is broken?"
-msgstr ""
-
-#: help.c:585 help.c:682
-#, c-format
-msgid "git: '%s' is not a git command. See 'git --help'."
-msgstr ""
-
-#: help.c:633
-msgid "Uh oh. Your system reports no Git commands at all."
-msgstr ""
-
-#: help.c:655
-#, c-format
-msgid "WARNING: You called a Git command named '%s', which does not exist."
-msgstr ""
-
-#: help.c:660
-#, c-format
-msgid "Continuing under the assumption that you meant '%s'."
-msgstr ""
-
-#: help.c:666
-#, c-format
-msgid "Run '%s' instead [y/N]? "
-msgstr ""
-
-#: help.c:674
-#, c-format
-msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
-msgstr ""
-
-#: help.c:686
-msgid ""
-"\n"
-"The most similar command is"
-msgid_plural ""
-"\n"
-"The most similar commands are"
-msgstr[0] ""
-msgstr[1] ""
-
-#: help.c:729
-msgid "git version [<options>]"
-msgstr ""
-
-#: help.c:784
-#, c-format
-msgid "%s: %s - %s"
-msgstr ""
-
-#: help.c:788
-msgid ""
-"\n"
-"Did you mean this?"
-msgid_plural ""
-"\n"
-"Did you mean one of these?"
-msgstr[0] ""
-msgstr[1] ""
-
-#: hook.c:28
-#, c-format
-msgid ""
-"The '%s' hook was ignored because it's not set as executable.\n"
-"You can disable this warning with `git config advice.ignoredHook false`."
-msgstr ""
-
-#: hook.c:87
-#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr ""
-
-#: ident.c:354
-msgid "Author identity unknown\n"
-msgstr ""
-
-#: ident.c:357
-msgid "Committer identity unknown\n"
-msgstr ""
-
-#: ident.c:363
-msgid ""
-"\n"
-"*** Please tell me who you are.\n"
-"\n"
-"Run\n"
-"\n"
-"  git config --global user.email \"you@example.com\"\n"
-"  git config --global user.name \"Your Name\"\n"
-"\n"
-"to set your account's default identity.\n"
-"Omit --global to set the identity only in this repository.\n"
-"\n"
-msgstr ""
-
-#: ident.c:398
-msgid "no email was given and auto-detection is disabled"
-msgstr ""
-
-#: ident.c:403
-#, c-format
-msgid "unable to auto-detect email address (got '%s')"
-msgstr ""
-
-#: ident.c:420
-msgid "no name was given and auto-detection is disabled"
-msgstr ""
-
-#: ident.c:426
-#, c-format
-msgid "unable to auto-detect name (got '%s')"
-msgstr ""
-
-#: ident.c:434
-#, c-format
-msgid "empty ident name (for <%s>) not allowed"
-msgstr ""
-
-#: ident.c:440
-#, c-format
-msgid "name consists only of disallowed characters: %s"
-msgstr ""
-
-#: ident.c:455 builtin/commit.c:649
-#, c-format
-msgid "invalid date format: %s"
-msgstr ""
-
-#: list-objects-filter-options.c:68
-msgid "expected 'tree:<depth>'"
-msgstr ""
-
-#: list-objects-filter-options.c:83
-msgid "sparse:path filters support has been dropped"
-msgstr ""
-
-#: list-objects-filter-options.c:90
-#, c-format
-msgid "'%s' for 'object:type=<type>' is not a valid object type"
-msgstr ""
-
-#: list-objects-filter-options.c:109
-#, c-format
-msgid "invalid filter-spec '%s'"
-msgstr ""
-
-#: list-objects-filter-options.c:125
-#, c-format
-msgid "must escape char in sub-filter-spec: '%c'"
-msgstr ""
-
-#: list-objects-filter-options.c:167
-msgid "expected something after combine:"
-msgstr ""
-
-#: list-objects-filter-options.c:249
-msgid "multiple filter-specs cannot be combined"
-msgstr ""
-
-#: list-objects-filter-options.c:365
-msgid "unable to upgrade repository format to support partial clone"
-msgstr ""
-
-#: list-objects-filter.c:532
-#, c-format
-msgid "unable to access sparse blob in '%s'"
-msgstr ""
-
-#: list-objects-filter.c:535
-#, c-format
-msgid "unable to parse sparse filter data in %s"
-msgstr ""
-
-#: list-objects.c:144
-#, c-format
-msgid "entry '%s' in tree %s has tree mode, but is not a tree"
-msgstr ""
-
-#: list-objects.c:157
-#, c-format
-msgid "entry '%s' in tree %s has blob mode, but is not a blob"
-msgstr ""
-
-#: list-objects.c:415
-#, c-format
-msgid "unable to load root tree for commit %s"
-msgstr ""
-
-#: lockfile.c:152
-#, c-format
-msgid ""
-"Unable to create '%s.lock': %s.\n"
-"\n"
-"Another git process seems to be running in this repository, e.g.\n"
-"an editor opened by 'git commit'. Please make sure all processes\n"
-"are terminated then try again. If it still fails, a git process\n"
-"may have crashed in this repository earlier:\n"
-"remove the file manually to continue."
-msgstr ""
-
-#: lockfile.c:160
-#, c-format
-msgid "Unable to create '%s.lock': %s"
-msgstr ""
-
-#: ls-refs.c:175
-#, c-format
-msgid "unexpected line: '%s'"
-msgstr ""
-
-#: ls-refs.c:179
-msgid "expected flush after ls-refs arguments"
-msgstr ""
-
-#: mailinfo.c:1050
-msgid "quoted CRLF detected"
-msgstr ""
-
-#: mailinfo.c:1254 builtin/am.c:185 builtin/mailinfo.c:46
-#, c-format
-msgid "bad action '%s' for '%s'"
-msgstr ""
-
-#: merge-ort.c:1630 merge-recursive.c:1214
-#, c-format
-msgid "Failed to merge submodule %s (not checked out)"
-msgstr ""
-
-#: merge-ort.c:1639 merge-recursive.c:1221
-#, c-format
-msgid "Failed to merge submodule %s (commits not present)"
-msgstr ""
-
-#: merge-ort.c:1648 merge-recursive.c:1228
-#, c-format
-msgid "Failed to merge submodule %s (commits don't follow merge-base)"
-msgstr ""
-
-#: merge-ort.c:1658 merge-ort.c:1666
-#, c-format
-msgid "Note: Fast-forwarding submodule %s to %s"
-msgstr ""
-
-#: merge-ort.c:1688
-#, c-format
-msgid "Failed to merge submodule %s"
-msgstr ""
-
-#: merge-ort.c:1695
-#, c-format
-msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-
-#: merge-ort.c:1699 merge-recursive.c:1284
-#, 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 ""
-
-#: merge-ort.c:1712
-#, c-format
-msgid ""
-"Failed to merge submodule %s, but multiple possible merges exist:\n"
-"%s"
-msgstr ""
-
-#: merge-ort.c:1937 merge-recursive.c:1375
-msgid "Failed to execute internal merge"
-msgstr ""
-
-#: merge-ort.c:1942 merge-recursive.c:1380
-#, c-format
-msgid "Unable to add %s to database"
-msgstr ""
-
-#: merge-ort.c:1949 merge-recursive.c:1413
-#, c-format
-msgid "Auto-merging %s"
-msgstr ""
-
-#: merge-ort.c:2088 merge-recursive.c:2135
-#, c-format
-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 ""
-
-#: merge-ort.c:2098 merge-recursive.c:2145
-#, c-format
-msgid ""
-"CONFLICT (implicit dir rename): Cannot map more than one path to %s; "
-"implicit directory renames tried to put these paths there: %s"
-msgstr ""
-
-#: merge-ort.c:2156
-#, c-format
-msgid ""
-"CONFLICT (directory rename split): Unclear where to rename %s to; it was "
-"renamed to multiple other directories, with no destination getting a "
-"majority of the files."
-msgstr ""
-
-#: merge-ort.c:2310 merge-recursive.c:2481
-#, c-format
-msgid ""
-"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
-"renamed."
-msgstr ""
-
-#: merge-ort.c:2450 merge-recursive.c:3264
-#, c-format
-msgid ""
-"Path updated: %s added in %s inside a directory that was renamed in %s; "
-"moving it to %s."
-msgstr ""
-
-#: merge-ort.c:2457 merge-recursive.c:3271
-#, c-format
-msgid ""
-"Path updated: %s renamed to %s in %s, inside a directory that was renamed in "
-"%s; moving it to %s."
-msgstr ""
-
-#: merge-ort.c:2470 merge-recursive.c:3267
-#, c-format
-msgid ""
-"CONFLICT (file location): %s added in %s inside a directory that was renamed "
-"in %s, suggesting it should perhaps be moved to %s."
-msgstr ""
-
-#: merge-ort.c:2478 merge-recursive.c:3274
-#, c-format
-msgid ""
-"CONFLICT (file location): %s renamed to %s in %s, inside a directory that "
-"was renamed in %s, suggesting it should perhaps be moved to %s."
-msgstr ""
-
-#: merge-ort.c:2634
-#, c-format
-msgid "CONFLICT (rename/rename): %s renamed to %s in %s and to %s in %s."
-msgstr ""
-
-#: merge-ort.c:2729
-#, c-format
-msgid ""
-"CONFLICT (rename involved in collision): rename of %s -> %s has content "
-"conflicts AND collides with another path; this may result in nested conflict "
-"markers."
-msgstr ""
-
-#: merge-ort.c:2748 merge-ort.c:2772
-#, c-format
-msgid "CONFLICT (rename/delete): %s renamed to %s in %s, but deleted in %s."
-msgstr ""
-
-#: merge-ort.c:3261 merge-recursive.c:3025
-#, c-format
-msgid "cannot read object %s"
-msgstr ""
-
-#: merge-ort.c:3264 merge-recursive.c:3028
-#, c-format
-msgid "object %s is not a blob"
-msgstr ""
-
-#: merge-ort.c:3693
-#, c-format
-msgid ""
-"CONFLICT (file/directory): directory in the way of %s from %s; moving it to "
-"%s instead."
-msgstr ""
-
-#: merge-ort.c:3770
-#, c-format
-msgid ""
-"CONFLICT (distinct types): %s had different types on each side; renamed both "
-"of them so each can be recorded somewhere."
-msgstr ""
-
-#: merge-ort.c:3777
-#, c-format
-msgid ""
-"CONFLICT (distinct types): %s had different types on each side; renamed one "
-"of them so each can be recorded somewhere."
-msgstr ""
-
-#: merge-ort.c:3866 merge-recursive.c:3104
-msgid "content"
-msgstr ""
-
-#: merge-ort.c:3868 merge-recursive.c:3108
-msgid "add/add"
-msgstr ""
-
-#: merge-ort.c:3870 merge-recursive.c:3153
-msgid "submodule"
-msgstr ""
-
-#: merge-ort.c:3872 merge-recursive.c:3154
-#, c-format
-msgid "CONFLICT (%s): Merge conflict in %s"
-msgstr ""
-
-#: merge-ort.c:3916
-#, c-format
-msgid ""
-"CONFLICT (modify/delete): %s deleted in %s and modified in %s.  Version %s "
-"of %s left in tree."
-msgstr ""
-
-#: merge-ort.c:4212
-#, c-format
-msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
-msgstr ""
-
-#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
-#. base, and 2-3) the trees for the two trees we're merging.
-#.
-#: merge-ort.c:4586
-#, c-format
-msgid "collecting merge info failed for trees %s, %s, %s"
-msgstr ""
-
-#: merge-ort-wrappers.c:13 merge-recursive.c:3723
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-"  %s"
-msgstr ""
-
-#: merge-ort-wrappers.c:33 merge-recursive.c:3485 builtin/merge.c:405
-msgid "Already up to date."
-msgstr ""
-
-#: merge-recursive.c:353
-msgid "(bad commit)\n"
-msgstr ""
-
-#: merge-recursive.c:381
-#, c-format
-msgid "add_cacheinfo failed for path '%s'; merge aborting."
-msgstr ""
-
-#: merge-recursive.c:390
-#, c-format
-msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
-msgstr ""
-
-#: merge-recursive.c:881
-#, c-format
-msgid "failed to create path '%s'%s"
-msgstr ""
-
-#: merge-recursive.c:892
-#, c-format
-msgid "Removing %s to make room for subdirectory\n"
-msgstr ""
-
-#: merge-recursive.c:906 merge-recursive.c:925
-msgid ": perhaps a D/F conflict?"
-msgstr ""
-
-#: merge-recursive.c:915
-#, c-format
-msgid "refusing to lose untracked file at '%s'"
-msgstr ""
-
-#: merge-recursive.c:956 builtin/cat-file.c:47
-#, c-format
-msgid "cannot read object %s '%s'"
-msgstr ""
-
-#: merge-recursive.c:961
-#, c-format
-msgid "blob expected for %s '%s'"
-msgstr ""
-
-#: merge-recursive.c:986
-#, c-format
-msgid "failed to open '%s': %s"
-msgstr ""
-
-#: merge-recursive.c:997
-#, c-format
-msgid "failed to symlink '%s': %s"
-msgstr ""
-
-#: merge-recursive.c:1002
-#, c-format
-msgid "do not know what to do with %06o %s '%s'"
-msgstr ""
-
-#: merge-recursive.c:1236 merge-recursive.c:1249
-#, c-format
-msgid "Fast-forwarding submodule %s to the following commit:"
-msgstr ""
-
-#: merge-recursive.c:1239 merge-recursive.c:1252
-#, c-format
-msgid "Fast-forwarding submodule %s"
-msgstr ""
-
-#: merge-recursive.c:1276
-#, c-format
-msgid "Failed to merge submodule %s (merge following commits not found)"
-msgstr ""
-
-#: merge-recursive.c:1280
-#, c-format
-msgid "Failed to merge submodule %s (not fast-forward)"
-msgstr ""
-
-#: merge-recursive.c:1281
-msgid "Found a possible merge resolution for the submodule:\n"
-msgstr ""
-
-#: merge-recursive.c:1293
-#, c-format
-msgid "Failed to merge submodule %s (multiple merges found)"
-msgstr ""
-
-#: merge-recursive.c:1437
-#, c-format
-msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
-msgstr ""
-
-#: merge-recursive.c:1509
-#, c-format
-msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
-"in tree."
-msgstr ""
-
-#: merge-recursive.c:1514
-#, c-format
-msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
-"left in tree."
-msgstr ""
-
-#: merge-recursive.c:1521
-#, c-format
-msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
-"in tree at %s."
-msgstr ""
-
-#: merge-recursive.c:1526
-#, c-format
-msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
-"left in tree at %s."
-msgstr ""
-
-#: merge-recursive.c:1561
-msgid "rename"
-msgstr ""
-
-#: merge-recursive.c:1561
-msgid "renamed"
-msgstr ""
-
-#: merge-recursive.c:1612 merge-recursive.c:2518 merge-recursive.c:3181
-#, c-format
-msgid "Refusing to lose dirty file at %s"
-msgstr ""
-
-#: merge-recursive.c:1622
-#, c-format
-msgid "Refusing to lose untracked file at %s, even though it's in the way."
-msgstr ""
-
-#: merge-recursive.c:1680
-#, c-format
-msgid "CONFLICT (rename/add): Rename %s->%s in %s.  Added %s in %s"
-msgstr ""
-
-#: merge-recursive.c:1711
-#, c-format
-msgid "%s is a directory in %s adding as %s instead"
-msgstr ""
-
-#: merge-recursive.c:1716
-#, c-format
-msgid "Refusing to lose untracked file at %s; adding as %s instead"
-msgstr ""
-
-#: merge-recursive.c:1743
-#, c-format
-msgid ""
-"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
-"\"->\"%s\" in \"%s\"%s"
-msgstr ""
-
-#: merge-recursive.c:1748
-msgid " (left unresolved)"
-msgstr ""
-
-#: merge-recursive.c:1840
-#, c-format
-msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
-msgstr ""
-
-#: merge-recursive.c:2103
-#, c-format
-msgid ""
-"CONFLICT (directory rename split): Unclear where to place %s because "
-"directory %s was renamed to multiple other directories, with no destination "
-"getting a majority of the files."
-msgstr ""
-
-#: merge-recursive.c:2237
-#, c-format
-msgid ""
-"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
-">%s in %s"
-msgstr ""
-
-#: merge-recursive.c:3092
-msgid "modify"
-msgstr ""
-
-#: merge-recursive.c:3092
-msgid "modified"
-msgstr ""
-
-#: merge-recursive.c:3131
-#, c-format
-msgid "Skipped %s (merged same as existing)"
-msgstr ""
-
-#: merge-recursive.c:3184
-#, c-format
-msgid "Adding as %s instead"
-msgstr ""
-
-#: merge-recursive.c:3388
-#, c-format
-msgid "Removing %s"
-msgstr ""
-
-#: merge-recursive.c:3411
-msgid "file/directory"
-msgstr ""
-
-#: merge-recursive.c:3416
-msgid "directory/file"
-msgstr ""
-
-#: merge-recursive.c:3423
-#, c-format
-msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
-msgstr ""
-
-#: merge-recursive.c:3432
-#, c-format
-msgid "Adding %s"
-msgstr ""
-
-#: merge-recursive.c:3441
-#, c-format
-msgid "CONFLICT (add/add): Merge conflict in %s"
-msgstr ""
-
-#: merge-recursive.c:3494
-#, c-format
-msgid "merging of trees %s and %s failed"
-msgstr ""
-
-#: merge-recursive.c:3588
-msgid "Merging:"
-msgstr ""
-
-#: merge-recursive.c:3601
-#, c-format
-msgid "found %u common ancestor:"
-msgid_plural "found %u common ancestors:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: merge-recursive.c:3651
-msgid "merge returned no commit"
-msgstr ""
-
-#: merge-recursive.c:3823
-#, c-format
-msgid "Could not parse object '%s'"
-msgstr ""
-
-#: merge-recursive.c:3841 builtin/merge.c:720 builtin/merge.c:912
-#: builtin/stash.c:489
-msgid "Unable to write index."
-msgstr ""
-
-#: merge.c:41
-msgid "failed to read the cache"
-msgstr ""
-
-#: merge.c:102 rerere.c:705 builtin/am.c:1989 builtin/am.c:2023
-#: builtin/checkout.c:603 builtin/checkout.c:865 builtin/clone.c:714
-#: builtin/stash.c:269
-msgid "unable to write new index file"
-msgstr ""
-
-#: midx.c:79
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr ""
-
-#: midx.c:112
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr ""
-
-#: midx.c:128
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr ""
-
-#: midx.c:133
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr ""
-
-#: midx.c:138
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr ""
-
-#: midx.c:155
-msgid "multi-pack-index missing required pack-name chunk"
-msgstr ""
-
-#: midx.c:157
-msgid "multi-pack-index missing required OID fanout chunk"
-msgstr ""
-
-#: midx.c:159
-msgid "multi-pack-index missing required OID lookup chunk"
-msgstr ""
-
-#: midx.c:161
-msgid "multi-pack-index missing required object offsets chunk"
-msgstr ""
-
-#: midx.c:180
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr ""
-
-#: midx.c:228
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr ""
-
-#: midx.c:278
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr ""
-
-#: midx.c:509
-#, c-format
-msgid "failed to add packfile '%s'"
-msgstr ""
-
-#: midx.c:515
-#, c-format
-msgid "failed to open pack-index '%s'"
-msgstr ""
-
-#: midx.c:583
-#, c-format
-msgid "failed to locate object %d in packfile"
-msgstr ""
-
-#: midx.c:911
-msgid "cannot store reverse index file"
-msgstr ""
-
-#: midx.c:1009
-#, c-format
-msgid "could not parse line: %s"
-msgstr ""
-
-#: midx.c:1011
-#, c-format
-msgid "malformed line: %s"
-msgstr ""
-
-#: midx.c:1181
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr ""
-
-#: midx.c:1206
-msgid "could not load pack"
-msgstr ""
-
-#: midx.c:1212
-#, c-format
-msgid "could not open index for %s"
-msgstr ""
-
-#: midx.c:1223
-msgid "Adding packfiles to multi-pack-index"
-msgstr ""
-
-#: midx.c:1266
-#, c-format
-msgid "unknown preferred pack: '%s'"
-msgstr ""
-
-#: midx.c:1311
-#, c-format
-msgid "cannot select preferred pack %s with no objects"
-msgstr ""
-
-#: midx.c:1343
-#, c-format
-msgid "did not see pack-file %s to drop"
-msgstr ""
-
-#: midx.c:1389
-#, c-format
-msgid "preferred pack '%s' is expired"
-msgstr ""
-
-#: midx.c:1402
-msgid "no pack files to index."
-msgstr ""
-
-#: midx.c:1409
-msgid "refusing to write multi-pack .bitmap without any objects"
-msgstr ""
-
-#: midx.c:1451
-msgid "could not write multi-pack bitmap"
-msgstr ""
-
-#: midx.c:1461
-msgid "could not write multi-pack-index"
-msgstr ""
-
-#: midx.c:1520 builtin/clean.c:37
-#, c-format
-msgid "failed to remove %s"
-msgstr ""
-
-#: midx.c:1553
-#, c-format
-msgid "failed to clear multi-pack-index at %s"
-msgstr ""
-
-#: midx.c:1616
-msgid "multi-pack-index file exists, but failed to parse"
-msgstr ""
-
-#: midx.c:1624
-msgid "incorrect checksum"
-msgstr ""
-
-#: midx.c:1627
-msgid "Looking for referenced packfiles"
-msgstr ""
-
-#: midx.c:1642
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-
-#: midx.c:1647
-msgid "the midx contains no oid"
-msgstr ""
-
-#: midx.c:1656
-msgid "Verifying OID order in multi-pack-index"
-msgstr ""
-
-#: midx.c:1665
-#, c-format
-msgid "oid lookup out of order: oid[%d] = %s >= %s = oid[%d]"
-msgstr ""
-
-#: midx.c:1685
-msgid "Sorting objects by packfile"
-msgstr ""
-
-#: midx.c:1692
-msgid "Verifying object offsets"
-msgstr ""
-
-#: midx.c:1708
-#, c-format
-msgid "failed to load pack entry for oid[%d] = %s"
-msgstr ""
-
-#: midx.c:1714
-#, c-format
-msgid "failed to load pack-index for packfile %s"
-msgstr ""
-
-#: midx.c:1723
-#, c-format
-msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
-msgstr ""
-
-#: midx.c:1750
-msgid "Counting referenced objects"
-msgstr ""
-
-#: midx.c:1760
-msgid "Finding and deleting unreferenced packfiles"
-msgstr ""
-
-#: midx.c:1952
-msgid "could not start pack-objects"
-msgstr ""
-
-#: midx.c:1972
-msgid "could not finish pack-objects"
-msgstr ""
-
-#: name-hash.c:542
-#, c-format
-msgid "unable to create lazy_dir thread: %s"
-msgstr ""
-
-#: name-hash.c:564
-#, c-format
-msgid "unable to create lazy_name thread: %s"
-msgstr ""
-
-#: name-hash.c:570
-#, c-format
-msgid "unable to join lazy_name thread: %s"
-msgstr ""
-
-#: notes-merge.c:276
-#, c-format
-msgid ""
-"You have not concluded your previous notes merge (%s exists).\n"
-"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 ""
-
-#: notes-merge.c:283
-#, c-format
-msgid "You have not concluded your notes merge (%s exists)."
-msgstr ""
-
-#: notes-utils.c:46
-msgid "Cannot commit uninitialized/unreferenced notes tree"
-msgstr ""
-
-#: notes-utils.c:105
-#, c-format
-msgid "Bad notes.rewriteMode value: '%s'"
-msgstr ""
-
-#: notes-utils.c:115
-#, c-format
-msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
-msgstr ""
-
-#. TRANSLATORS: The first %s is the name of
-#. the environment variable, the second %s is
-#. its value.
-#.
-#: notes-utils.c:145
-#, c-format
-msgid "Bad %s value: '%s'"
-msgstr ""
-
-#: object-file.c:457
-#, c-format
-msgid "object directory %s does not exist; check .git/objects/info/alternates"
-msgstr ""
-
-#: object-file.c:515
-#, c-format
-msgid "unable to normalize alternate object path: %s"
-msgstr ""
-
-#: object-file.c:589
-#, c-format
-msgid "%s: ignoring alternate object stores, nesting too deep"
-msgstr ""
-
-#: object-file.c:596
-#, c-format
-msgid "unable to normalize object directory: %s"
-msgstr ""
-
-#: object-file.c:639
-msgid "unable to fdopen alternates lockfile"
-msgstr ""
-
-#: object-file.c:657
-msgid "unable to read alternates file"
-msgstr ""
-
-#: object-file.c:664
-msgid "unable to move new alternates file into place"
-msgstr ""
-
-#: object-file.c:742
-#, c-format
-msgid "path '%s' does not exist"
-msgstr ""
-
-#: object-file.c:763
-#, c-format
-msgid "reference repository '%s' as a linked checkout is not supported yet."
-msgstr ""
-
-#: object-file.c:769
-#, c-format
-msgid "reference repository '%s' is not a local repository."
-msgstr ""
-
-#: object-file.c:775
-#, c-format
-msgid "reference repository '%s' is shallow"
-msgstr ""
-
-#: object-file.c:783
-#, c-format
-msgid "reference repository '%s' is grafted"
-msgstr ""
-
-#: object-file.c:814
-#, c-format
-msgid "could not find object directory matching %s"
-msgstr ""
-
-#: object-file.c:864
-#, c-format
-msgid "invalid line while parsing alternate refs: %s"
-msgstr ""
-
-#: object-file.c:1014
-#, c-format
-msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>"
-msgstr ""
-
-#: object-file.c:1049
-#, c-format
-msgid "mmap failed%s"
-msgstr ""
-
-#: object-file.c:1230
-#, c-format
-msgid "object file %s is empty"
-msgstr ""
-
-#: object-file.c:1349 object-file.c:2588
-#, c-format
-msgid "corrupt loose object '%s'"
-msgstr ""
-
-#: object-file.c:1351 object-file.c:2592
-#, c-format
-msgid "garbage at end of loose object '%s'"
-msgstr ""
-
-#: object-file.c:1473
-#, c-format
-msgid "unable to parse %s header"
-msgstr ""
-
-#: object-file.c:1475
-msgid "invalid object type"
-msgstr ""
-
-#: object-file.c:1486
-#, c-format
-msgid "unable to unpack %s header"
-msgstr ""
-
-#: object-file.c:1490
-#, c-format
-msgid "header for %s too long, exceeds %d bytes"
-msgstr ""
-
-#: object-file.c:1720
-#, c-format
-msgid "failed to read object %s"
-msgstr ""
-
-#: object-file.c:1724
-#, c-format
-msgid "replacement %s not found for %s"
-msgstr ""
-
-#: object-file.c:1728
-#, c-format
-msgid "loose object %s (stored in %s) is corrupt"
-msgstr ""
-
-#: object-file.c:1732
-#, c-format
-msgid "packed object %s (stored in %s) is corrupt"
-msgstr ""
-
-#: object-file.c:1855
-#, c-format
-msgid "unable to write file %s"
-msgstr ""
-
-#: object-file.c:1862
-#, c-format
-msgid "unable to set permission to '%s'"
-msgstr ""
-
-#: object-file.c:1869
-msgid "file write error"
-msgstr ""
-
-#: object-file.c:1904
-msgid "error when closing loose object file"
-msgstr ""
-
-#: object-file.c:1971
-#, c-format
-msgid "insufficient permission for adding an object to repository database %s"
-msgstr ""
-
-#: object-file.c:1973
-msgid "unable to create temporary file"
-msgstr ""
-
-#: object-file.c:1997
-msgid "unable to write loose object file"
-msgstr ""
-
-#: object-file.c:2003
-#, c-format
-msgid "unable to deflate new object %s (%d)"
-msgstr ""
-
-#: object-file.c:2007
-#, c-format
-msgid "deflateEnd on object %s failed (%d)"
-msgstr ""
-
-#: object-file.c:2011
-#, c-format
-msgid "confused by unstable object source data for %s"
-msgstr ""
-
-#: object-file.c:2022 builtin/pack-objects.c:1251
-#, c-format
-msgid "failed utime() on %s"
-msgstr ""
-
-#: object-file.c:2100
-#, c-format
-msgid "cannot read object for %s"
-msgstr ""
-
-#: object-file.c:2151
-msgid "corrupt commit"
-msgstr ""
-
-#: object-file.c:2159
-msgid "corrupt tag"
-msgstr ""
-
-#: object-file.c:2259
-#, c-format
-msgid "read error while indexing %s"
-msgstr ""
-
-#: object-file.c:2262
-#, c-format
-msgid "short read while indexing %s"
-msgstr ""
-
-#: object-file.c:2335 object-file.c:2345
-#, c-format
-msgid "%s: failed to insert into database"
-msgstr ""
-
-#: object-file.c:2351
-#, c-format
-msgid "%s: unsupported file type"
-msgstr ""
-
-#: object-file.c:2375 builtin/fetch.c:1494
-#, c-format
-msgid "%s is not a valid object"
-msgstr ""
-
-#: object-file.c:2377
-#, c-format
-msgid "%s is not a valid '%s' object"
-msgstr ""
-
-#: object-file.c:2404
-#, c-format
-msgid "unable to open %s"
-msgstr ""
-
-#: object-file.c:2599
-#, c-format
-msgid "hash mismatch for %s (expected %s)"
-msgstr ""
-
-#: object-file.c:2622
-#, c-format
-msgid "unable to mmap %s"
-msgstr ""
-
-#: object-file.c:2628
-#, c-format
-msgid "unable to unpack header of %s"
-msgstr ""
-
-#: object-file.c:2633
-#, c-format
-msgid "unable to parse header of %s"
-msgstr ""
-
-#: object-file.c:2644
-#, c-format
-msgid "unable to unpack contents of %s"
-msgstr ""
-
-#. TRANSLATORS: This is a line of ambiguous object
-#. output shown when we cannot look up or parse the
-#. object in question. E.g. "deadbeef [bad object]".
-#.
-#: object-name.c:382
-#, c-format
-msgid "%s [bad object]"
-msgstr ""
-
-#. TRANSLATORS: This is a line of ambiguous commit
-#. object output. E.g.:
-#. *
-#.    "deadbeef commit 2021-01-01 - Some Commit Message"
-#.
-#: object-name.c:407
-#, c-format
-msgid "%s commit %s - %s"
-msgstr ""
-
-#. TRANSLATORS: This is a line of ambiguous
-#. tag object output. E.g.:
-#. *
-#.    "deadbeef tag 2022-01-01 - Some Tag Message"
-#. *
-#. The second argument is the YYYY-MM-DD found
-#. in the tag.
-#. *
-#. The third argument is the "tag" string
-#. from object.c.
-#.
-#: object-name.c:428
-#, c-format
-msgid "%s tag %s - %s"
-msgstr ""
-
-#. 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]"
-#.
-#: object-name.c:439
-#, c-format
-msgid "%s [bad tag, could not parse it]"
-msgstr ""
-
-#. TRANSLATORS: This is a line of ambiguous <type>
-#. object output. E.g. "deadbeef tree".
-#.
-#: object-name.c:447
-#, c-format
-msgid "%s tree"
-msgstr ""
-
-#. TRANSLATORS: This is a line of ambiguous <type>
-#. object output. E.g. "deadbeef blob".
-#.
-#: object-name.c:453
-#, c-format
-msgid "%s blob"
-msgstr ""
-
-#: object-name.c:569
-#, c-format
-msgid "short object ID %s is ambiguous"
-msgstr ""
-
-#. TRANSLATORS: The argument is the list of ambiguous
-#. objects composed in show_ambiguous_object(). See
-#. its "TRANSLATORS" comments for details.
-#.
-#: object-name.c:591
-#, c-format
-msgid ""
-"The candidates are:\n"
-"%s"
-msgstr ""
-
-#: object-name.c:888
-msgid ""
-"Git normally never creates a ref that ends with 40 hex characters\n"
-"because it will be ignored when you just specify 40-hex. These refs\n"
-"may be created by mistake. For example,\n"
-"\n"
-"  git switch -c $br $(git rev-parse ...)\n"
-"\n"
-"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n"
-"examine these refs and maybe delete them. Turn this message off by\n"
-"running \"git config advice.objectNameWarning false\""
-msgstr ""
-
-#: object-name.c:1008
-#, c-format
-msgid "log for '%.*s' only goes back to %s"
-msgstr ""
-
-#: object-name.c:1016
-#, c-format
-msgid "log for '%.*s' only has %d entries"
-msgstr ""
-
-#: object-name.c:1794
-#, c-format
-msgid "path '%s' exists on disk, but not in '%.*s'"
-msgstr ""
-
-#: object-name.c:1800
-#, c-format
-msgid ""
-"path '%s' exists, but not '%s'\n"
-"hint: Did you mean '%.*s:%s' aka '%.*s:./%s'?"
-msgstr ""
-
-#: object-name.c:1809
-#, c-format
-msgid "path '%s' does not exist in '%.*s'"
-msgstr ""
-
-#: object-name.c:1837
-#, c-format
-msgid ""
-"path '%s' is in the index, but not at stage %d\n"
-"hint: Did you mean ':%d:%s'?"
-msgstr ""
-
-#: object-name.c:1853
-#, c-format
-msgid ""
-"path '%s' is in the index, but not '%s'\n"
-"hint: Did you mean ':%d:%s' aka ':%d:./%s'?"
-msgstr ""
-
-#: object-name.c:1861
-#, c-format
-msgid "path '%s' exists on disk, but not in the index"
-msgstr ""
-
-#: object-name.c:1863
-#, c-format
-msgid "path '%s' does not exist (neither on disk nor in the index)"
-msgstr ""
-
-#: object-name.c:1876
-msgid "relative path syntax can't be used outside working tree"
-msgstr ""
-
-#: object-name.c:1901
-#, c-format
-msgid "<object>:<path> required, only <object> '%s' given"
-msgstr ""
-
-#: object-name.c:2014
-#, c-format
-msgid "invalid object name '%.*s'."
-msgstr ""
-
-#: object.c:53
-#, c-format
-msgid "invalid object type \"%s\""
-msgstr ""
-
-#: object.c:173
-#, c-format
-msgid "object %s is a %s, not a %s"
-msgstr ""
-
-#: object.c:250
-#, c-format
-msgid "object %s has unknown type id %d"
-msgstr ""
-
-#: object.c:263
-#, c-format
-msgid "unable to parse object: %s"
-msgstr ""
-
-#: object.c:283 object.c:294
-#, c-format
-msgid "hash mismatch %s"
-msgstr ""
-
-#: pack-bitmap.c:353
-msgid "multi-pack bitmap is missing required reverse index"
-msgstr ""
-
-#: pack-bitmap.c:433
-msgid "load_reverse_index: could not open pack"
-msgstr ""
-
-#: pack-bitmap.c:1072 pack-bitmap.c:1078 builtin/pack-objects.c:2432
-#, c-format
-msgid "unable to get size of %s"
-msgstr ""
-
-#: pack-bitmap.c:1937
-#, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr ""
-
-#: pack-bitmap.c:1973 builtin/rev-list.c:91
-#, c-format
-msgid "unable to get disk usage of %s"
-msgstr ""
-
-#: pack-revindex.c:221
-#, c-format
-msgid "reverse-index file %s is too small"
-msgstr ""
-
-#: pack-revindex.c:226
-#, c-format
-msgid "reverse-index file %s is corrupt"
-msgstr ""
-
-#: pack-revindex.c:234
-#, c-format
-msgid "reverse-index file %s has unknown signature"
-msgstr ""
-
-#: pack-revindex.c:238
-#, c-format
-msgid "reverse-index file %s has unsupported version %<PRIu32>"
-msgstr ""
-
-#: pack-revindex.c:243
-#, c-format
-msgid "reverse-index file %s has unsupported hash id %<PRIu32>"
-msgstr ""
-
-#: pack-write.c:251
-msgid "cannot both write and verify reverse index"
-msgstr ""
-
-#: pack-write.c:270
-#, c-format
-msgid "could not stat: %s"
-msgstr ""
-
-#: pack-write.c:282
-#, c-format
-msgid "failed to make %s readable"
-msgstr ""
-
-#: pack-write.c:521
-#, c-format
-msgid "could not write '%s' promisor file"
-msgstr ""
-
-#: packfile.c:627
-msgid "offset before end of packfile (broken .idx?)"
-msgstr ""
-
-#: packfile.c:657
-#, c-format
-msgid "packfile %s cannot be mapped%s"
-msgstr ""
-
-#: packfile.c:1924
-#, c-format
-msgid "offset before start of pack index for %s (corrupt index?)"
-msgstr ""
-
-#: packfile.c:1928
-#, c-format
-msgid "offset beyond end of pack index for %s (truncated index?)"
-msgstr ""
-
-#: parse-options-cb.c:21 parse-options-cb.c:25 builtin/commit-graph.c:175
-#, c-format
-msgid "option `%s' expects a numerical value"
-msgstr ""
-
-#: parse-options-cb.c:42
-#, c-format
-msgid "malformed expiration date '%s'"
-msgstr ""
-
-#: parse-options-cb.c:55
-#, c-format
-msgid "option `%s' expects \"always\", \"auto\", or \"never\""
-msgstr ""
-
-#: parse-options-cb.c:133 parse-options-cb.c:150
-#, c-format
-msgid "malformed object name '%s'"
-msgstr ""
-
-#: parse-options-cb.c:307
-#, c-format
-msgid "option `%s' expects \"%s\" or \"%s\""
-msgstr ""
-
-#: parse-options.c:58
-#, c-format
-msgid "%s requires a value"
-msgstr ""
-
-#: parse-options.c:93
-#, c-format
-msgid "%s is incompatible with %s"
-msgstr ""
-
-#: parse-options.c:98
-#, c-format
-msgid "%s : incompatible with something else"
-msgstr ""
-
-#: parse-options.c:112 parse-options.c:116
-#, c-format
-msgid "%s takes no value"
-msgstr ""
-
-#: parse-options.c:114
-#, c-format
-msgid "%s isn't available"
-msgstr ""
-
-#: parse-options.c:237
-#, c-format
-msgid "%s expects a non-negative integer value with an optional k/m/g suffix"
-msgstr ""
-
-#: parse-options.c:393
-#, c-format
-msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
-msgstr ""
-
-#: parse-options.c:428 parse-options.c:436
-#, c-format
-msgid "did you mean `--%s` (with two dashes)?"
-msgstr ""
-
-#: parse-options.c:678 parse-options.c:1054
-#, c-format
-msgid "alias of --%s"
-msgstr ""
-
-#: parse-options.c:892
-#, c-format
-msgid "unknown option `%s'"
-msgstr ""
-
-#: parse-options.c:894
-#, c-format
-msgid "unknown switch `%c'"
-msgstr ""
-
-#: parse-options.c:896
-#, c-format
-msgid "unknown non-ascii option in string: `%s'"
-msgstr ""
-
-#: parse-options.c:920
-msgid "..."
-msgstr ""
-
-#: parse-options.c:934
-#, c-format
-msgid "usage: %s"
-msgstr ""
-
-#. TRANSLATORS: the colon here should align with the
-#. one in "usage: %s" translation.
-#.
-#: parse-options.c:949
-#, c-format
-msgid "   or: %s"
-msgstr ""
-
-#. TRANSLATORS: You should only need to translate this format
-#. string if your language is a RTL language (e.g. Arabic,
-#. Hebrew etc.), not if it's a LTR language (e.g. German,
-#. Russian, Chinese etc.).
-#. *
-#. When a translated usage string has an embedded "\n" it's
-#. because options have wrapped to the next line. The line
-#. after the "\n" will then be padded to align with the
-#. command name, such as N_("git cmd [opt]\n<8
-#. spaces>[opt2]"), where the 8 spaces are the same length as
-#. "git cmd ".
-#. *
-#. This format string prints out that already-translated
-#. line. The "%*s" is whitespace padding to account for the
-#. padding at the start of the line that we add in this
-#. function. The "%s" is a line in the (hopefully already
-#. translated) N_() usage string, which contained embedded
-#. newlines before we split it up.
-#.
-#: parse-options.c:970
-#, c-format
-msgid "%*s%s"
-msgstr ""
-
-#: parse-options.c:993
-#, c-format
-msgid "    %s"
-msgstr ""
-
-#: parse-options.c:1040
-msgid "-NUM"
-msgstr ""
-
-#: path.c:922
-#, c-format
-msgid "Could not make %s writable by group"
-msgstr ""
-
-#: pathspec.c:150
-msgid "Escape character '\\' not allowed as last character in attr value"
-msgstr ""
-
-#: pathspec.c:168
-msgid "Only one 'attr:' specification is allowed."
-msgstr ""
-
-#: pathspec.c:171
-msgid "attr spec must not be empty"
-msgstr ""
-
-#: pathspec.c:214
-#, c-format
-msgid "invalid attribute name %s"
-msgstr ""
-
-#: pathspec.c:279
-msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
-msgstr ""
-
-#: pathspec.c:286
-msgid ""
-"global 'literal' pathspec setting is incompatible with all other global "
-"pathspec settings"
-msgstr ""
-
-#: pathspec.c:326
-msgid "invalid parameter for pathspec magic 'prefix'"
-msgstr ""
-
-#: pathspec.c:347
-#, c-format
-msgid "Invalid pathspec magic '%.*s' in '%s'"
-msgstr ""
-
-#: pathspec.c:352
-#, c-format
-msgid "Missing ')' at the end of pathspec magic in '%s'"
-msgstr ""
-
-#: pathspec.c:390
-#, c-format
-msgid "Unimplemented pathspec magic '%c' in '%s'"
-msgstr ""
-
-#: pathspec.c:449
-#, c-format
-msgid "%s: 'literal' and 'glob' are incompatible"
-msgstr ""
-
-#: pathspec.c:465
-#, c-format
-msgid "%s: '%s' is outside repository at '%s'"
-msgstr ""
-
-#: pathspec.c:541
-#, c-format
-msgid "'%s' (mnemonic: '%c')"
-msgstr ""
-
-#: pathspec.c:551
-#, c-format
-msgid "%s: pathspec magic not supported by this command: %s"
-msgstr ""
-
-#: pathspec.c:618
-#, c-format
-msgid "pathspec '%s' is beyond a symbolic link"
-msgstr ""
-
-#: pathspec.c:663
-#, c-format
-msgid "line is badly quoted: %s"
-msgstr ""
-
-#: pkt-line.c:92
-msgid "unable to write flush packet"
-msgstr ""
-
-#: pkt-line.c:99
-msgid "unable to write delim packet"
-msgstr ""
-
-#: pkt-line.c:106
-msgid "unable to write response end packet"
-msgstr ""
-
-#: pkt-line.c:113
-msgid "flush packet write failed"
-msgstr ""
-
-#: pkt-line.c:153
-msgid "protocol error: impossibly long line"
-msgstr ""
-
-#: pkt-line.c:169 pkt-line.c:171
-msgid "packet write with format failed"
-msgstr ""
-
-#: pkt-line.c:204 pkt-line.c:252
-msgid "packet write failed - data exceeds max packet size"
-msgstr ""
-
-#: pkt-line.c:222
-#, c-format
-msgid "packet write failed: %s"
-msgstr ""
-
-#: pkt-line.c:349 pkt-line.c:350
-msgid "read error"
-msgstr ""
-
-#: pkt-line.c:360 pkt-line.c:361
-msgid "the remote end hung up unexpectedly"
-msgstr ""
-
-#: pkt-line.c:417 pkt-line.c:419
-#, c-format
-msgid "protocol error: bad line length character: %.4s"
-msgstr ""
-
-#: pkt-line.c:434 pkt-line.c:436 pkt-line.c:442 pkt-line.c:444
-#, c-format
-msgid "protocol error: bad line length %d"
-msgstr ""
-
-#: pkt-line.c:472 sideband.c:165
-#, c-format
-msgid "remote error: %s"
-msgstr ""
-
-#: preload-index.c:125
-msgid "Refreshing index"
-msgstr ""
-
-#: preload-index.c:144
-#, c-format
-msgid "unable to create threaded lstat: %s"
-msgstr ""
-
-#: pretty.c:1051
-msgid "unable to parse --pretty format"
-msgstr ""
-
-#: promisor-remote.c:31
-msgid "promisor-remote: unable to fork off fetch subprocess"
-msgstr ""
-
-#: promisor-remote.c:38 promisor-remote.c:40
-msgid "promisor-remote: could not write to fetch subprocess"
-msgstr ""
-
-#: promisor-remote.c:44
-msgid "promisor-remote: could not close stdin to fetch subprocess"
-msgstr ""
-
-#: promisor-remote.c:54
-#, c-format
-msgid "promisor remote name cannot begin with '/': %s"
-msgstr ""
-
-#: protocol-caps.c:103
-msgid "object-info: expected flush after arguments"
-msgstr ""
-
-#: prune-packed.c:35
-msgid "Removing duplicate objects"
-msgstr ""
-
-#: range-diff.c:68
-msgid "could not start `log`"
-msgstr ""
-
-#: range-diff.c:70
-msgid "could not read `log` output"
-msgstr ""
-
-#: range-diff.c:98 sequencer.c:5575
-#, c-format
-msgid "could not parse commit '%s'"
-msgstr ""
-
-#: range-diff.c:109
-#, c-format
-msgid ""
-"could not parse first line of `log` output: did not start with 'commit ': "
-"'%s'"
-msgstr ""
-
-#: range-diff.c:132
-#, c-format
-msgid "could not parse git header '%.*s'"
-msgstr ""
-
-#: range-diff.c:300
-msgid "failed to generate diff"
-msgstr ""
-
-#: range-diff.c:558 range-diff.c:560
-#, c-format
-msgid "could not parse log for '%s'"
-msgstr ""
-
-#: read-cache.c:737
-#, c-format
-msgid "will not add file alias '%s' ('%s' already exists in index)"
-msgstr ""
-
-#: read-cache.c:753
-msgid "cannot create an empty blob in the object database"
-msgstr ""
-
-#: read-cache.c:775
-#, c-format
-msgid "%s: can only add regular files, symbolic links or git-directories"
-msgstr ""
-
-#: read-cache.c:780 builtin/submodule--helper.c:3359
-#, c-format
-msgid "'%s' does not have a commit checked out"
-msgstr ""
-
-#: read-cache.c:832
-#, c-format
-msgid "unable to index file '%s'"
-msgstr ""
-
-#: read-cache.c:851
-#, c-format
-msgid "unable to add '%s' to index"
-msgstr ""
-
-#: read-cache.c:862
-#, c-format
-msgid "unable to stat '%s'"
-msgstr ""
-
-#: read-cache.c:1404
-#, c-format
-msgid "'%s' appears as both a file and as a directory"
-msgstr ""
-
-#: read-cache.c:1619
-msgid "Refresh index"
-msgstr ""
-
-#: read-cache.c:1751
-#, c-format
-msgid ""
-"index.version set, but the value is invalid.\n"
-"Using version %i"
-msgstr ""
-
-#: read-cache.c:1761
-#, c-format
-msgid ""
-"GIT_INDEX_VERSION set, but the value is invalid.\n"
-"Using version %i"
-msgstr ""
-
-#: read-cache.c:1817
-#, c-format
-msgid "bad signature 0x%08x"
-msgstr ""
-
-#: read-cache.c:1820
-#, c-format
-msgid "bad index version %d"
-msgstr ""
-
-#: read-cache.c:1829
-msgid "bad index file sha1 signature"
-msgstr ""
-
-#: read-cache.c:1863
-#, c-format
-msgid "index uses %.4s extension, which we do not understand"
-msgstr ""
-
-#: read-cache.c:1865
-#, c-format
-msgid "ignoring %.4s extension"
-msgstr ""
-
-#: read-cache.c:1902
-#, c-format
-msgid "unknown index entry format 0x%08x"
-msgstr ""
-
-#: read-cache.c:1918
-#, c-format
-msgid "malformed name field in the index, near path '%s'"
-msgstr ""
-
-#: read-cache.c:1975
-msgid "unordered stage entries in index"
-msgstr ""
-
-#: read-cache.c:1978
-#, c-format
-msgid "multiple stage entries for merged file '%s'"
-msgstr ""
-
-#: read-cache.c:1981
-#, c-format
-msgid "unordered stage entries for '%s'"
-msgstr ""
-
-#: read-cache.c:2096 read-cache.c:2402 rerere.c:549 rerere.c:583 rerere.c:1096
-#: submodule.c:1831 builtin/add.c:586 builtin/check-ignore.c:183
-#: builtin/checkout.c:532 builtin/checkout.c:724 builtin/clean.c:1016
-#: builtin/commit.c:379 builtin/diff-tree.c:122 builtin/grep.c:521
-#: builtin/mv.c:148 builtin/reset.c:506 builtin/rm.c:293
-#: builtin/submodule--helper.c:335 builtin/submodule--helper.c:3319
-msgid "index file corrupt"
-msgstr ""
-
-#: read-cache.c:2240
-#, c-format
-msgid "unable to create load_cache_entries thread: %s"
-msgstr ""
-
-#: read-cache.c:2253
-#, c-format
-msgid "unable to join load_cache_entries thread: %s"
-msgstr ""
-
-#: read-cache.c:2286
-#, c-format
-msgid "%s: index file open failed"
-msgstr ""
-
-#: read-cache.c:2290
-#, c-format
-msgid "%s: cannot stat the open index"
-msgstr ""
-
-#: read-cache.c:2294
-#, c-format
-msgid "%s: index file smaller than expected"
-msgstr ""
-
-#: read-cache.c:2298
-#, c-format
-msgid "%s: unable to map index file%s"
-msgstr ""
-
-#: read-cache.c:2341
-#, c-format
-msgid "unable to create load_index_extensions thread: %s"
-msgstr ""
-
-#: read-cache.c:2368
-#, c-format
-msgid "unable to join load_index_extensions thread: %s"
-msgstr ""
-
-#: read-cache.c:2414
-#, c-format
-msgid "could not freshen shared index '%s'"
-msgstr ""
-
-#: read-cache.c:2473
-#, c-format
-msgid "broken index, expect %s in %s, got %s"
-msgstr ""
-
-#: read-cache.c:3032
-msgid "cannot write split index for a sparse index"
-msgstr ""
-
-#: read-cache.c:3114 strbuf.c:1192 wrapper.c:717 builtin/merge.c:1156
-#, c-format
-msgid "could not close '%s'"
-msgstr ""
-
-#: read-cache.c:3157
-msgid "failed to convert to a sparse-index"
-msgstr ""
-
-#: read-cache.c:3228
-#, c-format
-msgid "could not stat '%s'"
-msgstr ""
-
-#: read-cache.c:3241
-#, c-format
-msgid "unable to open git dir: %s"
-msgstr ""
-
-#: read-cache.c:3253
-#, c-format
-msgid "unable to unlink: %s"
-msgstr ""
-
-#: read-cache.c:3282
-#, c-format
-msgid "cannot fix permission bits on '%s'"
-msgstr ""
-
-#: read-cache.c:3439
-#, c-format
-msgid "%s: cannot drop to stage #0"
-msgstr ""
-
-#: rebase-interactive.c:11
-msgid ""
-"You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
-"continue'.\n"
-"Or you can abort the rebase with 'git rebase --abort'.\n"
-msgstr ""
-
-#: rebase-interactive.c:33
-#, c-format
-msgid ""
-"unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
-msgstr ""
-
-#: rebase-interactive.c:42
-msgid ""
-"\n"
-"Commands:\n"
-"p, pick <commit> = use commit\n"
-"r, reword <commit> = use commit, but edit the commit message\n"
-"e, edit <commit> = use commit, but stop for amending\n"
-"s, squash <commit> = use commit, but meld into previous commit\n"
-"f, fixup [-C | -c] <commit> = like \"squash\" but keep only the previous\n"
-"                   commit's log message, unless -C is used, in which case\n"
-"                   keep only this commit's message; -c is same as -C but\n"
-"                   opens the editor\n"
-"x, exec <command> = run command (the rest of the line) using shell\n"
-"b, break = stop here (continue rebase later with 'git rebase --continue')\n"
-"d, drop <commit> = remove commit\n"
-"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"
-"\n"
-"These lines can be re-ordered; they are executed from top to bottom.\n"
-msgstr ""
-
-#: rebase-interactive.c:66
-#, c-format
-msgid "Rebase %s onto %s (%d command)"
-msgid_plural "Rebase %s onto %s (%d commands)"
-msgstr[0] ""
-msgstr[1] ""
-
-#: rebase-interactive.c:75
-msgid ""
-"\n"
-"Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
-msgstr ""
-
-#: rebase-interactive.c:78
-msgid ""
-"\n"
-"If you remove a line here THAT COMMIT WILL BE LOST.\n"
-msgstr ""
-
-#: rebase-interactive.c:84
-msgid ""
-"\n"
-"You are editing the todo file of an ongoing interactive rebase.\n"
-"To continue rebase after editing, run:\n"
-"    git rebase --continue\n"
-"\n"
-msgstr ""
-
-#: rebase-interactive.c:89
-msgid ""
-"\n"
-"However, if you remove everything, the rebase will be aborted.\n"
-"\n"
-msgstr ""
-
-#: rebase-interactive.c:113 rerere.c:469 rerere.c:677 sequencer.c:3879
-#: sequencer.c:3905 sequencer.c:5681 builtin/fsck.c:328 builtin/gc.c:1791
-#: builtin/rebase.c:191
-#, c-format
-msgid "could not write '%s'"
-msgstr ""
-
-#: rebase-interactive.c:119
-#, c-format
-msgid "could not write '%s'."
-msgstr ""
-
-#: rebase-interactive.c:196
-#, c-format
-msgid ""
-"Warning: some commits may have been dropped accidentally.\n"
-"Dropped commits (newer to older):\n"
-msgstr ""
-
-#: rebase-interactive.c:203
-#, c-format
-msgid ""
-"To avoid this message, use \"drop\" to explicitly remove a commit.\n"
-"\n"
-"Use 'git config rebase.missingCommitsCheck' to change the level of "
-"warnings.\n"
-"The possible behaviours are: ignore, warn, error.\n"
-"\n"
-msgstr ""
-
-#: rebase.c:29
-#, c-format
-msgid "%s: 'preserve' superseded by 'merges'"
-msgstr ""
-
-#: ref-filter.c:42 wt-status.c:2057
-msgid "gone"
-msgstr ""
-
-#: ref-filter.c:43
-#, c-format
-msgid "ahead %d"
-msgstr ""
-
-#: ref-filter.c:44
-#, c-format
-msgid "behind %d"
-msgstr ""
-
-#: ref-filter.c:45
-#, c-format
-msgid "ahead %d, behind %d"
-msgstr ""
-
-#: ref-filter.c:235
-#, c-format
-msgid "expected format: %%(color:<color>)"
-msgstr ""
-
-#: ref-filter.c:237
-#, c-format
-msgid "unrecognized color: %%(color:%s)"
-msgstr ""
-
-#: ref-filter.c:259
-#, c-format
-msgid "Integer value expected refname:lstrip=%s"
-msgstr ""
-
-#: ref-filter.c:263
-#, c-format
-msgid "Integer value expected refname:rstrip=%s"
-msgstr ""
-
-#: ref-filter.c:265 ref-filter.c:344 ref-filter.c:377 ref-filter.c:431
-#: ref-filter.c:443 ref-filter.c:462 ref-filter.c:534 ref-filter.c:560
-#, c-format
-msgid "unrecognized %%(%s) argument: %s"
-msgstr ""
-
-#: ref-filter.c:320
-#, c-format
-msgid "%%(objecttype) does not take arguments"
-msgstr ""
-
-#: ref-filter.c:352
-#, c-format
-msgid "%%(deltabase) does not take arguments"
-msgstr ""
-
-#: ref-filter.c:364
-#, c-format
-msgid "%%(body) does not take arguments"
-msgstr ""
-
-#: ref-filter.c:396
-#, c-format
-msgid "expected %%(trailers:key=<value>)"
-msgstr ""
-
-#: ref-filter.c:398
-#, c-format
-msgid "unknown %%(trailers) argument: %s"
-msgstr ""
-
-#: ref-filter.c:429
-#, c-format
-msgid "positive value expected contents:lines=%s"
-msgstr ""
-
-#: ref-filter.c:458
-#, c-format
-msgid "positive value expected '%s' in %%(%s)"
-msgstr ""
-
-#: ref-filter.c:476
-#, c-format
-msgid "unrecognized email option: %s"
-msgstr ""
-
-#: ref-filter.c:506
-#, c-format
-msgid "expected format: %%(align:<width>,<position>)"
-msgstr ""
-
-#: ref-filter.c:518
-#, c-format
-msgid "unrecognized position:%s"
-msgstr ""
-
-#: ref-filter.c:525
-#, c-format
-msgid "unrecognized width:%s"
-msgstr ""
-
-#: ref-filter.c:542
-#, c-format
-msgid "positive width expected with the %%(align) atom"
-msgstr ""
-
-#: ref-filter.c:568
-#, c-format
-msgid "%%(rest) does not take arguments"
-msgstr ""
-
-#: ref-filter.c:680
-#, c-format
-msgid "malformed field name: %.*s"
-msgstr ""
-
-#: ref-filter.c:707
-#, c-format
-msgid "unknown field name: %.*s"
-msgstr ""
-
-#: ref-filter.c:711
-#, c-format
-msgid ""
-"not a git repository, but the field '%.*s' requires access to object data"
-msgstr ""
-
-#: ref-filter.c:844 ref-filter.c:910 ref-filter.c:946 ref-filter.c:948
-#, c-format
-msgid "format: %%(%s) atom used without a %%(%s) atom"
-msgstr ""
-
-#: ref-filter.c:912
-#, c-format
-msgid "format: %%(then) atom used more than once"
-msgstr ""
-
-#: ref-filter.c:914
-#, c-format
-msgid "format: %%(then) atom used after %%(else)"
-msgstr ""
-
-#: ref-filter.c:950
-#, c-format
-msgid "format: %%(else) atom used more than once"
-msgstr ""
-
-#: ref-filter.c:965
-#, c-format
-msgid "format: %%(end) atom used without corresponding atom"
-msgstr ""
-
-#: ref-filter.c:1027
-#, c-format
-msgid "malformed format string %s"
-msgstr ""
-
-#: ref-filter.c:1033
-#, c-format
-msgid "this command reject atom %%(%.*s)"
-msgstr ""
-
-#: ref-filter.c:1040
-#, c-format
-msgid "--format=%.*s cannot be used with --python, --shell, --tcl"
-msgstr ""
-
-#: ref-filter.c:1707
-#, c-format
-msgid "(no branch, rebasing %s)"
-msgstr ""
-
-#: ref-filter.c:1710
-#, c-format
-msgid "(no branch, rebasing detached HEAD %s)"
-msgstr ""
-
-#: ref-filter.c:1713
-#, c-format
-msgid "(no branch, bisect started on %s)"
-msgstr ""
-
-#: ref-filter.c:1717
-#, c-format
-msgid "(HEAD detached at %s)"
-msgstr ""
-
-#: ref-filter.c:1720
-#, c-format
-msgid "(HEAD detached from %s)"
-msgstr ""
-
-#: ref-filter.c:1723
-msgid "(no branch)"
-msgstr ""
-
-#: ref-filter.c:1755 ref-filter.c:1973
-#, c-format
-msgid "missing object %s for %s"
-msgstr ""
-
-#: ref-filter.c:1765
-#, c-format
-msgid "parse_object_buffer failed on %s for %s"
-msgstr ""
-
-#: ref-filter.c:2156
-#, c-format
-msgid "malformed object at '%s'"
-msgstr ""
-
-#: ref-filter.c:2246
-#, c-format
-msgid "ignoring ref with broken name %s"
-msgstr ""
-
-#: ref-filter.c:2251 refs.c:672
-#, c-format
-msgid "ignoring broken ref %s"
-msgstr ""
-
-#: ref-filter.c:2630
-#, c-format
-msgid "format: %%(end) atom missing"
-msgstr ""
-
-#: ref-filter.c:2741
-#, c-format
-msgid "malformed object name %s"
-msgstr ""
-
-#: ref-filter.c:2746
-#, c-format
-msgid "option `%s' must point to a commit"
-msgstr ""
-
-#: reflog.c:407
-#, c-format
-msgid "not a reflog: %s"
-msgstr ""
-
-#: reflog.c:410
-#, c-format
-msgid "no reflog for '%s'"
-msgstr ""
-
-#: refs.c:262
-#, c-format
-msgid "%s does not point to a valid object!"
-msgstr ""
-
-#: refs.c:561
-#, c-format
-msgid ""
-"Using '%s' as the name for the initial branch. This default branch name\n"
-"is subject to change. To configure the initial branch name to use in all\n"
-"of your new repositories, which will suppress this warning, call:\n"
-"\n"
-"\tgit config --global init.defaultBranch <name>\n"
-"\n"
-"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n"
-"'development'. The just-created branch can be renamed via this command:\n"
-"\n"
-"\tgit branch -m <name>\n"
-msgstr ""
-
-#: refs.c:583
-#, c-format
-msgid "could not retrieve `%s`"
-msgstr ""
-
-#: refs.c:593
-#, c-format
-msgid "invalid branch name: %s = %s"
-msgstr ""
-
-#: refs.c:670
-#, c-format
-msgid "ignoring dangling symref %s"
-msgstr ""
-
-#: refs.c:919
-#, c-format
-msgid "log for ref %s has gap after %s"
-msgstr ""
-
-#: refs.c:926
-#, c-format
-msgid "log for ref %s unexpectedly ended on %s"
-msgstr ""
-
-#: refs.c:991
-#, c-format
-msgid "log for %s is empty"
-msgstr ""
-
-#: refs.c:1086
-#, c-format
-msgid "refusing to update ref with bad name '%s'"
-msgstr ""
-
-#: refs.c:1164
-#, c-format
-msgid "update_ref failed for ref '%s': %s"
-msgstr ""
-
-#: refs.c:2059
-#, c-format
-msgid "multiple updates for ref '%s' not allowed"
-msgstr ""
-
-#: refs.c:2145
-msgid "ref updates forbidden inside quarantine environment"
-msgstr ""
-
-#: refs.c:2156
-msgid "ref updates aborted by hook"
-msgstr ""
-
-#: refs.c:2264 refs.c:2294
-#, c-format
-msgid "'%s' exists; cannot create '%s'"
-msgstr ""
-
-#: refs.c:2270 refs.c:2305
-#, c-format
-msgid "cannot process '%s' and '%s' at the same time"
-msgstr ""
-
-#: refs/files-backend.c:1295
-#, c-format
-msgid "could not remove reference %s"
-msgstr ""
-
-#: refs/files-backend.c:1310 refs/packed-backend.c:1565
-#: refs/packed-backend.c:1575
-#, c-format
-msgid "could not delete reference %s: %s"
-msgstr ""
-
-#: refs/files-backend.c:1313 refs/packed-backend.c:1578
-#, c-format
-msgid "could not delete references: %s"
-msgstr ""
-
-#: refspec.c:170
-#, c-format
-msgid "invalid refspec '%s'"
-msgstr ""
-
-#: remote.c:402
-#, c-format
-msgid "config remote shorthand cannot begin with '/': %s"
-msgstr ""
-
-#: remote.c:450
-msgid "more than one receivepack given, using the first"
-msgstr ""
-
-#: remote.c:458
-msgid "more than one uploadpack given, using the first"
-msgstr ""
-
-#: remote.c:698
-#, c-format
-msgid "Cannot fetch both %s and %s to %s"
-msgstr ""
-
-#: remote.c:702
-#, c-format
-msgid "%s usually tracks %s, not %s"
-msgstr ""
-
-#: remote.c:706
-#, c-format
-msgid "%s tracks both %s and %s"
-msgstr ""
-
-#: remote.c:774
-#, c-format
-msgid "key '%s' of pattern had no '*'"
-msgstr ""
-
-#: remote.c:784
-#, c-format
-msgid "value '%s' of pattern has no '*'"
-msgstr ""
-
-#: remote.c:1191
-#, c-format
-msgid "src refspec %s does not match any"
-msgstr ""
-
-#: remote.c:1196
-#, c-format
-msgid "src refspec %s matches more than one"
-msgstr ""
-
-#. TRANSLATORS: "matches '%s'%" is the <dst> part of "git push
-#. <remote> <src>:<dst>" push, and "being pushed ('%s')" is
-#. the <src>.
-#.
-#: remote.c:1211
-#, c-format
-msgid ""
-"The destination you provided is not a full refname (i.e.,\n"
-"starting with \"refs/\"). We tried to guess what you meant by:\n"
-"\n"
-"- Looking for a ref that matches '%s' on the remote side.\n"
-"- Checking if the <src> being pushed ('%s')\n"
-"  is a ref in \"refs/{heads,tags}/\". If so we add a corresponding\n"
-"  refs/{heads,tags}/ prefix on the remote side.\n"
-"\n"
-"Neither worked, so we gave up. You must fully qualify the ref."
-msgstr ""
-
-#: remote.c:1231
-#, c-format
-msgid ""
-"The <src> part of the refspec is a commit object.\n"
-"Did you mean to create a new branch by pushing to\n"
-"'%s:refs/heads/%s'?"
-msgstr ""
-
-#: remote.c:1236
-#, c-format
-msgid ""
-"The <src> part of the refspec is a tag object.\n"
-"Did you mean to create a new tag by pushing to\n"
-"'%s:refs/tags/%s'?"
-msgstr ""
-
-#: remote.c:1241
-#, c-format
-msgid ""
-"The <src> part of the refspec is a tree object.\n"
-"Did you mean to tag a new tree by pushing to\n"
-"'%s:refs/tags/%s'?"
-msgstr ""
-
-#: remote.c:1246
-#, c-format
-msgid ""
-"The <src> part of the refspec is a blob object.\n"
-"Did you mean to tag a new blob by pushing to\n"
-"'%s:refs/tags/%s'?"
-msgstr ""
-
-#: remote.c:1282
-#, c-format
-msgid "%s cannot be resolved to branch"
-msgstr ""
-
-#: remote.c:1293
-#, c-format
-msgid "unable to delete '%s': remote ref does not exist"
-msgstr ""
-
-#: remote.c:1305
-#, c-format
-msgid "dst refspec %s matches more than one"
-msgstr ""
-
-#: remote.c:1312
-#, c-format
-msgid "dst ref %s receives from more than one src"
-msgstr ""
-
-#: remote.c:1833 remote.c:1940
-msgid "HEAD does not point to a branch"
-msgstr ""
-
-#: remote.c:1842
-#, c-format
-msgid "no such branch: '%s'"
-msgstr ""
-
-#: remote.c:1845
-#, c-format
-msgid "no upstream configured for branch '%s'"
-msgstr ""
-
-#: remote.c:1851
-#, c-format
-msgid "upstream branch '%s' not stored as a remote-tracking branch"
-msgstr ""
-
-#: remote.c:1866
-#, c-format
-msgid "push destination '%s' on remote '%s' has no local tracking branch"
-msgstr ""
-
-#: remote.c:1881
-#, c-format
-msgid "branch '%s' has no remote for pushing"
-msgstr ""
-
-#: remote.c:1891
-#, c-format
-msgid "push refspecs for '%s' do not include '%s'"
-msgstr ""
-
-#: remote.c:1904
-msgid "push has no destination (push.default is 'nothing')"
-msgstr ""
-
-#: remote.c:1926
-msgid "cannot resolve 'simple' push to a single destination"
-msgstr ""
-
-#: remote.c:2059
-#, c-format
-msgid "couldn't find remote ref %s"
-msgstr ""
-
-#: remote.c:2072
-#, c-format
-msgid "* Ignoring funny ref '%s' locally"
-msgstr ""
-
-#: remote.c:2235
-#, c-format
-msgid "Your branch is based on '%s', but the upstream is gone.\n"
-msgstr ""
-
-#: remote.c:2239
-msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
-msgstr ""
-
-#: remote.c:2242
-#, c-format
-msgid "Your branch is up to date with '%s'.\n"
-msgstr ""
-
-#: remote.c:2246
-#, c-format
-msgid "Your branch and '%s' refer to different commits.\n"
-msgstr ""
-
-#: remote.c:2249
-#, c-format
-msgid "  (use \"%s\" for details)\n"
-msgstr ""
-
-#: remote.c:2253
-#, c-format
-msgid "Your branch is ahead of '%s' by %d commit.\n"
-msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: remote.c:2259
-msgid "  (use \"git push\" to publish your local commits)\n"
-msgstr ""
-
-#: remote.c:2262
-#, c-format
-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] ""
-msgstr[1] ""
-
-#: remote.c:2270
-msgid "  (use \"git pull\" to update your local branch)\n"
-msgstr ""
-
-#: remote.c:2273
-#, c-format
-msgid ""
-"Your branch and '%s' have diverged,\n"
-"and have %d and %d different commit each, respectively.\n"
-msgid_plural ""
-"Your branch and '%s' have diverged,\n"
-"and have %d and %d different commits each, respectively.\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: remote.c:2283
-msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
-msgstr ""
-
-#: remote.c:2475
-#, c-format
-msgid "cannot parse expected object name '%s'"
-msgstr ""
-
-#: replace-object.c:21
-#, c-format
-msgid "bad replace ref name: %s"
-msgstr ""
-
-#: replace-object.c:30
-#, c-format
-msgid "duplicate replace ref: %s"
-msgstr ""
-
-#: replace-object.c:82
-#, c-format
-msgid "replace depth too high for object %s"
-msgstr ""
-
-#: rerere.c:201 rerere.c:210 rerere.c:213
-msgid "corrupt MERGE_RR"
-msgstr ""
-
-#: rerere.c:248 rerere.c:253
-msgid "unable to write rerere record"
-msgstr ""
-
-#: rerere.c:479
-#, c-format
-msgid "there were errors while writing '%s' (%s)"
-msgstr ""
-
-#: rerere.c:482 builtin/gc.c:2263 builtin/gc.c:2298
-#, c-format
-msgid "failed to flush '%s'"
-msgstr ""
-
-#: rerere.c:487 rerere.c:1024
-#, c-format
-msgid "could not parse conflict hunks in '%s'"
-msgstr ""
-
-#: rerere.c:669
-#, c-format
-msgid "failed utime() on '%s'"
-msgstr ""
-
-#: rerere.c:679
-#, c-format
-msgid "writing '%s' failed"
-msgstr ""
-
-#: rerere.c:699
-#, c-format
-msgid "Staged '%s' using previous resolution."
-msgstr ""
-
-#: rerere.c:738
-#, c-format
-msgid "Recorded resolution for '%s'."
-msgstr ""
-
-#: rerere.c:773
-#, c-format
-msgid "Resolved '%s' using previous resolution."
-msgstr ""
-
-#: rerere.c:788
-#, c-format
-msgid "cannot unlink stray '%s'"
-msgstr ""
-
-#: rerere.c:792
-#, c-format
-msgid "Recorded preimage for '%s'"
-msgstr ""
-
-#: rerere.c:866 submodule.c:2290 builtin/log.c:2042
-#: builtin/submodule--helper.c:1786 builtin/submodule--helper.c:1833
-#, c-format
-msgid "could not create directory '%s'"
-msgstr ""
-
-#: rerere.c:1042
-#, c-format
-msgid "failed to update conflicted state in '%s'"
-msgstr ""
-
-#: rerere.c:1053 rerere.c:1060
-#, c-format
-msgid "no remembered resolution for '%s'"
-msgstr ""
-
-#: rerere.c:1062
-#, c-format
-msgid "cannot unlink '%s'"
-msgstr ""
-
-#: rerere.c:1072
-#, c-format
-msgid "Updated preimage for '%s'"
-msgstr ""
-
-#: rerere.c:1081
-#, c-format
-msgid "Forgot resolution for '%s'\n"
-msgstr ""
-
-#: rerere.c:1192
-msgid "unable to open rr-cache directory"
-msgstr ""
-
-#: reset.c:112
-msgid "could not determine HEAD revision"
-msgstr ""
-
-#: reset.c:141 reset.c:147 sequencer.c:3696
-#, c-format
-msgid "failed to find tree of %s"
-msgstr ""
-
-#: revision.c:2358
-msgid "--unpacked=<packfile> no longer supported"
-msgstr ""
-
-#: revision.c:2712
-msgid "your current branch appears to be broken"
-msgstr ""
-
-#: revision.c:2715
-#, c-format
-msgid "your current branch '%s' does not have any commits yet"
-msgstr ""
-
-#: revision.c:2901
-msgid "object filtering requires --objects"
-msgstr ""
-
-#: revision.c:2918
-msgid "-L does not yet support diff formats besides -p and -s"
-msgstr ""
-
-#: run-command.c:1262
-#, c-format
-msgid "cannot create async thread: %s"
-msgstr ""
-
-#: send-pack.c:150
-msgid "unexpected flush packet while reading remote unpack status"
-msgstr ""
-
-#: send-pack.c:152
-#, c-format
-msgid "unable to parse remote unpack status: %s"
-msgstr ""
-
-#: send-pack.c:154
-#, c-format
-msgid "remote unpack failed: %s"
-msgstr ""
-
-#: send-pack.c:378
-msgid "failed to sign the push certificate"
-msgstr ""
-
-#: send-pack.c:435
-msgid "send-pack: unable to fork off fetch subprocess"
-msgstr ""
-
-#: send-pack.c:457
-msgid "push negotiation failed; proceeding anyway with push"
-msgstr ""
-
-#: send-pack.c:528
-msgid "the receiving end does not support this repository's hash algorithm"
-msgstr ""
-
-#: send-pack.c:537
-msgid "the receiving end does not support --signed push"
-msgstr ""
-
-#: send-pack.c:539
-msgid ""
-"not sending a push certificate since the receiving end does not support --"
-"signed push"
-msgstr ""
-
-#: send-pack.c:546
-msgid "the receiving end does not support --atomic push"
-msgstr ""
-
-#: send-pack.c:551
-msgid "the receiving end does not support push options"
-msgstr ""
-
-#: sequencer.c:197
-#, c-format
-msgid "invalid commit message cleanup mode '%s'"
-msgstr ""
-
-#: sequencer.c:325
-#, c-format
-msgid "could not delete '%s'"
-msgstr ""
-
-#: sequencer.c:345 sequencer.c:4724 builtin/rebase.c:564 builtin/rebase.c:1326
-#: builtin/rm.c:409
-#, c-format
-msgid "could not remove '%s'"
-msgstr ""
-
-#: sequencer.c:355
-msgid "revert"
-msgstr ""
-
-#: sequencer.c:357
-msgid "cherry-pick"
-msgstr ""
-
-#: sequencer.c:359
-msgid "rebase"
-msgstr ""
-
-#: sequencer.c:361
-#, c-format
-msgid "unknown action: %d"
-msgstr ""
-
-#: sequencer.c:420
-msgid ""
-"after resolving the conflicts, mark the corrected paths\n"
-"with 'git add <paths>' or 'git rm <paths>'"
-msgstr ""
-
-#: sequencer.c:423
-msgid ""
-"After resolving the conflicts, mark them with\n"
-"\"git add/rm <pathspec>\", then run\n"
-"\"git cherry-pick --continue\".\n"
-"You can instead skip this commit with \"git cherry-pick --skip\".\n"
-"To abort and get back to the state before \"git cherry-pick\",\n"
-"run \"git cherry-pick --abort\"."
-msgstr ""
-
-#: sequencer.c:430
-msgid ""
-"After resolving the conflicts, mark them with\n"
-"\"git add/rm <pathspec>\", then run\n"
-"\"git revert --continue\".\n"
-"You can instead skip this commit with \"git revert --skip\".\n"
-"To abort and get back to the state before \"git revert\",\n"
-"run \"git revert --abort\"."
-msgstr ""
-
-#: sequencer.c:448 sequencer.c:3288
-#, c-format
-msgid "could not lock '%s'"
-msgstr ""
-
-#: sequencer.c:450 sequencer.c:3087 sequencer.c:3292 sequencer.c:3306
-#: sequencer.c:3557 sequencer.c:5591 strbuf.c:1189 wrapper.c:715
-#, c-format
-msgid "could not write to '%s'"
-msgstr ""
-
-#: sequencer.c:455
-#, c-format
-msgid "could not write eol to '%s'"
-msgstr ""
-
-#: sequencer.c:460 sequencer.c:3092 sequencer.c:3294 sequencer.c:3308
-#: sequencer.c:3565
-#, c-format
-msgid "failed to finalize '%s'"
-msgstr ""
-
-#: sequencer.c:473 sequencer.c:1930 sequencer.c:3112 sequencer.c:3547
-#: sequencer.c:3675 builtin/am.c:290 builtin/commit.c:837 builtin/merge.c:1154
-#, c-format
-msgid "could not read '%s'"
-msgstr ""
-
-#: sequencer.c:499
-#, c-format
-msgid "your local changes would be overwritten by %s."
-msgstr ""
-
-#: sequencer.c:503
-msgid "commit your changes or stash them to proceed."
-msgstr ""
-
-#: sequencer.c:535
-#, c-format
-msgid "%s: fast-forward"
-msgstr ""
-
-#: sequencer.c:574 builtin/tag.c:615
-#, c-format
-msgid "Invalid cleanup mode %s"
-msgstr ""
-
-#. TRANSLATORS: %s will be "revert", "cherry-pick" or
-#. "rebase".
-#.
-#: sequencer.c:685
-#, c-format
-msgid "%s: Unable to write new index file"
-msgstr ""
-
-#: sequencer.c:699
-msgid "unable to update cache tree"
-msgstr ""
-
-#: sequencer.c:713
-msgid "could not resolve HEAD commit"
-msgstr ""
-
-#: sequencer.c:793
-#, c-format
-msgid "no key present in '%.*s'"
-msgstr ""
-
-#: sequencer.c:804
-#, c-format
-msgid "unable to dequote value of '%s'"
-msgstr ""
-
-#: sequencer.c:841 wrapper.c:219 wrapper.c:389 builtin/am.c:757
-#: builtin/am.c:849 builtin/rebase.c:699
-#, c-format
-msgid "could not open '%s' for reading"
-msgstr ""
-
-#: sequencer.c:851
-msgid "'GIT_AUTHOR_NAME' already given"
-msgstr ""
-
-#: sequencer.c:856
-msgid "'GIT_AUTHOR_EMAIL' already given"
-msgstr ""
-
-#: sequencer.c:861
-msgid "'GIT_AUTHOR_DATE' already given"
-msgstr ""
-
-#: sequencer.c:865
-#, c-format
-msgid "unknown variable '%s'"
-msgstr ""
-
-#: sequencer.c:870
-msgid "missing 'GIT_AUTHOR_NAME'"
-msgstr ""
-
-#: sequencer.c:872
-msgid "missing 'GIT_AUTHOR_EMAIL'"
-msgstr ""
-
-#: sequencer.c:874
-msgid "missing 'GIT_AUTHOR_DATE'"
-msgstr ""
-
-#: sequencer.c:939
-#, c-format
-msgid ""
-"you have staged changes in your working tree\n"
-"If these changes are meant to be squashed into the previous commit, run:\n"
-"\n"
-"  git commit --amend %s\n"
-"\n"
-"If they are meant to go into a new commit, run:\n"
-"\n"
-"  git commit %s\n"
-"\n"
-"In both cases, once you're done, continue with:\n"
-"\n"
-"  git rebase --continue\n"
-msgstr ""
-
-#: sequencer.c:1225
-msgid "'prepare-commit-msg' hook failed"
-msgstr ""
-
-#: sequencer.c:1231
-msgid ""
-"Your name and email address were configured automatically based\n"
-"on your username and hostname. Please check that they are accurate.\n"
-"You can suppress this message by setting them explicitly. Run the\n"
-"following command and follow the instructions in your editor to edit\n"
-"your configuration file:\n"
-"\n"
-"    git config --global --edit\n"
-"\n"
-"After doing this, you may fix the identity used for this commit with:\n"
-"\n"
-"    git commit --amend --reset-author\n"
-msgstr ""
-
-#: sequencer.c:1244
-msgid ""
-"Your name and email address were configured automatically based\n"
-"on your username and hostname. Please check that they are accurate.\n"
-"You can suppress this message by setting them explicitly:\n"
-"\n"
-"    git config --global user.name \"Your Name\"\n"
-"    git config --global user.email you@example.com\n"
-"\n"
-"After doing this, you may fix the identity used for this commit with:\n"
-"\n"
-"    git commit --amend --reset-author\n"
-msgstr ""
-
-#: sequencer.c:1287
-msgid "couldn't look up newly created commit"
-msgstr ""
-
-#: sequencer.c:1289
-msgid "could not parse newly created commit"
-msgstr ""
-
-#: sequencer.c:1336
-msgid "unable to resolve HEAD after creating commit"
-msgstr ""
-
-#: sequencer.c:1338
-msgid "detached HEAD"
-msgstr ""
-
-#: sequencer.c:1342
-msgid " (root-commit)"
-msgstr ""
-
-#: sequencer.c:1363
-msgid "could not parse HEAD"
-msgstr ""
-
-#: sequencer.c:1365
-#, c-format
-msgid "HEAD %s is not a commit!"
-msgstr ""
-
-#: sequencer.c:1369 sequencer.c:1447 builtin/commit.c:1707
-msgid "could not parse HEAD commit"
-msgstr ""
-
-#: sequencer.c:1425 sequencer.c:2310
-msgid "unable to parse commit author"
-msgstr ""
-
-#: sequencer.c:1436 builtin/am.c:1644 builtin/merge.c:710
-msgid "git write-tree failed to write a tree"
-msgstr ""
-
-#: sequencer.c:1469 sequencer.c:1589
-#, c-format
-msgid "unable to read commit message from '%s'"
-msgstr ""
-
-#: sequencer.c:1500 sequencer.c:1532
-#, c-format
-msgid "invalid author identity '%s'"
-msgstr ""
-
-#: sequencer.c:1506
-msgid "corrupt author: missing date information"
-msgstr ""
-
-#: sequencer.c:1545 builtin/am.c:1671 builtin/commit.c:1821 builtin/merge.c:921
-#: builtin/merge.c:946 t/helper/test-fast-rebase.c:78
-msgid "failed to write commit object"
-msgstr ""
-
-#: sequencer.c:1572 sequencer.c:4496 t/helper/test-fast-rebase.c:199
-#: t/helper/test-fast-rebase.c:217
-#, c-format
-msgid "could not update %s"
-msgstr ""
-
-#: sequencer.c:1621
-#, c-format
-msgid "could not parse commit %s"
-msgstr ""
-
-#: sequencer.c:1626
-#, c-format
-msgid "could not parse parent commit %s"
-msgstr ""
-
-#: sequencer.c:1709 sequencer.c:1990
-#, c-format
-msgid "unknown command: %d"
-msgstr ""
-
-#: sequencer.c:1751
-msgid "This is the 1st commit message:"
-msgstr ""
-
-#: sequencer.c:1752
-#, c-format
-msgid "This is the commit message #%d:"
-msgstr ""
-
-#: sequencer.c:1753
-msgid "The 1st commit message will be skipped:"
-msgstr ""
-
-#: sequencer.c:1754
-#, c-format
-msgid "The commit message #%d will be skipped:"
-msgstr ""
-
-#: sequencer.c:1755
-#, c-format
-msgid "This is a combination of %d commits."
-msgstr ""
-
-#: sequencer.c:1902 sequencer.c:1959
-#, c-format
-msgid "cannot write '%s'"
-msgstr ""
-
-#: sequencer.c:1949
-msgid "need a HEAD to fixup"
-msgstr ""
-
-#: sequencer.c:1951 sequencer.c:3592
-msgid "could not read HEAD"
-msgstr ""
-
-#: sequencer.c:1953
-msgid "could not read HEAD's commit message"
-msgstr ""
-
-#: sequencer.c:1977
-#, c-format
-msgid "could not read commit message of %s"
-msgstr ""
-
-#: sequencer.c:2087
-msgid "your index file is unmerged."
-msgstr ""
-
-#: sequencer.c:2094
-msgid "cannot fixup root commit"
-msgstr ""
-
-#: sequencer.c:2113
-#, c-format
-msgid "commit %s is a merge but no -m option was given."
-msgstr ""
-
-#: sequencer.c:2121 sequencer.c:2129
-#, c-format
-msgid "commit %s does not have parent %d"
-msgstr ""
-
-#: sequencer.c:2135
-#, c-format
-msgid "cannot get commit message for %s"
-msgstr ""
-
-#. TRANSLATORS: The first %s will be a "todo" command like
-#. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:2154
-#, c-format
-msgid "%s: cannot parse parent commit %s"
-msgstr ""
-
-#: sequencer.c:2220
-#, c-format
-msgid "could not rename '%s' to '%s'"
-msgstr ""
-
-#: sequencer.c:2280
-#, c-format
-msgid "could not revert %s... %s"
-msgstr ""
-
-#: sequencer.c:2281
-#, c-format
-msgid "could not apply %s... %s"
-msgstr ""
-
-#: sequencer.c:2302
-#, c-format
-msgid "dropping %s %s -- patch contents already upstream\n"
-msgstr ""
-
-#: sequencer.c:2360
-#, c-format
-msgid "git %s: failed to read the index"
-msgstr ""
-
-#: sequencer.c:2368
-#, c-format
-msgid "git %s: failed to refresh the index"
-msgstr ""
-
-#: sequencer.c:2448
-#, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr ""
-
-#: sequencer.c:2457
-#, c-format
-msgid "missing arguments for %s"
-msgstr ""
-
-#: sequencer.c:2500
-#, c-format
-msgid "could not parse '%s'"
-msgstr ""
-
-#: sequencer.c:2561
-#, c-format
-msgid "invalid line %d: %.*s"
-msgstr ""
-
-#: sequencer.c:2572
-#, c-format
-msgid "cannot '%s' without a previous commit"
-msgstr ""
-
-#: sequencer.c:2620 builtin/rebase.c:185
-#, c-format
-msgid "could not read '%s'."
-msgstr ""
-
-#: sequencer.c:2658
-msgid "cancelling a cherry picking in progress"
-msgstr ""
-
-#: sequencer.c:2667
-msgid "cancelling a revert in progress"
-msgstr ""
-
-#: sequencer.c:2707
-msgid "please fix this using 'git rebase --edit-todo'."
-msgstr ""
-
-#: sequencer.c:2709
-#, c-format
-msgid "unusable instruction sheet: '%s'"
-msgstr ""
-
-#: sequencer.c:2714
-msgid "no commits parsed."
-msgstr ""
-
-#: sequencer.c:2725
-msgid "cannot cherry-pick during a revert."
-msgstr ""
-
-#: sequencer.c:2727
-msgid "cannot revert during a cherry-pick."
-msgstr ""
-
-#: sequencer.c:2914
-msgid "unusable squash-onto"
-msgstr ""
-
-#: sequencer.c:2934
-#, c-format
-msgid "malformed options sheet: '%s'"
-msgstr ""
-
-#: sequencer.c:3029 sequencer.c:4875
-msgid "empty commit set passed"
-msgstr ""
-
-#: sequencer.c:3046
-msgid "revert is already in progress"
-msgstr ""
-
-#: sequencer.c:3048
-#, c-format
-msgid "try \"git revert (--continue | %s--abort | --quit)\""
-msgstr ""
-
-#: sequencer.c:3051
-msgid "cherry-pick is already in progress"
-msgstr ""
-
-#: sequencer.c:3053
-#, c-format
-msgid "try \"git cherry-pick (--continue | %s--abort | --quit)\""
-msgstr ""
-
-#: sequencer.c:3067
-#, c-format
-msgid "could not create sequencer directory '%s'"
-msgstr ""
-
-#: sequencer.c:3082
-msgid "could not lock HEAD"
-msgstr ""
-
-#: sequencer.c:3142 sequencer.c:4585
-msgid "no cherry-pick or revert in progress"
-msgstr ""
-
-#: sequencer.c:3144 sequencer.c:3155
-msgid "cannot resolve HEAD"
-msgstr ""
-
-#: sequencer.c:3146 sequencer.c:3190
-msgid "cannot abort from a branch yet to be born"
-msgstr ""
-
-#: sequencer.c:3176 builtin/fetch.c:1030 builtin/fetch.c:1457
-#: builtin/grep.c:774
-#, c-format
-msgid "cannot open '%s'"
-msgstr ""
-
-#: sequencer.c:3178
-#, c-format
-msgid "cannot read '%s': %s"
-msgstr ""
-
-#: sequencer.c:3179
-msgid "unexpected end of file"
-msgstr ""
-
-#: sequencer.c:3185
-#, c-format
-msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
-msgstr ""
-
-#: sequencer.c:3196
-msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
-msgstr ""
-
-#: sequencer.c:3237
-msgid "no revert in progress"
-msgstr ""
-
-#: sequencer.c:3246
-msgid "no cherry-pick in progress"
-msgstr ""
-
-#: sequencer.c:3256
-msgid "failed to skip the commit"
-msgstr ""
-
-#: sequencer.c:3263
-msgid "there is nothing to skip"
-msgstr ""
-
-#: sequencer.c:3266
-#, c-format
-msgid ""
-"have you committed already?\n"
-"try \"git %s --continue\""
-msgstr ""
-
-#: sequencer.c:3428 sequencer.c:4476
-msgid "cannot read HEAD"
-msgstr ""
-
-#: sequencer.c:3445
-#, c-format
-msgid "unable to copy '%s' to '%s'"
-msgstr ""
-
-#: sequencer.c:3453
-#, c-format
-msgid ""
-"You can amend the commit now, with\n"
-"\n"
-"  git commit --amend %s\n"
-"\n"
-"Once you are satisfied with your changes, run\n"
-"\n"
-"  git rebase --continue\n"
-msgstr ""
-
-#: sequencer.c:3463
-#, c-format
-msgid "Could not apply %s... %.*s"
-msgstr ""
-
-#: sequencer.c:3470
-#, c-format
-msgid "Could not merge %.*s"
-msgstr ""
-
-#: sequencer.c:3484 sequencer.c:3488 builtin/difftool.c:633
-#, c-format
-msgid "could not copy '%s' to '%s'"
-msgstr ""
-
-#: sequencer.c:3499
-#, c-format
-msgid "Executing: %s\n"
-msgstr ""
-
-#: sequencer.c:3510
-#, c-format
-msgid ""
-"execution failed: %s\n"
-"%sYou can fix the problem, and then run\n"
-"\n"
-"  git rebase --continue\n"
-"\n"
-msgstr ""
-
-#: sequencer.c:3516
-msgid "and made changes to the index and/or the working tree\n"
-msgstr ""
-
-#: sequencer.c:3522
-#, c-format
-msgid ""
-"execution succeeded: %s\n"
-"but left changes to the index and/or the working tree\n"
-"Commit or stash your changes, and then run\n"
-"\n"
-"  git rebase --continue\n"
-"\n"
-msgstr ""
-
-#: sequencer.c:3582
-#, c-format
-msgid "illegal label name: '%.*s'"
-msgstr ""
-
-#: sequencer.c:3655
-msgid "writing fake root commit"
-msgstr ""
-
-#: sequencer.c:3660
-msgid "writing squash-onto"
-msgstr ""
-
-#: sequencer.c:3739
-#, c-format
-msgid "could not resolve '%s'"
-msgstr ""
-
-#: sequencer.c:3771
-msgid "cannot merge without a current revision"
-msgstr ""
-
-#: sequencer.c:3793
-#, c-format
-msgid "unable to parse '%.*s'"
-msgstr ""
-
-#: sequencer.c:3802
-#, c-format
-msgid "nothing to merge: '%.*s'"
-msgstr ""
-
-#: sequencer.c:3814
-msgid "octopus merge cannot be executed on top of a [new root]"
-msgstr ""
-
-#: sequencer.c:3869
-#, c-format
-msgid "could not get commit message of '%s'"
-msgstr ""
-
-#: sequencer.c:4013
-#, c-format
-msgid "could not even attempt to merge '%.*s'"
-msgstr ""
-
-#: sequencer.c:4029
-msgid "merge: Unable to write new index file"
-msgstr ""
-
-#: sequencer.c:4110
-msgid "Cannot autostash"
-msgstr ""
-
-#: sequencer.c:4113
-#, c-format
-msgid "Unexpected stash response: '%s'"
-msgstr ""
-
-#: sequencer.c:4119
-#, c-format
-msgid "Could not create directory for '%s'"
-msgstr ""
-
-#: sequencer.c:4122
-#, c-format
-msgid "Created autostash: %s\n"
-msgstr ""
-
-#: sequencer.c:4124
-msgid "could not reset --hard"
-msgstr ""
-
-#: sequencer.c:4148
-#, c-format
-msgid "Applied autostash.\n"
-msgstr ""
-
-#: sequencer.c:4160
-#, c-format
-msgid "cannot store %s"
-msgstr ""
-
-#: sequencer.c:4163
-#, c-format
-msgid ""
-"%s\n"
-"Your changes are safe in the stash.\n"
-"You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
-msgstr ""
-
-#: sequencer.c:4168
-msgid "Applying autostash resulted in conflicts."
-msgstr ""
-
-#: sequencer.c:4169
-msgid "Autostash exists; creating a new stash entry."
-msgstr ""
-
-#: sequencer.c:4225
-msgid "could not detach HEAD"
-msgstr ""
-
-#: sequencer.c:4240
-#, c-format
-msgid "Stopped at HEAD\n"
-msgstr ""
-
-#: sequencer.c:4242
-#, c-format
-msgid "Stopped at %s\n"
-msgstr ""
-
-#: sequencer.c:4274
-#, c-format
-msgid ""
-"Could not execute the todo command\n"
-"\n"
-"    %.*s\n"
-"It has been rescheduled; To edit the command before continuing, please\n"
-"edit the todo list first:\n"
-"\n"
-"    git rebase --edit-todo\n"
-"    git rebase --continue\n"
-msgstr ""
-
-#: sequencer.c:4320
-#, c-format
-msgid "Rebasing (%d/%d)%s"
-msgstr ""
-
-#: sequencer.c:4366
-#, c-format
-msgid "Stopped at %s...  %.*s\n"
-msgstr ""
-
-#: sequencer.c:4436
-#, c-format
-msgid "unknown command %d"
-msgstr ""
-
-#: sequencer.c:4484
-msgid "could not read orig-head"
-msgstr ""
-
-#: sequencer.c:4489
-msgid "could not read 'onto'"
-msgstr ""
-
-#: sequencer.c:4503
-#, c-format
-msgid "could not update HEAD to %s"
-msgstr ""
-
-#: sequencer.c:4563
-#, c-format
-msgid "Successfully rebased and updated %s.\n"
-msgstr ""
-
-#: sequencer.c:4615
-msgid "cannot rebase: You have unstaged changes."
-msgstr ""
-
-#: sequencer.c:4624
-msgid "cannot amend non-existing commit"
-msgstr ""
-
-#: sequencer.c:4626
-#, c-format
-msgid "invalid file: '%s'"
-msgstr ""
-
-#: sequencer.c:4628
-#, c-format
-msgid "invalid contents: '%s'"
-msgstr ""
-
-#: sequencer.c:4631
-msgid ""
-"\n"
-"You have uncommitted changes in your working tree. Please, commit them\n"
-"first and then run 'git rebase --continue' again."
-msgstr ""
-
-#: sequencer.c:4667 sequencer.c:4706
-#, c-format
-msgid "could not write file: '%s'"
-msgstr ""
-
-#: sequencer.c:4722
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr ""
-
-#: sequencer.c:4732
-msgid "could not commit staged changes."
-msgstr ""
-
-#: sequencer.c:4852
-#, c-format
-msgid "%s: can't cherry-pick a %s"
-msgstr ""
-
-#: sequencer.c:4856
-#, c-format
-msgid "%s: bad revision"
-msgstr ""
-
-#: sequencer.c:4891
-msgid "can't revert as initial commit"
-msgstr ""
-
-#: sequencer.c:5162 sequencer.c:5391
-#, c-format
-msgid "skipped previously applied commit %s"
-msgstr ""
-
-#: sequencer.c:5232 sequencer.c:5407
-msgid "use --reapply-cherry-picks to include skipped commits"
-msgstr ""
-
-#: sequencer.c:5378
-msgid "make_script: unhandled options"
-msgstr ""
-
-#: sequencer.c:5381
-msgid "make_script: error preparing revisions"
-msgstr ""
-
-#: sequencer.c:5639 sequencer.c:5656
-msgid "nothing to do"
-msgstr ""
-
-#: sequencer.c:5675
-msgid "could not skip unnecessary pick commands"
-msgstr ""
-
-#: sequencer.c:5775
-msgid "the script was already rearranged."
-msgstr ""
-
-#: setup.c:135
-#, c-format
-msgid "'%s' is outside repository at '%s'"
-msgstr ""
-
-#: setup.c:187
-#, c-format
-msgid ""
-"%s: no such path in the working tree.\n"
-"Use 'git <command> -- <path>...' to specify paths that do not exist locally."
-msgstr ""
-
-#: setup.c:200
-#, c-format
-msgid ""
-"ambiguous argument '%s': unknown revision or path not in the working tree.\n"
-"Use '--' to separate paths from revisions, like this:\n"
-"'git <command> [<revision>...] -- [<file>...]'"
-msgstr ""
-
-#: setup.c:266
-#, c-format
-msgid "option '%s' must come before non-option arguments"
-msgstr ""
-
-#: setup.c:285
-#, c-format
-msgid ""
-"ambiguous argument '%s': both revision and filename\n"
-"Use '--' to separate paths from revisions, like this:\n"
-"'git <command> [<revision>...] -- [<file>...]'"
-msgstr ""
-
-#: setup.c:421
-msgid "unable to set up work tree using invalid config"
-msgstr ""
-
-#: setup.c:425 builtin/rev-parse.c:895
-msgid "this operation must be run in a work tree"
-msgstr ""
-
-#: setup.c:724
-#, c-format
-msgid "Expected git repo version <= %d, found %d"
-msgstr ""
-
-#: setup.c:732
-msgid "unknown repository extension found:"
-msgid_plural "unknown repository extensions found:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: setup.c:746
-msgid "repo version is 0, but v1-only extension found:"
-msgid_plural "repo version is 0, but v1-only extensions found:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: setup.c:767
-#, c-format
-msgid "error opening '%s'"
-msgstr ""
-
-#: setup.c:769
-#, c-format
-msgid "too large to be a .git file: '%s'"
-msgstr ""
-
-#: setup.c:771
-#, c-format
-msgid "error reading %s"
-msgstr ""
-
-#: setup.c:773
-#, c-format
-msgid "invalid gitfile format: %s"
-msgstr ""
-
-#: setup.c:775
-#, c-format
-msgid "no path in gitfile: %s"
-msgstr ""
-
-#: setup.c:777
-#, c-format
-msgid "not a git repository: %s"
-msgstr ""
-
-#: setup.c:879
-#, c-format
-msgid "'$%s' too big"
-msgstr ""
-
-#: setup.c:893
-#, c-format
-msgid "not a git repository: '%s'"
-msgstr ""
-
-#: setup.c:922 setup.c:924 setup.c:955
-#, c-format
-msgid "cannot chdir to '%s'"
-msgstr ""
-
-#: setup.c:927 setup.c:983 setup.c:993 setup.c:1032 setup.c:1040
-msgid "cannot come back to cwd"
-msgstr ""
-
-#: setup.c:1054
-#, c-format
-msgid "failed to stat '%*s%s%s'"
-msgstr ""
-
-#: setup.c:1338
-msgid "Unable to read current working directory"
-msgstr ""
-
-#: setup.c:1347 setup.c:1353
-#, c-format
-msgid "cannot change to '%s'"
-msgstr ""
-
-#: setup.c:1358
-#, c-format
-msgid "not a git repository (or any of the parent directories): %s"
-msgstr ""
-
-#: setup.c:1364
-#, c-format
-msgid ""
-"not a git repository (or any parent up to mount point %s)\n"
-"Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."
-msgstr ""
-
-#: setup.c:1374
-#, c-format
-msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
-"\n"
-"\tgit config --global --add safe.directory %s"
-msgstr ""
-
-#: setup.c:1502
-#, c-format
-msgid ""
-"problem with core.sharedRepository filemode value (0%.3o).\n"
-"The owner of files must always have read and write permissions."
-msgstr ""
-
-#: setup.c:1564
-msgid "fork failed"
-msgstr ""
-
-#: setup.c:1569
-msgid "setsid failed"
-msgstr ""
-
-#: sparse-index.c:285
-#, c-format
-msgid "index entry is a directory, but not sparse (%08x)"
-msgstr ""
-
-#: split-index.c:9
-msgid "cannot use split index with a sparse index"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 gibibyte
-#: strbuf.c:851
-#, c-format
-msgid "%u.%2.2u GiB"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 gibibyte/second
-#: strbuf.c:853
-#, c-format
-msgid "%u.%2.2u GiB/s"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 mebibyte
-#: strbuf.c:861
-#, c-format
-msgid "%u.%2.2u MiB"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 mebibyte/second
-#: strbuf.c:863
-#, c-format
-msgid "%u.%2.2u MiB/s"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 kibibyte
-#: strbuf.c:870
-#, c-format
-msgid "%u.%2.2u KiB"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 kibibyte/second
-#: strbuf.c:872
-#, c-format
-msgid "%u.%2.2u KiB/s"
-msgstr ""
-
-#. TRANSLATORS: IEC 80000-13:2008 byte
-#: strbuf.c:878
-#, c-format
-msgid "%u byte"
-msgid_plural "%u bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#. TRANSLATORS: IEC 80000-13:2008 byte/second
-#: strbuf.c:880
-#, c-format
-msgid "%u byte/s"
-msgid_plural "%u bytes/s"
-msgstr[0] ""
-msgstr[1] ""
-
-#: strbuf.c:1187 wrapper.c:217 wrapper.c:387 builtin/am.c:766
-#: builtin/rebase.c:653
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr ""
-
-#: strbuf.c:1196
-#, c-format
-msgid "could not edit '%s'"
-msgstr ""
-
-#: submodule-config.c:238
-#, c-format
-msgid "ignoring suspicious submodule name: %s"
-msgstr ""
-
-#: submodule-config.c:305
-msgid "negative values not allowed for submodule.fetchjobs"
-msgstr ""
-
-#: submodule-config.c:403
-#, c-format
-msgid "ignoring '%s' which may be interpreted as a command-line option: %s"
-msgstr ""
-
-#: submodule-config.c:500 builtin/push.c:489 builtin/send-pack.c:148
-#, c-format
-msgid "invalid value for '%s'"
-msgstr ""
-
-#: submodule-config.c:828
-#, c-format
-msgid "Could not update .gitmodules entry %s"
-msgstr ""
-
-#: submodule.c:115 submodule.c:144
-msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
-msgstr ""
-
-#: submodule.c:119 submodule.c:148
-#, c-format
-msgid "Could not find section in .gitmodules where path=%s"
-msgstr ""
-
-#: submodule.c:155
-#, c-format
-msgid "Could not remove .gitmodules entry for %s"
-msgstr ""
-
-#: submodule.c:166
-msgid "staging updated .gitmodules failed"
-msgstr ""
-
-#: submodule.c:346
-#, c-format
-msgid "in unpopulated submodule '%s'"
-msgstr ""
-
-#: submodule.c:377
-#, c-format
-msgid "Pathspec '%s' is in submodule '%.*s'"
-msgstr ""
-
-#: submodule.c:454
-#, c-format
-msgid "bad --ignore-submodules argument: %s"
-msgstr ""
-
-#: submodule.c:866
-#, c-format
-msgid ""
-"Submodule in commit %s at path: '%s' collides with a submodule named the "
-"same. Skipping it."
-msgstr ""
-
-#: submodule.c:987
-#, c-format
-msgid "submodule entry '%s' (%s) is a %s, not a commit"
-msgstr ""
-
-#: submodule.c:1069
-#, c-format
-msgid ""
-"Could not run 'git rev-list <commits> --not --remotes -n 1' command in "
-"submodule %s"
-msgstr ""
-
-#: submodule.c:1192
-#, c-format
-msgid "process for submodule '%s' failed"
-msgstr ""
-
-#: submodule.c:1221 builtin/branch.c:714 builtin/submodule--helper.c:2827
-msgid "Failed to resolve HEAD as a valid ref."
-msgstr ""
-
-#: submodule.c:1232
-#, c-format
-msgid "Pushing submodule '%s'\n"
-msgstr ""
-
-#: submodule.c:1235
-#, c-format
-msgid "Unable to push submodule '%s'\n"
-msgstr ""
-
-#: submodule.c:1567
-#, c-format
-msgid "Fetching submodule %s%s\n"
-msgstr ""
-
-#: submodule.c:1589
-#, c-format
-msgid "Could not access submodule '%s'\n"
-msgstr ""
-
-#: submodule.c:1618
-#, c-format
-msgid "Could not access submodule '%s' at commit %s\n"
-msgstr ""
-
-#: submodule.c:1629
-#, c-format
-msgid "Fetching submodule %s%s at commit %s\n"
-msgstr ""
-
-#: submodule.c:1849
-#, c-format
-msgid ""
-"Errors during submodule fetch:\n"
-"%s"
-msgstr ""
-
-#: submodule.c:1874
-#, c-format
-msgid "'%s' not recognized as a git repository"
-msgstr ""
-
-#: submodule.c:1891
-#, c-format
-msgid "Could not run 'git status --porcelain=2' in submodule %s"
-msgstr ""
-
-#: submodule.c:1932
-#, c-format
-msgid "'git status --porcelain=2' failed in submodule %s"
-msgstr ""
-
-#: submodule.c:2007
-#, c-format
-msgid "could not start 'git status' in submodule '%s'"
-msgstr ""
-
-#: submodule.c:2020
-#, c-format
-msgid "could not run 'git status' in submodule '%s'"
-msgstr ""
-
-#: submodule.c:2037
-#, c-format
-msgid "Could not unset core.worktree setting in submodule '%s'"
-msgstr ""
-
-#: submodule.c:2064 submodule.c:2379
-#, c-format
-msgid "could not recurse into submodule '%s'"
-msgstr ""
-
-#: submodule.c:2086
-msgid "could not reset submodule index"
-msgstr ""
-
-#: submodule.c:2128
-#, c-format
-msgid "submodule '%s' has dirty index"
-msgstr ""
-
-#: submodule.c:2182
-#, c-format
-msgid "Submodule '%s' could not be updated."
-msgstr ""
-
-#: submodule.c:2250
-#, c-format
-msgid "submodule git dir '%s' is inside git dir '%.*s'"
-msgstr ""
-
-#: submodule.c:2271
-#, c-format
-msgid ""
-"relocate_gitdir for submodule '%s' with more than one worktree not supported"
-msgstr ""
-
-#: submodule.c:2283 submodule.c:2343
-#, c-format
-msgid "could not lookup name for submodule '%s'"
-msgstr ""
-
-#: submodule.c:2287
-#, c-format
-msgid "refusing to move '%s' into an existing git dir"
-msgstr ""
-
-#: submodule.c:2293
-#, c-format
-msgid ""
-"Migrating git directory of '%s%s' from\n"
-"'%s' to\n"
-"'%s'\n"
-msgstr ""
-
-#: submodule.c:2424
-msgid "could not start ls-files in .."
-msgstr ""
-
-#: submodule.c:2464
-#, c-format
-msgid "ls-tree returned unexpected return code %d"
-msgstr ""
-
-#: symlinks.c:244
-#, c-format
-msgid "failed to lstat '%s'"
-msgstr ""
-
-#: trailer.c:244
-#, c-format
-msgid "running trailer command '%s' failed"
-msgstr ""
-
-#: trailer.c:493 trailer.c:498 trailer.c:503 trailer.c:562 trailer.c:566
-#: trailer.c:570
-#, c-format
-msgid "unknown value '%s' for key '%s'"
-msgstr ""
-
-#: trailer.c:547 trailer.c:552 trailer.c:557 builtin/remote.c:300
-#: builtin/remote.c:328
-#, c-format
-msgid "more than one %s"
-msgstr ""
-
-#: trailer.c:743
-#, c-format
-msgid "empty trailer token in trailer '%.*s'"
-msgstr ""
-
-#: trailer.c:763
-#, c-format
-msgid "could not read input file '%s'"
-msgstr ""
-
-#: trailer.c:766 builtin/mktag.c:88 imap-send.c:1563
-msgid "could not read from stdin"
-msgstr ""
-
-#: trailer.c:1024 wrapper.c:760
-#, c-format
-msgid "could not stat %s"
-msgstr ""
-
-#: trailer.c:1026
-#, c-format
-msgid "file %s is not a regular file"
-msgstr ""
-
-#: trailer.c:1028
-#, c-format
-msgid "file %s is not writable by user"
-msgstr ""
-
-#: trailer.c:1040
-msgid "could not open temporary file"
-msgstr ""
-
-#: trailer.c:1080
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr ""
-
-#: transport-helper.c:62 transport-helper.c:91
-msgid "full write to remote helper failed"
-msgstr ""
-
-#: transport-helper.c:145
-#, c-format
-msgid "unable to find remote helper for '%s'"
-msgstr ""
-
-#: transport-helper.c:161 transport-helper.c:575
-msgid "can't dup helper output fd"
-msgstr ""
-
-#: transport-helper.c:214
-#, c-format
-msgid ""
-"unknown mandatory capability %s; this remote helper probably needs newer "
-"version of Git"
-msgstr ""
-
-#: transport-helper.c:220
-msgid "this remote helper should implement refspec capability"
-msgstr ""
-
-#: transport-helper.c:287 transport-helper.c:429
-#, c-format
-msgid "%s unexpectedly said: '%s'"
-msgstr ""
-
-#: transport-helper.c:417
-#, c-format
-msgid "%s also locked %s"
-msgstr ""
-
-#: transport-helper.c:497
-msgid "couldn't run fast-import"
-msgstr ""
-
-#: transport-helper.c:520
-msgid "error while running fast-import"
-msgstr ""
-
-#: transport-helper.c:549 transport-helper.c:1254
-#, c-format
-msgid "could not read ref %s"
-msgstr ""
-
-#: transport-helper.c:594
-#, c-format
-msgid "unknown response to connect: %s"
-msgstr ""
-
-#: transport-helper.c:616
-msgid "setting remote service path not supported by protocol"
-msgstr ""
-
-#: transport-helper.c:618
-msgid "invalid remote service path"
-msgstr ""
-
-#: transport-helper.c:661 transport.c:1496
-msgid "operation not supported by protocol"
-msgstr ""
-
-#: transport-helper.c:664
-#, c-format
-msgid "can't connect to subservice %s"
-msgstr ""
-
-#: transport-helper.c:693 transport.c:415
-msgid "--negotiate-only requires protocol v2"
-msgstr ""
-
-#: transport-helper.c:758
-msgid "'option' without a matching 'ok/error' directive"
-msgstr ""
-
-#: transport-helper.c:801
-#, c-format
-msgid "expected ok/error, helper said '%s'"
-msgstr ""
-
-#: transport-helper.c:862
-#, c-format
-msgid "helper reported unexpected status of %s"
-msgstr ""
-
-#: transport-helper.c:945
-#, c-format
-msgid "helper %s does not support dry-run"
-msgstr ""
-
-#: transport-helper.c:948
-#, c-format
-msgid "helper %s does not support --signed"
-msgstr ""
-
-#: transport-helper.c:951
-#, c-format
-msgid "helper %s does not support --signed=if-asked"
-msgstr ""
-
-#: transport-helper.c:956
-#, c-format
-msgid "helper %s does not support --atomic"
-msgstr ""
-
-#: transport-helper.c:960
-#, c-format
-msgid "helper %s does not support --%s"
-msgstr ""
-
-#: transport-helper.c:967
-#, c-format
-msgid "helper %s does not support 'push-option'"
-msgstr ""
-
-#: transport-helper.c:1067
-msgid "remote-helper doesn't support push; refspec needed"
-msgstr ""
-
-#: transport-helper.c:1072
-#, c-format
-msgid "helper %s does not support 'force'"
-msgstr ""
-
-#: transport-helper.c:1119
-msgid "couldn't run fast-export"
-msgstr ""
-
-#: transport-helper.c:1124
-msgid "error while running fast-export"
-msgstr ""
-
-#: transport-helper.c:1149
-#, c-format
-msgid ""
-"No refs in common and none specified; doing nothing.\n"
-"Perhaps you should specify a branch.\n"
-msgstr ""
-
-#: transport-helper.c:1231
-#, c-format
-msgid "unsupported object format '%s'"
-msgstr ""
-
-#: transport-helper.c:1240
-#, c-format
-msgid "malformed response in ref list: %s"
-msgstr ""
-
-#: transport-helper.c:1392
-#, c-format
-msgid "read(%s) failed"
-msgstr ""
-
-#: transport-helper.c:1419
-#, c-format
-msgid "write(%s) failed"
-msgstr ""
-
-#: transport-helper.c:1468
-#, c-format
-msgid "%s thread failed"
-msgstr ""
-
-#: transport-helper.c:1472
-#, c-format
-msgid "%s thread failed to join: %s"
-msgstr ""
-
-#: transport-helper.c:1491 transport-helper.c:1495
-#, c-format
-msgid "can't start thread for copying data: %s"
-msgstr ""
-
-#: transport-helper.c:1532
-#, c-format
-msgid "%s process failed to wait"
-msgstr ""
-
-#: transport-helper.c:1536
-#, c-format
-msgid "%s process failed"
-msgstr ""
-
-#: transport-helper.c:1554 transport-helper.c:1563
-msgid "can't start thread for copying data"
-msgstr ""
-
-#: transport.c:116
-#, c-format
-msgid "Would set upstream of '%s' to '%s' of '%s'\n"
-msgstr ""
-
-#: transport.c:138
-#, c-format
-msgid "could not read bundle '%s'"
-msgstr ""
-
-#: transport.c:234
-#, c-format
-msgid "transport: invalid depth option '%s'"
-msgstr ""
-
-#: transport.c:289
-msgid "see protocol.version in 'git help config' for more details"
-msgstr ""
-
-#: transport.c:290
-msgid "server options require protocol version 2 or later"
-msgstr ""
-
-#: transport.c:418
-msgid "server does not support wait-for-done"
-msgstr ""
-
-#: transport.c:770
-msgid "could not parse transport.color.* config"
-msgstr ""
-
-#: transport.c:845
-msgid "support for protocol v2 not implemented yet"
-msgstr ""
-
-#: transport.c:978
-#, c-format
-msgid "unknown value for config '%s': %s"
-msgstr ""
-
-#: transport.c:1044
-#, c-format
-msgid "transport '%s' not allowed"
-msgstr ""
-
-#: transport.c:1093
-msgid "git-over-rsync is no longer supported"
-msgstr ""
-
-#: transport.c:1196
-#, c-format
-msgid ""
-"The following submodule paths contain changes that can\n"
-"not be found on any remote:\n"
-msgstr ""
-
-#: transport.c:1200
-#, c-format
-msgid ""
-"\n"
-"Please try\n"
-"\n"
-"\tgit push --recurse-submodules=on-demand\n"
-"\n"
-"or cd to the path and use\n"
-"\n"
-"\tgit push\n"
-"\n"
-"to push them to a remote.\n"
-"\n"
-msgstr ""
-
-#: transport.c:1208
-msgid "Aborting."
-msgstr ""
-
-#: transport.c:1354
-msgid "failed to push all needed submodules"
-msgstr ""
-
-#: tree-walk.c:33
-msgid "too-short tree object"
-msgstr ""
-
-#: tree-walk.c:39
-msgid "malformed mode in tree entry"
-msgstr ""
-
-#: tree-walk.c:43
-msgid "empty filename in tree entry"
-msgstr ""
-
-#: tree-walk.c:118
-msgid "too-short tree file"
-msgstr ""
-
-#: unpack-trees.c:118
-#, c-format
-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 ""
-
-#: unpack-trees.c:120
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by checkout:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:123
-#, c-format
-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 ""
-
-#: unpack-trees.c:125
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:128
-#, c-format
-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 ""
-
-#: unpack-trees.c:130
-#, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by %s:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:135
-#, c-format
-msgid ""
-"Updating the following directories would lose untracked files in them:\n"
-"%s"
-msgstr ""
-
-#: unpack-trees.c:138
-#, c-format
-msgid ""
-"Refusing to remove the current working directory:\n"
-"%s"
-msgstr ""
-
-#: unpack-trees.c:142
-#, c-format
-msgid ""
-"The following untracked working tree files would be removed by checkout:\n"
-"%%sPlease move or remove them before you switch branches."
-msgstr ""
-
-#: unpack-trees.c:144
-#, c-format
-msgid ""
-"The following untracked working tree files would be removed by checkout:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:147
-#, c-format
-msgid ""
-"The following untracked working tree files would be removed by merge:\n"
-"%%sPlease move or remove them before you merge."
-msgstr ""
-
-#: unpack-trees.c:149
-#, c-format
-msgid ""
-"The following untracked working tree files would be removed by merge:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:152
-#, c-format
-msgid ""
-"The following untracked working tree files would be removed by %s:\n"
-"%%sPlease move or remove them before you %s."
-msgstr ""
-
-#: unpack-trees.c:154
-#, c-format
-msgid ""
-"The following untracked working tree files would be removed by %s:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:160
-#, c-format
-msgid ""
-"The following untracked working tree files would be overwritten by "
-"checkout:\n"
-"%%sPlease move or remove them before you switch branches."
-msgstr ""
-
-#: unpack-trees.c:162
-#, c-format
-msgid ""
-"The following untracked working tree files would be overwritten by "
-"checkout:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:165
-#, c-format
-msgid ""
-"The following untracked working tree files would be overwritten by merge:\n"
-"%%sPlease move or remove them before you merge."
-msgstr ""
-
-#: unpack-trees.c:167
-#, c-format
-msgid ""
-"The following untracked working tree files would be overwritten by merge:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:170
-#, c-format
-msgid ""
-"The following untracked working tree files would be overwritten by %s:\n"
-"%%sPlease move or remove them before you %s."
-msgstr ""
-
-#: unpack-trees.c:172
-#, c-format
-msgid ""
-"The following untracked working tree files would be overwritten by %s:\n"
-"%%s"
-msgstr ""
-
-#: unpack-trees.c:180
-#, c-format
-msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
-msgstr ""
-
-#: unpack-trees.c:183
-#, c-format
-msgid ""
-"Cannot update submodule:\n"
-"%s"
-msgstr ""
-
-#: unpack-trees.c:186
-#, c-format
-msgid ""
-"The following paths are not up to date and were left despite sparse "
-"patterns:\n"
-"%s"
-msgstr ""
-
-#: unpack-trees.c:188
-#, c-format
-msgid ""
-"The following paths are unmerged and were left despite sparse patterns:\n"
-"%s"
-msgstr ""
-
-#: unpack-trees.c:190
-#, c-format
-msgid ""
-"The following paths were already present and thus not updated despite sparse "
-"patterns:\n"
-"%s"
-msgstr ""
-
-#: unpack-trees.c:270
-#, c-format
-msgid "Aborting\n"
-msgstr ""
-
-#: unpack-trees.c:297
-#, c-format
-msgid ""
-"After fixing the above paths, you may want to run `git sparse-checkout "
-"reapply`.\n"
-msgstr ""
-
-#: unpack-trees.c:358
-msgid "Updating files"
-msgstr ""
-
-#: unpack-trees.c:390
-msgid ""
-"the following paths have collided (e.g. case-sensitive paths\n"
-"on a case-insensitive filesystem) and only one from the same\n"
-"colliding group is in the working tree:\n"
-msgstr ""
-
-#: unpack-trees.c:1664
-msgid "Updating index flags"
-msgstr ""
-
-#: unpack-trees.c:2925
-#, c-format
-msgid "worktree and untracked commit have duplicate entries: %s"
-msgstr ""
-
-#: upload-pack.c:1579
-msgid "expected flush after fetch arguments"
-msgstr ""
-
-#: urlmatch.c:163
-msgid "invalid URL scheme name or missing '://' suffix"
-msgstr ""
-
-#: urlmatch.c:187 urlmatch.c:346 urlmatch.c:405
-#, c-format
-msgid "invalid %XX escape sequence"
-msgstr ""
-
-#: urlmatch.c:215
-msgid "missing host and scheme is not 'file:'"
-msgstr ""
-
-#: urlmatch.c:232
-msgid "a 'file:' URL may not have a port number"
-msgstr ""
-
-#: urlmatch.c:247
-msgid "invalid characters in host name"
-msgstr ""
-
-#: urlmatch.c:292 urlmatch.c:303
-msgid "invalid port number"
-msgstr ""
-
-#: urlmatch.c:371
-msgid "invalid '..' path segment"
-msgstr ""
-
-#: walker.c:170
-msgid "Fetching objects"
-msgstr ""
-
-#: worktree.c:237 builtin/am.c:2210 builtin/bisect--helper.c:156
-#, c-format
-msgid "failed to read '%s'"
-msgstr ""
-
-#: worktree.c:304
-#, c-format
-msgid "'%s' at main working tree is not the repository directory"
-msgstr ""
-
-#: worktree.c:315
-#, c-format
-msgid "'%s' file does not contain absolute path to the working tree location"
-msgstr ""
-
-#: worktree.c:327
-#, c-format
-msgid "'%s' does not exist"
-msgstr ""
-
-#: worktree.c:333
-#, c-format
-msgid "'%s' is not a .git file, error code %d"
-msgstr ""
-
-#: worktree.c:342
-#, c-format
-msgid "'%s' does not point back to '%s'"
-msgstr ""
-
-#: worktree.c:600
-msgid "not a directory"
-msgstr ""
-
-#: worktree.c:609
-msgid ".git is not a file"
-msgstr ""
-
-#: worktree.c:611
-msgid ".git file broken"
-msgstr ""
-
-#: worktree.c:613
-msgid ".git file incorrect"
-msgstr ""
-
-#: worktree.c:719
-msgid "not a valid path"
-msgstr ""
-
-#: worktree.c:725
-msgid "unable to locate repository; .git is not a file"
-msgstr ""
-
-#: worktree.c:729
-msgid "unable to locate repository; .git file does not reference a repository"
-msgstr ""
-
-#: worktree.c:733
-msgid "unable to locate repository; .git file broken"
-msgstr ""
-
-#: worktree.c:739
-msgid "gitdir unreadable"
-msgstr ""
-
-#: worktree.c:743
-msgid "gitdir incorrect"
-msgstr ""
-
-#: worktree.c:768
-msgid "not a valid directory"
-msgstr ""
-
-#: worktree.c:774
-msgid "gitdir file does not exist"
-msgstr ""
-
-#: worktree.c:779 worktree.c:788
-#, c-format
-msgid "unable to read gitdir file (%s)"
-msgstr ""
-
-#: worktree.c:798
-#, c-format
-msgid "short read (expected %<PRIuMAX> bytes, read %<PRIuMAX>)"
-msgstr ""
-
-#: worktree.c:806
-msgid "invalid gitdir file"
-msgstr ""
-
-#: worktree.c:814
-msgid "gitdir file points to non-existent location"
-msgstr ""
-
-#: worktree.c:830
-#, c-format
-msgid "unable to set %s in '%s'"
-msgstr ""
-
-#: worktree.c:832
-#, c-format
-msgid "unable to unset %s in '%s'"
-msgstr ""
-
-#: worktree.c:852
-msgid "failed to set extensions.worktreeConfig setting"
-msgstr ""
-
-#: wrapper.c:161
-#, c-format
-msgid "could not setenv '%s'"
-msgstr ""
-
-#: wrapper.c:213
-#, c-format
-msgid "unable to create '%s'"
-msgstr ""
-
-#: wrapper.c:215 wrapper.c:385
-#, c-format
-msgid "could not open '%s' for reading and writing"
-msgstr ""
-
-#: wrapper.c:416 wrapper.c:683
-#, c-format
-msgid "unable to access '%s'"
-msgstr ""
-
-#: wrapper.c:691
-msgid "unable to get current working directory"
-msgstr ""
-
-#: wt-status.c:158
-msgid "Unmerged paths:"
-msgstr ""
-
-#: wt-status.c:187 wt-status.c:219
-msgid "  (use \"git restore --staged <file>...\" to unstage)"
-msgstr ""
-
-#: wt-status.c:190 wt-status.c:222
-#, c-format
-msgid "  (use \"git restore --source=%s --staged <file>...\" to unstage)"
-msgstr ""
-
-#: wt-status.c:193 wt-status.c:225
-msgid "  (use \"git rm --cached <file>...\" to unstage)"
-msgstr ""
-
-#: wt-status.c:197
-msgid "  (use \"git add <file>...\" to mark resolution)"
-msgstr ""
-
-#: wt-status.c:199 wt-status.c:203
-msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
-msgstr ""
-
-#: wt-status.c:201
-msgid "  (use \"git rm <file>...\" to mark resolution)"
-msgstr ""
-
-#: wt-status.c:211 wt-status.c:1140
-msgid "Changes to be committed:"
-msgstr ""
-
-#: wt-status.c:234 wt-status.c:1149
-msgid "Changes not staged for commit:"
-msgstr ""
-
-#: wt-status.c:238
-msgid "  (use \"git add <file>...\" to update what will be committed)"
-msgstr ""
-
-#: wt-status.c:240
-msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
-msgstr ""
-
-#: wt-status.c:241
-msgid ""
-"  (use \"git restore <file>...\" to discard changes in working directory)"
-msgstr ""
-
-#: wt-status.c:243
-msgid "  (commit or discard the untracked or modified content in submodules)"
-msgstr ""
-
-#: wt-status.c:254
-#, c-format
-msgid "  (use \"git %s <file>...\" to include in what will be committed)"
-msgstr ""
-
-#: wt-status.c:266
-msgid "both deleted:"
-msgstr ""
-
-#: wt-status.c:268
-msgid "added by us:"
-msgstr ""
-
-#: wt-status.c:270
-msgid "deleted by them:"
-msgstr ""
-
-#: wt-status.c:272
-msgid "added by them:"
-msgstr ""
-
-#: wt-status.c:274
-msgid "deleted by us:"
-msgstr ""
-
-#: wt-status.c:276
-msgid "both added:"
-msgstr ""
-
-#: wt-status.c:278
-msgid "both modified:"
-msgstr ""
-
-#: wt-status.c:288
-msgid "new file:"
-msgstr ""
-
-#: wt-status.c:290
-msgid "copied:"
-msgstr ""
-
-#: wt-status.c:292
-msgid "deleted:"
-msgstr ""
-
-#: wt-status.c:294
-msgid "modified:"
-msgstr ""
-
-#: wt-status.c:296
-msgid "renamed:"
-msgstr ""
-
-#: wt-status.c:298
-msgid "typechange:"
-msgstr ""
-
-#: wt-status.c:300
-msgid "unknown:"
-msgstr ""
-
-#: wt-status.c:302
-msgid "unmerged:"
-msgstr ""
-
-#: wt-status.c:382
-msgid "new commits, "
-msgstr ""
-
-#: wt-status.c:384
-msgid "modified content, "
-msgstr ""
-
-#: wt-status.c:386
-msgid "untracked content, "
-msgstr ""
-
-#: wt-status.c:973
-#, c-format
-msgid "Your stash currently has %d entry"
-msgid_plural "Your stash currently has %d entries"
-msgstr[0] ""
-msgstr[1] ""
-
-#: wt-status.c:1004
-msgid "Submodules changed but not updated:"
-msgstr ""
-
-#: wt-status.c:1006
-msgid "Submodule changes to be committed:"
-msgstr ""
-
-#: wt-status.c:1088
-msgid ""
-"Do not modify or remove the line above.\n"
-"Everything below it will be ignored."
-msgstr ""
-
-#: wt-status.c:1180
-#, c-format
-msgid ""
-"\n"
-"It took %.2f seconds to compute the branch ahead/behind values.\n"
-"You can use '--no-ahead-behind' to avoid this.\n"
-msgstr ""
-
-#: wt-status.c:1210
-msgid "You have unmerged paths."
-msgstr ""
-
-#: wt-status.c:1213
-msgid "  (fix conflicts and run \"git commit\")"
-msgstr ""
-
-#: wt-status.c:1215
-msgid "  (use \"git merge --abort\" to abort the merge)"
-msgstr ""
-
-#: wt-status.c:1219
-msgid "All conflicts fixed but you are still merging."
-msgstr ""
-
-#: wt-status.c:1222
-msgid "  (use \"git commit\" to conclude merge)"
-msgstr ""
-
-#: wt-status.c:1233
-msgid "You are in the middle of an am session."
-msgstr ""
-
-#: wt-status.c:1236
-msgid "The current patch is empty."
-msgstr ""
-
-#: wt-status.c:1241
-msgid "  (fix conflicts and then run \"git am --continue\")"
-msgstr ""
-
-#: wt-status.c:1243
-msgid "  (use \"git am --skip\" to skip this patch)"
-msgstr ""
-
-#: wt-status.c:1246
-msgid ""
-"  (use \"git am --allow-empty\" to record this patch as an empty commit)"
-msgstr ""
-
-#: wt-status.c:1248
-msgid "  (use \"git am --abort\" to restore the original branch)"
-msgstr ""
-
-#: wt-status.c:1381
-msgid "git-rebase-todo is missing."
-msgstr ""
-
-#: wt-status.c:1383
-msgid "No commands done."
-msgstr ""
-
-#: wt-status.c:1386
-#, c-format
-msgid "Last command done (%<PRIuMAX> command done):"
-msgid_plural "Last commands done (%<PRIuMAX> commands done):"
-msgstr[0] ""
-msgstr[1] ""
-
-#: wt-status.c:1397
-#, c-format
-msgid "  (see more in file %s)"
-msgstr ""
-
-#: wt-status.c:1402
-msgid "No commands remaining."
-msgstr ""
-
-#: wt-status.c:1405
-#, c-format
-msgid "Next command to do (%<PRIuMAX> remaining command):"
-msgid_plural "Next commands to do (%<PRIuMAX> remaining commands):"
-msgstr[0] ""
-msgstr[1] ""
-
-#: wt-status.c:1413
-msgid "  (use \"git rebase --edit-todo\" to view and edit)"
-msgstr ""
-
-#: wt-status.c:1425
-#, c-format
-msgid "You are currently rebasing branch '%s' on '%s'."
-msgstr ""
-
-#: wt-status.c:1430
-msgid "You are currently rebasing."
-msgstr ""
-
-#: wt-status.c:1443
-msgid "  (fix conflicts and then run \"git rebase --continue\")"
-msgstr ""
-
-#: wt-status.c:1445
-msgid "  (use \"git rebase --skip\" to skip this patch)"
-msgstr ""
-
-#: wt-status.c:1447
-msgid "  (use \"git rebase --abort\" to check out the original branch)"
-msgstr ""
-
-#: wt-status.c:1454
-msgid "  (all conflicts fixed: run \"git rebase --continue\")"
-msgstr ""
-
-#: wt-status.c:1458
-#, c-format
-msgid ""
-"You are currently splitting a commit while rebasing branch '%s' on '%s'."
-msgstr ""
-
-#: wt-status.c:1463
-msgid "You are currently splitting a commit during a rebase."
-msgstr ""
-
-#: wt-status.c:1466
-msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
-msgstr ""
-
-#: wt-status.c:1470
-#, c-format
-msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
-msgstr ""
-
-#: wt-status.c:1475
-msgid "You are currently editing a commit during a rebase."
-msgstr ""
-
-#: wt-status.c:1478
-msgid "  (use \"git commit --amend\" to amend the current commit)"
-msgstr ""
-
-#: wt-status.c:1480
-msgid ""
-"  (use \"git rebase --continue\" once you are satisfied with your changes)"
-msgstr ""
-
-#: wt-status.c:1491
-msgid "Cherry-pick currently in progress."
-msgstr ""
-
-#: wt-status.c:1494
-#, c-format
-msgid "You are currently cherry-picking commit %s."
-msgstr ""
-
-#: wt-status.c:1501
-msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
-msgstr ""
-
-#: wt-status.c:1504
-msgid "  (run \"git cherry-pick --continue\" to continue)"
-msgstr ""
-
-#: wt-status.c:1507
-msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
-msgstr ""
-
-#: wt-status.c:1509
-msgid "  (use \"git cherry-pick --skip\" to skip this patch)"
-msgstr ""
-
-#: wt-status.c:1511
-msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
-msgstr ""
-
-#: wt-status.c:1521
-msgid "Revert currently in progress."
-msgstr ""
-
-#: wt-status.c:1524
-#, c-format
-msgid "You are currently reverting commit %s."
-msgstr ""
-
-#: wt-status.c:1530
-msgid "  (fix conflicts and run \"git revert --continue\")"
-msgstr ""
-
-#: wt-status.c:1533
-msgid "  (run \"git revert --continue\" to continue)"
-msgstr ""
-
-#: wt-status.c:1536
-msgid "  (all conflicts fixed: run \"git revert --continue\")"
-msgstr ""
-
-#: wt-status.c:1538
-msgid "  (use \"git revert --skip\" to skip this patch)"
-msgstr ""
-
-#: wt-status.c:1540
-msgid "  (use \"git revert --abort\" to cancel the revert operation)"
-msgstr ""
-
-#: wt-status.c:1550
-#, c-format
-msgid "You are currently bisecting, started from branch '%s'."
-msgstr ""
-
-#: wt-status.c:1554
-msgid "You are currently bisecting."
-msgstr ""
-
-#: wt-status.c:1557
-msgid "  (use \"git bisect reset\" to get back to the original branch)"
-msgstr ""
-
-#: wt-status.c:1568
-msgid "You are in a sparse checkout."
-msgstr ""
-
-#: wt-status.c:1571
-#, c-format
-msgid "You are in a sparse checkout with %d%% of tracked files present."
-msgstr ""
-
-#: wt-status.c:1815
-msgid "On branch "
-msgstr ""
-
-#: wt-status.c:1822
-msgid "interactive rebase in progress; onto "
-msgstr ""
-
-#: wt-status.c:1824
-msgid "rebase in progress; onto "
-msgstr ""
-
-#: wt-status.c:1829
-msgid "HEAD detached at "
-msgstr ""
-
-#: wt-status.c:1831
-msgid "HEAD detached from "
-msgstr ""
-
-#: wt-status.c:1834
-msgid "Not currently on any branch."
-msgstr ""
-
-#: wt-status.c:1851
-msgid "Initial commit"
-msgstr ""
-
-#: wt-status.c:1852
-msgid "No commits yet"
-msgstr ""
-
-#: wt-status.c:1866
-msgid "Untracked files"
-msgstr ""
-
-#: wt-status.c:1868
-msgid "Ignored files"
-msgstr ""
-
-#: wt-status.c:1872
-#, c-format
-msgid ""
-"It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
-"may speed it up, but you have to be careful not to forget to add\n"
-"new files yourself (see 'git help status')."
-msgstr ""
-
-#: wt-status.c:1878
-#, c-format
-msgid "Untracked files not listed%s"
-msgstr ""
-
-#: wt-status.c:1880
-msgid " (use -u option to show untracked files)"
-msgstr ""
-
-#: wt-status.c:1886
-msgid "No changes"
-msgstr ""
-
-#: wt-status.c:1891
-#, c-format
-msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
-msgstr ""
-
-#: wt-status.c:1895
-#, c-format
-msgid "no changes added to commit\n"
-msgstr ""
-
-#: wt-status.c:1899
-#, c-format
-msgid ""
-"nothing added to commit but untracked files present (use \"git add\" to "
-"track)\n"
-msgstr ""
-
-#: wt-status.c:1903
-#, c-format
-msgid "nothing added to commit but untracked files present\n"
-msgstr ""
-
-#: wt-status.c:1907
-#, c-format
-msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
-msgstr ""
-
-#: wt-status.c:1911 wt-status.c:1917
-#, c-format
-msgid "nothing to commit\n"
-msgstr ""
-
-#: wt-status.c:1914
-#, c-format
-msgid "nothing to commit (use -u to show untracked files)\n"
-msgstr ""
-
-#: wt-status.c:1919
-#, c-format
-msgid "nothing to commit, working tree clean\n"
-msgstr ""
-
-#: wt-status.c:2024
-msgid "No commits yet on "
-msgstr ""
-
-#: wt-status.c:2028
-msgid "HEAD (no branch)"
-msgstr ""
-
-#: wt-status.c:2059
-msgid "different"
-msgstr ""
-
-#: wt-status.c:2061 wt-status.c:2069
-msgid "behind "
-msgstr ""
-
-#: wt-status.c:2064 wt-status.c:2067
-msgid "ahead "
-msgstr ""
-
-#. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2605
-#, c-format
-msgid "cannot %s: You have unstaged changes."
-msgstr ""
-
-#: wt-status.c:2611
-msgid "additionally, your index contains uncommitted changes."
-msgstr ""
-
-#: wt-status.c:2613
-#, c-format
-msgid "cannot %s: Your index contains uncommitted changes."
-msgstr ""
-
-#: compat/simple-ipc/ipc-unix-socket.c:205
-msgid "could not send IPC command"
-msgstr ""
-
-#: compat/simple-ipc/ipc-unix-socket.c:212
-msgid "could not read IPC response"
-msgstr ""
-
-#: compat/simple-ipc/ipc-unix-socket.c:892
-#, c-format
-msgid "could not start accept_thread '%s'"
-msgstr ""
-
-#: compat/simple-ipc/ipc-unix-socket.c:904
-#, c-format
-msgid "could not start worker[0] for '%s'"
-msgstr ""
-
-#: compat/precompose_utf8.c:58 builtin/clone.c:353
-#, c-format
-msgid "failed to unlink '%s'"
-msgstr ""
-
-#: compat/fsmonitor/fsm-listen-darwin.c:355
-msgid "Unable to create FSEventStream."
-msgstr ""
-
-#: compat/fsmonitor/fsm-listen-darwin.c:403
-msgid "Failed to start the FSEventStream"
-msgstr ""
-
-#: builtin/add.c:26
-msgid "git add [<options>] [--] <pathspec>..."
-msgstr ""
-
-#: builtin/add.c:63
-#, c-format
-msgid "cannot chmod %cx '%s'"
-msgstr ""
-
-#: builtin/add.c:105
-#, c-format
-msgid "unexpected diff status %c"
-msgstr ""
-
-#: builtin/add.c:110 builtin/commit.c:299
-msgid "updating files failed"
-msgstr ""
-
-#: builtin/add.c:120
-#, c-format
-msgid "remove '%s'\n"
-msgstr ""
-
-#: builtin/add.c:204
-msgid "Unstaged changes after refreshing the index:"
-msgstr ""
-
-#: builtin/add.c:312 builtin/rev-parse.c:993
-msgid "Could not read the index"
-msgstr ""
-
-#: builtin/add.c:325
-msgid "Could not write patch"
-msgstr ""
-
-#: builtin/add.c:328
-msgid "editing patch failed"
-msgstr ""
-
-#: builtin/add.c:331
-#, c-format
-msgid "Could not stat '%s'"
-msgstr ""
-
-#: builtin/add.c:333
-msgid "Empty patch. Aborted."
-msgstr ""
-
-#: builtin/add.c:339
-#, c-format
-msgid "Could not apply '%s'"
-msgstr ""
-
-#: builtin/add.c:347
-msgid "The following paths are ignored by one of your .gitignore files:\n"
-msgstr ""
-
-#: builtin/add.c:367 builtin/clean.c:927 builtin/fetch.c:175 builtin/mv.c:124
-#: builtin/prune-packed.c:14 builtin/pull.c:208 builtin/push.c:550
-#: builtin/remote.c:1454 builtin/rm.c:244 builtin/send-pack.c:194
-msgid "dry run"
-msgstr ""
-
-#: builtin/add.c:368 builtin/check-ignore.c:22 builtin/commit.c:1483
-#: builtin/count-objects.c:98 builtin/fsck.c:789 builtin/log.c:2338
-#: builtin/mv.c:123 builtin/read-tree.c:120
-msgid "be verbose"
-msgstr ""
-
-#: builtin/add.c:370
-msgid "interactive picking"
-msgstr ""
-
-#: builtin/add.c:371 builtin/checkout.c:1599 builtin/reset.c:417
-msgid "select hunks interactively"
-msgstr ""
-
-#: builtin/add.c:372
-msgid "edit current diff and apply"
-msgstr ""
-
-#: builtin/add.c:373
-msgid "allow adding otherwise ignored files"
-msgstr ""
-
-#: builtin/add.c:374
-msgid "update tracked files"
-msgstr ""
-
-#: builtin/add.c:375
-msgid "renormalize EOL of tracked files (implies -u)"
-msgstr ""
-
-#: builtin/add.c:376
-msgid "record only the fact that the path will be added later"
-msgstr ""
-
-#: builtin/add.c:377
-msgid "add changes from all tracked and untracked files"
-msgstr ""
-
-#: builtin/add.c:380
-msgid "ignore paths removed in the working tree (same as --no-all)"
-msgstr ""
-
-#: builtin/add.c:382
-msgid "don't add, only refresh the index"
-msgstr ""
-
-#: builtin/add.c:383
-msgid "just skip files which cannot be added because of errors"
-msgstr ""
-
-#: builtin/add.c:384
-msgid "check if - even missing - files are ignored in dry run"
-msgstr ""
-
-#: builtin/add.c:385 builtin/mv.c:128 builtin/rm.c:251
-msgid "allow updating entries outside of the sparse-checkout cone"
-msgstr ""
-
-#: builtin/add.c:387 builtin/update-index.c:1023
-msgid "override the executable bit of the listed files"
-msgstr ""
-
-#: builtin/add.c:389
-msgid "warn when adding an embedded repository"
-msgstr ""
-
-#: builtin/add.c:407
-#, c-format
-msgid ""
-"You've added another git repository inside your current repository.\n"
-"Clones of the outer repository will not contain the contents of\n"
-"the embedded repository and will not know how to obtain it.\n"
-"If you meant to add a submodule, use:\n"
-"\n"
-"\tgit submodule add <url> %s\n"
-"\n"
-"If you added this path by mistake, you can remove it from the\n"
-"index with:\n"
-"\n"
-"\tgit rm --cached %s\n"
-"\n"
-"See \"git help submodule\" for more information."
-msgstr ""
-
-#: builtin/add.c:436
-#, c-format
-msgid "adding embedded git repository: %s"
-msgstr ""
-
-#: builtin/add.c:456
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-
-#: builtin/add.c:471
-msgid "adding files failed"
-msgstr ""
-
-#: builtin/add.c:534
-#, c-format
-msgid "--chmod param '%s' must be either -x or +x"
-msgstr ""
-
-#: builtin/add.c:555 builtin/checkout.c:1770 builtin/commit.c:365
-#: builtin/reset.c:436 builtin/rm.c:275 builtin/stash.c:1702
-#, c-format
-msgid "'%s' and pathspec arguments cannot be used together"
-msgstr ""
-
-#: builtin/add.c:566
-#, c-format
-msgid "Nothing specified, nothing added.\n"
-msgstr ""
-
-#: builtin/add.c:568
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-
-#: builtin/am.c:393
-msgid "could not parse author script"
-msgstr ""
-
-#: builtin/am.c:483
-#, c-format
-msgid "'%s' was deleted by the applypatch-msg hook"
-msgstr ""
-
-#: builtin/am.c:525
-#, c-format
-msgid "Malformed input line: '%s'."
-msgstr ""
-
-#: builtin/am.c:563
-#, c-format
-msgid "Failed to copy notes from '%s' to '%s'"
-msgstr ""
-
-#: builtin/am.c:589
-msgid "fseek failed"
-msgstr ""
-
-#: builtin/am.c:777
-#, c-format
-msgid "could not parse patch '%s'"
-msgstr ""
-
-#: builtin/am.c:842
-msgid "Only one StGIT patch series can be applied at once"
-msgstr ""
-
-#: builtin/am.c:890
-msgid "invalid timestamp"
-msgstr ""
-
-#: builtin/am.c:895 builtin/am.c:907
-msgid "invalid Date line"
-msgstr ""
-
-#: builtin/am.c:902
-msgid "invalid timezone offset"
-msgstr ""
-
-#: builtin/am.c:995
-msgid "Patch format detection failed."
-msgstr ""
-
-#: builtin/am.c:1000 builtin/clone.c:306
-#, c-format
-msgid "failed to create directory '%s'"
-msgstr ""
-
-#: builtin/am.c:1005
-msgid "Failed to split patches."
-msgstr ""
-
-#: builtin/am.c:1154
-#, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr ""
-
-#: builtin/am.c:1155
-#, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr ""
-
-#: builtin/am.c:1160
-#, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
-msgstr ""
-
-#: builtin/am.c:1162
-#, c-format
-msgid "To restore the original branch and stop patching, run \"%s --abort\"."
-msgstr ""
-
-#: builtin/am.c:1257
-msgid "Patch sent with format=flowed; space at the end of lines might be lost."
-msgstr ""
-
-#: builtin/am.c:1345
-#, c-format
-msgid "missing author line in commit %s"
-msgstr ""
-
-#: builtin/am.c:1348
-#, c-format
-msgid "invalid ident line: %.*s"
-msgstr ""
-
-#: builtin/am.c:1567
-msgid "Repository lacks necessary blobs to fall back on 3-way merge."
-msgstr ""
-
-#: builtin/am.c:1569
-msgid "Using index info to reconstruct a base tree..."
-msgstr ""
-
-#: builtin/am.c:1588
-msgid ""
-"Did you hand edit your patch?\n"
-"It does not apply to blobs recorded in its index."
-msgstr ""
-
-#: builtin/am.c:1594
-msgid "Falling back to patching base and 3-way merge..."
-msgstr ""
-
-#: builtin/am.c:1620
-msgid "Failed to merge in the changes."
-msgstr ""
-
-#: builtin/am.c:1652
-msgid "applying to an empty history"
-msgstr ""
-
-#: builtin/am.c:1704 builtin/am.c:1708
-#, c-format
-msgid "cannot resume: %s does not exist."
-msgstr ""
-
-#: builtin/am.c:1726
-msgid "Commit Body is:"
-msgstr ""
-
-#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
-#. in your translation. The program will only accept English
-#. input at this point.
-#.
-#: builtin/am.c:1736
-#, c-format
-msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "
-msgstr ""
-
-#: builtin/am.c:1782 builtin/commit.c:410
-msgid "unable to write index file"
-msgstr ""
-
-#: builtin/am.c:1786
-#, c-format
-msgid "Dirty index: cannot apply patches (dirty: %s)"
-msgstr ""
-
-#: builtin/am.c:1828
-#, c-format
-msgid "Skipping: %.*s"
-msgstr ""
-
-#: builtin/am.c:1833
-#, c-format
-msgid "Creating an empty commit: %.*s"
-msgstr ""
-
-#: builtin/am.c:1837
-msgid "Patch is empty."
-msgstr ""
-
-#: builtin/am.c:1848 builtin/am.c:1917
-#, c-format
-msgid "Applying: %.*s"
-msgstr ""
-
-#: builtin/am.c:1865
-msgid "No changes -- Patch already applied."
-msgstr ""
-
-#: builtin/am.c:1871
-#, c-format
-msgid "Patch failed at %s %.*s"
-msgstr ""
-
-#: builtin/am.c:1875
-msgid "Use 'git am --show-current-patch=diff' to see the failed patch"
-msgstr ""
-
-#: builtin/am.c:1921
-msgid "No changes - recorded it as an empty commit."
-msgstr ""
-
-#: builtin/am.c:1923
-msgid ""
-"No changes - did you forget to use 'git add'?\n"
-"If there is nothing left to stage, chances are that something else\n"
-"already introduced the same changes; you might want to skip this patch."
-msgstr ""
-
-#: builtin/am.c:1931
-msgid ""
-"You still have unmerged paths in your index.\n"
-"You should 'git add' each file with resolved conflicts to mark them as "
-"such.\n"
-"You might run `git rm` on a file to accept \"deleted by them\" for it."
-msgstr ""
-
-#: builtin/am.c:2039 builtin/am.c:2043 builtin/am.c:2055 builtin/reset.c:455
-#: builtin/reset.c:463
-#, c-format
-msgid "Could not parse object '%s'."
-msgstr ""
-
-#: builtin/am.c:2091 builtin/am.c:2167
-msgid "failed to clean index"
-msgstr ""
-
-#: builtin/am.c:2135
-msgid ""
-"You seem to have moved HEAD since the last 'am' failure.\n"
-"Not rewinding to ORIG_HEAD"
-msgstr ""
-
-#: builtin/am.c:2292
-#, c-format
-msgid "options '%s=%s' and '%s=%s' cannot be used together"
-msgstr ""
-
-#: builtin/am.c:2323
-msgid "git am [<options>] [(<mbox> | <Maildir>)...]"
-msgstr ""
-
-#: builtin/am.c:2324
-msgid "git am [<options>] (--continue | --skip | --abort)"
-msgstr ""
-
-#: builtin/am.c:2330
-msgid "run interactively"
-msgstr ""
-
-#: builtin/am.c:2332
-msgid "historical option -- no-op"
-msgstr ""
-
-#: builtin/am.c:2334
-msgid "allow fall back on 3way merging if needed"
-msgstr ""
-
-#: builtin/am.c:2335 builtin/init-db.c:547 builtin/prune-packed.c:16
-#: builtin/repack.c:646 builtin/stash.c:946
-msgid "be quiet"
-msgstr ""
-
-#: builtin/am.c:2337
-msgid "add a Signed-off-by trailer to the commit message"
-msgstr ""
-
-#: builtin/am.c:2340
-msgid "recode into utf8 (default)"
-msgstr ""
-
-#: builtin/am.c:2342
-msgid "pass -k flag to git-mailinfo"
-msgstr ""
-
-#: builtin/am.c:2344
-msgid "pass -b flag to git-mailinfo"
-msgstr ""
-
-#: builtin/am.c:2346
-msgid "pass -m flag to git-mailinfo"
-msgstr ""
-
-#: builtin/am.c:2348
-msgid "pass --keep-cr flag to git-mailsplit for mbox format"
-msgstr ""
-
-#: builtin/am.c:2351
-msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"
-msgstr ""
-
-#: builtin/am.c:2354
-msgid "strip everything before a scissors line"
-msgstr ""
-
-#: builtin/am.c:2356
-msgid "pass it through git-mailinfo"
-msgstr ""
-
-#: builtin/am.c:2359 builtin/am.c:2362 builtin/am.c:2365 builtin/am.c:2368
-#: builtin/am.c:2371 builtin/am.c:2374 builtin/am.c:2377 builtin/am.c:2380
-#: builtin/am.c:2386
-msgid "pass it through git-apply"
-msgstr ""
-
-#: builtin/am.c:2376 builtin/commit.c:1514 builtin/fmt-merge-msg.c:18
-#: builtin/fmt-merge-msg.c:21 builtin/grep.c:920 builtin/merge.c:263
-#: builtin/pull.c:142 builtin/pull.c:204 builtin/pull.c:221
-#: builtin/rebase.c:1074 builtin/repack.c:657 builtin/repack.c:661
-#: builtin/repack.c:663 builtin/show-branch.c:650 builtin/show-ref.c:172
-#: builtin/tag.c:446 parse-options.h:159 parse-options.h:180
-#: parse-options.h:348
-msgid "n"
-msgstr ""
-
-#: builtin/am.c:2382 builtin/branch.c:695 builtin/bugreport.c:109
-#: builtin/cat-file.c:848 builtin/cat-file.c:852 builtin/cat-file.c:856
-#: builtin/for-each-ref.c:41 builtin/ls-tree.c:357 builtin/replace.c:555
-#: builtin/tag.c:480 builtin/verify-tag.c:38
-msgid "format"
-msgstr ""
-
-#: builtin/am.c:2383
-msgid "format the patch(es) are in"
-msgstr ""
-
-#: builtin/am.c:2389
-msgid "override error message when patch failure occurs"
-msgstr ""
-
-#: builtin/am.c:2391
-msgid "continue applying patches after resolving a conflict"
-msgstr ""
-
-#: builtin/am.c:2394
-msgid "synonyms for --continue"
-msgstr ""
-
-#: builtin/am.c:2397
-msgid "skip the current patch"
-msgstr ""
-
-#: builtin/am.c:2400
-msgid "restore the original branch and abort the patching operation"
-msgstr ""
-
-#: builtin/am.c:2403
-msgid "abort the patching operation but keep HEAD where it is"
-msgstr ""
-
-#: builtin/am.c:2407
-msgid "show the patch being applied"
-msgstr ""
-
-#: builtin/am.c:2411
-msgid "record the empty patch as an empty commit"
-msgstr ""
-
-#: builtin/am.c:2415
-msgid "lie about committer date"
-msgstr ""
-
-#: builtin/am.c:2417
-msgid "use current timestamp for author date"
-msgstr ""
-
-#: builtin/am.c:2419 builtin/commit-tree.c:118 builtin/commit.c:1642
-#: builtin/merge.c:302 builtin/pull.c:179 builtin/rebase.c:1127
-#: builtin/revert.c:117 builtin/tag.c:461
-msgid "key-id"
-msgstr ""
-
-#: builtin/am.c:2420 builtin/rebase.c:1128
-msgid "GPG-sign commits"
-msgstr ""
-
-#: builtin/am.c:2423
-msgid "how to handle empty patches"
-msgstr ""
-
-#: builtin/am.c:2426
-msgid "(internal use for git-rebase)"
-msgstr ""
-
-#: builtin/am.c:2444
-msgid ""
-"The -b/--binary option has been a no-op for long time, and\n"
-"it will be removed. Please do not use it anymore."
-msgstr ""
-
-#: builtin/am.c:2451
-msgid "failed to read the index"
-msgstr ""
-
-#: builtin/am.c:2466
-#, c-format
-msgid "previous rebase directory %s still exists but mbox given."
-msgstr ""
-
-#: builtin/am.c:2490
-#, c-format
-msgid ""
-"Stray %s directory found.\n"
-"Use \"git am --abort\" to remove it."
-msgstr ""
-
-#: builtin/am.c:2496
-msgid "Resolve operation not in progress, we are not resuming."
-msgstr ""
-
-#: builtin/am.c:2506
-msgid "interactive mode requires patches on the command line"
-msgstr ""
-
-#: builtin/apply.c:8
-msgid "git apply [<options>] [<patch>...]"
-msgstr ""
-
-#: builtin/archive.c:18
-msgid "could not redirect output"
-msgstr ""
-
-#: builtin/archive.c:35
-msgid "git archive: Remote with no URL"
-msgstr ""
-
-#: builtin/archive.c:59
-msgid "git archive: expected ACK/NAK, got a flush packet"
-msgstr ""
-
-#: builtin/archive.c:62
-#, c-format
-msgid "git archive: NACK %s"
-msgstr ""
-
-#: builtin/archive.c:63
-msgid "git archive: protocol error"
-msgstr ""
-
-#: builtin/archive.c:67
-msgid "git archive: expected a flush"
-msgstr ""
-
-#: builtin/bisect--helper.c:24
-msgid "git bisect--helper --bisect-reset [<commit>]"
-msgstr ""
-
-#: builtin/bisect--helper.c:26
-msgid ""
-"git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}"
-"=<term>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] "
-"[<paths>...]"
-msgstr ""
-
-#: builtin/bisect--helper.c:29
-msgid "git bisect--helper --bisect-state (bad|new) [<rev>]"
-msgstr ""
-
-#: builtin/bisect--helper.c:30
-msgid "git bisect--helper --bisect-state (good|old) [<rev>...]"
-msgstr ""
-
-#: builtin/bisect--helper.c:31
-msgid "git bisect--helper --bisect-replay <filename>"
-msgstr ""
-
-#: builtin/bisect--helper.c:32
-msgid "git bisect--helper --bisect-skip [(<rev>|<range>)...]"
-msgstr ""
-
-#: builtin/bisect--helper.c:34
-msgid "git bisect--helper --bisect-run <cmd>..."
-msgstr ""
-
-#: builtin/bisect--helper.c:109
-#, c-format
-msgid "cannot open file '%s' in mode '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:116
-#, c-format
-msgid "could not write to file '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:154
-#, c-format
-msgid "cannot open file '%s' for reading"
-msgstr ""
-
-#: builtin/bisect--helper.c:170
-#, c-format
-msgid "'%s' is not a valid term"
-msgstr ""
-
-#: builtin/bisect--helper.c:174
-#, c-format
-msgid "can't use the builtin command '%s' as a term"
-msgstr ""
-
-#: builtin/bisect--helper.c:184
-#, c-format
-msgid "can't change the meaning of the term '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:194
-msgid "please use two different terms"
-msgstr ""
-
-#: builtin/bisect--helper.c:210
-#, c-format
-msgid "We are not bisecting.\n"
-msgstr ""
-
-#: builtin/bisect--helper.c:218
-#, c-format
-msgid "'%s' is not a valid commit"
-msgstr ""
-
-#: builtin/bisect--helper.c:227
-#, c-format
-msgid ""
-"could not check out original HEAD '%s'. Try 'git bisect reset <commit>'."
-msgstr ""
-
-#: builtin/bisect--helper.c:271
-#, c-format
-msgid "Bad bisect_write argument: %s"
-msgstr ""
-
-#: builtin/bisect--helper.c:276
-#, c-format
-msgid "couldn't get the oid of the rev '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:288
-#, c-format
-msgid "couldn't open the file '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:314
-#, c-format
-msgid "Invalid command: you're currently in a %s/%s bisect"
-msgstr ""
-
-#: builtin/bisect--helper.c:341
-#, c-format
-msgid ""
-"You need to give me at least one %s and %s revision.\n"
-"You can use \"git bisect %s\" and \"git bisect %s\" for that."
-msgstr ""
-
-#: builtin/bisect--helper.c:345
-#, c-format
-msgid ""
-"You need to start by \"git bisect start\".\n"
-"You then need to give me at least one %s and %s revision.\n"
-"You can use \"git bisect %s\" and \"git bisect %s\" for that."
-msgstr ""
-
-#: builtin/bisect--helper.c:365
-#, c-format
-msgid "bisecting only with a %s commit"
-msgstr ""
-
-#. TRANSLATORS: Make sure to include [Y] and [n] in your
-#. translation. The program will only accept English input
-#. at this point.
-#.
-#: builtin/bisect--helper.c:373
-msgid "Are you sure [Y/n]? "
-msgstr ""
-
-#: builtin/bisect--helper.c:434
-msgid "no terms defined"
-msgstr ""
-
-#: builtin/bisect--helper.c:437
-#, c-format
-msgid ""
-"Your current terms are %s for the old state\n"
-"and %s for the new state.\n"
-msgstr ""
-
-#: builtin/bisect--helper.c:447
-#, c-format
-msgid ""
-"invalid argument %s for 'git bisect terms'.\n"
-"Supported options are: --term-good|--term-old and --term-bad|--term-new."
-msgstr ""
-
-#: builtin/bisect--helper.c:514 builtin/bisect--helper.c:1038
-msgid "revision walk setup failed\n"
-msgstr ""
-
-#: builtin/bisect--helper.c:536
-#, c-format
-msgid "could not open '%s' for appending"
-msgstr ""
-
-#: builtin/bisect--helper.c:655 builtin/bisect--helper.c:668
-msgid "'' is not a valid term"
-msgstr ""
-
-#: builtin/bisect--helper.c:678
-#, c-format
-msgid "unrecognized option: '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:682
-#, c-format
-msgid "'%s' does not appear to be a valid revision"
-msgstr ""
-
-#: builtin/bisect--helper.c:713
-msgid "bad HEAD - I need a HEAD"
-msgstr ""
-
-#: builtin/bisect--helper.c:728
-#, c-format
-msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'."
-msgstr ""
-
-#: builtin/bisect--helper.c:749
-msgid "won't bisect on cg-seek'ed tree"
-msgstr ""
-
-#: builtin/bisect--helper.c:752
-msgid "bad HEAD - strange symbolic ref"
-msgstr ""
-
-#: builtin/bisect--helper.c:772
-#, c-format
-msgid "invalid ref: '%s'"
-msgstr ""
-
-#: builtin/bisect--helper.c:830
-msgid "You need to start by \"git bisect start\"\n"
-msgstr ""
-
-#. TRANSLATORS: Make sure to include [Y] and [n] in your
-#. translation. The program will only accept English input
-#. at this point.
-#.
-#: builtin/bisect--helper.c:841
-msgid "Do you want me to do it for you [Y/n]? "
-msgstr ""
-
-#: builtin/bisect--helper.c:859
-msgid "Please call `--bisect-state` with at least one argument"
-msgstr ""
-
-#: builtin/bisect--helper.c:872
-#, c-format
-msgid "'git bisect %s' can take only one argument."
-msgstr ""
-
-#: builtin/bisect--helper.c:884 builtin/bisect--helper.c:897
-#, c-format
-msgid "Bad rev input: %s"
-msgstr ""
-
-#: builtin/bisect--helper.c:904
-#, c-format
-msgid "Bad rev input (not a commit): %s"
-msgstr ""
-
-#: builtin/bisect--helper.c:936
-msgid "We are not bisecting."
-msgstr ""
-
-#: builtin/bisect--helper.c:986
-#, c-format
-msgid "'%s'?? what are you talking about?"
-msgstr ""
-
-#: builtin/bisect--helper.c:998
-#, c-format
-msgid "cannot read file '%s' for replaying"
-msgstr ""
-
-#: builtin/bisect--helper.c:1120 builtin/bisect--helper.c:1152
-#, c-format
-msgid "running %s\n"
-msgstr ""
-
-#: builtin/bisect--helper.c:1145 builtin/bisect--helper.c:1335
-msgid "bisect run failed: no command provided."
-msgstr ""
-
-#: builtin/bisect--helper.c:1166
-#, c-format
-msgid "unable to verify '%s' on good revision"
-msgstr ""
-
-#: builtin/bisect--helper.c:1172
-#, c-format
-msgid "bogus exit code %d for good revision"
-msgstr ""
-
-#: builtin/bisect--helper.c:1180
-#, c-format
-msgid "bisect run failed: exit code %d from '%s' is < 0 or >= 128"
-msgstr ""
-
-#: builtin/bisect--helper.c:1195
-#, c-format
-msgid "cannot open file '%s' for writing"
-msgstr ""
-
-#: builtin/bisect--helper.c:1213
-msgid "bisect run cannot continue any more"
-msgstr ""
-
-#: builtin/bisect--helper.c:1215
-#, c-format
-msgid "bisect run success"
-msgstr ""
-
-#: builtin/bisect--helper.c:1218
-#, c-format
-msgid "bisect found first bad commit"
-msgstr ""
-
-#: builtin/bisect--helper.c:1221
-#, c-format
-msgid ""
-"bisect run failed: 'git bisect--helper --bisect-state %s' exited with error "
-"code %d"
-msgstr ""
-
-#: builtin/bisect--helper.c:1253
-msgid "reset the bisection state"
-msgstr ""
-
-#: builtin/bisect--helper.c:1255
-msgid "check whether bad or good terms exist"
-msgstr ""
-
-#: builtin/bisect--helper.c:1257
-msgid "print out the bisect terms"
-msgstr ""
-
-#: builtin/bisect--helper.c:1259
-msgid "start the bisect session"
-msgstr ""
-
-#: builtin/bisect--helper.c:1261
-msgid "find the next bisection commit"
-msgstr ""
-
-#: builtin/bisect--helper.c:1263
-msgid "mark the state of ref (or refs)"
-msgstr ""
-
-#: builtin/bisect--helper.c:1265
-msgid "list the bisection steps so far"
-msgstr ""
-
-#: builtin/bisect--helper.c:1267
-msgid "replay the bisection process from the given file"
-msgstr ""
-
-#: builtin/bisect--helper.c:1269
-msgid "skip some commits for checkout"
-msgstr ""
-
-#: builtin/bisect--helper.c:1271
-msgid "visualize the bisection"
-msgstr ""
-
-#: builtin/bisect--helper.c:1273
-msgid "use <cmd>... to automatically bisect"
-msgstr ""
-
-#: builtin/bisect--helper.c:1275
-msgid "no log for BISECT_WRITE"
-msgstr ""
-
-#: builtin/bisect--helper.c:1290
-msgid "--bisect-reset requires either no argument or a commit"
-msgstr ""
-
-#: builtin/bisect--helper.c:1295
-msgid "--bisect-terms requires 0 or 1 argument"
-msgstr ""
-
-#: builtin/bisect--helper.c:1304
-msgid "--bisect-next requires 0 arguments"
-msgstr ""
-
-#: builtin/bisect--helper.c:1315
-msgid "--bisect-log requires 0 arguments"
-msgstr ""
-
-#: builtin/bisect--helper.c:1320
-msgid "no logfile given"
-msgstr ""
-
-#: builtin/blame.c:32
-msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
-msgstr ""
-
-#: builtin/blame.c:37
-msgid "<rev-opts> are documented in git-rev-list(1)"
-msgstr ""
-
-#: builtin/blame.c:406
-#, c-format
-msgid "expecting a color: %s"
-msgstr ""
-
-#: builtin/blame.c:413
-msgid "must end with a color"
-msgstr ""
-
-#: builtin/blame.c:842
-#, c-format
-msgid "cannot find revision %s to ignore"
-msgstr ""
-
-#: builtin/blame.c:864
-msgid "show blame entries as we find them, incrementally"
-msgstr ""
-
-#: builtin/blame.c:865
-msgid "do not show object names of boundary commits (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:866
-msgid "do not treat root commits as boundaries (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:867
-msgid "show work cost statistics"
-msgstr ""
-
-#: builtin/blame.c:868 builtin/checkout.c:1554 builtin/clone.c:98
-#: builtin/commit-graph.c:75 builtin/commit-graph.c:228 builtin/fetch.c:181
-#: builtin/merge.c:301 builtin/multi-pack-index.c:103
-#: builtin/multi-pack-index.c:154 builtin/multi-pack-index.c:180
-#: builtin/multi-pack-index.c:208 builtin/pull.c:120 builtin/push.c:566
-#: builtin/remote.c:683 builtin/send-pack.c:202
-msgid "force progress reporting"
-msgstr ""
-
-#: builtin/blame.c:869
-msgid "show output score for blame entries"
-msgstr ""
-
-#: builtin/blame.c:870
-msgid "show original filename (Default: auto)"
-msgstr ""
-
-#: builtin/blame.c:871
-msgid "show original linenumber (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:872
-msgid "show in a format designed for machine consumption"
-msgstr ""
-
-#: builtin/blame.c:873
-msgid "show porcelain format with per-line commit information"
-msgstr ""
-
-#: builtin/blame.c:874
-msgid "use the same output mode as git-annotate (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:875
-msgid "show raw timestamp (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:876
-msgid "show long commit SHA1 (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:877
-msgid "suppress author name and timestamp (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:878
-msgid "show author email instead of name (Default: off)"
-msgstr ""
-
-#: builtin/blame.c:879
-msgid "ignore whitespace differences"
-msgstr ""
-
-#: builtin/blame.c:880 builtin/log.c:1857
-msgid "rev"
-msgstr ""
-
-#: builtin/blame.c:880
-msgid "ignore <rev> when blaming"
-msgstr ""
-
-#: builtin/blame.c:881
-msgid "ignore revisions from <file>"
-msgstr ""
-
-#: builtin/blame.c:882
-msgid "color redundant metadata from previous line differently"
-msgstr ""
-
-#: builtin/blame.c:883
-msgid "color lines by age"
-msgstr ""
-
-#: builtin/blame.c:884
-msgid "spend extra cycles to find better match"
-msgstr ""
-
-#: builtin/blame.c:885
-msgid "use revisions from <file> instead of calling git-rev-list"
-msgstr ""
-
-#: builtin/blame.c:886
-msgid "use <file>'s contents as the final image"
-msgstr ""
-
-#: builtin/blame.c:887 builtin/blame.c:888
-msgid "score"
-msgstr ""
-
-#: builtin/blame.c:887
-msgid "find line copies within and across files"
-msgstr ""
-
-#: builtin/blame.c:888
-msgid "find line movements within and across files"
-msgstr ""
-
-#: builtin/blame.c:889
-msgid "range"
-msgstr ""
-
-#: builtin/blame.c:890
-msgid "process only line range <start>,<end> or function :<funcname>"
-msgstr ""
-
-#: builtin/blame.c:949
-msgid "--progress can't be used with --incremental or porcelain formats"
-msgstr ""
-
-#. TRANSLATORS: This string is used to tell us the
-#. maximum display width for a relative timestamp in
-#. "git blame" output.  For C locale, "4 years, 11
-#. months ago", which takes 22 places, is the longest
-#. among various forms of relative timestamps, but
-#. your language may need more or fewer display
-#. columns.
-#.
-#: builtin/blame.c:1000
-msgid "4 years, 11 months ago"
-msgstr ""
-
-#: builtin/blame.c:1116
-#, c-format
-msgid "file %s has only %lu line"
-msgid_plural "file %s has only %lu lines"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/blame.c:1161
-msgid "Blaming lines"
-msgstr ""
-
-#: builtin/branch.c:29
-msgid "git branch [<options>] [-r | -a] [--merged] [--no-merged]"
-msgstr ""
-
-#: builtin/branch.c:30
-msgid ""
-"git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-"
-"point>]"
-msgstr ""
-
-#: builtin/branch.c:31
-msgid "git branch [<options>] [-l] [<pattern>...]"
-msgstr ""
-
-#: builtin/branch.c:32
-msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..."
-msgstr ""
-
-#: builtin/branch.c:33
-msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"
-msgstr ""
-
-#: builtin/branch.c:34
-msgid "git branch [<options>] (-c | -C) [<old-branch>] <new-branch>"
-msgstr ""
-
-#: builtin/branch.c:35
-msgid "git branch [<options>] [-r | -a] [--points-at]"
-msgstr ""
-
-#: builtin/branch.c:36
-msgid "git branch [<options>] [-r | -a] [--format]"
-msgstr ""
-
-#: builtin/branch.c:165
-#, c-format
-msgid ""
-"deleting branch '%s' that has been merged to\n"
-"         '%s', but not yet merged to HEAD."
-msgstr ""
-
-#: builtin/branch.c:169
-#, c-format
-msgid ""
-"not deleting branch '%s' that is not yet merged to\n"
-"         '%s', even though it is merged to HEAD."
-msgstr ""
-
-#: builtin/branch.c:183
-#, c-format
-msgid "Couldn't look up commit object for '%s'"
-msgstr ""
-
-#: builtin/branch.c:187
-#, c-format
-msgid ""
-"The branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'."
-msgstr ""
-
-#: builtin/branch.c:200
-msgid "Update of config-file failed"
-msgstr ""
-
-#: builtin/branch.c:235
-msgid "cannot use -a with -d"
-msgstr ""
-
-#: builtin/branch.c:242
-msgid "Couldn't look up commit object for HEAD"
-msgstr ""
-
-#: builtin/branch.c:259
-#, c-format
-msgid "Cannot delete branch '%s' checked out at '%s'"
-msgstr ""
-
-#: builtin/branch.c:274
-#, c-format
-msgid "remote-tracking branch '%s' not found."
-msgstr ""
-
-#: builtin/branch.c:275
-#, c-format
-msgid "branch '%s' not found."
-msgstr ""
-
-#: builtin/branch.c:306
-#, c-format
-msgid "Deleted remote-tracking branch %s (was %s).\n"
-msgstr ""
-
-#: builtin/branch.c:307
-#, c-format
-msgid "Deleted branch %s (was %s).\n"
-msgstr ""
-
-#: builtin/branch.c:457 builtin/tag.c:64
-msgid "unable to parse format string"
-msgstr ""
-
-#: builtin/branch.c:488
-msgid "could not resolve HEAD"
-msgstr ""
-
-#: builtin/branch.c:494
-#, c-format
-msgid "HEAD (%s) points outside of refs/heads/"
-msgstr ""
-
-#: builtin/branch.c:509
-#, c-format
-msgid "Branch %s is being rebased at %s"
-msgstr ""
-
-#: builtin/branch.c:513
-#, c-format
-msgid "Branch %s is being bisected at %s"
-msgstr ""
-
-#: builtin/branch.c:530
-msgid "cannot copy the current branch while not on any."
-msgstr ""
-
-#: builtin/branch.c:532
-msgid "cannot rename the current branch while not on any."
-msgstr ""
-
-#: builtin/branch.c:543
-#, c-format
-msgid "Invalid branch name: '%s'"
-msgstr ""
-
-#: builtin/branch.c:572
-msgid "Branch rename failed"
-msgstr ""
-
-#: builtin/branch.c:574
-msgid "Branch copy failed"
-msgstr ""
-
-#: builtin/branch.c:578
-#, c-format
-msgid "Created a copy of a misnamed branch '%s'"
-msgstr ""
-
-#: builtin/branch.c:581
-#, c-format
-msgid "Renamed a misnamed branch '%s' away"
-msgstr ""
-
-#: builtin/branch.c:587
-#, c-format
-msgid "Branch renamed to %s, but HEAD is not updated!"
-msgstr ""
-
-#: builtin/branch.c:596
-msgid "Branch is renamed, but update of config-file failed"
-msgstr ""
-
-#: builtin/branch.c:598
-msgid "Branch is copied, but update of config-file failed"
-msgstr ""
-
-#: builtin/branch.c:614
-#, c-format
-msgid ""
-"Please edit the description for the branch\n"
-"  %s\n"
-"Lines starting with '%c' will be stripped.\n"
-msgstr ""
-
-#: builtin/branch.c:651
-msgid "Generic options"
-msgstr ""
-
-#: builtin/branch.c:653
-msgid "show hash and subject, give twice for upstream branch"
-msgstr ""
-
-#: builtin/branch.c:654
-msgid "suppress informational messages"
-msgstr ""
-
-#: builtin/branch.c:656 builtin/checkout.c:1571
-#: builtin/submodule--helper.c:3077
-msgid "set branch tracking configuration"
-msgstr ""
-
-#: builtin/branch.c:659
-msgid "do not use"
-msgstr ""
-
-#: builtin/branch.c:661
-msgid "upstream"
-msgstr ""
-
-#: builtin/branch.c:661
-msgid "change the upstream info"
-msgstr ""
-
-#: builtin/branch.c:662
-msgid "unset the upstream info"
-msgstr ""
-
-#: builtin/branch.c:663
-msgid "use colored output"
-msgstr ""
-
-#: builtin/branch.c:664
-msgid "act on remote-tracking branches"
-msgstr ""
-
-#: builtin/branch.c:666 builtin/branch.c:668
-msgid "print only branches that contain the commit"
-msgstr ""
-
-#: builtin/branch.c:667 builtin/branch.c:669
-msgid "print only branches that don't contain the commit"
-msgstr ""
-
-#: builtin/branch.c:672
-msgid "Specific git-branch actions:"
-msgstr ""
-
-#: builtin/branch.c:673
-msgid "list both remote-tracking and local branches"
-msgstr ""
-
-#: builtin/branch.c:675
-msgid "delete fully merged branch"
-msgstr ""
-
-#: builtin/branch.c:676
-msgid "delete branch (even if not merged)"
-msgstr ""
-
-#: builtin/branch.c:677
-msgid "move/rename a branch and its reflog"
-msgstr ""
-
-#: builtin/branch.c:678
-msgid "move/rename a branch, even if target exists"
-msgstr ""
-
-#: builtin/branch.c:679
-msgid "copy a branch and its reflog"
-msgstr ""
-
-#: builtin/branch.c:680
-msgid "copy a branch, even if target exists"
-msgstr ""
-
-#: builtin/branch.c:681
-msgid "list branch names"
-msgstr ""
-
-#: builtin/branch.c:682
-msgid "show current branch name"
-msgstr ""
-
-#: builtin/branch.c:683 builtin/submodule--helper.c:3075
-msgid "create the branch's reflog"
-msgstr ""
-
-#: builtin/branch.c:685
-msgid "edit the description for the branch"
-msgstr ""
-
-#: builtin/branch.c:686
-msgid "force creation, move/rename, deletion"
-msgstr ""
-
-#: builtin/branch.c:687
-msgid "print only branches that are merged"
-msgstr ""
-
-#: builtin/branch.c:688
-msgid "print only branches that are not merged"
-msgstr ""
-
-#: builtin/branch.c:689
-msgid "list branches in columns"
-msgstr ""
-
-#: builtin/branch.c:691 builtin/for-each-ref.c:45 builtin/notes.c:413
-#: builtin/notes.c:416 builtin/notes.c:579 builtin/notes.c:582
-#: builtin/tag.c:476
-msgid "object"
-msgstr ""
-
-#: builtin/branch.c:692
-msgid "print only branches of the object"
-msgstr ""
-
-#: builtin/branch.c:693 builtin/for-each-ref.c:51 builtin/tag.c:483
-msgid "sorting and filtering are case insensitive"
-msgstr ""
-
-#: builtin/branch.c:694 builtin/ls-files.c:667
-msgid "recurse through submodules"
-msgstr ""
-
-#: builtin/branch.c:695 builtin/for-each-ref.c:41 builtin/ls-tree.c:358
-#: builtin/tag.c:481 builtin/verify-tag.c:38
-msgid "format to use for the output"
-msgstr ""
-
-#: builtin/branch.c:718 builtin/clone.c:684
-msgid "HEAD not found below refs/heads!"
-msgstr ""
-
-#: builtin/branch.c:739
-msgid ""
-"branch with --recurse-submodules can only be used if submodule."
-"propagateBranches is enabled"
-msgstr ""
-
-#: builtin/branch.c:741
-msgid "--recurse-submodules can only be used to create branches"
-msgstr ""
-
-#: builtin/branch.c:770 builtin/branch.c:826 builtin/branch.c:835
-msgid "branch name required"
-msgstr ""
-
-#: builtin/branch.c:802
-msgid "Cannot give description to detached HEAD"
-msgstr ""
-
-#: builtin/branch.c:807
-msgid "cannot edit description of more than one branch"
-msgstr ""
-
-#: builtin/branch.c:814
-#, c-format
-msgid "No commit on branch '%s' yet."
-msgstr ""
-
-#: builtin/branch.c:817
-#, c-format
-msgid "No branch named '%s'."
-msgstr ""
-
-#: builtin/branch.c:832
-msgid "too many branches for a copy operation"
-msgstr ""
-
-#: builtin/branch.c:841
-msgid "too many arguments for a rename operation"
-msgstr ""
-
-#: builtin/branch.c:846
-msgid "too many arguments to set new upstream"
-msgstr ""
-
-#: builtin/branch.c:850
-#, c-format
-msgid ""
-"could not set upstream of HEAD to %s when it does not point to any branch."
-msgstr ""
-
-#: builtin/branch.c:853 builtin/branch.c:873
-#, c-format
-msgid "no such branch '%s'"
-msgstr ""
-
-#: builtin/branch.c:857
-#, c-format
-msgid "branch '%s' does not exist"
-msgstr ""
-
-#: builtin/branch.c:867
-msgid "too many arguments to unset upstream"
-msgstr ""
-
-#: builtin/branch.c:871
-msgid "could not unset upstream of HEAD when it does not point to any branch."
-msgstr ""
-
-#: builtin/branch.c:877
-#, c-format
-msgid "Branch '%s' has no upstream information"
-msgstr ""
-
-#: builtin/branch.c:890
-msgid ""
-"The -a, and -r, options to 'git branch' do not take a branch name.\n"
-"Did you mean to use: -a|-r --list <pattern>?"
-msgstr ""
-
-#: builtin/branch.c:894
-msgid ""
-"the '--set-upstream' option is no longer supported. Please use '--track' or "
-"'--set-upstream-to' instead."
-msgstr ""
-
-#: builtin/bugreport.c:16
-msgid "git version:\n"
-msgstr ""
-
-#: builtin/bugreport.c:22
-#, c-format
-msgid "uname() failed with error '%s' (%d)\n"
-msgstr ""
-
-#: builtin/bugreport.c:32
-msgid "compiler info: "
-msgstr ""
-
-#: builtin/bugreport.c:35
-msgid "libc info: "
-msgstr ""
-
-#: builtin/bugreport.c:49
-msgid "not run from a git repository - no hooks to show\n"
-msgstr ""
-
-#: builtin/bugreport.c:62
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
-msgstr ""
-
-#: builtin/bugreport.c:69
-msgid ""
-"Thank you for filling out a Git bug report!\n"
-"Please answer the following questions to help us understand your issue.\n"
-"\n"
-"What did you do before the bug happened? (Steps to reproduce your issue)\n"
-"\n"
-"What did you expect to happen? (Expected behavior)\n"
-"\n"
-"What happened instead? (Actual behavior)\n"
-"\n"
-"What's different between what you expected and what actually happened?\n"
-"\n"
-"Anything else you want to add:\n"
-"\n"
-"Please review the rest of the bug report below.\n"
-"You can delete any lines you don't wish to share.\n"
-msgstr ""
-
-#: builtin/bugreport.c:108
-msgid "specify a destination for the bugreport file"
-msgstr ""
-
-#: builtin/bugreport.c:110
-msgid "specify a strftime format suffix for the filename"
-msgstr ""
-
-#: builtin/bugreport.c:132
-#, c-format
-msgid "could not create leading directories for '%s'"
-msgstr ""
-
-#: builtin/bugreport.c:139
-msgid "System Info"
-msgstr ""
-
-#: builtin/bugreport.c:142
-msgid "Enabled Hooks"
-msgstr ""
-
-#: builtin/bugreport.c:149
-#, c-format
-msgid "unable to write to %s"
-msgstr ""
-
-#: builtin/bugreport.c:159
-#, c-format
-msgid "Created new report at '%s'.\n"
-msgstr ""
-
-#: builtin/bundle.c:15 builtin/bundle.c:23
-msgid "git bundle create [<options>] <file> <git-rev-list args>"
-msgstr ""
-
-#: builtin/bundle.c:16 builtin/bundle.c:28
-msgid "git bundle verify [<options>] <file>"
-msgstr ""
-
-#: builtin/bundle.c:17 builtin/bundle.c:33
-msgid "git bundle list-heads <file> [<refname>...]"
-msgstr ""
-
-#: builtin/bundle.c:18 builtin/bundle.c:38
-msgid "git bundle unbundle <file> [<refname>...]"
-msgstr ""
-
-#: builtin/bundle.c:65 builtin/pack-objects.c:3899
-msgid "do not show progress meter"
-msgstr ""
-
-#: builtin/bundle.c:67 builtin/bundle.c:168 builtin/pack-objects.c:3901
-msgid "show progress meter"
-msgstr ""
-
-#: builtin/bundle.c:69 builtin/pack-objects.c:3903
-msgid "show progress meter during object writing phase"
-msgstr ""
-
-#: builtin/bundle.c:72 builtin/pack-objects.c:3906
-msgid "similar to --all-progress when progress meter is shown"
-msgstr ""
-
-#: builtin/bundle.c:74
-msgid "specify bundle format version"
-msgstr ""
-
-#: builtin/bundle.c:94
-msgid "Need a repository to create a bundle."
-msgstr ""
-
-#: builtin/bundle.c:108
-msgid "do not show bundle details"
-msgstr ""
-
-#: builtin/bundle.c:127
-#, c-format
-msgid "%s is okay\n"
-msgstr ""
-
-#: builtin/bundle.c:183
-msgid "Need a repository to unbundle."
-msgstr ""
-
-#: builtin/bundle.c:186
-msgid "Unbundling objects"
-msgstr ""
-
-#: builtin/bundle.c:220 builtin/remote.c:1758
-#, c-format
-msgid "Unknown subcommand: %s"
-msgstr ""
-
-#: builtin/cat-file.c:568
-msgid "flush is only for --buffer mode"
-msgstr ""
-
-#: builtin/cat-file.c:612
-msgid "empty command in input"
-msgstr ""
-
-#: builtin/cat-file.c:614
-#, c-format
-msgid "whitespace before command: '%s'"
-msgstr ""
-
-#: builtin/cat-file.c:623
-#, c-format
-msgid "%s requires arguments"
-msgstr ""
-
-#: builtin/cat-file.c:628
-#, c-format
-msgid "%s takes no arguments"
-msgstr ""
-
-#: builtin/cat-file.c:636
-#, c-format
-msgid "unknown command: '%s'"
-msgstr ""
-
-#: builtin/cat-file.c:795
-msgid "only one batch option may be specified"
-msgstr ""
-
-#: builtin/cat-file.c:824
-msgid "git cat-file <type> <object>"
-msgstr ""
-
-#: builtin/cat-file.c:825
-msgid "git cat-file (-e | -p) <object>"
-msgstr ""
-
-#: builtin/cat-file.c:826
-msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>"
-msgstr ""
-
-#: builtin/cat-file.c:827
-msgid ""
-"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
-"objects]\n"
-"             [--buffer] [--follow-symlinks] [--unordered]\n"
-"             [--textconv | --filters]"
-msgstr ""
-
-#: builtin/cat-file.c:830
-msgid ""
-"git cat-file (--textconv | --filters)\n"
-"             [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"
-msgstr ""
-
-#: builtin/cat-file.c:836
-msgid "Check object existence or emit object contents"
-msgstr ""
-
-#: builtin/cat-file.c:838
-msgid "check if <object> exists"
-msgstr ""
-
-#: builtin/cat-file.c:839
-msgid "pretty-print <object> content"
-msgstr ""
-
-#: builtin/cat-file.c:841
-msgid "Emit [broken] object attributes"
-msgstr ""
-
-#: builtin/cat-file.c:842
-msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"
-msgstr ""
-
-#: builtin/cat-file.c:843
-msgid "show object size"
-msgstr ""
-
-#: builtin/cat-file.c:845
-msgid "allow -s and -t to work with broken/corrupt objects"
-msgstr ""
-
-#: builtin/cat-file.c:847
-msgid "Batch objects requested on stdin (or --batch-all-objects)"
-msgstr ""
-
-#: builtin/cat-file.c:849
-msgid "show full <object> or <rev> contents"
-msgstr ""
-
-#: builtin/cat-file.c:853
-msgid "like --batch, but don't emit <contents>"
-msgstr ""
-
-#: builtin/cat-file.c:857
-msgid "read commands from stdin"
-msgstr ""
-
-#: builtin/cat-file.c:861
-msgid "with --batch[-check]: ignores stdin, batches all known objects"
-msgstr ""
-
-#: builtin/cat-file.c:863
-msgid "Change or optimize batch output"
-msgstr ""
-
-#: builtin/cat-file.c:864
-msgid "buffer --batch output"
-msgstr ""
-
-#: builtin/cat-file.c:866
-msgid "follow in-tree symlinks"
-msgstr ""
-
-#: builtin/cat-file.c:868
-msgid "do not order objects before emitting them"
-msgstr ""
-
-#: builtin/cat-file.c:870
-msgid ""
-"Emit object (blob or tree) with conversion or filter (stand-alone, or with "
-"batch)"
-msgstr ""
-
-#: builtin/cat-file.c:872
-msgid "run textconv on object's content"
-msgstr ""
-
-#: builtin/cat-file.c:874
-msgid "run filters on object's content"
-msgstr ""
-
-#: builtin/cat-file.c:875
-msgid "blob|tree"
-msgstr ""
-
-#: builtin/cat-file.c:876
-msgid "use a <path> for (--textconv | --filters); Not with 'batch'"
-msgstr ""
-
-#: builtin/cat-file.c:894
-#, c-format
-msgid "'%s=<%s>' needs '%s' or '%s'"
-msgstr ""
-
-#: builtin/cat-file.c:896
-msgid "path|tree-ish"
-msgstr ""
-
-#: builtin/cat-file.c:903 builtin/cat-file.c:906 builtin/cat-file.c:909
-#, c-format
-msgid "'%s' requires a batch mode"
-msgstr ""
-
-#: builtin/cat-file.c:921
-#, c-format
-msgid "'-%c' is incompatible with batch mode"
-msgstr ""
-
-#: builtin/cat-file.c:924
-msgid "batch modes take no arguments"
-msgstr ""
-
-#: builtin/cat-file.c:932 builtin/cat-file.c:935
-#, c-format
-msgid "<rev> required with '%s'"
-msgstr ""
-
-#: builtin/cat-file.c:938
-#, c-format
-msgid "<object> required with '-%c'"
-msgstr ""
-
-#: builtin/cat-file.c:943 builtin/notes.c:374 builtin/notes.c:429
-#: builtin/notes.c:507 builtin/notes.c:519 builtin/notes.c:596
-#: builtin/notes.c:663 builtin/notes.c:813 builtin/notes.c:965
-#: builtin/notes.c:987 builtin/prune-packed.c:25 builtin/receive-pack.c:2489
-#: builtin/tag.c:592
-msgid "too many arguments"
-msgstr ""
-
-#: builtin/cat-file.c:947
-#, c-format
-msgid "only two arguments allowed in <type> <object> mode, not %d"
-msgstr ""
-
-#: builtin/check-attr.c:13
-msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..."
-msgstr ""
-
-#: builtin/check-attr.c:14
-msgid "git check-attr --stdin [-z] [-a | --all | <attr>...]"
-msgstr ""
-
-#: builtin/check-attr.c:21
-msgid "report all attributes set on file"
-msgstr ""
-
-#: builtin/check-attr.c:22
-msgid "use .gitattributes only from the index"
-msgstr ""
-
-#: builtin/check-attr.c:23 builtin/check-ignore.c:25 builtin/hash-object.c:101
-msgid "read file names from stdin"
-msgstr ""
-
-#: builtin/check-attr.c:25 builtin/check-ignore.c:27
-msgid "terminate input and output records by a NUL character"
-msgstr ""
-
-#: builtin/check-ignore.c:21 builtin/checkout.c:1550 builtin/gc.c:550
-#: builtin/worktree.c:565
-msgid "suppress progress reporting"
-msgstr ""
-
-#: builtin/check-ignore.c:29
-msgid "show non-matching input paths"
-msgstr ""
-
-#: builtin/check-ignore.c:31
-msgid "ignore index when checking"
-msgstr ""
-
-#: builtin/check-ignore.c:165
-msgid "cannot specify pathnames with --stdin"
-msgstr ""
-
-#: builtin/check-ignore.c:168
-msgid "-z only makes sense with --stdin"
-msgstr ""
-
-#: builtin/check-ignore.c:170
-msgid "no path specified"
-msgstr ""
-
-#: builtin/check-ignore.c:174
-msgid "--quiet is only valid with a single pathname"
-msgstr ""
-
-#: builtin/check-ignore.c:176
-msgid "cannot have both --quiet and --verbose"
-msgstr ""
-
-#: builtin/check-ignore.c:179
-msgid "--non-matching is only valid with --verbose"
-msgstr ""
-
-#: builtin/check-mailmap.c:9
-msgid "git check-mailmap [<options>] <contact>..."
-msgstr ""
-
-#: builtin/check-mailmap.c:14
-msgid "also read contacts from stdin"
-msgstr ""
-
-#: builtin/check-mailmap.c:25
-#, c-format
-msgid "unable to parse contact: %s"
-msgstr ""
-
-#: builtin/check-mailmap.c:48
-msgid "no contacts specified"
-msgstr ""
-
-#: builtin/checkout--worker.c:110
-msgid "git checkout--worker [<options>]"
-msgstr ""
-
-#: builtin/checkout--worker.c:118 builtin/checkout-index.c:235
-#: builtin/column.c:31 builtin/column.c:32 builtin/submodule--helper.c:1878
-#: builtin/submodule--helper.c:1881 builtin/submodule--helper.c:1889
-#: builtin/submodule--helper.c:2716 builtin/worktree.c:563
-#: builtin/worktree.c:808
-msgid "string"
-msgstr ""
-
-#: builtin/checkout--worker.c:119 builtin/checkout-index.c:236
-msgid "when creating files, prepend <string>"
-msgstr ""
-
-#: builtin/checkout-index.c:184
-msgid "git checkout-index [<options>] [--] [<file>...]"
-msgstr ""
-
-#: builtin/checkout-index.c:201
-msgid "stage should be between 1 and 3 or all"
-msgstr ""
-
-#: builtin/checkout-index.c:219
-msgid "check out all files in the index"
-msgstr ""
-
-#: builtin/checkout-index.c:221
-msgid "do not skip files with skip-worktree set"
-msgstr ""
-
-#: builtin/checkout-index.c:222
-msgid "force overwrite of existing files"
-msgstr ""
-
-#: builtin/checkout-index.c:224
-msgid "no warning for existing files and files not in index"
-msgstr ""
-
-#: builtin/checkout-index.c:226
-msgid "don't checkout new files"
-msgstr ""
-
-#: builtin/checkout-index.c:228
-msgid "update stat information in the index file"
-msgstr ""
-
-#: builtin/checkout-index.c:232
-msgid "read list of paths from the standard input"
-msgstr ""
-
-#: builtin/checkout-index.c:234
-msgid "write the content to temporary files"
-msgstr ""
-
-#: builtin/checkout-index.c:238
-msgid "copy out the files from named stage"
-msgstr ""
-
-#: builtin/checkout.c:34
-msgid "git checkout [<options>] <branch>"
-msgstr ""
-
-#: builtin/checkout.c:35
-msgid "git checkout [<options>] [<branch>] -- <file>..."
-msgstr ""
-
-#: builtin/checkout.c:40
-msgid "git switch [<options>] [<branch>]"
-msgstr ""
-
-#: builtin/checkout.c:45
-msgid "git restore [<options>] [--source=<branch>] <file>..."
-msgstr ""
-
-#: builtin/checkout.c:199 builtin/checkout.c:238
-#, c-format
-msgid "path '%s' does not have our version"
-msgstr ""
-
-#: builtin/checkout.c:201 builtin/checkout.c:240
-#, c-format
-msgid "path '%s' does not have their version"
-msgstr ""
-
-#: builtin/checkout.c:217
-#, c-format
-msgid "path '%s' does not have all necessary versions"
-msgstr ""
-
-#: builtin/checkout.c:271
-#, c-format
-msgid "path '%s' does not have necessary versions"
-msgstr ""
-
-#: builtin/checkout.c:291
-#, c-format
-msgid "path '%s': cannot merge"
-msgstr ""
-
-#: builtin/checkout.c:307
-#, c-format
-msgid "Unable to add merge result for '%s'"
-msgstr ""
-
-#: builtin/checkout.c:424
-#, c-format
-msgid "Recreated %d merge conflict"
-msgid_plural "Recreated %d merge conflicts"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/checkout.c:429
-#, c-format
-msgid "Updated %d path from %s"
-msgid_plural "Updated %d paths from %s"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/checkout.c:436
-#, c-format
-msgid "Updated %d path from the index"
-msgid_plural "Updated %d paths from the index"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/checkout.c:459 builtin/checkout.c:462 builtin/checkout.c:465
-#: builtin/checkout.c:469
-#, c-format
-msgid "'%s' cannot be used with updating paths"
-msgstr ""
-
-#: builtin/checkout.c:479
-#, c-format
-msgid "Cannot update paths and switch to branch '%s' at the same time."
-msgstr ""
-
-#: builtin/checkout.c:483
-#, c-format
-msgid "neither '%s' or '%s' is specified"
-msgstr ""
-
-#: builtin/checkout.c:487
-#, c-format
-msgid "'%s' must be used when '%s' is not specified"
-msgstr ""
-
-#: builtin/checkout.c:492 builtin/checkout.c:497
-#, c-format
-msgid "'%s' or '%s' cannot be used with %s"
-msgstr ""
-
-#: builtin/checkout.c:571 builtin/checkout.c:578
-#, c-format
-msgid "path '%s' is unmerged"
-msgstr ""
-
-#: builtin/checkout.c:753
-msgid "you need to resolve your current index first"
-msgstr ""
-
-#: builtin/checkout.c:809
-#, c-format
-msgid ""
-"cannot continue with staged changes in the following files:\n"
-"%s"
-msgstr ""
-
-#: builtin/checkout.c:902
-#, c-format
-msgid "Can not do reflog for '%s': %s\n"
-msgstr ""
-
-#: builtin/checkout.c:947
-msgid "HEAD is now at"
-msgstr ""
-
-#: builtin/checkout.c:951 builtin/clone.c:615 t/helper/test-fast-rebase.c:203
-msgid "unable to update HEAD"
-msgstr ""
-
-#: builtin/checkout.c:955
-#, c-format
-msgid "Reset branch '%s'\n"
-msgstr ""
-
-#: builtin/checkout.c:958
-#, c-format
-msgid "Already on '%s'\n"
-msgstr ""
-
-#: builtin/checkout.c:962
-#, c-format
-msgid "Switched to and reset branch '%s'\n"
-msgstr ""
-
-#: builtin/checkout.c:964 builtin/checkout.c:1398
-#, c-format
-msgid "Switched to a new branch '%s'\n"
-msgstr ""
-
-#: builtin/checkout.c:966
-#, c-format
-msgid "Switched to branch '%s'\n"
-msgstr ""
-
-#: builtin/checkout.c:1017
-#, c-format
-msgid " ... and %d more.\n"
-msgstr ""
-
-#: builtin/checkout.c:1023
-#, c-format
-msgid ""
-"Warning: you are leaving %d commit behind, not connected to\n"
-"any of your branches:\n"
-"\n"
-"%s\n"
-msgid_plural ""
-"Warning: you are leaving %d commits behind, not connected to\n"
-"any of your branches:\n"
-"\n"
-"%s\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/checkout.c:1042
-#, c-format
-msgid ""
-"If you want to keep it by creating a new branch, this may be a good time\n"
-"to do so with:\n"
-"\n"
-" git branch <new-branch-name> %s\n"
-"\n"
-msgid_plural ""
-"If you want to keep them by creating a new branch, this may be a good time\n"
-"to do so with:\n"
-"\n"
-" git branch <new-branch-name> %s\n"
-"\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/checkout.c:1077
-msgid "internal error in revision walk"
-msgstr ""
-
-#: builtin/checkout.c:1081
-msgid "Previous HEAD position was"
-msgstr ""
-
-#: builtin/checkout.c:1124 builtin/checkout.c:1393
-msgid "You are on a branch yet to be born"
-msgstr ""
-
-#: builtin/checkout.c:1206
-#, c-format
-msgid ""
-"'%s' could be both a local file and a tracking branch.\n"
-"Please use -- (and optionally --no-guess) to disambiguate"
-msgstr ""
-
-#: builtin/checkout.c:1213
-msgid ""
-"If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
-"you can do so by fully qualifying the name with the --track option:\n"
-"\n"
-"    git checkout --track origin/<name>\n"
-"\n"
-"If you'd like to always have checkouts of an ambiguous <name> prefer\n"
-"one remote, e.g. the 'origin' remote, consider setting\n"
-"checkout.defaultRemote=origin in your config."
-msgstr ""
-
-#: builtin/checkout.c:1223
-#, c-format
-msgid "'%s' matched multiple (%d) remote tracking branches"
-msgstr ""
-
-#: builtin/checkout.c:1289
-msgid "only one reference expected"
-msgstr ""
-
-#: builtin/checkout.c:1306
-#, c-format
-msgid "only one reference expected, %d given."
-msgstr ""
-
-#: builtin/checkout.c:1352 builtin/worktree.c:338 builtin/worktree.c:508
-#, c-format
-msgid "invalid reference: %s"
-msgstr ""
-
-#: builtin/checkout.c:1365 builtin/checkout.c:1744
-#, c-format
-msgid "reference is not a tree: %s"
-msgstr ""
-
-#: builtin/checkout.c:1413
-#, c-format
-msgid "a branch is expected, got tag '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1415
-#, c-format
-msgid "a branch is expected, got remote branch '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1417 builtin/checkout.c:1426
-#, c-format
-msgid "a branch is expected, got '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1420
-#, c-format
-msgid "a branch is expected, got commit '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1429
-msgid ""
-"If you want to detach HEAD at the commit, try again with the --detach option."
-msgstr ""
-
-#: builtin/checkout.c:1442
-msgid ""
-"cannot switch branch while merging\n"
-"Consider \"git merge --quit\" or \"git worktree add\"."
-msgstr ""
-
-#: builtin/checkout.c:1446
-msgid ""
-"cannot switch branch in the middle of an am session\n"
-"Consider \"git am --quit\" or \"git worktree add\"."
-msgstr ""
-
-#: builtin/checkout.c:1450
-msgid ""
-"cannot switch branch while rebasing\n"
-"Consider \"git rebase --quit\" or \"git worktree add\"."
-msgstr ""
-
-#: builtin/checkout.c:1454
-msgid ""
-"cannot switch branch while cherry-picking\n"
-"Consider \"git cherry-pick --quit\" or \"git worktree add\"."
-msgstr ""
-
-#: builtin/checkout.c:1458
-msgid ""
-"cannot switch branch while reverting\n"
-"Consider \"git revert --quit\" or \"git worktree add\"."
-msgstr ""
-
-#: builtin/checkout.c:1462
-msgid "you are switching branch while bisecting"
-msgstr ""
-
-#: builtin/checkout.c:1469
-msgid "paths cannot be used with switching branches"
-msgstr ""
-
-#: builtin/checkout.c:1472 builtin/checkout.c:1476 builtin/checkout.c:1480
-#, c-format
-msgid "'%s' cannot be used with switching branches"
-msgstr ""
-
-#: builtin/checkout.c:1484 builtin/checkout.c:1487 builtin/checkout.c:1490
-#: builtin/checkout.c:1495 builtin/checkout.c:1500
-#, c-format
-msgid "'%s' cannot be used with '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1497
-#, c-format
-msgid "'%s' cannot take <start-point>"
-msgstr ""
-
-#: builtin/checkout.c:1505
-#, c-format
-msgid "Cannot switch branch to a non-commit '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1512
-msgid "missing branch or commit argument"
-msgstr ""
-
-#: builtin/checkout.c:1555
-msgid "perform a 3-way merge with the new branch"
-msgstr ""
-
-#: builtin/checkout.c:1556 builtin/log.c:1844 parse-options.h:354
-msgid "style"
-msgstr ""
-
-#: builtin/checkout.c:1557
-msgid "conflict style (merge, diff3, or zdiff3)"
-msgstr ""
-
-#: builtin/checkout.c:1569 builtin/worktree.c:560
-msgid "detach HEAD at named commit"
-msgstr ""
-
-#: builtin/checkout.c:1574
-msgid "force checkout (throw away local modifications)"
-msgstr ""
-
-#: builtin/checkout.c:1576
-msgid "new-branch"
-msgstr ""
-
-#: builtin/checkout.c:1576
-msgid "new unparented branch"
-msgstr ""
-
-#: builtin/checkout.c:1578 builtin/merge.c:305
-msgid "update ignored files (default)"
-msgstr ""
-
-#: builtin/checkout.c:1581
-msgid "do not check if another worktree is holding the given ref"
-msgstr ""
-
-#: builtin/checkout.c:1594
-msgid "checkout our version for unmerged files"
-msgstr ""
-
-#: builtin/checkout.c:1597
-msgid "checkout their version for unmerged files"
-msgstr ""
-
-#: builtin/checkout.c:1601
-msgid "do not limit pathspecs to sparse entries only"
-msgstr ""
-
-#: builtin/checkout.c:1659
-#, c-format
-msgid "options '-%c', '-%c', and '%s' cannot be used together"
-msgstr ""
-
-#: builtin/checkout.c:1700
-msgid "--track needs a branch name"
-msgstr ""
-
-#: builtin/checkout.c:1705
-#, c-format
-msgid "missing branch name; try -%c"
-msgstr ""
-
-#: builtin/checkout.c:1737
-#, c-format
-msgid "could not resolve %s"
-msgstr ""
-
-#: builtin/checkout.c:1753
-msgid "invalid path specification"
-msgstr ""
-
-#: builtin/checkout.c:1760
-#, c-format
-msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
-msgstr ""
-
-#: builtin/checkout.c:1764
-#, c-format
-msgid "git checkout: --detach does not take a path argument '%s'"
-msgstr ""
-
-#: builtin/checkout.c:1789
-msgid ""
-"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
-"checking out of the index."
-msgstr ""
-
-#: builtin/checkout.c:1794
-msgid "you must specify path(s) to restore"
-msgstr ""
-
-#: builtin/checkout.c:1819 builtin/checkout.c:1821 builtin/checkout.c:1873
-#: builtin/checkout.c:1875 builtin/clone.c:130 builtin/remote.c:171
-#: builtin/remote.c:173 builtin/submodule--helper.c:3038
-#: builtin/submodule--helper.c:3371 builtin/worktree.c:556
-#: builtin/worktree.c:558
-msgid "branch"
-msgstr ""
-
-#: builtin/checkout.c:1820
-msgid "create and checkout a new branch"
-msgstr ""
-
-#: builtin/checkout.c:1822
-msgid "create/reset and checkout a branch"
-msgstr ""
-
-#: builtin/checkout.c:1823
-msgid "create reflog for new branch"
-msgstr ""
-
-#: builtin/checkout.c:1825
-msgid "second guess 'git checkout <no-such-branch>' (default)"
-msgstr ""
-
-#: builtin/checkout.c:1826
-msgid "use overlay mode (default)"
-msgstr ""
-
-#: builtin/checkout.c:1874
-msgid "create and switch to a new branch"
-msgstr ""
-
-#: builtin/checkout.c:1876
-msgid "create/reset and switch to a branch"
-msgstr ""
-
-#: builtin/checkout.c:1878
-msgid "second guess 'git switch <no-such-branch>'"
-msgstr ""
-
-#: builtin/checkout.c:1880
-msgid "throw away local modifications"
-msgstr ""
-
-#: builtin/checkout.c:1916
-msgid "which tree-ish to checkout from"
-msgstr ""
-
-#: builtin/checkout.c:1918
-msgid "restore the index"
-msgstr ""
-
-#: builtin/checkout.c:1920
-msgid "restore the working tree (default)"
-msgstr ""
-
-#: builtin/checkout.c:1922
-msgid "ignore unmerged entries"
-msgstr ""
-
-#: builtin/checkout.c:1923
-msgid "use overlay mode"
-msgstr ""
-
-#: builtin/clean.c:29
-msgid ""
-"git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
-msgstr ""
-
-#: builtin/clean.c:33
-#, c-format
-msgid "Removing %s\n"
-msgstr ""
-
-#: builtin/clean.c:34
-#, c-format
-msgid "Would remove %s\n"
-msgstr ""
-
-#: builtin/clean.c:35
-#, c-format
-msgid "Skipping repository %s\n"
-msgstr ""
-
-#: builtin/clean.c:36
-#, c-format
-msgid "Would skip repository %s\n"
-msgstr ""
-
-#: builtin/clean.c:38
-#, c-format
-msgid "could not lstat %s\n"
-msgstr ""
-
-#: builtin/clean.c:39
-msgid "Refusing to remove current working directory\n"
-msgstr ""
-
-#: builtin/clean.c:40
-msgid "Would refuse to remove current working directory\n"
-msgstr ""
-
-#: builtin/clean.c:326 git-add--interactive.perl:593
-#, c-format
-msgid ""
-"Prompt help:\n"
-"1          - select a numbered item\n"
-"foo        - select item based on unique prefix\n"
-"           - (empty) select nothing\n"
-msgstr ""
-
-#: builtin/clean.c:330 git-add--interactive.perl:602
-#, c-format
-msgid ""
-"Prompt help:\n"
-"1          - select a single item\n"
-"3-5        - select a range of items\n"
-"2-3,6-9    - select multiple ranges\n"
-"foo        - select item based on unique prefix\n"
-"-...       - unselect specified items\n"
-"*          - choose all items\n"
-"           - (empty) finish selecting\n"
-msgstr ""
-
-#: builtin/clean.c:545 git-add--interactive.perl:568
-#: git-add--interactive.perl:573
-#, c-format, perl-format
-msgid "Huh (%s)?\n"
-msgstr ""
-
-#: builtin/clean.c:685
-#, c-format
-msgid "Input ignore patterns>> "
-msgstr ""
-
-#: builtin/clean.c:719
-#, c-format
-msgid "WARNING: Cannot find items matched by: %s"
-msgstr ""
-
-#: builtin/clean.c:740
-msgid "Select items to delete"
-msgstr ""
-
-#. TRANSLATORS: Make sure to keep [y/N] as is
-#: builtin/clean.c:781
-#, c-format
-msgid "Remove %s [y/N]? "
-msgstr ""
-
-#: builtin/clean.c:812
-msgid ""
-"clean               - start cleaning\n"
-"filter by pattern   - exclude items from deletion\n"
-"select by numbers   - select items to be deleted by numbers\n"
-"ask each            - confirm each deletion (like \"rm -i\")\n"
-"quit                - stop cleaning\n"
-"help                - this screen\n"
-"?                   - help for prompt selection"
-msgstr ""
-
-#: builtin/clean.c:848
-msgid "Would remove the following item:"
-msgid_plural "Would remove the following items:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/clean.c:864
-msgid "No more files to clean, exiting."
-msgstr ""
-
-#: builtin/clean.c:926
-msgid "do not print names of files removed"
-msgstr ""
-
-#: builtin/clean.c:928
-msgid "force"
-msgstr ""
-
-#: builtin/clean.c:929
-msgid "interactive cleaning"
-msgstr ""
-
-#: builtin/clean.c:931
-msgid "remove whole directories"
-msgstr ""
-
-#: builtin/clean.c:932 builtin/describe.c:565 builtin/describe.c:567
-#: builtin/grep.c:938 builtin/log.c:185 builtin/log.c:187
-#: builtin/ls-files.c:651 builtin/name-rev.c:585 builtin/name-rev.c:587
-#: builtin/show-ref.c:179
-msgid "pattern"
-msgstr ""
-
-#: builtin/clean.c:933
-msgid "add <pattern> to ignore rules"
-msgstr ""
-
-#: builtin/clean.c:934
-msgid "remove ignored files, too"
-msgstr ""
-
-#: builtin/clean.c:936
-msgid "remove only ignored files"
-msgstr ""
-
-#: builtin/clean.c:951
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
-msgstr ""
-
-#: builtin/clean.c:954
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-
-#: builtin/clean.c:966
-msgid "-x and -X cannot be used together"
-msgstr ""
-
-#: builtin/clone.c:47
-msgid "git clone [<options>] [--] <repo> [<dir>]"
-msgstr ""
-
-#: builtin/clone.c:100
-msgid "don't clone shallow repository"
-msgstr ""
-
-#: builtin/clone.c:102
-msgid "don't create a checkout"
-msgstr ""
-
-#: builtin/clone.c:103 builtin/clone.c:105 builtin/init-db.c:542
-msgid "create a bare repository"
-msgstr ""
-
-#: builtin/clone.c:107
-msgid "create a mirror repository (implies bare)"
-msgstr ""
-
-#: builtin/clone.c:109
-msgid "to clone from a local repository"
-msgstr ""
-
-#: builtin/clone.c:111
-msgid "don't use local hardlinks, always copy"
-msgstr ""
-
-#: builtin/clone.c:113
-msgid "setup as shared repository"
-msgstr ""
-
-#: builtin/clone.c:115
-msgid "pathspec"
-msgstr ""
-
-#: builtin/clone.c:115
-msgid "initialize submodules in the clone"
-msgstr ""
-
-#: builtin/clone.c:119
-msgid "number of submodules cloned in parallel"
-msgstr ""
-
-#: builtin/clone.c:120 builtin/init-db.c:539
-msgid "template-directory"
-msgstr ""
-
-#: builtin/clone.c:121 builtin/init-db.c:540
-msgid "directory from which templates will be used"
-msgstr ""
-
-#: builtin/clone.c:123 builtin/clone.c:125 builtin/submodule--helper.c:1885
-#: builtin/submodule--helper.c:2719 builtin/submodule--helper.c:3378
-msgid "reference repository"
-msgstr ""
-
-#: builtin/clone.c:127 builtin/submodule--helper.c:1887
-#: builtin/submodule--helper.c:2721
-msgid "use --reference only while cloning"
-msgstr ""
-
-#: builtin/clone.c:128 builtin/column.c:27 builtin/fmt-merge-msg.c:27
-#: builtin/init-db.c:550 builtin/merge-file.c:48 builtin/merge.c:290
-#: builtin/pack-objects.c:3967 builtin/repack.c:669
-#: builtin/submodule--helper.c:3380 t/helper/test-simple-ipc.c:595
-#: t/helper/test-simple-ipc.c:597
-msgid "name"
-msgstr ""
-
-#: builtin/clone.c:129
-msgid "use <name> instead of 'origin' to track upstream"
-msgstr ""
-
-#: builtin/clone.c:131
-msgid "checkout <branch> instead of the remote's HEAD"
-msgstr ""
-
-#: builtin/clone.c:133
-msgid "path to git-upload-pack on the remote"
-msgstr ""
-
-#: builtin/clone.c:134 builtin/fetch.c:182 builtin/grep.c:877
-#: builtin/pull.c:212
-msgid "depth"
-msgstr ""
-
-#: builtin/clone.c:135
-msgid "create a shallow clone of that depth"
-msgstr ""
-
-#: builtin/clone.c:136 builtin/fetch.c:184 builtin/pack-objects.c:3956
-#: builtin/pull.c:215
-msgid "time"
-msgstr ""
-
-#: builtin/clone.c:137
-msgid "create a shallow clone since a specific time"
-msgstr ""
-
-#: builtin/clone.c:138 builtin/fetch.c:186 builtin/fetch.c:212
-#: builtin/pull.c:218 builtin/pull.c:243 builtin/rebase.c:1050
-msgid "revision"
-msgstr ""
-
-#: builtin/clone.c:139 builtin/fetch.c:187 builtin/pull.c:219
-msgid "deepen history of shallow clone, excluding rev"
-msgstr ""
-
-#: builtin/clone.c:141 builtin/submodule--helper.c:1897
-#: builtin/submodule--helper.c:2735
-msgid "clone only one branch, HEAD or --branch"
-msgstr ""
-
-#: builtin/clone.c:143
-msgid "don't clone any tags, and make later fetches not to follow them"
-msgstr ""
-
-#: builtin/clone.c:145
-msgid "any cloned submodules will be shallow"
-msgstr ""
-
-#: builtin/clone.c:146 builtin/init-db.c:548
-msgid "gitdir"
-msgstr ""
-
-#: builtin/clone.c:147 builtin/init-db.c:549
-msgid "separate git dir from working tree"
-msgstr ""
-
-#: builtin/clone.c:148
-msgid "key=value"
-msgstr ""
-
-#: builtin/clone.c:149
-msgid "set config inside the new repository"
-msgstr ""
-
-#: builtin/clone.c:151 builtin/fetch.c:207 builtin/ls-remote.c:77
-#: builtin/pull.c:234 builtin/push.c:575 builtin/send-pack.c:200
-msgid "server-specific"
-msgstr ""
-
-#: builtin/clone.c:151 builtin/fetch.c:207 builtin/ls-remote.c:77
-#: builtin/pull.c:235 builtin/push.c:575 builtin/send-pack.c:201
-msgid "option to transmit"
-msgstr ""
-
-#: builtin/clone.c:152 builtin/fetch.c:208 builtin/pull.c:238
-#: builtin/push.c:576
-msgid "use IPv4 addresses only"
-msgstr ""
-
-#: builtin/clone.c:154 builtin/fetch.c:210 builtin/pull.c:241
-#: builtin/push.c:578
-msgid "use IPv6 addresses only"
-msgstr ""
-
-#: builtin/clone.c:158
-msgid "apply partial clone filters to submodules"
-msgstr ""
-
-#: builtin/clone.c:160
-msgid "any cloned submodules will use their remote-tracking branch"
-msgstr ""
-
-#: builtin/clone.c:162
-msgid "initialize sparse-checkout file to include only files at root"
-msgstr ""
-
-#: builtin/clone.c:237
-#, c-format
-msgid "info: Could not add alternate for '%s': %s\n"
-msgstr ""
-
-#: builtin/clone.c:310
-#, c-format
-msgid "%s exists and is not a directory"
-msgstr ""
-
-#: builtin/clone.c:328
-#, c-format
-msgid "failed to start iterator over '%s'"
-msgstr ""
-
-#: builtin/clone.c:359
-#, c-format
-msgid "failed to create link '%s'"
-msgstr ""
-
-#: builtin/clone.c:363
-#, c-format
-msgid "failed to copy file to '%s'"
-msgstr ""
-
-#: builtin/clone.c:368
-#, c-format
-msgid "failed to iterate over '%s'"
-msgstr ""
-
-#: builtin/clone.c:395
-#, c-format
-msgid "done.\n"
-msgstr ""
-
-#: builtin/clone.c:409
-msgid ""
-"Clone succeeded, but checkout failed.\n"
-"You can inspect what was checked out with 'git status'\n"
-"and retry with 'git restore --source=HEAD :/'\n"
-msgstr ""
-
-#: builtin/clone.c:486
-#, c-format
-msgid "Could not find remote branch %s to clone."
-msgstr ""
-
-#: builtin/clone.c:603
-#, c-format
-msgid "unable to update %s"
-msgstr ""
-
-#: builtin/clone.c:651
-msgid "failed to initialize sparse-checkout"
-msgstr ""
-
-#: builtin/clone.c:674
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr ""
-
-#: builtin/clone.c:709
-msgid "unable to checkout working tree"
-msgstr ""
-
-#: builtin/clone.c:793
-msgid "unable to write parameters to config file"
-msgstr ""
-
-#: builtin/clone.c:856
-msgid "cannot repack to clean up"
-msgstr ""
-
-#: builtin/clone.c:858
-msgid "cannot unlink temporary alternates file"
-msgstr ""
-
-#: builtin/clone.c:901
-msgid "Too many arguments."
-msgstr ""
-
-#: builtin/clone.c:905 contrib/scalar/scalar.c:413
-msgid "You must specify a repository to clone."
-msgstr ""
-
-#: builtin/clone.c:918
-#, c-format
-msgid "options '%s' and '%s %s' cannot be used together"
-msgstr ""
-
-#: builtin/clone.c:935
-#, c-format
-msgid "repository '%s' does not exist"
-msgstr ""
-
-#: builtin/clone.c:939 builtin/fetch.c:2176
-#, c-format
-msgid "depth %s is not a positive number"
-msgstr ""
-
-#: builtin/clone.c:949
-#, c-format
-msgid "destination path '%s' already exists and is not an empty directory."
-msgstr ""
-
-#: builtin/clone.c:955
-#, c-format
-msgid "repository path '%s' already exists and is not an empty directory."
-msgstr ""
-
-#: builtin/clone.c:969
-#, c-format
-msgid "working tree '%s' already exists."
-msgstr ""
-
-#: builtin/clone.c:984 builtin/clone.c:1005 builtin/difftool.c:256
-#: builtin/log.c:2037 builtin/worktree.c:350 builtin/worktree.c:382
-#, c-format
-msgid "could not create leading directories of '%s'"
-msgstr ""
-
-#: builtin/clone.c:989
-#, c-format
-msgid "could not create work tree dir '%s'"
-msgstr ""
-
-#: builtin/clone.c:1009
-#, c-format
-msgid "Cloning into bare repository '%s'...\n"
-msgstr ""
-
-#: builtin/clone.c:1011
-#, c-format
-msgid "Cloning into '%s'...\n"
-msgstr ""
-
-#: builtin/clone.c:1040
-msgid ""
-"clone --recursive is not compatible with both --reference and --reference-if-"
-"able"
-msgstr ""
-
-#: builtin/clone.c:1116 builtin/remote.c:201 builtin/remote.c:721
-#, c-format
-msgid "'%s' is not a valid remote name"
-msgstr ""
-
-#: builtin/clone.c:1157
-msgid "--depth is ignored in local clones; use file:// instead."
-msgstr ""
-
-#: builtin/clone.c:1159
-msgid "--shallow-since is ignored in local clones; use file:// instead."
-msgstr ""
-
-#: builtin/clone.c:1161
-msgid "--shallow-exclude is ignored in local clones; use file:// instead."
-msgstr ""
-
-#: builtin/clone.c:1163
-msgid "--filter is ignored in local clones; use file:// instead."
-msgstr ""
-
-#: builtin/clone.c:1168
-msgid "source repository is shallow, ignoring --local"
-msgstr ""
-
-#: builtin/clone.c:1173
-msgid "--local is ignored"
-msgstr ""
-
-#: builtin/clone.c:1185
-msgid "cannot clone from filtered bundle"
-msgstr ""
-
-#: builtin/clone.c:1265 builtin/clone.c:1324
-msgid "remote transport reported error"
-msgstr ""
-
-#: builtin/clone.c:1277 builtin/clone.c:1289
-#, c-format
-msgid "Remote branch %s not found in upstream %s"
-msgstr ""
-
-#: builtin/clone.c:1292
-msgid "You appear to have cloned an empty repository."
-msgstr ""
-
-#: builtin/column.c:10
-msgid "git column [<options>]"
-msgstr ""
-
-#: builtin/column.c:27
-msgid "lookup config vars"
-msgstr ""
-
-#: builtin/column.c:28 builtin/column.c:29
-msgid "layout to use"
-msgstr ""
-
-#: builtin/column.c:30
-msgid "maximum width"
-msgstr ""
-
-#: builtin/column.c:31
-msgid "padding space on left border"
-msgstr ""
-
-#: builtin/column.c:32
-msgid "padding space on right border"
-msgstr ""
-
-#: builtin/column.c:33
-msgid "padding space between columns"
-msgstr ""
-
-#: builtin/column.c:51
-msgid "--command must be the first argument"
-msgstr ""
-
-#: builtin/commit-graph.c:13
-msgid ""
-"git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"
-msgstr ""
-
-#: builtin/commit-graph.c:16
-msgid ""
-"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>"
-msgstr ""
-
-#: builtin/commit-graph.c:51 builtin/fetch.c:196 builtin/log.c:1813
-msgid "dir"
-msgstr ""
-
-#: builtin/commit-graph.c:52
-msgid "the object directory to store the graph"
-msgstr ""
-
-#: builtin/commit-graph.c:73
-msgid "if the commit-graph is split, only verify the tip file"
-msgstr ""
-
-#: builtin/commit-graph.c:100
-#, c-format
-msgid "Could not open commit-graph '%s'"
-msgstr ""
-
-#: builtin/commit-graph.c:137
-#, c-format
-msgid "unrecognized --split argument, %s"
-msgstr ""
-
-#: builtin/commit-graph.c:150
-#, c-format
-msgid "unexpected non-hex object ID: %s"
-msgstr ""
-
-#: builtin/commit-graph.c:155
-#, c-format
-msgid "invalid object: %s"
-msgstr ""
-
-#: builtin/commit-graph.c:205
-msgid "start walk at all refs"
-msgstr ""
-
-#: builtin/commit-graph.c:207
-msgid "scan pack-indexes listed by stdin for commits"
-msgstr ""
-
-#: builtin/commit-graph.c:209
-msgid "start walk at commits listed by stdin"
-msgstr ""
-
-#: builtin/commit-graph.c:211
-msgid "include all commits already in the commit-graph file"
-msgstr ""
-
-#: builtin/commit-graph.c:213
-msgid "enable computation for changed paths"
-msgstr ""
-
-#: builtin/commit-graph.c:215
-msgid "allow writing an incremental commit-graph file"
-msgstr ""
-
-#: builtin/commit-graph.c:219
-msgid "maximum number of commits in a non-base split commit-graph"
-msgstr ""
-
-#: builtin/commit-graph.c:221
-msgid "maximum ratio between two levels of a split commit-graph"
-msgstr ""
-
-#: builtin/commit-graph.c:223
-msgid "only expire files older than a given date-time"
-msgstr ""
-
-#: builtin/commit-graph.c:225
-msgid "maximum number of changed-path Bloom filters to compute"
-msgstr ""
-
-#: builtin/commit-graph.c:251
-msgid "use at most one of --reachable, --stdin-commits, or --stdin-packs"
-msgstr ""
-
-#: builtin/commit-graph.c:282
-msgid "Collecting commits from input"
-msgstr ""
-
-#: builtin/commit-graph.c:328 builtin/multi-pack-index.c:259
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr ""
-
-#: builtin/commit-tree.c:18
-msgid ""
-"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
-"<file>)...] <tree>"
-msgstr ""
-
-#: builtin/commit-tree.c:31
-#, c-format
-msgid "duplicate parent %s ignored"
-msgstr ""
-
-#: builtin/commit-tree.c:56 builtin/commit-tree.c:134 builtin/log.c:590
-#, c-format
-msgid "not a valid object name %s"
-msgstr ""
-
-#: builtin/commit-tree.c:94
-#, c-format
-msgid "git commit-tree: failed to read '%s'"
-msgstr ""
-
-#: builtin/commit-tree.c:96
-#, c-format
-msgid "git commit-tree: failed to close '%s'"
-msgstr ""
-
-#: builtin/commit-tree.c:109
-msgid "parent"
-msgstr ""
-
-#: builtin/commit-tree.c:110
-msgid "id of a parent commit object"
-msgstr ""
-
-#: builtin/commit-tree.c:112 builtin/commit.c:1626 builtin/merge.c:284
-#: builtin/notes.c:407 builtin/notes.c:573 builtin/stash.c:1666
-#: builtin/tag.c:455
-msgid "message"
-msgstr ""
-
-#: builtin/commit-tree.c:113 builtin/commit.c:1626
-msgid "commit message"
-msgstr ""
-
-#: builtin/commit-tree.c:116
-msgid "read commit log message from file"
-msgstr ""
-
-#: builtin/commit-tree.c:119 builtin/commit.c:1643 builtin/merge.c:303
-#: builtin/pull.c:180 builtin/revert.c:118
-msgid "GPG sign commit"
-msgstr ""
-
-#: builtin/commit-tree.c:131
-msgid "must give exactly one tree"
-msgstr ""
-
-#: builtin/commit-tree.c:138
-msgid "git commit-tree: failed to read"
-msgstr ""
-
-#: builtin/commit.c:43
-msgid "git commit [<options>] [--] <pathspec>..."
-msgstr ""
-
-#: builtin/commit.c:48
-msgid "git status [<options>] [--] <pathspec>..."
-msgstr ""
-
-#: builtin/commit.c:53
-msgid ""
-"You asked to amend the most recent commit, but doing so would make\n"
-"it empty. You can repeat your command with --allow-empty, or you can\n"
-"remove the commit entirely with \"git reset HEAD^\".\n"
-msgstr ""
-
-#: builtin/commit.c:58
-msgid ""
-"The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
-"If you wish to commit it anyway, use:\n"
-"\n"
-"    git commit --allow-empty\n"
-"\n"
-msgstr ""
-
-#: builtin/commit.c:65
-msgid "Otherwise, please use 'git rebase --skip'\n"
-msgstr ""
-
-#: builtin/commit.c:68
-msgid "Otherwise, please use 'git cherry-pick --skip'\n"
-msgstr ""
-
-#: builtin/commit.c:71
-msgid ""
-"and then use:\n"
-"\n"
-"    git cherry-pick --continue\n"
-"\n"
-"to resume cherry-picking the remaining commits.\n"
-"If you wish to skip this commit, use:\n"
-"\n"
-"    git cherry-pick --skip\n"
-"\n"
-msgstr ""
-
-#: builtin/commit.c:326
-msgid "failed to unpack HEAD tree object"
-msgstr ""
-
-#: builtin/commit.c:376
-msgid "No paths with --include/--only does not make sense."
-msgstr ""
-
-#: builtin/commit.c:388
-msgid "unable to create temporary index"
-msgstr ""
-
-#: builtin/commit.c:397
-msgid "interactive add failed"
-msgstr ""
-
-#: builtin/commit.c:412
-msgid "unable to update temporary index"
-msgstr ""
-
-#: builtin/commit.c:414
-msgid "Failed to update main cache tree"
-msgstr ""
-
-#: builtin/commit.c:439 builtin/commit.c:462 builtin/commit.c:510
-msgid "unable to write new_index file"
-msgstr ""
-
-#: builtin/commit.c:491
-msgid "cannot do a partial commit during a merge."
-msgstr ""
-
-#: builtin/commit.c:493
-msgid "cannot do a partial commit during a cherry-pick."
-msgstr ""
-
-#: builtin/commit.c:495
-msgid "cannot do a partial commit during a rebase."
-msgstr ""
-
-#: builtin/commit.c:503
-msgid "cannot read the index"
-msgstr ""
-
-#: builtin/commit.c:522
-msgid "unable to write temporary index file"
-msgstr ""
-
-#: builtin/commit.c:620
-#, c-format
-msgid "commit '%s' lacks author header"
-msgstr ""
-
-#: builtin/commit.c:622
-#, c-format
-msgid "commit '%s' has malformed author line"
-msgstr ""
-
-#: builtin/commit.c:641
-msgid "malformed --author parameter"
-msgstr ""
-
-#: builtin/commit.c:694
-msgid ""
-"unable to select a comment character that is not used\n"
-"in the current commit message"
-msgstr ""
-
-#: builtin/commit.c:750 builtin/commit.c:784 builtin/commit.c:1170
-#, c-format
-msgid "could not lookup commit %s"
-msgstr ""
-
-#: builtin/commit.c:762 builtin/shortlog.c:417
-#, c-format
-msgid "(reading log message from standard input)\n"
-msgstr ""
-
-#: builtin/commit.c:764
-msgid "could not read log from standard input"
-msgstr ""
-
-#: builtin/commit.c:768
-#, c-format
-msgid "could not read log file '%s'"
-msgstr ""
-
-#: builtin/commit.c:805
-#, c-format
-msgid "options '%s' and '%s:%s' cannot be used together"
-msgstr ""
-
-#: builtin/commit.c:817 builtin/commit.c:833
-msgid "could not read SQUASH_MSG"
-msgstr ""
-
-#: builtin/commit.c:824
-msgid "could not read MERGE_MSG"
-msgstr ""
-
-#: builtin/commit.c:884
-msgid "could not write commit template"
-msgstr ""
-
-#: builtin/commit.c:897
-#, c-format
-msgid ""
-"Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
-msgstr ""
-
-#: builtin/commit.c:899
-#, c-format
-msgid ""
-"Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored, and an empty message aborts the commit.\n"
-msgstr ""
-
-#: builtin/commit.c:903
-#, c-format
-msgid ""
-"Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be kept; you may remove them yourself if you want to.\n"
-msgstr ""
-
-#: builtin/commit.c:907
-#, c-format
-msgid ""
-"Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be kept; you may remove them yourself if you want to.\n"
-"An empty message aborts the commit.\n"
-msgstr ""
-
-#: builtin/commit.c:919
-msgid ""
-"\n"
-"It looks like you may be committing a merge.\n"
-"If this is not correct, please run\n"
-"\tgit update-ref -d MERGE_HEAD\n"
-"and try again.\n"
-msgstr ""
-
-#: builtin/commit.c:924
-msgid ""
-"\n"
-"It looks like you may be committing a cherry-pick.\n"
-"If this is not correct, please run\n"
-"\tgit update-ref -d CHERRY_PICK_HEAD\n"
-"and try again.\n"
-msgstr ""
-
-#: builtin/commit.c:951
-#, c-format
-msgid "%sAuthor:    %.*s <%.*s>"
-msgstr ""
-
-#: builtin/commit.c:959
-#, c-format
-msgid "%sDate:      %s"
-msgstr ""
-
-#: builtin/commit.c:966
-#, c-format
-msgid "%sCommitter: %.*s <%.*s>"
-msgstr ""
-
-#: builtin/commit.c:984
-msgid "Cannot read index"
-msgstr ""
-
-#: builtin/commit.c:1029
-msgid "unable to pass trailers to --trailers"
-msgstr ""
-
-#: builtin/commit.c:1069
-msgid "Error building trees"
-msgstr ""
-
-#: builtin/commit.c:1083 builtin/tag.c:317
-#, c-format
-msgid "Please supply the message using either -m or -F option.\n"
-msgstr ""
-
-#: builtin/commit.c:1128
-#, c-format
-msgid "--author '%s' is not 'Name <email>' and matches no existing author"
-msgstr ""
-
-#: builtin/commit.c:1142
-#, c-format
-msgid "Invalid ignored mode '%s'"
-msgstr ""
-
-#: builtin/commit.c:1160 builtin/commit.c:1450
-#, c-format
-msgid "Invalid untracked files mode '%s'"
-msgstr ""
-
-#: builtin/commit.c:1231
-msgid "You are in the middle of a merge -- cannot reword."
-msgstr ""
-
-#: builtin/commit.c:1233
-msgid "You are in the middle of a cherry-pick -- cannot reword."
-msgstr ""
-
-#: builtin/commit.c:1236
-#, c-format
-msgid "reword option of '%s' and path '%s' cannot be used together"
-msgstr ""
-
-#: builtin/commit.c:1238
-#, c-format
-msgid "reword option of '%s' and '%s' cannot be used together"
-msgstr ""
-
-#: builtin/commit.c:1263
-msgid "You have nothing to amend."
-msgstr ""
-
-#: builtin/commit.c:1266
-msgid "You are in the middle of a merge -- cannot amend."
-msgstr ""
-
-#: builtin/commit.c:1268
-msgid "You are in the middle of a cherry-pick -- cannot amend."
-msgstr ""
-
-#: builtin/commit.c:1270
-msgid "You are in the middle of a rebase -- cannot amend."
-msgstr ""
-
-#: builtin/commit.c:1290
-msgid "--reset-author can be used only with -C, -c or --amend."
-msgstr ""
-
-#: builtin/commit.c:1337
-#, c-format
-msgid "unknown option: --fixup=%s:%s"
-msgstr ""
-
-#: builtin/commit.c:1354
-#, c-format
-msgid "paths '%s ...' with -a does not make sense"
-msgstr ""
-
-#: builtin/commit.c:1485 builtin/commit.c:1654
-msgid "show status concisely"
-msgstr ""
-
-#: builtin/commit.c:1487 builtin/commit.c:1656
-msgid "show branch information"
-msgstr ""
-
-#: builtin/commit.c:1489
-msgid "show stash information"
-msgstr ""
-
-#: builtin/commit.c:1491 builtin/commit.c:1658
-msgid "compute full ahead/behind values"
-msgstr ""
-
-#: builtin/commit.c:1493
-msgid "version"
-msgstr ""
-
-#: builtin/commit.c:1493 builtin/commit.c:1660 builtin/push.c:551
-#: builtin/worktree.c:765
-msgid "machine-readable output"
-msgstr ""
-
-#: builtin/commit.c:1496 builtin/commit.c:1662
-msgid "show status in long format (default)"
-msgstr ""
-
-#: builtin/commit.c:1499 builtin/commit.c:1665
-msgid "terminate entries with NUL"
-msgstr ""
-
-#: builtin/commit.c:1501 builtin/commit.c:1505 builtin/commit.c:1668
-#: builtin/fast-export.c:1172 builtin/fast-export.c:1175
-#: builtin/fast-export.c:1178 builtin/rebase.c:1139 parse-options.h:368
-msgid "mode"
-msgstr ""
-
-#: builtin/commit.c:1502 builtin/commit.c:1668
-msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
-msgstr ""
-
-#: builtin/commit.c:1506
-msgid ""
-"show ignored files, optional modes: traditional, matching, no. (Default: "
-"traditional)"
-msgstr ""
-
-#: builtin/commit.c:1508 parse-options.h:197
-msgid "when"
-msgstr ""
-
-#: builtin/commit.c:1509
-msgid ""
-"ignore changes to submodules, optional when: all, dirty, untracked. "
-"(Default: all)"
-msgstr ""
-
-#: builtin/commit.c:1511
-msgid "list untracked files in columns"
-msgstr ""
-
-#: builtin/commit.c:1512
-msgid "do not detect renames"
-msgstr ""
-
-#: builtin/commit.c:1514
-msgid "detect renames, optionally set similarity index"
-msgstr ""
-
-#: builtin/commit.c:1537
-msgid "Unsupported combination of ignored and untracked-files arguments"
-msgstr ""
-
-#: builtin/commit.c:1619
-msgid "suppress summary after successful commit"
-msgstr ""
-
-#: builtin/commit.c:1620
-msgid "show diff in commit message template"
-msgstr ""
-
-#: builtin/commit.c:1622
-msgid "Commit message options"
-msgstr ""
-
-#: builtin/commit.c:1623 builtin/merge.c:288 builtin/tag.c:457
-msgid "read message from file"
-msgstr ""
-
-#: builtin/commit.c:1624
-msgid "author"
-msgstr ""
-
-#: builtin/commit.c:1624
-msgid "override author for commit"
-msgstr ""
-
-#: builtin/commit.c:1625 builtin/gc.c:551
-msgid "date"
-msgstr ""
-
-#: builtin/commit.c:1625
-msgid "override date for commit"
-msgstr ""
-
-#: builtin/commit.c:1627 builtin/commit.c:1628 builtin/commit.c:1634
-#: parse-options.h:360 ref-filter.h:89
-msgid "commit"
-msgstr ""
-
-#: builtin/commit.c:1627
-msgid "reuse and edit message from specified commit"
-msgstr ""
-
-#: builtin/commit.c:1628
-msgid "reuse message from specified commit"
-msgstr ""
-
-#. TRANSLATORS: Leave "[(amend|reword):]" as-is,
-#. and only translate <commit>.
-#.
-#: builtin/commit.c:1633
-msgid "[(amend|reword):]commit"
-msgstr ""
-
-#: builtin/commit.c:1633
-msgid ""
-"use autosquash formatted message to fixup or amend/reword specified commit"
-msgstr ""
-
-#: builtin/commit.c:1634
-msgid "use autosquash formatted message to squash specified commit"
-msgstr ""
-
-#: builtin/commit.c:1635
-msgid "the commit is authored by me now (used with -C/-c/--amend)"
-msgstr ""
-
-#: builtin/commit.c:1636 builtin/interpret-trailers.c:111
-msgid "trailer"
-msgstr ""
-
-#: builtin/commit.c:1636
-msgid "add custom trailer(s)"
-msgstr ""
-
-#: builtin/commit.c:1637 builtin/log.c:1788 builtin/merge.c:306
-#: builtin/pull.c:146 builtin/revert.c:110
-msgid "add a Signed-off-by trailer"
-msgstr ""
-
-#: builtin/commit.c:1638
-msgid "use specified template file"
-msgstr ""
-
-#: builtin/commit.c:1639
-msgid "force edit of commit"
-msgstr ""
-
-#: builtin/commit.c:1641
-msgid "include status in commit message template"
-msgstr ""
-
-#: builtin/commit.c:1646
-msgid "Commit contents options"
-msgstr ""
-
-#: builtin/commit.c:1647
-msgid "commit all changed files"
-msgstr ""
-
-#: builtin/commit.c:1648
-msgid "add specified files to index for commit"
-msgstr ""
-
-#: builtin/commit.c:1649
-msgid "interactively add files"
-msgstr ""
-
-#: builtin/commit.c:1650
-msgid "interactively add changes"
-msgstr ""
-
-#: builtin/commit.c:1651
-msgid "commit only specified files"
-msgstr ""
-
-#: builtin/commit.c:1652
-msgid "bypass pre-commit and commit-msg hooks"
-msgstr ""
-
-#: builtin/commit.c:1653
-msgid "show what would be committed"
-msgstr ""
-
-#: builtin/commit.c:1666
-msgid "amend previous commit"
-msgstr ""
-
-#: builtin/commit.c:1667
-msgid "bypass post-rewrite hook"
-msgstr ""
-
-#: builtin/commit.c:1674
-msgid "ok to record an empty change"
-msgstr ""
-
-#: builtin/commit.c:1676
-msgid "ok to record a change with an empty message"
-msgstr ""
-
-#: builtin/commit.c:1752
-#, c-format
-msgid "Corrupt MERGE_HEAD file (%s)"
-msgstr ""
-
-#: builtin/commit.c:1759
-msgid "could not read MERGE_MODE"
-msgstr ""
-
-#: builtin/commit.c:1780
-#, c-format
-msgid "could not read commit message: %s"
-msgstr ""
-
-#: builtin/commit.c:1787
-#, c-format
-msgid "Aborting commit due to empty commit message.\n"
-msgstr ""
-
-#: builtin/commit.c:1792
-#, c-format
-msgid "Aborting commit; you did not edit the message.\n"
-msgstr ""
-
-#: builtin/commit.c:1803
-#, c-format
-msgid "Aborting commit due to empty commit message body.\n"
-msgstr ""
-
-#: builtin/commit.c:1839
-msgid ""
-"repository has been updated, but unable to write\n"
-"new_index file. Check that disk is not full and quota is\n"
-"not exceeded, and then \"git restore --staged :/\" to recover."
-msgstr ""
-
-#: builtin/config.c:11
-msgid "git config [<options>]"
-msgstr ""
-
-#: builtin/config.c:109 builtin/env--helper.c:27
-#, c-format
-msgid "unrecognized --type argument, %s"
-msgstr ""
-
-#: builtin/config.c:121
-msgid "only one type at a time"
-msgstr ""
-
-#: builtin/config.c:130
-msgid "Config file location"
-msgstr ""
-
-#: builtin/config.c:131
-msgid "use global config file"
-msgstr ""
-
-#: builtin/config.c:132
-msgid "use system config file"
-msgstr ""
-
-#: builtin/config.c:133
-msgid "use repository config file"
-msgstr ""
-
-#: builtin/config.c:134
-msgid "use per-worktree config file"
-msgstr ""
-
-#: builtin/config.c:135
-msgid "use given config file"
-msgstr ""
-
-#: builtin/config.c:136
-msgid "blob-id"
-msgstr ""
-
-#: builtin/config.c:136
-msgid "read config from given blob object"
-msgstr ""
-
-#: builtin/config.c:137
-msgid "Action"
-msgstr ""
-
-#: builtin/config.c:138
-msgid "get value: name [value-pattern]"
-msgstr ""
-
-#: builtin/config.c:139
-msgid "get all values: key [value-pattern]"
-msgstr ""
-
-#: builtin/config.c:140
-msgid "get values for regexp: name-regex [value-pattern]"
-msgstr ""
-
-#: builtin/config.c:141
-msgid "get value specific for the URL: section[.var] URL"
-msgstr ""
-
-#: builtin/config.c:142
-msgid "replace all matching variables: name value [value-pattern]"
-msgstr ""
-
-#: builtin/config.c:143
-msgid "add a new variable: name value"
-msgstr ""
-
-#: builtin/config.c:144
-msgid "remove a variable: name [value-pattern]"
-msgstr ""
-
-#: builtin/config.c:145
-msgid "remove all matches: name [value-pattern]"
-msgstr ""
-
-#: builtin/config.c:146
-msgid "rename section: old-name new-name"
-msgstr ""
-
-#: builtin/config.c:147
-msgid "remove a section: name"
-msgstr ""
-
-#: builtin/config.c:148
-msgid "list all"
-msgstr ""
-
-#: builtin/config.c:149
-msgid "use string equality when comparing values to 'value-pattern'"
-msgstr ""
-
-#: builtin/config.c:150
-msgid "open an editor"
-msgstr ""
-
-#: builtin/config.c:151
-msgid "find the color configured: slot [default]"
-msgstr ""
-
-#: builtin/config.c:152
-msgid "find the color setting: slot [stdout-is-tty]"
-msgstr ""
-
-#: builtin/config.c:153
-msgid "Type"
-msgstr ""
-
-#: builtin/config.c:154 builtin/env--helper.c:42 builtin/hash-object.c:97
-msgid "type"
-msgstr ""
-
-#: builtin/config.c:154 builtin/env--helper.c:43
-msgid "value is given this type"
-msgstr ""
-
-#: builtin/config.c:155
-msgid "value is \"true\" or \"false\""
-msgstr ""
-
-#: builtin/config.c:156
-msgid "value is decimal number"
-msgstr ""
-
-#: builtin/config.c:157
-msgid "value is --bool or --int"
-msgstr ""
-
-#: builtin/config.c:158
-msgid "value is --bool or string"
-msgstr ""
-
-#: builtin/config.c:159
-msgid "value is a path (file or directory name)"
-msgstr ""
-
-#: builtin/config.c:160
-msgid "value is an expiry date"
-msgstr ""
-
-#: builtin/config.c:161
-msgid "Other"
-msgstr ""
-
-#: builtin/config.c:162
-msgid "terminate values with NUL byte"
-msgstr ""
-
-#: builtin/config.c:163
-msgid "show variable names only"
-msgstr ""
-
-#: builtin/config.c:164
-msgid "respect include directives on lookup"
-msgstr ""
-
-#: builtin/config.c:165
-msgid "show origin of config (file, standard input, blob, command line)"
-msgstr ""
-
-#: builtin/config.c:166
-msgid "show scope of config (worktree, local, global, system, command)"
-msgstr ""
-
-#: builtin/config.c:167 builtin/env--helper.c:45
-msgid "value"
-msgstr ""
-
-#: builtin/config.c:167
-msgid "with --get, use default value when missing entry"
-msgstr ""
-
-#: builtin/config.c:181
-#, c-format
-msgid "wrong number of arguments, should be %d"
-msgstr ""
-
-#: builtin/config.c:183
-#, c-format
-msgid "wrong number of arguments, should be from %d to %d"
-msgstr ""
-
-#: builtin/config.c:339
-#, c-format
-msgid "invalid key pattern: %s"
-msgstr ""
-
-#: builtin/config.c:377
-#, c-format
-msgid "failed to format default config value: %s"
-msgstr ""
-
-#: builtin/config.c:441
-#, c-format
-msgid "cannot parse color '%s'"
-msgstr ""
-
-#: builtin/config.c:483
-msgid "unable to parse default color value"
-msgstr ""
-
-#: builtin/config.c:536 builtin/config.c:833
-msgid "not in a git directory"
-msgstr ""
-
-#: builtin/config.c:539
-msgid "writing to stdin is not supported"
-msgstr ""
-
-#: builtin/config.c:542
-msgid "writing config blobs is not supported"
-msgstr ""
-
-#: builtin/config.c:627
-#, c-format
-msgid ""
-"# This is Git's per-user configuration file.\n"
-"[user]\n"
-"# Please adapt and uncomment the following lines:\n"
-"#\tname = %s\n"
-"#\temail = %s\n"
-msgstr ""
-
-#: builtin/config.c:652
-msgid "only one config file at a time"
-msgstr ""
-
-#: builtin/config.c:658
-msgid "--local can only be used inside a git repository"
-msgstr ""
-
-#: builtin/config.c:660
-msgid "--blob can only be used inside a git repository"
-msgstr ""
-
-#: builtin/config.c:662
-msgid "--worktree can only be used inside a git repository"
-msgstr ""
-
-#: builtin/config.c:684
-msgid "$HOME not set"
-msgstr ""
-
-#: builtin/config.c:708
-msgid ""
-"--worktree cannot be used with multiple working trees unless the config\n"
-"extension worktreeConfig is enabled. Please read \"CONFIGURATION FILE\"\n"
-"section in \"git help worktree\" for details"
-msgstr ""
-
-#: builtin/config.c:743
-msgid "--get-color and variable type are incoherent"
-msgstr ""
-
-#: builtin/config.c:748
-msgid "only one action at a time"
-msgstr ""
-
-#: builtin/config.c:761
-msgid "--name-only is only applicable to --list or --get-regexp"
-msgstr ""
-
-#: builtin/config.c:767
-msgid ""
-"--show-origin is only applicable to --get, --get-all, --get-regexp, and --"
-"list"
-msgstr ""
-
-#: builtin/config.c:773
-msgid "--default is only applicable to --get"
-msgstr ""
-
-#: builtin/config.c:806
-msgid "--fixed-value only applies with 'value-pattern'"
-msgstr ""
-
-#: builtin/config.c:822
-#, c-format
-msgid "unable to read config file '%s'"
-msgstr ""
-
-#: builtin/config.c:825
-msgid "error processing config file(s)"
-msgstr ""
-
-#: builtin/config.c:835
-msgid "editing stdin is not supported"
-msgstr ""
-
-#: builtin/config.c:837
-msgid "editing blobs is not supported"
-msgstr ""
-
-#: builtin/config.c:851
-#, c-format
-msgid "cannot create configuration file %s"
-msgstr ""
-
-#: builtin/config.c:864
-#, c-format
-msgid ""
-"cannot overwrite multiple values with a single value\n"
-"       Use a regexp, --add or --replace-all to change %s."
-msgstr ""
-
-#: builtin/config.c:943 builtin/config.c:954
-#, c-format
-msgid "no such section: %s"
-msgstr ""
-
-#: builtin/count-objects.c:100
-msgid "print sizes in human readable format"
-msgstr ""
-
-#: builtin/credential-cache--daemon.c:227
-#, c-format
-msgid ""
-"The permissions on your socket directory are too loose; other\n"
-"users may be able to read your cached credentials. Consider running:\n"
-"\n"
-"\tchmod 0700 %s"
-msgstr ""
-
-#: builtin/credential-cache--daemon.c:276
-msgid "print debugging messages to stderr"
-msgstr ""
-
-#: builtin/credential-cache--daemon.c:316
-msgid "credential-cache--daemon unavailable; no unix socket support"
-msgstr ""
-
-#: builtin/credential-cache.c:180
-msgid "credential-cache unavailable; no unix socket support"
-msgstr ""
-
-#: builtin/credential-store.c:66
-#, c-format
-msgid "unable to get credential storage lock in %d ms"
-msgstr ""
-
-#: builtin/describe.c:26
-msgid "git describe [<options>] [<commit-ish>...]"
-msgstr ""
-
-#: builtin/describe.c:27
-msgid "git describe [<options>] --dirty"
-msgstr ""
-
-#: builtin/describe.c:63
-msgid "head"
-msgstr ""
-
-#: builtin/describe.c:63
-msgid "lightweight"
-msgstr ""
-
-#: builtin/describe.c:63
-msgid "annotated"
-msgstr ""
-
-#: builtin/describe.c:277
-#, c-format
-msgid "annotated tag %s not available"
-msgstr ""
-
-#: builtin/describe.c:281
-#, c-format
-msgid "tag '%s' is externally known as '%s'"
-msgstr ""
-
-#: builtin/describe.c:328
-#, c-format
-msgid "no tag exactly matches '%s'"
-msgstr ""
-
-#: builtin/describe.c:330
-#, c-format
-msgid "No exact match on refs or tags, searching to describe\n"
-msgstr ""
-
-#: builtin/describe.c:397
-#, c-format
-msgid "finished search at %s\n"
-msgstr ""
-
-#: builtin/describe.c:424
-#, c-format
-msgid ""
-"No annotated tags can describe '%s'.\n"
-"However, there were unannotated tags: try --tags."
-msgstr ""
-
-#: builtin/describe.c:428
-#, c-format
-msgid ""
-"No tags can describe '%s'.\n"
-"Try --always, or create some tags."
-msgstr ""
-
-#: builtin/describe.c:458
-#, c-format
-msgid "traversed %lu commits\n"
-msgstr ""
-
-#: builtin/describe.c:461
-#, c-format
-msgid ""
-"more than %i tags found; listed %i most recent\n"
-"gave up search at %s\n"
-msgstr ""
-
-#: builtin/describe.c:529
-#, c-format
-msgid "describe %s\n"
-msgstr ""
-
-#: builtin/describe.c:532
-#, c-format
-msgid "Not a valid object name %s"
-msgstr ""
-
-#: builtin/describe.c:540
-#, c-format
-msgid "%s is neither a commit nor blob"
-msgstr ""
-
-#: builtin/describe.c:554
-msgid "find the tag that comes after the commit"
-msgstr ""
-
-#: builtin/describe.c:555
-msgid "debug search strategy on stderr"
-msgstr ""
-
-#: builtin/describe.c:556
-msgid "use any ref"
-msgstr ""
-
-#: builtin/describe.c:557
-msgid "use any tag, even unannotated"
-msgstr ""
-
-#: builtin/describe.c:558
-msgid "always use long format"
-msgstr ""
-
-#: builtin/describe.c:559
-msgid "only follow first parent"
-msgstr ""
-
-#: builtin/describe.c:562
-msgid "only output exact matches"
-msgstr ""
-
-#: builtin/describe.c:564
-msgid "consider <n> most recent tags (default: 10)"
-msgstr ""
-
-#: builtin/describe.c:566
-msgid "only consider tags matching <pattern>"
-msgstr ""
-
-#: builtin/describe.c:568
-msgid "do not consider tags matching <pattern>"
-msgstr ""
-
-#: builtin/describe.c:570 builtin/name-rev.c:595
-msgid "show abbreviated commit object as fallback"
-msgstr ""
-
-#: builtin/describe.c:571 builtin/describe.c:574
-msgid "mark"
-msgstr ""
-
-#: builtin/describe.c:572
-msgid "append <mark> on dirty working tree (default: \"-dirty\")"
-msgstr ""
-
-#: builtin/describe.c:575
-msgid "append <mark> on broken working tree (default: \"-broken\")"
-msgstr ""
-
-#: builtin/describe.c:622
-msgid "No names found, cannot describe anything."
-msgstr ""
-
-#: builtin/describe.c:673 builtin/describe.c:675
-#, c-format
-msgid "option '%s' and commit-ishes cannot be used together"
-msgstr ""
-
-#: builtin/diff-tree.c:157
-msgid "--merge-base only works with two commits"
-msgstr ""
-
-#: builtin/diff.c:92
-#, c-format
-msgid "'%s': not a regular file or symlink"
-msgstr ""
-
-#: builtin/diff.c:259
-#, c-format
-msgid "invalid option: %s"
-msgstr ""
-
-#: builtin/diff.c:376
-#, c-format
-msgid "%s...%s: no merge base"
-msgstr ""
-
-#: builtin/diff.c:491
-msgid "Not a git repository"
-msgstr ""
-
-#: builtin/diff.c:537 builtin/grep.c:700
-#, c-format
-msgid "invalid object '%s' given."
-msgstr ""
-
-#: builtin/diff.c:548
-#, c-format
-msgid "more than two blobs given: '%s'"
-msgstr ""
-
-#: builtin/diff.c:553
-#, c-format
-msgid "unhandled object '%s' given."
-msgstr ""
-
-#: builtin/diff.c:587
-#, c-format
-msgid "%s...%s: multiple merge bases, using %s"
-msgstr ""
-
-#: builtin/difftool.c:31
-msgid "git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]"
-msgstr ""
-
-#: builtin/difftool.c:287
-#, c-format
-msgid "could not read symlink %s"
-msgstr ""
-
-#: builtin/difftool.c:289
-#, c-format
-msgid "could not read symlink file %s"
-msgstr ""
-
-#: builtin/difftool.c:297
-#, c-format
-msgid "could not read object %s for symlink %s"
-msgstr ""
-
-#: builtin/difftool.c:421
-msgid ""
-"combined diff formats ('-c' and '--cc') are not supported in\n"
-"directory diff mode ('-d' and '--dir-diff')."
-msgstr ""
-
-#: builtin/difftool.c:626
-#, c-format
-msgid "both files modified: '%s' and '%s'."
-msgstr ""
-
-#: builtin/difftool.c:628
-msgid "working tree file has been left."
-msgstr ""
-
-#: builtin/difftool.c:639
-#, c-format
-msgid "temporary files exist in '%s'."
-msgstr ""
-
-#: builtin/difftool.c:640
-msgid "you may want to cleanup or recover these."
-msgstr ""
-
-#: builtin/difftool.c:645
-#, c-format
-msgid "failed: %d"
-msgstr ""
-
-#: builtin/difftool.c:690
-msgid "use `diff.guitool` instead of `diff.tool`"
-msgstr ""
-
-#: builtin/difftool.c:692
-msgid "perform a full-directory diff"
-msgstr ""
-
-#: builtin/difftool.c:694
-msgid "do not prompt before launching a diff tool"
-msgstr ""
-
-#: builtin/difftool.c:699
-msgid "use symlinks in dir-diff mode"
-msgstr ""
-
-#: builtin/difftool.c:700
-msgid "tool"
-msgstr ""
-
-#: builtin/difftool.c:701
-msgid "use the specified diff tool"
-msgstr ""
-
-#: builtin/difftool.c:703
-msgid "print a list of diff tools that may be used with `--tool`"
-msgstr ""
-
-#: builtin/difftool.c:706
-msgid ""
-"make 'git-difftool' exit when an invoked diff tool returns a non-zero exit "
-"code"
-msgstr ""
-
-#: builtin/difftool.c:709
-msgid "specify a custom command for viewing diffs"
-msgstr ""
-
-#: builtin/difftool.c:710
-msgid "passed to `diff`"
-msgstr ""
-
-#: builtin/difftool.c:726
-msgid "difftool requires worktree or --no-index"
-msgstr ""
-
-#: builtin/difftool.c:745
-msgid "no <tool> given for --tool=<tool>"
-msgstr ""
-
-#: builtin/difftool.c:752
-msgid "no <cmd> given for --extcmd=<cmd>"
-msgstr ""
-
-#: builtin/env--helper.c:6
-msgid "git env--helper --type=[bool|ulong] <options> <env-var>"
-msgstr ""
-
-#: builtin/env--helper.c:46
-msgid "default for git_env_*(...) to fall back on"
-msgstr ""
-
-#: builtin/env--helper.c:48
-msgid "be quiet only use git_env_*() value as exit code"
-msgstr ""
-
-#: builtin/env--helper.c:67
-#, c-format
-msgid "option `--default' expects a boolean value with `--type=bool`, not `%s`"
-msgstr ""
-
-#: builtin/env--helper.c:82
-#, c-format
-msgid ""
-"option `--default' expects an unsigned long value with `--type=ulong`, not `"
-"%s`"
-msgstr ""
-
-#: builtin/fast-export.c:29
-msgid "git fast-export [<rev-list-opts>]"
-msgstr ""
-
-#: builtin/fast-export.c:843
-msgid "Error: Cannot export nested tags unless --mark-tags is specified."
-msgstr ""
-
-#: builtin/fast-export.c:1152
-msgid "--anonymize-map token cannot be empty"
-msgstr ""
-
-#: builtin/fast-export.c:1171
-msgid "show progress after <n> objects"
-msgstr ""
-
-#: builtin/fast-export.c:1173
-msgid "select handling of signed tags"
-msgstr ""
-
-#: builtin/fast-export.c:1176
-msgid "select handling of tags that tag filtered objects"
-msgstr ""
-
-#: builtin/fast-export.c:1179
-msgid "select handling of commit messages in an alternate encoding"
-msgstr ""
-
-#: builtin/fast-export.c:1182
-msgid "dump marks to this file"
-msgstr ""
-
-#: builtin/fast-export.c:1184
-msgid "import marks from this file"
-msgstr ""
-
-#: builtin/fast-export.c:1188
-msgid "import marks from this file if it exists"
-msgstr ""
-
-#: builtin/fast-export.c:1190
-msgid "fake a tagger when tags lack one"
-msgstr ""
-
-#: builtin/fast-export.c:1192
-msgid "output full tree for each commit"
-msgstr ""
-
-#: builtin/fast-export.c:1194
-msgid "use the done feature to terminate the stream"
-msgstr ""
-
-#: builtin/fast-export.c:1195
-msgid "skip output of blob data"
-msgstr ""
-
-#: builtin/fast-export.c:1196 builtin/log.c:1860
-msgid "refspec"
-msgstr ""
-
-#: builtin/fast-export.c:1197
-msgid "apply refspec to exported refs"
-msgstr ""
-
-#: builtin/fast-export.c:1198
-msgid "anonymize output"
-msgstr ""
-
-#: builtin/fast-export.c:1199
-msgid "from:to"
-msgstr ""
-
-#: builtin/fast-export.c:1200
-msgid "convert <from> to <to> in anonymized output"
-msgstr ""
-
-#: builtin/fast-export.c:1203
-msgid "reference parents which are not in fast-export stream by object id"
-msgstr ""
-
-#: builtin/fast-export.c:1205
-msgid "show original object ids of blobs/commits"
-msgstr ""
-
-#: builtin/fast-export.c:1207
-msgid "label tags with mark ids"
-msgstr ""
-
-#: builtin/fast-import.c:3097
-#, c-format
-msgid "Missing from marks for submodule '%s'"
-msgstr ""
-
-#: builtin/fast-import.c:3099
-#, c-format
-msgid "Missing to marks for submodule '%s'"
-msgstr ""
-
-#: builtin/fast-import.c:3234
-#, c-format
-msgid "Expected 'mark' command, got %s"
-msgstr ""
-
-#: builtin/fast-import.c:3239
-#, c-format
-msgid "Expected 'to' command, got %s"
-msgstr ""
-
-#: builtin/fast-import.c:3331
-msgid "Expected format name:filename for submodule rewrite option"
-msgstr ""
-
-#: builtin/fast-import.c:3386
-#, c-format
-msgid "feature '%s' forbidden in input without --allow-unsafe-features"
-msgstr ""
-
-#: builtin/fetch-pack.c:246
-#, c-format
-msgid "Lockfile created but not reported: %s"
-msgstr ""
-
-#: builtin/fetch.c:36
-msgid "git fetch [<options>] [<repository> [<refspec>...]]"
-msgstr ""
-
-#: builtin/fetch.c:37
-msgid "git fetch [<options>] <group>"
-msgstr ""
-
-#: builtin/fetch.c:38
-msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
-msgstr ""
-
-#: builtin/fetch.c:39
-msgid "git fetch --all [<options>]"
-msgstr ""
-
-#: builtin/fetch.c:124
-msgid "fetch.parallel cannot be negative"
-msgstr ""
-
-#: builtin/fetch.c:147 builtin/pull.c:189
-msgid "fetch from all remotes"
-msgstr ""
-
-#: builtin/fetch.c:149 builtin/pull.c:249
-msgid "set upstream for git pull/fetch"
-msgstr ""
-
-#: builtin/fetch.c:151 builtin/pull.c:192
-msgid "append to .git/FETCH_HEAD instead of overwriting"
-msgstr ""
-
-#: builtin/fetch.c:153
-msgid "use atomic transaction to update references"
-msgstr ""
-
-#: builtin/fetch.c:155 builtin/pull.c:195
-msgid "path to upload pack on remote end"
-msgstr ""
-
-#: builtin/fetch.c:156
-msgid "force overwrite of local reference"
-msgstr ""
-
-#: builtin/fetch.c:158
-msgid "fetch from multiple remotes"
-msgstr ""
-
-#: builtin/fetch.c:160 builtin/pull.c:199
-msgid "fetch all tags and associated objects"
-msgstr ""
-
-#: builtin/fetch.c:162
-msgid "do not fetch all tags (--no-tags)"
-msgstr ""
-
-#: builtin/fetch.c:164
-msgid "number of submodules fetched in parallel"
-msgstr ""
-
-#: builtin/fetch.c:166
-msgid "modify the refspec to place all refs within refs/prefetch/"
-msgstr ""
-
-#: builtin/fetch.c:168 builtin/pull.c:202
-msgid "prune remote-tracking branches no longer on remote"
-msgstr ""
-
-#: builtin/fetch.c:170
-msgid "prune local tags no longer on remote and clobber changed tags"
-msgstr ""
-
-#: builtin/fetch.c:171 builtin/fetch.c:199 builtin/pull.c:123
-msgid "on-demand"
-msgstr ""
-
-#: builtin/fetch.c:172
-msgid "control recursive fetching of submodules"
-msgstr ""
-
-#: builtin/fetch.c:177
-msgid "write fetched references to the FETCH_HEAD file"
-msgstr ""
-
-#: builtin/fetch.c:178 builtin/pull.c:210
-msgid "keep downloaded pack"
-msgstr ""
-
-#: builtin/fetch.c:180
-msgid "allow updating of HEAD ref"
-msgstr ""
-
-#: builtin/fetch.c:183 builtin/fetch.c:189 builtin/pull.c:213
-#: builtin/pull.c:222
-msgid "deepen history of shallow clone"
-msgstr ""
-
-#: builtin/fetch.c:185 builtin/pull.c:216
-msgid "deepen history of shallow repository based on time"
-msgstr ""
-
-#: builtin/fetch.c:191 builtin/pull.c:225
-msgid "convert to a complete repository"
-msgstr ""
-
-#: builtin/fetch.c:194
-msgid "re-fetch without negotiating common commits"
-msgstr ""
-
-#: builtin/fetch.c:197
-msgid "prepend this to submodule path output"
-msgstr ""
-
-#: builtin/fetch.c:200
-msgid ""
-"default for recursive fetching of submodules (lower priority than config "
-"files)"
-msgstr ""
-
-#: builtin/fetch.c:204 builtin/pull.c:228
-msgid "accept refs that update .git/shallow"
-msgstr ""
-
-#: builtin/fetch.c:205 builtin/pull.c:230
-msgid "refmap"
-msgstr ""
-
-#: builtin/fetch.c:206 builtin/pull.c:231
-msgid "specify fetch refmap"
-msgstr ""
-
-#: builtin/fetch.c:213 builtin/pull.c:244
-msgid "report that we have only objects reachable from this object"
-msgstr ""
-
-#: builtin/fetch.c:215
-msgid "do not fetch a packfile; instead, print ancestors of negotiation tips"
-msgstr ""
-
-#: builtin/fetch.c:218 builtin/fetch.c:220
-msgid "run 'maintenance --auto' after fetching"
-msgstr ""
-
-#: builtin/fetch.c:222 builtin/pull.c:247
-msgid "check for forced-updates on all updated branches"
-msgstr ""
-
-#: builtin/fetch.c:224
-msgid "write the commit-graph after fetching"
-msgstr ""
-
-#: builtin/fetch.c:226
-msgid "accept refspecs from stdin"
-msgstr ""
-
-#: builtin/fetch.c:618
-msgid "couldn't find remote ref HEAD"
-msgstr ""
-
-#: builtin/fetch.c:893
-#, c-format
-msgid "object %s not found"
-msgstr ""
-
-#: builtin/fetch.c:897
-msgid "[up to date]"
-msgstr ""
-
-#: builtin/fetch.c:909 builtin/fetch.c:927 builtin/fetch.c:999
-msgid "[rejected]"
-msgstr ""
-
-#: builtin/fetch.c:911
-msgid "can't fetch in current branch"
-msgstr ""
-
-#: builtin/fetch.c:912
-msgid "checked out in another worktree"
-msgstr ""
-
-#: builtin/fetch.c:922
-msgid "[tag update]"
-msgstr ""
-
-#: builtin/fetch.c:923 builtin/fetch.c:960 builtin/fetch.c:982
-#: builtin/fetch.c:994
-msgid "unable to update local ref"
-msgstr ""
-
-#: builtin/fetch.c:927
-msgid "would clobber existing tag"
-msgstr ""
-
-#: builtin/fetch.c:949
-msgid "[new tag]"
-msgstr ""
-
-#: builtin/fetch.c:952
-msgid "[new branch]"
-msgstr ""
-
-#: builtin/fetch.c:955
-msgid "[new ref]"
-msgstr ""
-
-#: builtin/fetch.c:994
-msgid "forced update"
-msgstr ""
-
-#: builtin/fetch.c:999
-msgid "non-fast-forward"
-msgstr ""
-
-#: builtin/fetch.c:1102
-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 ""
-
-#: builtin/fetch.c:1106
-#, 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 ""
-
-#: builtin/fetch.c:1136
-#, c-format
-msgid "%s did not send all necessary objects\n"
-msgstr ""
-
-#: builtin/fetch.c:1156
-#, c-format
-msgid "rejected %s because shallow roots are not allowed to be updated"
-msgstr ""
-
-#: builtin/fetch.c:1259 builtin/fetch.c:1418
-#, c-format
-msgid "From %.*s\n"
-msgstr ""
-
-#: builtin/fetch.c:1269
-#, c-format
-msgid ""
-"some local refs could not be updated; try running\n"
-" 'git remote prune %s' to remove any old, conflicting branches"
-msgstr ""
-
-#: builtin/fetch.c:1377
-#, c-format
-msgid "   (%s will become dangling)"
-msgstr ""
-
-#: builtin/fetch.c:1378
-#, c-format
-msgid "   (%s has become dangling)"
-msgstr ""
-
-#: builtin/fetch.c:1421
-msgid "[deleted]"
-msgstr ""
-
-#: builtin/fetch.c:1422 builtin/remote.c:1153
-msgid "(none)"
-msgstr ""
-
-#: builtin/fetch.c:1446
-#, c-format
-msgid "refusing to fetch into branch '%s' checked out at '%s'"
-msgstr ""
-
-#: builtin/fetch.c:1466
-#, c-format
-msgid "option \"%s\" value \"%s\" is not valid for %s"
-msgstr ""
-
-#: builtin/fetch.c:1469
-#, c-format
-msgid "option \"%s\" is ignored for %s\n"
-msgstr ""
-
-#: builtin/fetch.c:1496
-#, c-format
-msgid "the object %s does not exist"
-msgstr ""
-
-#: builtin/fetch.c:1748
-msgid "multiple branches detected, incompatible with --set-upstream"
-msgstr ""
-
-#: builtin/fetch.c:1760
-#, c-format
-msgid ""
-"could not set upstream of HEAD to '%s' from '%s' when it does not point to "
-"any branch."
-msgstr ""
-
-#: builtin/fetch.c:1773
-msgid "not setting upstream for a remote remote-tracking branch"
-msgstr ""
-
-#: builtin/fetch.c:1775
-msgid "not setting upstream for a remote tag"
-msgstr ""
-
-#: builtin/fetch.c:1777
-msgid "unknown branch type"
-msgstr ""
-
-#: builtin/fetch.c:1779
-msgid ""
-"no source branch found;\n"
-"you need to specify exactly one branch with the --set-upstream option"
-msgstr ""
-
-#: builtin/fetch.c:1904 builtin/fetch.c:1967
-#, c-format
-msgid "Fetching %s\n"
-msgstr ""
-
-#: builtin/fetch.c:1914 builtin/fetch.c:1969
-#, c-format
-msgid "could not fetch %s"
-msgstr ""
-
-#: builtin/fetch.c:1926
-#, c-format
-msgid "could not fetch '%s' (exit code: %d)\n"
-msgstr ""
-
-#: builtin/fetch.c:2030
-msgid ""
-"no remote repository specified; please specify either a URL or a\n"
-"remote name from which new revisions should be fetched"
-msgstr ""
-
-#: builtin/fetch.c:2066
-msgid "you need to specify a tag name"
-msgstr ""
-
-#: builtin/fetch.c:2156
-msgid "--negotiate-only needs one or more --negotiation-tip=*"
-msgstr ""
-
-#: builtin/fetch.c:2160
-msgid "negative depth in --deepen is not supported"
-msgstr ""
-
-#: builtin/fetch.c:2169
-msgid "--unshallow on a complete repository does not make sense"
-msgstr ""
-
-#: builtin/fetch.c:2186
-msgid "fetch --all does not take a repository argument"
-msgstr ""
-
-#: builtin/fetch.c:2188
-msgid "fetch --all does not make sense with refspecs"
-msgstr ""
-
-#: builtin/fetch.c:2197
-#, c-format
-msgid "no such remote or remote group: %s"
-msgstr ""
-
-#: builtin/fetch.c:2205
-msgid "fetching a group and specifying refspecs does not make sense"
-msgstr ""
-
-#: builtin/fetch.c:2221
-msgid "must supply remote when using --negotiate-only"
-msgstr ""
-
-#: builtin/fetch.c:2226
-msgid "protocol does not support --negotiate-only, exiting"
-msgstr ""
-
-#: builtin/fetch.c:2246
-msgid ""
-"--filter can only be used with the remote configured in extensions."
-"partialclone"
-msgstr ""
-
-#: builtin/fetch.c:2250
-msgid "--atomic can only be used when fetching from one remote"
-msgstr ""
-
-#: builtin/fetch.c:2254
-msgid "--stdin can only be used when fetching from one remote"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:7
-msgid ""
-"git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:19
-msgid "populate log with at most <n> entries from shortlog"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:22
-msgid "alias for --log (deprecated)"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:25
-msgid "text"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:26
-msgid "use <text> as start of message"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:28
-msgid "use <name> instead of the real target branch"
-msgstr ""
-
-#: builtin/fmt-merge-msg.c:29
-msgid "file to read from"
-msgstr ""
-
-#: builtin/for-each-ref.c:10
-msgid "git for-each-ref [<options>] [<pattern>]"
-msgstr ""
-
-#: builtin/for-each-ref.c:11
-msgid "git for-each-ref [--points-at <object>]"
-msgstr ""
-
-#: builtin/for-each-ref.c:12
-msgid "git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]"
-msgstr ""
-
-#: builtin/for-each-ref.c:13
-msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"
-msgstr ""
-
-#: builtin/for-each-ref.c:31
-msgid "quote placeholders suitably for shells"
-msgstr ""
-
-#: builtin/for-each-ref.c:33
-msgid "quote placeholders suitably for perl"
-msgstr ""
-
-#: builtin/for-each-ref.c:35
-msgid "quote placeholders suitably for python"
-msgstr ""
-
-#: builtin/for-each-ref.c:37
-msgid "quote placeholders suitably for Tcl"
-msgstr ""
-
-#: builtin/for-each-ref.c:40
-msgid "show only <n> matched refs"
-msgstr ""
-
-#: builtin/for-each-ref.c:42 builtin/tag.c:482
-msgid "respect format colors"
-msgstr ""
-
-#: builtin/for-each-ref.c:45
-msgid "print only refs which points at the given object"
-msgstr ""
-
-#: builtin/for-each-ref.c:47
-msgid "print only refs that are merged"
-msgstr ""
-
-#: builtin/for-each-ref.c:48
-msgid "print only refs that are not merged"
-msgstr ""
-
-#: builtin/for-each-ref.c:49
-msgid "print only refs which contain the commit"
-msgstr ""
-
-#: builtin/for-each-ref.c:50
-msgid "print only refs which don't contain the commit"
-msgstr ""
-
-#: builtin/for-each-repo.c:9
-msgid "git for-each-repo --config=<config> <command-args>"
-msgstr ""
-
-#: builtin/for-each-repo.c:34
-msgid "config"
-msgstr ""
-
-#: builtin/for-each-repo.c:35
-msgid "config key storing a list of repository paths"
-msgstr ""
-
-#: builtin/for-each-repo.c:43
-msgid "missing --config=<config>"
-msgstr ""
-
-#: builtin/fsck.c:69 builtin/fsck.c:128 builtin/fsck.c:129
-msgid "unknown"
-msgstr ""
-
-#. TRANSLATORS: e.g. error in tree 01bfda: <more explanation>
-#: builtin/fsck.c:78 builtin/fsck.c:100
-#, c-format
-msgid "error in %s %s: %s"
-msgstr ""
-
-#. TRANSLATORS: e.g. warning in tree 01bfda: <more explanation>
-#: builtin/fsck.c:94
-#, c-format
-msgid "warning in %s %s: %s"
-msgstr ""
-
-#: builtin/fsck.c:124 builtin/fsck.c:127
-#, c-format
-msgid "broken link from %7s %s"
-msgstr ""
-
-#: builtin/fsck.c:136
-msgid "wrong object type in link"
-msgstr ""
-
-#: builtin/fsck.c:152
-#, c-format
-msgid ""
-"broken link from %7s %s\n"
-"              to %7s %s"
-msgstr ""
-
-#: builtin/fsck.c:264
-#, c-format
-msgid "missing %s %s"
-msgstr ""
-
-#: builtin/fsck.c:291
-#, c-format
-msgid "unreachable %s %s"
-msgstr ""
-
-#: builtin/fsck.c:311
-#, c-format
-msgid "dangling %s %s"
-msgstr ""
-
-#: builtin/fsck.c:321
-msgid "could not create lost-found"
-msgstr ""
-
-#: builtin/fsck.c:332
-#, c-format
-msgid "could not finish '%s'"
-msgstr ""
-
-#: builtin/fsck.c:349
-#, c-format
-msgid "Checking %s"
-msgstr ""
-
-#: builtin/fsck.c:387
-#, c-format
-msgid "Checking connectivity (%d objects)"
-msgstr ""
-
-#: builtin/fsck.c:406
-#, c-format
-msgid "Checking %s %s"
-msgstr ""
-
-#: builtin/fsck.c:411
-msgid "broken links"
-msgstr ""
-
-#: builtin/fsck.c:420
-#, c-format
-msgid "root %s"
-msgstr ""
-
-#: builtin/fsck.c:428
-#, c-format
-msgid "tagged %s %s (%s) in %s"
-msgstr ""
-
-#: builtin/fsck.c:457
-#, c-format
-msgid "%s: object corrupt or missing"
-msgstr ""
-
-#: builtin/fsck.c:482
-#, c-format
-msgid "%s: invalid reflog entry %s"
-msgstr ""
-
-#: builtin/fsck.c:496
-#, c-format
-msgid "Checking reflog %s->%s"
-msgstr ""
-
-#: builtin/fsck.c:530
-#, c-format
-msgid "%s: invalid sha1 pointer %s"
-msgstr ""
-
-#: builtin/fsck.c:537
-#, c-format
-msgid "%s: not a commit"
-msgstr ""
-
-#: builtin/fsck.c:591
-msgid "notice: No default references"
-msgstr ""
-
-#: builtin/fsck.c:621
-#, c-format
-msgid "%s: hash-path mismatch, found at: %s"
-msgstr ""
-
-#: builtin/fsck.c:624
-#, c-format
-msgid "%s: object corrupt or missing: %s"
-msgstr ""
-
-#: builtin/fsck.c:628
-#, c-format
-msgid "%s: object is of unknown type '%s': %s"
-msgstr ""
-
-#: builtin/fsck.c:645
-#, c-format
-msgid "%s: object could not be parsed: %s"
-msgstr ""
-
-#: builtin/fsck.c:665
-#, c-format
-msgid "bad sha1 file: %s"
-msgstr ""
-
-#: builtin/fsck.c:686
-msgid "Checking object directory"
-msgstr ""
-
-#: builtin/fsck.c:689
-msgid "Checking object directories"
-msgstr ""
-
-#: builtin/fsck.c:705
-#, c-format
-msgid "Checking %s link"
-msgstr ""
-
-#: builtin/fsck.c:710 builtin/index-pack.c:862
-#, c-format
-msgid "invalid %s"
-msgstr ""
-
-#: builtin/fsck.c:717
-#, c-format
-msgid "%s points to something strange (%s)"
-msgstr ""
-
-#: builtin/fsck.c:723
-#, c-format
-msgid "%s: detached HEAD points at nothing"
-msgstr ""
-
-#: builtin/fsck.c:727
-#, c-format
-msgid "notice: %s points to an unborn branch (%s)"
-msgstr ""
-
-#: builtin/fsck.c:739
-msgid "Checking cache tree"
-msgstr ""
-
-#: builtin/fsck.c:744
-#, c-format
-msgid "%s: invalid sha1 pointer in cache-tree"
-msgstr ""
-
-#: builtin/fsck.c:753
-msgid "non-tree in cache-tree"
-msgstr ""
-
-#: builtin/fsck.c:784
-msgid "git fsck [<options>] [<object>...]"
-msgstr ""
-
-#: builtin/fsck.c:790
-msgid "show unreachable objects"
-msgstr ""
-
-#: builtin/fsck.c:791
-msgid "show dangling objects"
-msgstr ""
-
-#: builtin/fsck.c:792
-msgid "report tags"
-msgstr ""
-
-#: builtin/fsck.c:793
-msgid "report root nodes"
-msgstr ""
-
-#: builtin/fsck.c:794
-msgid "make index objects head nodes"
-msgstr ""
-
-#: builtin/fsck.c:795
-msgid "make reflogs head nodes (default)"
-msgstr ""
-
-#: builtin/fsck.c:796
-msgid "also consider packs and alternate objects"
-msgstr ""
-
-#: builtin/fsck.c:797
-msgid "check only connectivity"
-msgstr ""
-
-#: builtin/fsck.c:798 builtin/mktag.c:75
-msgid "enable more strict checking"
-msgstr ""
-
-#: builtin/fsck.c:800
-msgid "write dangling objects in .git/lost-found"
-msgstr ""
-
-#: builtin/fsck.c:801 builtin/prune.c:146
-msgid "show progress"
-msgstr ""
-
-#: builtin/fsck.c:802
-msgid "show verbose names for reachable objects"
-msgstr ""
-
-#: builtin/fsck.c:862 builtin/index-pack.c:261
-msgid "Checking objects"
-msgstr ""
-
-#: builtin/fsck.c:890
-#, c-format
-msgid "%s: object missing"
-msgstr ""
-
-#: builtin/fsck.c:901
-#, c-format
-msgid "invalid parameter: expected sha1, got '%s'"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:13
-msgid "git fsmonitor--daemon start [<options>]"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:14
-msgid "git fsmonitor--daemon run [<options>]"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:15
-msgid "git fsmonitor--daemon stop"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:16
-msgid "git fsmonitor--daemon status"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:38 builtin/fsmonitor--daemon.c:47
-#, c-format
-msgid "value of '%s' out of range: %d"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:57
-#, c-format
-msgid "value of '%s' not bool or int: %d"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:99
-#, c-format
-msgid "fsmonitor-daemon is watching '%s'\n"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:104
-#, c-format
-msgid "fsmonitor-daemon is not watching '%s'\n"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:170
-#, c-format
-msgid "could not create fsmonitor cookie '%s'"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:753
-#, c-format
-msgid "fsmonitor: cookie_result '%d' != SEEN"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1187
-#, c-format
-msgid "could not start IPC thread pool on '%s'"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1199
-msgid "could not start fsmonitor listener thread"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1297
-msgid "could not initialize listener thread"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1328 builtin/fsmonitor--daemon.c:1383
-#, c-format
-msgid "fsmonitor--daemon is already running '%s'"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1332
-#, c-format
-msgid "running fsmonitor-daemon in '%s'\n"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1387
-#, c-format
-msgid "starting fsmonitor-daemon in '%s'\n"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1413
-msgid "daemon failed to start"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1416
-msgid "daemon not online yet"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1419
-msgid "daemon terminated"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1429
-msgid "detach from console"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1432
-msgid "use <n> ipc worker threads"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1435
-msgid "max seconds to wait for background daemon startup"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1449
-#, c-format
-msgid "invalid 'ipc-threads' value (%d)"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1464
-#, c-format
-msgid "Unhandled subcommand '%s'"
-msgstr ""
-
-#: builtin/fsmonitor--daemon.c:1477
-msgid "fsmonitor--daemon not supported on this platform"
-msgstr ""
-
-#: builtin/gc.c:39
-msgid "git gc [<options>]"
-msgstr ""
-
-#: builtin/gc.c:93
-#, c-format
-msgid "Failed to fstat %s: %s"
-msgstr ""
-
-#: builtin/gc.c:129
-#, c-format
-msgid "failed to parse '%s' value '%s'"
-msgstr ""
-
-#: builtin/gc.c:488 builtin/init-db.c:57
-#, c-format
-msgid "cannot stat '%s'"
-msgstr ""
-
-#: builtin/gc.c:504
-#, c-format
-msgid ""
-"The last gc run reported the following. Please correct the root cause\n"
-"and remove %s\n"
-"Automatic cleanup will not be performed until the file is removed.\n"
-"\n"
-"%s"
-msgstr ""
-
-#: builtin/gc.c:552
-msgid "prune unreferenced objects"
-msgstr ""
-
-#: builtin/gc.c:554
-msgid "be more thorough (increased runtime)"
-msgstr ""
-
-#: builtin/gc.c:555
-msgid "enable auto-gc mode"
-msgstr ""
-
-#: builtin/gc.c:558
-msgid "force running gc even if there may be another gc running"
-msgstr ""
-
-#: builtin/gc.c:561
-msgid "repack all other packs except the largest pack"
-msgstr ""
-
-#: builtin/gc.c:577
-#, c-format
-msgid "failed to parse gc.logexpiry value %s"
-msgstr ""
-
-#: builtin/gc.c:588
-#, c-format
-msgid "failed to parse prune expiry value %s"
-msgstr ""
-
-#: builtin/gc.c:608
-#, c-format
-msgid "Auto packing the repository in background for optimum performance.\n"
-msgstr ""
-
-#: builtin/gc.c:610
-#, c-format
-msgid "Auto packing the repository for optimum performance.\n"
-msgstr ""
-
-#: builtin/gc.c:611
-#, c-format
-msgid "See \"git help gc\" for manual housekeeping.\n"
-msgstr ""
-
-#: builtin/gc.c:652
-#, c-format
-msgid ""
-"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
-msgstr ""
-
-#: builtin/gc.c:707
-msgid ""
-"There are too many unreachable loose objects; run 'git prune' to remove them."
-msgstr ""
-
-#: builtin/gc.c:717
-msgid ""
-"git maintenance run [--auto] [--[no-]quiet] [--task=<task>] [--schedule]"
-msgstr ""
-
-#: builtin/gc.c:747
-msgid "--no-schedule is not allowed"
-msgstr ""
-
-#: builtin/gc.c:752
-#, c-format
-msgid "unrecognized --schedule argument '%s'"
-msgstr ""
-
-#: builtin/gc.c:870
-msgid "failed to write commit-graph"
-msgstr ""
-
-#: builtin/gc.c:906
-msgid "failed to prefetch remotes"
-msgstr ""
-
-#: builtin/gc.c:1022
-msgid "failed to start 'git pack-objects' process"
-msgstr ""
-
-#: builtin/gc.c:1039
-msgid "failed to finish 'git pack-objects' process"
-msgstr ""
-
-#: builtin/gc.c:1090
-msgid "failed to write multi-pack-index"
-msgstr ""
-
-#: builtin/gc.c:1106
-msgid "'git multi-pack-index expire' failed"
-msgstr ""
-
-#: builtin/gc.c:1165
-msgid "'git multi-pack-index repack' failed"
-msgstr ""
-
-#: builtin/gc.c:1174
-msgid ""
-"skipping incremental-repack task because core.multiPackIndex is disabled"
-msgstr ""
-
-#: builtin/gc.c:1278
-#, c-format
-msgid "lock file '%s' exists, skipping maintenance"
-msgstr ""
-
-#: builtin/gc.c:1308
-#, c-format
-msgid "task '%s' failed"
-msgstr ""
-
-#: builtin/gc.c:1390
-#, c-format
-msgid "'%s' is not a valid task"
-msgstr ""
-
-#: builtin/gc.c:1395
-#, c-format
-msgid "task '%s' cannot be selected multiple times"
-msgstr ""
-
-#: builtin/gc.c:1410
-msgid "run tasks based on the state of the repository"
-msgstr ""
-
-#: builtin/gc.c:1411
-msgid "frequency"
-msgstr ""
-
-#: builtin/gc.c:1412
-msgid "run tasks based on frequency"
-msgstr ""
-
-#: builtin/gc.c:1415
-msgid "do not report progress or other information over stderr"
-msgstr ""
-
-#: builtin/gc.c:1416
-msgid "task"
-msgstr ""
-
-#: builtin/gc.c:1417
-msgid "run a specific task"
-msgstr ""
-
-#: builtin/gc.c:1434
-msgid "use at most one of --auto and --schedule=<frequency>"
-msgstr ""
-
-#: builtin/gc.c:1477
-msgid "failed to run 'git config'"
-msgstr ""
-
-#: builtin/gc.c:1629
-#, c-format
-msgid "failed to expand path '%s'"
-msgstr ""
-
-#: builtin/gc.c:1656 builtin/gc.c:1694
-msgid "failed to start launchctl"
-msgstr ""
-
-#: builtin/gc.c:1769 builtin/gc.c:2237
-#, c-format
-msgid "failed to create directories for '%s'"
-msgstr ""
-
-#: builtin/gc.c:1796
-#, c-format
-msgid "failed to bootstrap service %s"
-msgstr ""
-
-#: builtin/gc.c:1889
-msgid "failed to create temp xml file"
-msgstr ""
-
-#: builtin/gc.c:1979
-msgid "failed to start schtasks"
-msgstr ""
-
-#: builtin/gc.c:2063
-msgid "failed to run 'crontab -l'; your system might not support 'cron'"
-msgstr ""
-
-#: builtin/gc.c:2080
-msgid "failed to run 'crontab'; your system might not support 'cron'"
-msgstr ""
-
-#: builtin/gc.c:2084
-msgid "failed to open stdin of 'crontab'"
-msgstr ""
-
-#: builtin/gc.c:2126
-msgid "'crontab' died"
-msgstr ""
-
-#: builtin/gc.c:2191
-msgid "failed to start systemctl"
-msgstr ""
-
-#: builtin/gc.c:2201
-msgid "failed to run systemctl"
-msgstr ""
-
-#: builtin/gc.c:2210 builtin/gc.c:2215 builtin/worktree.c:63
-#: builtin/worktree.c:1024
-#, c-format
-msgid "failed to delete '%s'"
-msgstr ""
-
-#: builtin/gc.c:2395
-#, c-format
-msgid "unrecognized --scheduler argument '%s'"
-msgstr ""
-
-#: builtin/gc.c:2420
-msgid "neither systemd timers nor crontab are available"
-msgstr ""
-
-#: builtin/gc.c:2435
-#, c-format
-msgid "%s scheduler is not available"
-msgstr ""
-
-#: builtin/gc.c:2449
-msgid "another process is scheduling background maintenance"
-msgstr ""
-
-#: builtin/gc.c:2471
-msgid "git maintenance start [--scheduler=<scheduler>]"
-msgstr ""
-
-#: builtin/gc.c:2480
-msgid "scheduler"
-msgstr ""
-
-#: builtin/gc.c:2481
-msgid "scheduler to trigger git maintenance run"
-msgstr ""
-
-#: builtin/gc.c:2495
-msgid "failed to add repo to global config"
-msgstr ""
-
-#: builtin/gc.c:2504
-msgid "git maintenance <subcommand> [<options>]"
-msgstr ""
-
-#: builtin/gc.c:2523
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr ""
-
-#: builtin/grep.c:32
-msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
-msgstr ""
-
-#: builtin/grep.c:241
-#, c-format
-msgid "grep: failed to create thread: %s"
-msgstr ""
-
-#: builtin/grep.c:295
-#, c-format
-msgid "invalid number of threads specified (%d) for %s"
-msgstr ""
-
-#. TRANSLATORS: %s is the configuration
-#. variable for tweaking threads, currently
-#. grep.threads
-#.
-#: builtin/grep.c:303 builtin/index-pack.c:1587 builtin/index-pack.c:1791
-#: builtin/pack-objects.c:3150
-#, c-format
-msgid "no threads support, ignoring %s"
-msgstr ""
-
-#: builtin/grep.c:490 builtin/grep.c:619 builtin/grep.c:659
-#, c-format
-msgid "unable to read tree (%s)"
-msgstr ""
-
-#: builtin/grep.c:674
-#, c-format
-msgid "unable to grep from object of type %s"
-msgstr ""
-
-#: builtin/grep.c:754
-#, c-format
-msgid "switch `%c' expects a numerical value"
-msgstr ""
-
-#: builtin/grep.c:852
-msgid "search in index instead of in the work tree"
-msgstr ""
-
-#: builtin/grep.c:854
-msgid "find in contents not managed by git"
-msgstr ""
-
-#: builtin/grep.c:856
-msgid "search in both tracked and untracked files"
-msgstr ""
-
-#: builtin/grep.c:858
-msgid "ignore files specified via '.gitignore'"
-msgstr ""
-
-#: builtin/grep.c:860
-msgid "recursively search in each submodule"
-msgstr ""
-
-#: builtin/grep.c:863
-msgid "show non-matching lines"
-msgstr ""
-
-#: builtin/grep.c:865
-msgid "case insensitive matching"
-msgstr ""
-
-#: builtin/grep.c:867
-msgid "match patterns only at word boundaries"
-msgstr ""
-
-#: builtin/grep.c:869
-msgid "process binary files as text"
-msgstr ""
-
-#: builtin/grep.c:871
-msgid "don't match patterns in binary files"
-msgstr ""
-
-#: builtin/grep.c:874
-msgid "process binary files with textconv filters"
-msgstr ""
-
-#: builtin/grep.c:876
-msgid "search in subdirectories (default)"
-msgstr ""
-
-#: builtin/grep.c:878
-msgid "descend at most <depth> levels"
-msgstr ""
-
-#: builtin/grep.c:882
-msgid "use extended POSIX regular expressions"
-msgstr ""
-
-#: builtin/grep.c:885
-msgid "use basic POSIX regular expressions (default)"
-msgstr ""
-
-#: builtin/grep.c:888
-msgid "interpret patterns as fixed strings"
-msgstr ""
-
-#: builtin/grep.c:891
-msgid "use Perl-compatible regular expressions"
-msgstr ""
-
-#: builtin/grep.c:894
-msgid "show line numbers"
-msgstr ""
-
-#: builtin/grep.c:895
-msgid "show column number of first match"
-msgstr ""
-
-#: builtin/grep.c:896
-msgid "don't show filenames"
-msgstr ""
-
-#: builtin/grep.c:897
-msgid "show filenames"
-msgstr ""
-
-#: builtin/grep.c:899
-msgid "show filenames relative to top directory"
-msgstr ""
-
-#: builtin/grep.c:901
-msgid "show only filenames instead of matching lines"
-msgstr ""
-
-#: builtin/grep.c:903
-msgid "synonym for --files-with-matches"
-msgstr ""
-
-#: builtin/grep.c:906
-msgid "show only the names of files without match"
-msgstr ""
-
-#: builtin/grep.c:908
-msgid "print NUL after filenames"
-msgstr ""
-
-#: builtin/grep.c:911
-msgid "show only matching parts of a line"
-msgstr ""
-
-#: builtin/grep.c:913
-msgid "show the number of matches instead of matching lines"
-msgstr ""
-
-#: builtin/grep.c:914
-msgid "highlight matches"
-msgstr ""
-
-#: builtin/grep.c:916
-msgid "print empty line between matches from different files"
-msgstr ""
-
-#: builtin/grep.c:918
-msgid "show filename only once above matches from same file"
-msgstr ""
-
-#: builtin/grep.c:921
-msgid "show <n> context lines before and after matches"
-msgstr ""
-
-#: builtin/grep.c:924
-msgid "show <n> context lines before matches"
-msgstr ""
-
-#: builtin/grep.c:926
-msgid "show <n> context lines after matches"
-msgstr ""
-
-#: builtin/grep.c:928
-msgid "use <n> worker threads"
-msgstr ""
-
-#: builtin/grep.c:929
-msgid "shortcut for -C NUM"
-msgstr ""
-
-#: builtin/grep.c:932
-msgid "show a line with the function name before matches"
-msgstr ""
-
-#: builtin/grep.c:934
-msgid "show the surrounding function"
-msgstr ""
-
-#: builtin/grep.c:937
-msgid "read patterns from file"
-msgstr ""
-
-#: builtin/grep.c:939
-msgid "match <pattern>"
-msgstr ""
-
-#: builtin/grep.c:941
-msgid "combine patterns specified with -e"
-msgstr ""
-
-#: builtin/grep.c:953
-msgid "indicate hit with exit status without output"
-msgstr ""
-
-#: builtin/grep.c:955
-msgid "show only matches from files that match all patterns"
-msgstr ""
-
-#: builtin/grep.c:958
-msgid "pager"
-msgstr ""
-
-#: builtin/grep.c:958
-msgid "show matching files in the pager"
-msgstr ""
-
-#: builtin/grep.c:962
-msgid "allow calling of grep(1) (ignored by this build)"
-msgstr ""
-
-#: builtin/grep.c:1028
-msgid "no pattern given"
-msgstr ""
-
-#: builtin/grep.c:1064
-msgid "--no-index or --untracked cannot be used with revs"
-msgstr ""
-
-#: builtin/grep.c:1072
-#, c-format
-msgid "unable to resolve revision: %s"
-msgstr ""
-
-#: builtin/grep.c:1102
-msgid "--untracked not supported with --recurse-submodules"
-msgstr ""
-
-#: builtin/grep.c:1106
-msgid "invalid option combination, ignoring --threads"
-msgstr ""
-
-#: builtin/grep.c:1109 builtin/pack-objects.c:4084
-msgid "no threads support, ignoring --threads"
-msgstr ""
-
-#: builtin/grep.c:1112 builtin/index-pack.c:1584 builtin/pack-objects.c:3147
-#, c-format
-msgid "invalid number of threads specified (%d)"
-msgstr ""
-
-#: builtin/grep.c:1146
-msgid "--open-files-in-pager only works on the worktree"
-msgstr ""
-
-#: builtin/grep.c:1179
-msgid "--[no-]exclude-standard cannot be used for tracked contents"
-msgstr ""
-
-#: builtin/grep.c:1187
-msgid "both --cached and trees are given"
-msgstr ""
-
-#: builtin/hash-object.c:83
-msgid ""
-"git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] "
-"[--] <file>..."
-msgstr ""
-
-#: builtin/hash-object.c:97
-msgid "object type"
-msgstr ""
-
-#: builtin/hash-object.c:98
-msgid "write the object into the object database"
-msgstr ""
-
-#: builtin/hash-object.c:100
-msgid "read the object from stdin"
-msgstr ""
-
-#: builtin/hash-object.c:102
-msgid "store file as is without filters"
-msgstr ""
-
-#: builtin/hash-object.c:103
-msgid ""
-"just hash any random garbage to create corrupt objects for debugging Git"
-msgstr ""
-
-#: builtin/hash-object.c:104
-msgid "process file as it were from this path"
-msgstr ""
-
-#: builtin/help.c:57
-msgid "print all available commands"
-msgstr ""
-
-#: builtin/help.c:60
-msgid "show external commands in --all"
-msgstr ""
-
-#: builtin/help.c:61
-msgid "show aliases in --all"
-msgstr ""
-
-#: builtin/help.c:62
-msgid "exclude guides"
-msgstr ""
-
-#: builtin/help.c:63
-msgid "show man page"
-msgstr ""
-
-#: builtin/help.c:64
-msgid "show manual in web browser"
-msgstr ""
-
-#: builtin/help.c:66
-msgid "show info page"
-msgstr ""
-
-#: builtin/help.c:68
-msgid "print command description"
-msgstr ""
-
-#: builtin/help.c:70
-msgid "print list of useful guides"
-msgstr ""
-
-#: builtin/help.c:72
-msgid "print all configuration variable names"
-msgstr ""
-
-#: builtin/help.c:84
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr ""
-
-#: builtin/help.c:201
-#, c-format
-msgid "unrecognized help format '%s'"
-msgstr ""
-
-#: builtin/help.c:227
-msgid "Failed to start emacsclient."
-msgstr ""
-
-#: builtin/help.c:240
-msgid "Failed to parse emacsclient version."
-msgstr ""
-
-#: builtin/help.c:248
-#, c-format
-msgid "emacsclient version '%d' too old (< 22)."
-msgstr ""
-
-#: builtin/help.c:266 builtin/help.c:288 builtin/help.c:298 builtin/help.c:306
-#, c-format
-msgid "failed to exec '%s'"
-msgstr ""
-
-#: builtin/help.c:344
-#, c-format
-msgid ""
-"'%s': path for unsupported man viewer.\n"
-"Please consider using 'man.<tool>.cmd' instead."
-msgstr ""
-
-#: builtin/help.c:356
-#, c-format
-msgid ""
-"'%s': cmd for supported man viewer.\n"
-"Please consider using 'man.<tool>.path' instead."
-msgstr ""
-
-#: builtin/help.c:471
-#, c-format
-msgid "'%s': unknown man viewer."
-msgstr ""
-
-#: builtin/help.c:487
-msgid "no man viewer handled the request"
-msgstr ""
-
-#: builtin/help.c:494
-msgid "no info viewer handled the request"
-msgstr ""
-
-#: builtin/help.c:555 builtin/help.c:566 git.c:348
-#, c-format
-msgid "'%s' is aliased to '%s'"
-msgstr ""
-
-#: builtin/help.c:569 git.c:380
-#, c-format
-msgid "bad alias.%s string: %s"
-msgstr ""
-
-#: builtin/help.c:611
-#, c-format
-msgid "the '%s' option doesn't take any non-option arguments"
-msgstr ""
-
-#: builtin/help.c:631
-msgid ""
-"the '--no-[external-commands|aliases]' options can only be used with '--all'"
-msgstr ""
-
-#: builtin/help.c:643 builtin/help.c:671
-#, c-format
-msgid "usage: %s%s"
-msgstr ""
-
-#: builtin/help.c:666
-msgid "'git help config' for more information"
-msgstr ""
-
-#: builtin/hook.c:10
-msgid "git hook run [--ignore-missing] <hook-name> [-- <hook-args>]"
-msgstr ""
-
-#: builtin/hook.c:30
-msgid "silently ignore missing requested <hook-name>"
-msgstr ""
-
-#: builtin/index-pack.c:221
-#, c-format
-msgid "object type mismatch at %s"
-msgstr ""
-
-#: builtin/index-pack.c:241
-#, c-format
-msgid "did not receive expected object %s"
-msgstr ""
-
-#: builtin/index-pack.c:244
-#, c-format
-msgid "object %s: expected type %s, found %s"
-msgstr ""
-
-#: builtin/index-pack.c:294
-#, c-format
-msgid "cannot fill %d byte"
-msgid_plural "cannot fill %d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/index-pack.c:304
-msgid "early EOF"
-msgstr ""
-
-#: builtin/index-pack.c:305
-msgid "read error on input"
-msgstr ""
-
-#: builtin/index-pack.c:317
-msgid "used more bytes than were available"
-msgstr ""
-
-#: builtin/index-pack.c:324 builtin/pack-objects.c:754
-msgid "pack too large for current definition of off_t"
-msgstr ""
-
-#: builtin/index-pack.c:329
-#, c-format
-msgid "pack exceeds maximum allowed size (%s)"
-msgstr ""
-
-#: builtin/index-pack.c:362
-msgid "pack signature mismatch"
-msgstr ""
-
-#: builtin/index-pack.c:364
-#, c-format
-msgid "pack version %<PRIu32> unsupported"
-msgstr ""
-
-#: builtin/index-pack.c:380
-#, c-format
-msgid "pack has bad object at offset %<PRIuMAX>: %s"
-msgstr ""
-
-#: builtin/index-pack.c:485
-#, c-format
-msgid "inflate returned %d"
-msgstr ""
-
-#: builtin/index-pack.c:534
-msgid "offset value overflow for delta base object"
-msgstr ""
-
-#: builtin/index-pack.c:542
-msgid "delta base offset is out of bound"
-msgstr ""
-
-#: builtin/index-pack.c:550
-#, c-format
-msgid "unknown object type %d"
-msgstr ""
-
-#: builtin/index-pack.c:581
-msgid "cannot pread pack file"
-msgstr ""
-
-#: builtin/index-pack.c:583
-#, c-format
-msgid "premature end of pack file, %<PRIuMAX> byte missing"
-msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/index-pack.c:609
-msgid "serious inflate inconsistency"
-msgstr ""
-
-#: builtin/index-pack.c:754 builtin/index-pack.c:760 builtin/index-pack.c:784
-#: builtin/index-pack.c:823 builtin/index-pack.c:832
-#, c-format
-msgid "SHA1 COLLISION FOUND WITH %s !"
-msgstr ""
-
-#: builtin/index-pack.c:757 builtin/pack-objects.c:290
-#: builtin/pack-objects.c:350 builtin/pack-objects.c:456
-#, c-format
-msgid "unable to read %s"
-msgstr ""
-
-#: builtin/index-pack.c:821
-#, c-format
-msgid "cannot read existing object info %s"
-msgstr ""
-
-#: builtin/index-pack.c:829
-#, c-format
-msgid "cannot read existing object %s"
-msgstr ""
-
-#: builtin/index-pack.c:843
-#, c-format
-msgid "invalid blob object %s"
-msgstr ""
-
-#: builtin/index-pack.c:846 builtin/index-pack.c:865
-msgid "fsck error in packed object"
-msgstr ""
-
-#: builtin/index-pack.c:867
-#, c-format
-msgid "Not all child objects of %s are reachable"
-msgstr ""
-
-#: builtin/index-pack.c:928 builtin/index-pack.c:975
-msgid "failed to apply delta"
-msgstr ""
-
-#: builtin/index-pack.c:1161
-msgid "Receiving objects"
-msgstr ""
-
-#: builtin/index-pack.c:1161
-msgid "Indexing objects"
-msgstr ""
-
-#: builtin/index-pack.c:1195
-msgid "pack is corrupted (SHA1 mismatch)"
-msgstr ""
-
-#: builtin/index-pack.c:1200
-msgid "cannot fstat packfile"
-msgstr ""
-
-#: builtin/index-pack.c:1203
-msgid "pack has junk at the end"
-msgstr ""
-
-#: builtin/index-pack.c:1215
-msgid "confusion beyond insanity in parse_pack_objects()"
-msgstr ""
-
-#: builtin/index-pack.c:1238
-msgid "Resolving deltas"
-msgstr ""
-
-#: builtin/index-pack.c:1249 builtin/pack-objects.c:2913
-#, c-format
-msgid "unable to create thread: %s"
-msgstr ""
-
-#: builtin/index-pack.c:1282
-msgid "confusion beyond insanity"
-msgstr ""
-
-#: builtin/index-pack.c:1288
-#, c-format
-msgid "completed with %d local object"
-msgid_plural "completed with %d local objects"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/index-pack.c:1300
-#, c-format
-msgid "Unexpected tail checksum for %s (disk corruption?)"
-msgstr ""
-
-#: builtin/index-pack.c:1304
-#, c-format
-msgid "pack has %d unresolved delta"
-msgid_plural "pack has %d unresolved deltas"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/index-pack.c:1328
-#, c-format
-msgid "unable to deflate appended object (%d)"
-msgstr ""
-
-#: builtin/index-pack.c:1423
-#, c-format
-msgid "local object %s is corrupt"
-msgstr ""
-
-#: builtin/index-pack.c:1445
-#, c-format
-msgid "packfile name '%s' does not end with '.%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1469
-#, c-format
-msgid "cannot write %s file '%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1477
-#, c-format
-msgid "cannot close written %s file '%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1494
-#, c-format
-msgid "unable to rename temporary '*.%s' file to '%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1519
-msgid "error while closing pack file"
-msgstr ""
-
-#: builtin/index-pack.c:1578 builtin/pack-objects.c:3158
-#, c-format
-msgid "bad pack.indexversion=%<PRIu32>"
-msgstr ""
-
-#: builtin/index-pack.c:1648
-#, c-format
-msgid "Cannot open existing pack file '%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1650
-#, c-format
-msgid "Cannot open existing pack idx file for '%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1698
-#, c-format
-msgid "non delta: %d object"
-msgid_plural "non delta: %d objects"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/index-pack.c:1705
-#, c-format
-msgid "chain length = %d: %lu object"
-msgid_plural "chain length = %d: %lu objects"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/index-pack.c:1748
-msgid "Cannot come back to cwd"
-msgstr ""
-
-#: builtin/index-pack.c:1802 builtin/index-pack.c:1805
-#: builtin/index-pack.c:1825 builtin/index-pack.c:1829
-#, c-format
-msgid "bad %s"
-msgstr ""
-
-#: builtin/index-pack.c:1835 builtin/init-db.c:379 builtin/init-db.c:614
-#, c-format
-msgid "unknown hash algorithm '%s'"
-msgstr ""
-
-#: builtin/index-pack.c:1856
-msgid "--stdin requires a git repository"
-msgstr ""
-
-#: builtin/index-pack.c:1873
-msgid "--verify with no packfile name given"
-msgstr ""
-
-#: builtin/index-pack.c:1939 builtin/unpack-objects.c:584
-msgid "fsck error in pack objects"
-msgstr ""
-
-#: builtin/init-db.c:63
-#, c-format
-msgid "cannot stat template '%s'"
-msgstr ""
-
-#: builtin/init-db.c:68
-#, c-format
-msgid "cannot opendir '%s'"
-msgstr ""
-
-#: builtin/init-db.c:80
-#, c-format
-msgid "cannot readlink '%s'"
-msgstr ""
-
-#: builtin/init-db.c:82
-#, c-format
-msgid "cannot symlink '%s' '%s'"
-msgstr ""
-
-#: builtin/init-db.c:88
-#, c-format
-msgid "cannot copy '%s' to '%s'"
-msgstr ""
-
-#: builtin/init-db.c:92
-#, c-format
-msgid "ignoring template %s"
-msgstr ""
-
-#: builtin/init-db.c:123
-#, c-format
-msgid "templates not found in %s"
-msgstr ""
-
-#: builtin/init-db.c:138
-#, c-format
-msgid "not copying templates from '%s': %s"
-msgstr ""
-
-#: builtin/init-db.c:263
-#, c-format
-msgid "invalid initial branch name: '%s'"
-msgstr ""
-
-#: builtin/init-db.c:354
-#, c-format
-msgid "unable to handle file type %d"
-msgstr ""
-
-#: builtin/init-db.c:357
-#, c-format
-msgid "unable to move %s to %s"
-msgstr ""
-
-#: builtin/init-db.c:373
-msgid "attempt to reinitialize repository with different hash"
-msgstr ""
-
-#: builtin/init-db.c:397 builtin/init-db.c:400
-#, c-format
-msgid "%s already exists"
-msgstr ""
-
-#: builtin/init-db.c:432
-#, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr ""
-
-#: builtin/init-db.c:463
-#, c-format
-msgid "Reinitialized existing shared Git repository in %s%s\n"
-msgstr ""
-
-#: builtin/init-db.c:464
-#, c-format
-msgid "Reinitialized existing Git repository in %s%s\n"
-msgstr ""
-
-#: builtin/init-db.c:468
-#, c-format
-msgid "Initialized empty shared Git repository in %s%s\n"
-msgstr ""
-
-#: builtin/init-db.c:469
-#, c-format
-msgid "Initialized empty Git repository in %s%s\n"
-msgstr ""
-
-#: builtin/init-db.c:518
-msgid ""
-"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--"
-"shared[=<permissions>]] [<directory>]"
-msgstr ""
-
-#: builtin/init-db.c:544
-msgid "permissions"
-msgstr ""
-
-#: builtin/init-db.c:545
-msgid "specify that the git repository is to be shared amongst several users"
-msgstr ""
-
-#: builtin/init-db.c:551
-msgid "override the name of the initial branch"
-msgstr ""
-
-#: builtin/init-db.c:552 builtin/verify-pack.c:74
-msgid "hash"
-msgstr ""
-
-#: builtin/init-db.c:553 builtin/show-index.c:22 builtin/verify-pack.c:75
-msgid "specify the hash algorithm to use"
-msgstr ""
-
-#: builtin/init-db.c:591 builtin/init-db.c:596
-#, c-format
-msgid "cannot mkdir %s"
-msgstr ""
-
-#: builtin/init-db.c:600 builtin/init-db.c:655
-#, c-format
-msgid "cannot chdir to %s"
-msgstr ""
-
-#: builtin/init-db.c:627
-#, c-format
-msgid ""
-"%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
-"dir=<directory>)"
-msgstr ""
-
-#: builtin/init-db.c:679
-#, c-format
-msgid "Cannot access work tree '%s'"
-msgstr ""
-
-#: builtin/init-db.c:684
-msgid "--separate-git-dir incompatible with bare repository"
-msgstr ""
-
-#: builtin/interpret-trailers.c:16
-msgid ""
-"git interpret-trailers [--in-place] [--trim-empty] [(--trailer "
-"<token>[(=|:)<value>])...] [<file>...]"
-msgstr ""
-
-#: builtin/interpret-trailers.c:95
-msgid "edit files in place"
-msgstr ""
-
-#: builtin/interpret-trailers.c:96
-msgid "trim empty trailers"
-msgstr ""
-
-#: builtin/interpret-trailers.c:99
-msgid "where to place the new trailer"
-msgstr ""
-
-#: builtin/interpret-trailers.c:101
-msgid "action if trailer already exists"
-msgstr ""
-
-#: builtin/interpret-trailers.c:103
-msgid "action if trailer is missing"
-msgstr ""
-
-#: builtin/interpret-trailers.c:105
-msgid "output only the trailers"
-msgstr ""
-
-#: builtin/interpret-trailers.c:106
-msgid "do not apply config rules"
-msgstr ""
-
-#: builtin/interpret-trailers.c:107
-msgid "join whitespace-continued values"
-msgstr ""
-
-#: builtin/interpret-trailers.c:108
-msgid "set parsing options"
-msgstr ""
-
-#: builtin/interpret-trailers.c:110
-msgid "do not treat --- specially"
-msgstr ""
-
-#: builtin/interpret-trailers.c:112
-msgid "trailer(s) to add"
-msgstr ""
-
-#: builtin/interpret-trailers.c:123
-msgid "--trailer with --only-input does not make sense"
-msgstr ""
-
-#: builtin/interpret-trailers.c:133
-msgid "no input file given for in-place editing"
-msgstr ""
-
-#: builtin/log.c:60
-msgid "git log [<options>] [<revision-range>] [[--] <path>...]"
-msgstr ""
-
-#: builtin/log.c:61
-msgid "git show [<options>] <object>..."
-msgstr ""
-
-#: builtin/log.c:114
-#, c-format
-msgid "invalid --decorate option: %s"
-msgstr ""
-
-#: builtin/log.c:181
-msgid "show source"
-msgstr ""
-
-#: builtin/log.c:182
-msgid "use mail map file"
-msgstr ""
-
-#: builtin/log.c:185
-msgid "only decorate refs that match <pattern>"
-msgstr ""
-
-#: builtin/log.c:187
-msgid "do not decorate refs that match <pattern>"
-msgstr ""
-
-#: builtin/log.c:188
-msgid "decorate options"
-msgstr ""
-
-#: builtin/log.c:191
-msgid ""
-"trace the evolution of line range <start>,<end> or function :<funcname> in "
-"<file>"
-msgstr ""
-
-#: builtin/log.c:214
-msgid "-L<range>:<file> cannot be used with pathspec"
-msgstr ""
-
-#: builtin/log.c:322
-#, c-format
-msgid "Final output: %d %s\n"
-msgstr ""
-
-#: builtin/log.c:429
-msgid "unable to create temporary object directory"
-msgstr ""
-
-#: builtin/log.c:599
-#, c-format
-msgid "git show %s: bad file"
-msgstr ""
-
-#: builtin/log.c:614 builtin/log.c:706
-#, c-format
-msgid "could not read object %s"
-msgstr ""
-
-#: builtin/log.c:731
-#, c-format
-msgid "unknown type: %d"
-msgstr ""
-
-#: builtin/log.c:880
-#, c-format
-msgid "%s: invalid cover from description mode"
-msgstr ""
-
-#: builtin/log.c:887
-msgid "format.headers without value"
-msgstr ""
-
-#: builtin/log.c:1016
-#, c-format
-msgid "cannot open patch file %s"
-msgstr ""
-
-#: builtin/log.c:1033
-msgid "need exactly one range"
-msgstr ""
-
-#: builtin/log.c:1043
-msgid "not a range"
-msgstr ""
-
-#: builtin/log.c:1207
-msgid "cover letter needs email format"
-msgstr ""
-
-#: builtin/log.c:1213
-msgid "failed to create cover-letter file"
-msgstr ""
-
-#: builtin/log.c:1300
-#, c-format
-msgid "insane in-reply-to: %s"
-msgstr ""
-
-#: builtin/log.c:1327
-msgid "git format-patch [<options>] [<since> | <revision-range>]"
-msgstr ""
-
-#: builtin/log.c:1385
-msgid "two output directories?"
-msgstr ""
-
-#: builtin/log.c:1536 builtin/log.c:2369 builtin/log.c:2371 builtin/log.c:2383
-#, c-format
-msgid "unknown commit %s"
-msgstr ""
-
-#: builtin/log.c:1547 builtin/replace.c:58 builtin/replace.c:207
-#: builtin/replace.c:210
-#, c-format
-msgid "failed to resolve '%s' as a valid ref"
-msgstr ""
-
-#: builtin/log.c:1556
-msgid "could not find exact merge base"
-msgstr ""
-
-#: builtin/log.c:1566
-msgid ""
-"failed to get upstream, if you want to record base commit automatically,\n"
-"please use git branch --set-upstream-to to track a remote branch.\n"
-"Or you could specify base commit by --base=<base-commit-id> manually"
-msgstr ""
-
-#: builtin/log.c:1589
-msgid "failed to find exact merge base"
-msgstr ""
-
-#: builtin/log.c:1606
-msgid "base commit should be the ancestor of revision list"
-msgstr ""
-
-#: builtin/log.c:1616
-msgid "base commit shouldn't be in revision list"
-msgstr ""
-
-#: builtin/log.c:1674
-msgid "cannot get patch id"
-msgstr ""
-
-#: builtin/log.c:1737
-msgid "failed to infer range-diff origin of current series"
-msgstr ""
-
-#: builtin/log.c:1739
-#, c-format
-msgid "using '%s' as range-diff origin of current series"
-msgstr ""
-
-#: builtin/log.c:1783
-msgid "use [PATCH n/m] even with a single patch"
-msgstr ""
-
-#: builtin/log.c:1786
-msgid "use [PATCH] even with multiple patches"
-msgstr ""
-
-#: builtin/log.c:1790
-msgid "print patches to standard out"
-msgstr ""
-
-#: builtin/log.c:1792
-msgid "generate a cover letter"
-msgstr ""
-
-#: builtin/log.c:1794
-msgid "use simple number sequence for output file names"
-msgstr ""
-
-#: builtin/log.c:1795
-msgid "sfx"
-msgstr ""
-
-#: builtin/log.c:1796
-msgid "use <sfx> instead of '.patch'"
-msgstr ""
-
-#: builtin/log.c:1798
-msgid "start numbering patches at <n> instead of 1"
-msgstr ""
-
-#: builtin/log.c:1799
-msgid "reroll-count"
-msgstr ""
-
-#: builtin/log.c:1800
-msgid "mark the series as Nth re-roll"
-msgstr ""
-
-#: builtin/log.c:1802
-msgid "max length of output filename"
-msgstr ""
-
-#: builtin/log.c:1804
-msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr ""
-
-#: builtin/log.c:1807
-msgid "cover-from-description-mode"
-msgstr ""
-
-#: builtin/log.c:1808
-msgid "generate parts of a cover letter based on a branch's description"
-msgstr ""
-
-#: builtin/log.c:1810
-msgid "use [<prefix>] instead of [PATCH]"
-msgstr ""
-
-#: builtin/log.c:1813
-msgid "store resulting files in <dir>"
-msgstr ""
-
-#: builtin/log.c:1816
-msgid "don't strip/add [PATCH]"
-msgstr ""
-
-#: builtin/log.c:1819
-msgid "don't output binary diffs"
-msgstr ""
-
-#: builtin/log.c:1821
-msgid "output all-zero hash in From header"
-msgstr ""
-
-#: builtin/log.c:1823
-msgid "don't include a patch matching a commit upstream"
-msgstr ""
-
-#: builtin/log.c:1825
-msgid "show patch format instead of default (patch + stat)"
-msgstr ""
-
-#: builtin/log.c:1827
-msgid "Messaging"
-msgstr ""
-
-#: builtin/log.c:1828
-msgid "header"
-msgstr ""
-
-#: builtin/log.c:1829
-msgid "add email header"
-msgstr ""
-
-#: builtin/log.c:1830 builtin/log.c:1831
-msgid "email"
-msgstr ""
-
-#: builtin/log.c:1830
-msgid "add To: header"
-msgstr ""
-
-#: builtin/log.c:1831
-msgid "add Cc: header"
-msgstr ""
-
-#: builtin/log.c:1832
-msgid "ident"
-msgstr ""
-
-#: builtin/log.c:1833
-msgid "set From address to <ident> (or committer ident if absent)"
-msgstr ""
-
-#: builtin/log.c:1835
-msgid "message-id"
-msgstr ""
-
-#: builtin/log.c:1836
-msgid "make first mail a reply to <message-id>"
-msgstr ""
-
-#: builtin/log.c:1837 builtin/log.c:1840
-msgid "boundary"
-msgstr ""
-
-#: builtin/log.c:1838
-msgid "attach the patch"
-msgstr ""
-
-#: builtin/log.c:1841
-msgid "inline the patch"
-msgstr ""
-
-#: builtin/log.c:1845
-msgid "enable message threading, styles: shallow, deep"
-msgstr ""
-
-#: builtin/log.c:1847
-msgid "signature"
-msgstr ""
-
-#: builtin/log.c:1848
-msgid "add a signature"
-msgstr ""
-
-#: builtin/log.c:1849
-msgid "base-commit"
-msgstr ""
-
-#: builtin/log.c:1850
-msgid "add prerequisite tree info to the patch series"
-msgstr ""
-
-#: builtin/log.c:1853
-msgid "add a signature from a file"
-msgstr ""
-
-#: builtin/log.c:1854
-msgid "don't print the patch filenames"
-msgstr ""
-
-#: builtin/log.c:1856
-msgid "show progress while generating patches"
-msgstr ""
-
-#: builtin/log.c:1858
-msgid "show changes against <rev> in cover letter or single patch"
-msgstr ""
-
-#: builtin/log.c:1861
-msgid "show changes against <refspec> in cover letter or single patch"
-msgstr ""
-
-#: builtin/log.c:1863 builtin/range-diff.c:28
-msgid "percentage by which creation is weighted"
-msgstr ""
-
-#: builtin/log.c:1953
-#, c-format
-msgid "invalid ident line: %s"
-msgstr ""
-
-#: builtin/log.c:1978
-msgid "--name-only does not make sense"
-msgstr ""
-
-#: builtin/log.c:1980
-msgid "--name-status does not make sense"
-msgstr ""
-
-#: builtin/log.c:1982
-msgid "--check does not make sense"
-msgstr ""
-
-#: builtin/log.c:1984
-msgid "--remerge-diff does not make sense"
-msgstr ""
-
-#: builtin/log.c:2129
-msgid "--interdiff requires --cover-letter or single patch"
-msgstr ""
-
-#: builtin/log.c:2133
-msgid "Interdiff:"
-msgstr ""
-
-#: builtin/log.c:2134
-#, c-format
-msgid "Interdiff against v%d:"
-msgstr ""
-
-#: builtin/log.c:2144
-msgid "--range-diff requires --cover-letter or single patch"
-msgstr ""
-
-#: builtin/log.c:2152
-msgid "Range-diff:"
-msgstr ""
-
-#: builtin/log.c:2153
-#, c-format
-msgid "Range-diff against v%d:"
-msgstr ""
-
-#: builtin/log.c:2164
-#, c-format
-msgid "unable to read signature file '%s'"
-msgstr ""
-
-#: builtin/log.c:2200
-msgid "Generating patches"
-msgstr ""
-
-#: builtin/log.c:2244
-msgid "failed to create output files"
-msgstr ""
-
-#: builtin/log.c:2304
-msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
-msgstr ""
-
-#: builtin/log.c:2358
-#, c-format
-msgid ""
-"Could not find a tracked remote branch, please specify <upstream> manually.\n"
-msgstr ""
-
-#: builtin/ls-files.c:564
-msgid "git ls-files [<options>] [<file>...]"
-msgstr ""
-
-#: builtin/ls-files.c:618
-msgid "separate paths with the NUL character"
-msgstr ""
-
-#: builtin/ls-files.c:620
-msgid "identify the file status with tags"
-msgstr ""
-
-#: builtin/ls-files.c:622
-msgid "use lowercase letters for 'assume unchanged' files"
-msgstr ""
-
-#: builtin/ls-files.c:624
-msgid "use lowercase letters for 'fsmonitor clean' files"
-msgstr ""
-
-#: builtin/ls-files.c:626
-msgid "show cached files in the output (default)"
-msgstr ""
-
-#: builtin/ls-files.c:628
-msgid "show deleted files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:630
-msgid "show modified files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:632
-msgid "show other files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:634
-msgid "show ignored files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:637
-msgid "show staged contents' object name in the output"
-msgstr ""
-
-#: builtin/ls-files.c:639
-msgid "show files on the filesystem that need to be removed"
-msgstr ""
-
-#: builtin/ls-files.c:641
-msgid "show 'other' directories' names only"
-msgstr ""
-
-#: builtin/ls-files.c:643
-msgid "show line endings of files"
-msgstr ""
-
-#: builtin/ls-files.c:645
-msgid "don't show empty directories"
-msgstr ""
-
-#: builtin/ls-files.c:648
-msgid "show unmerged files in the output"
-msgstr ""
-
-#: builtin/ls-files.c:650
-msgid "show resolve-undo information"
-msgstr ""
-
-#: builtin/ls-files.c:652
-msgid "skip files matching pattern"
-msgstr ""
-
-#: builtin/ls-files.c:655
-msgid "read exclude patterns from <file>"
-msgstr ""
-
-#: builtin/ls-files.c:658
-msgid "read additional per-directory exclude patterns in <file>"
-msgstr ""
-
-#: builtin/ls-files.c:660
-msgid "add the standard git exclusions"
-msgstr ""
-
-#: builtin/ls-files.c:664
-msgid "make the output relative to the project top directory"
-msgstr ""
-
-#: builtin/ls-files.c:669
-msgid "if any <file> is not in the index, treat this as an error"
-msgstr ""
-
-#: builtin/ls-files.c:670
-msgid "tree-ish"
-msgstr ""
-
-#: builtin/ls-files.c:671
-msgid "pretend that paths removed since <tree-ish> are still present"
-msgstr ""
-
-#: builtin/ls-files.c:673
-msgid "show debugging data"
-msgstr ""
-
-#: builtin/ls-files.c:675
-msgid "suppress duplicate entries"
-msgstr ""
-
-#: builtin/ls-files.c:677
-msgid "show sparse directories in the presence of a sparse index"
-msgstr ""
-
-#: builtin/ls-remote.c:9
-msgid ""
-"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
-"              [-q | --quiet] [--exit-code] [--get-url]\n"
-"              [--symref] [<repository> [<refs>...]]"
-msgstr ""
-
-#: builtin/ls-remote.c:60
-msgid "do not print remote URL"
-msgstr ""
-
-#: builtin/ls-remote.c:61 builtin/ls-remote.c:63 builtin/rebase.c:1131
-msgid "exec"
-msgstr ""
-
-#: builtin/ls-remote.c:62 builtin/ls-remote.c:64
-msgid "path of git-upload-pack on the remote host"
-msgstr ""
-
-#: builtin/ls-remote.c:66
-msgid "limit to tags"
-msgstr ""
-
-#: builtin/ls-remote.c:67
-msgid "limit to heads"
-msgstr ""
-
-#: builtin/ls-remote.c:68
-msgid "do not show peeled tags"
-msgstr ""
-
-#: builtin/ls-remote.c:70
-msgid "take url.<base>.insteadOf into account"
-msgstr ""
-
-#: builtin/ls-remote.c:73
-msgid "exit with exit code 2 if no matching refs are found"
-msgstr ""
-
-#: builtin/ls-remote.c:76
-msgid "show underlying ref in addition to the object pointed by it"
-msgstr ""
-
-#: builtin/ls-tree.c:36
-msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
-msgstr ""
-
-#: builtin/ls-tree.c:54
-#, c-format
-msgid "could not get object info about '%s'"
-msgstr ""
-
-#: builtin/ls-tree.c:79
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr ""
-
-#: builtin/ls-tree.c:83
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr ""
-
-#: builtin/ls-tree.c:109
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr ""
-
-#: builtin/ls-tree.c:336
-msgid "only show trees"
-msgstr ""
-
-#: builtin/ls-tree.c:338
-msgid "recurse into subtrees"
-msgstr ""
-
-#: builtin/ls-tree.c:340
-msgid "show trees when recursing"
-msgstr ""
-
-#: builtin/ls-tree.c:343
-msgid "terminate entries with NUL byte"
-msgstr ""
-
-#: builtin/ls-tree.c:344
-msgid "include object size"
-msgstr ""
-
-#: builtin/ls-tree.c:346 builtin/ls-tree.c:348
-msgid "list only filenames"
-msgstr ""
-
-#: builtin/ls-tree.c:350
-msgid "list only objects"
-msgstr ""
-
-#: builtin/ls-tree.c:353
-msgid "use full path names"
-msgstr ""
-
-#: builtin/ls-tree.c:355
-msgid "list entire tree; not just current directory (implies --full-name)"
-msgstr ""
-
-#: builtin/ls-tree.c:391
-msgid "--format can't be combined with other format-altering options"
-msgstr ""
-
-#. TRANSLATORS: keep <> in "<" mail ">" info.
-#: builtin/mailinfo.c:14
-msgid "git mailinfo [<options>] <msg> <patch> < mail >info"
-msgstr ""
-
-#: builtin/mailinfo.c:58
-msgid "keep subject"
-msgstr ""
-
-#: builtin/mailinfo.c:60
-msgid "keep non patch brackets in subject"
-msgstr ""
-
-#: builtin/mailinfo.c:62
-msgid "copy Message-ID to the end of commit message"
-msgstr ""
-
-#: builtin/mailinfo.c:64
-msgid "re-code metadata to i18n.commitEncoding"
-msgstr ""
-
-#: builtin/mailinfo.c:67
-msgid "disable charset re-coding of metadata"
-msgstr ""
-
-#: builtin/mailinfo.c:69
-msgid "encoding"
-msgstr ""
-
-#: builtin/mailinfo.c:70
-msgid "re-code metadata to this encoding"
-msgstr ""
-
-#: builtin/mailinfo.c:72
-msgid "use scissors"
-msgstr ""
-
-#: builtin/mailinfo.c:73
-msgid "<action>"
-msgstr ""
-
-#: builtin/mailinfo.c:74
-msgid "action when quoted CR is found"
-msgstr ""
-
-#: builtin/mailinfo.c:77
-msgid "use headers in message's body"
-msgstr ""
-
-#: builtin/mailsplit.c:227
-msgid "reading patches from stdin/tty..."
-msgstr ""
-
-#: builtin/mailsplit.c:242
-#, c-format
-msgid "empty mbox: '%s'"
-msgstr ""
-
-#: builtin/merge-base.c:32
-msgid "git merge-base [-a | --all] <commit> <commit>..."
-msgstr ""
-
-#: builtin/merge-base.c:33
-msgid "git merge-base [-a | --all] --octopus <commit>..."
-msgstr ""
-
-#: builtin/merge-base.c:34
-msgid "git merge-base --independent <commit>..."
-msgstr ""
-
-#: builtin/merge-base.c:35
-msgid "git merge-base --is-ancestor <commit> <commit>"
-msgstr ""
-
-#: builtin/merge-base.c:36
-msgid "git merge-base --fork-point <ref> [<commit>]"
-msgstr ""
-
-#: builtin/merge-base.c:144
-msgid "output all common ancestors"
-msgstr ""
-
-#: builtin/merge-base.c:146
-msgid "find ancestors for a single n-way merge"
-msgstr ""
-
-#: builtin/merge-base.c:148
-msgid "list revs not reachable from others"
-msgstr ""
-
-#: builtin/merge-base.c:150
-msgid "is the first one ancestor of the other?"
-msgstr ""
-
-#: builtin/merge-base.c:152
-msgid "find where <commit> forked from reflog of <ref>"
-msgstr ""
-
-#: builtin/merge-file.c:9
-msgid ""
-"git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> "
-"<orig-file> <file2>"
-msgstr ""
-
-#: builtin/merge-file.c:35
-msgid "send results to standard output"
-msgstr ""
-
-#: builtin/merge-file.c:36
-msgid "use a diff3 based merge"
-msgstr ""
-
-#: builtin/merge-file.c:37
-msgid "use a zealous diff3 based merge"
-msgstr ""
-
-#: builtin/merge-file.c:39
-msgid "for conflicts, use our version"
-msgstr ""
-
-#: builtin/merge-file.c:41
-msgid "for conflicts, use their version"
-msgstr ""
-
-#: builtin/merge-file.c:43
-msgid "for conflicts, use a union version"
-msgstr ""
-
-#: builtin/merge-file.c:46
-msgid "for conflicts, use this marker size"
-msgstr ""
-
-#: builtin/merge-file.c:47
-msgid "do not warn about conflicts"
-msgstr ""
-
-#: builtin/merge-file.c:49
-msgid "set labels for file1/orig-file/file2"
-msgstr ""
-
-#: builtin/merge-recursive.c:47
-#, c-format
-msgid "unknown option %s"
-msgstr ""
-
-#: builtin/merge-recursive.c:53
-#, c-format
-msgid "could not parse object '%s'"
-msgstr ""
-
-#: builtin/merge-recursive.c:57
-#, 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] ""
-
-#: builtin/merge-recursive.c:65
-msgid "not handling anything other than two heads merge."
-msgstr ""
-
-#: builtin/merge-recursive.c:74 builtin/merge-recursive.c:76
-#, c-format
-msgid "could not resolve ref '%s'"
-msgstr ""
-
-#: builtin/merge-recursive.c:82
-#, c-format
-msgid "Merging %s with %s\n"
-msgstr ""
-
-#: builtin/merge.c:59
-msgid "git merge [<options>] [<commit>...]"
-msgstr ""
-
-#: builtin/merge.c:125
-msgid "switch `m' requires a value"
-msgstr ""
-
-#: builtin/merge.c:148
-#, c-format
-msgid "option `%s' requires a value"
-msgstr ""
-
-#: builtin/merge.c:201
-#, c-format
-msgid "Could not find merge strategy '%s'.\n"
-msgstr ""
-
-#: builtin/merge.c:202
-#, c-format
-msgid "Available strategies are:"
-msgstr ""
-
-#: builtin/merge.c:207
-#, c-format
-msgid "Available custom strategies are:"
-msgstr ""
-
-#: builtin/merge.c:258 builtin/pull.c:134
-msgid "do not show a diffstat at the end of the merge"
-msgstr ""
-
-#: builtin/merge.c:261 builtin/pull.c:137
-msgid "show a diffstat at the end of the merge"
-msgstr ""
-
-#: builtin/merge.c:262 builtin/pull.c:140
-msgid "(synonym to --stat)"
-msgstr ""
-
-#: builtin/merge.c:264 builtin/pull.c:143
-msgid "add (at most <n>) entries from shortlog to merge commit message"
-msgstr ""
-
-#: builtin/merge.c:267 builtin/pull.c:149
-msgid "create a single commit instead of doing a merge"
-msgstr ""
-
-#: builtin/merge.c:269 builtin/pull.c:152
-msgid "perform a commit if the merge succeeds (default)"
-msgstr ""
-
-#: builtin/merge.c:271 builtin/pull.c:155
-msgid "edit message before committing"
-msgstr ""
-
-#: builtin/merge.c:273
-msgid "allow fast-forward (default)"
-msgstr ""
-
-#: builtin/merge.c:275 builtin/pull.c:162
-msgid "abort if fast-forward is not possible"
-msgstr ""
-
-#: builtin/merge.c:279 builtin/pull.c:168
-msgid "verify that the named commit has a valid GPG signature"
-msgstr ""
-
-#: builtin/merge.c:280 builtin/notes.c:785 builtin/pull.c:172
-#: builtin/rebase.c:1145 builtin/revert.c:114
-msgid "strategy"
-msgstr ""
-
-#: builtin/merge.c:281 builtin/pull.c:173
-msgid "merge strategy to use"
-msgstr ""
-
-#: builtin/merge.c:282 builtin/pull.c:176
-msgid "option=value"
-msgstr ""
-
-#: builtin/merge.c:283 builtin/pull.c:177
-msgid "option for selected merge strategy"
-msgstr ""
-
-#: builtin/merge.c:285
-msgid "merge commit message (for a non-fast-forward merge)"
-msgstr ""
-
-#: builtin/merge.c:291
-msgid "use <name> instead of the real target"
-msgstr ""
-
-#: builtin/merge.c:294
-msgid "abort the current in-progress merge"
-msgstr ""
-
-#: builtin/merge.c:296
-msgid "--abort but leave index and working tree alone"
-msgstr ""
-
-#: builtin/merge.c:298
-msgid "continue the current in-progress merge"
-msgstr ""
-
-#: builtin/merge.c:300 builtin/pull.c:184
-msgid "allow merging unrelated histories"
-msgstr ""
-
-#: builtin/merge.c:307
-msgid "bypass pre-merge-commit and commit-msg hooks"
-msgstr ""
-
-#: builtin/merge.c:323
-msgid "could not run stash."
-msgstr ""
-
-#: builtin/merge.c:328
-msgid "stash failed"
-msgstr ""
-
-#: builtin/merge.c:333
-#, c-format
-msgid "not a valid object: %s"
-msgstr ""
-
-#: builtin/merge.c:355 builtin/merge.c:372
-msgid "read-tree failed"
-msgstr ""
-
-#: builtin/merge.c:403
-msgid "Already up to date. (nothing to squash)"
-msgstr ""
-
-#: builtin/merge.c:417
-#, c-format
-msgid "Squash commit -- not updating HEAD\n"
-msgstr ""
-
-#: builtin/merge.c:467
-#, c-format
-msgid "No merge message -- not updating HEAD\n"
-msgstr ""
-
-#: builtin/merge.c:517
-#, c-format
-msgid "'%s' does not point to a commit"
-msgstr ""
-
-#: builtin/merge.c:605
-#, c-format
-msgid "Bad branch.%s.mergeoptions string: %s"
-msgstr ""
-
-#: builtin/merge.c:732
-msgid "Not handling anything other than two heads merge."
-msgstr ""
-
-#: builtin/merge.c:745
-#, c-format
-msgid "unknown strategy option: -X%s"
-msgstr ""
-
-#: builtin/merge.c:764 t/helper/test-fast-rebase.c:223
-#, c-format
-msgid "unable to write %s"
-msgstr ""
-
-#: builtin/merge.c:816
-#, c-format
-msgid "Could not read from '%s'"
-msgstr ""
-
-#: builtin/merge.c:825
-#, c-format
-msgid "Not committing merge; use 'git commit' to complete the merge.\n"
-msgstr ""
-
-#: builtin/merge.c:831
-msgid ""
-"Please enter a commit message to explain why this merge is necessary,\n"
-"especially if it merges an updated upstream into a topic branch.\n"
-"\n"
-msgstr ""
-
-#: builtin/merge.c:836
-msgid "An empty message aborts the commit.\n"
-msgstr ""
-
-#: builtin/merge.c:839
-#, c-format
-msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
-"the commit.\n"
-msgstr ""
-
-#: builtin/merge.c:900
-msgid "Empty commit message."
-msgstr ""
-
-#: builtin/merge.c:915
-#, c-format
-msgid "Wonderful.\n"
-msgstr ""
-
-#: builtin/merge.c:976
-#, c-format
-msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
-msgstr ""
-
-#: builtin/merge.c:1015
-msgid "No current branch."
-msgstr ""
-
-#: builtin/merge.c:1017
-msgid "No remote for the current branch."
-msgstr ""
-
-#: builtin/merge.c:1019
-msgid "No default upstream defined for the current branch."
-msgstr ""
-
-#: builtin/merge.c:1024
-#, c-format
-msgid "No remote-tracking branch for %s from %s"
-msgstr ""
-
-#: builtin/merge.c:1081
-#, c-format
-msgid "Bad value '%s' in environment '%s'"
-msgstr ""
-
-#: builtin/merge.c:1183
-#, c-format
-msgid "not something we can merge in %s: %s"
-msgstr ""
-
-#: builtin/merge.c:1217
-msgid "not something we can merge"
-msgstr ""
-
-#: builtin/merge.c:1330
-msgid "--abort expects no arguments"
-msgstr ""
-
-#: builtin/merge.c:1334
-msgid "There is no merge to abort (MERGE_HEAD missing)."
-msgstr ""
-
-#: builtin/merge.c:1352
-msgid "--quit expects no arguments"
-msgstr ""
-
-#: builtin/merge.c:1365
-msgid "--continue expects no arguments"
-msgstr ""
-
-#: builtin/merge.c:1369
-msgid "There is no merge in progress (MERGE_HEAD missing)."
-msgstr ""
-
-#: builtin/merge.c:1385
-msgid ""
-"You have not concluded your merge (MERGE_HEAD exists).\n"
-"Please, commit your changes before you merge."
-msgstr ""
-
-#: builtin/merge.c:1392
-msgid ""
-"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
-"Please, commit your changes before you merge."
-msgstr ""
-
-#: builtin/merge.c:1395
-msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
-msgstr ""
-
-#: builtin/merge.c:1427
-msgid "No commit specified and merge.defaultToUpstream not set."
-msgstr ""
-
-#: builtin/merge.c:1444
-msgid "Squash commit into empty head not supported yet"
-msgstr ""
-
-#: builtin/merge.c:1446
-msgid "Non-fast-forward commit does not make sense into an empty head"
-msgstr ""
-
-#: builtin/merge.c:1451
-#, c-format
-msgid "%s - not something we can merge"
-msgstr ""
-
-#: builtin/merge.c:1453
-msgid "Can merge only exactly one commit into empty head"
-msgstr ""
-
-#: builtin/merge.c:1540
-msgid "refusing to merge unrelated histories"
-msgstr ""
-
-#: builtin/merge.c:1559
-#, c-format
-msgid "Updating %s..%s\n"
-msgstr ""
-
-#: builtin/merge.c:1606
-#, c-format
-msgid "Trying really trivial in-index merge...\n"
-msgstr ""
-
-#: builtin/merge.c:1613
-#, c-format
-msgid "Nope.\n"
-msgstr ""
-
-#: builtin/merge.c:1671 builtin/merge.c:1737
-#, c-format
-msgid "Rewinding the tree to pristine...\n"
-msgstr ""
-
-#: builtin/merge.c:1675
-#, c-format
-msgid "Trying merge strategy %s...\n"
-msgstr ""
-
-#: builtin/merge.c:1727
-#, c-format
-msgid "No merge strategy handled the merge.\n"
-msgstr ""
-
-#: builtin/merge.c:1729
-#, c-format
-msgid "Merge with strategy %s failed.\n"
-msgstr ""
-
-#: builtin/merge.c:1739
-#, c-format
-msgid "Using the %s strategy to prepare resolving by hand.\n"
-msgstr ""
-
-#: builtin/merge.c:1753
-#, c-format
-msgid "Automatic merge went well; stopped before committing as requested\n"
-msgstr ""
-
-#: builtin/mktag.c:27
-#, c-format
-msgid "warning: tag input does not pass fsck: %s"
-msgstr ""
-
-#: builtin/mktag.c:38
-#, c-format
-msgid "error: tag input does not pass fsck: %s"
-msgstr ""
-
-#: builtin/mktag.c:41
-#, c-format
-msgid "%d (FSCK_IGNORE?) should never trigger this callback"
-msgstr ""
-
-#: builtin/mktag.c:56
-#, c-format
-msgid "could not read tagged object '%s'"
-msgstr ""
-
-#: builtin/mktag.c:59
-#, c-format
-msgid "object '%s' tagged as '%s', but is a '%s' type"
-msgstr ""
-
-#: builtin/mktag.c:97
-msgid "tag on stdin did not pass our strict fsck check"
-msgstr ""
-
-#: builtin/mktag.c:100
-msgid "tag on stdin did not refer to a valid object"
-msgstr ""
-
-#: builtin/mktag.c:103 builtin/tag.c:243
-msgid "unable to write tag file"
-msgstr ""
-
-#: builtin/mktree.c:154
-msgid "input is NUL terminated"
-msgstr ""
-
-#: builtin/mktree.c:155 builtin/write-tree.c:26
-msgid "allow missing objects"
-msgstr ""
-
-#: builtin/mktree.c:156
-msgid "allow creation of more than one tree"
-msgstr ""
-
-#: builtin/multi-pack-index.c:10
-msgid ""
-"git multi-pack-index [<options>] write [--preferred-pack=<pack>][--refs-"
-"snapshot=<path>]"
-msgstr ""
-
-#: builtin/multi-pack-index.c:14
-msgid "git multi-pack-index [<options>] verify"
-msgstr ""
-
-#: builtin/multi-pack-index.c:17
-msgid "git multi-pack-index [<options>] expire"
-msgstr ""
-
-#: builtin/multi-pack-index.c:20
-msgid "git multi-pack-index [<options>] repack [--batch-size=<size>]"
-msgstr ""
-
-#: builtin/multi-pack-index.c:57
-msgid "object directory containing set of packfile and pack-index pairs"
-msgstr ""
-
-#: builtin/multi-pack-index.c:98
-msgid "preferred-pack"
-msgstr ""
-
-#: builtin/multi-pack-index.c:99
-msgid "pack for reuse when computing a multi-pack bitmap"
-msgstr ""
-
-#: builtin/multi-pack-index.c:100
-msgid "write multi-pack bitmap"
-msgstr ""
-
-#: builtin/multi-pack-index.c:105
-msgid "write multi-pack index containing only given indexes"
-msgstr ""
-
-#: builtin/multi-pack-index.c:107
-msgid "refs snapshot for selecting bitmap commits"
-msgstr ""
-
-#: builtin/multi-pack-index.c:206
-msgid ""
-"during repack, collect pack-files of smaller size into a batch that is "
-"larger than this size"
-msgstr ""
-
-#: builtin/mv.c:18
-msgid "git mv [<options>] <source>... <destination>"
-msgstr ""
-
-#: builtin/mv.c:83
-#, c-format
-msgid "Directory %s is in index and no submodule?"
-msgstr ""
-
-#: builtin/mv.c:85
-msgid "Please stage your changes to .gitmodules or stash them to proceed"
-msgstr ""
-
-#: builtin/mv.c:103
-#, c-format
-msgid "%.*s is in index"
-msgstr ""
-
-#: builtin/mv.c:125
-msgid "force move/rename even if target exists"
-msgstr ""
-
-#: builtin/mv.c:127
-msgid "skip move/rename errors"
-msgstr ""
-
-#: builtin/mv.c:172
-#, c-format
-msgid "destination '%s' is not a directory"
-msgstr ""
-
-#: builtin/mv.c:184
-#, c-format
-msgid "Checking rename of '%s' to '%s'\n"
-msgstr ""
-
-#: builtin/mv.c:190
-msgid "bad source"
-msgstr ""
-
-#: builtin/mv.c:193
-msgid "can not move directory into itself"
-msgstr ""
-
-#: builtin/mv.c:196
-msgid "cannot move directory over file"
-msgstr ""
-
-#: builtin/mv.c:205
-msgid "source directory is empty"
-msgstr ""
-
-#: builtin/mv.c:231
-msgid "not under version control"
-msgstr ""
-
-#: builtin/mv.c:233
-msgid "conflicted"
-msgstr ""
-
-#: builtin/mv.c:236
-msgid "destination exists"
-msgstr ""
-
-#: builtin/mv.c:244
-#, c-format
-msgid "overwriting '%s'"
-msgstr ""
-
-#: builtin/mv.c:247
-msgid "Cannot overwrite"
-msgstr ""
-
-#: builtin/mv.c:250
-msgid "multiple sources for the same target"
-msgstr ""
-
-#: builtin/mv.c:252
-msgid "destination directory does not exist"
-msgstr ""
-
-#: builtin/mv.c:280
-#, c-format
-msgid "%s, source=%s, destination=%s"
-msgstr ""
-
-#: builtin/mv.c:308
-#, c-format
-msgid "Renaming %s to %s\n"
-msgstr ""
-
-#: builtin/mv.c:314 builtin/remote.c:812 builtin/repack.c:861
-#, c-format
-msgid "renaming '%s' failed"
-msgstr ""
-
-#: builtin/name-rev.c:524
-msgid "git name-rev [<options>] <commit>..."
-msgstr ""
-
-#: builtin/name-rev.c:525
-msgid "git name-rev [<options>] --all"
-msgstr ""
-
-#: builtin/name-rev.c:526
-msgid "git name-rev [<options>] --annotate-stdin"
-msgstr ""
-
-#: builtin/name-rev.c:583
-msgid "print only ref-based names (no object names)"
-msgstr ""
-
-#: builtin/name-rev.c:584
-msgid "only use tags to name the commits"
-msgstr ""
-
-#: builtin/name-rev.c:586
-msgid "only use refs matching <pattern>"
-msgstr ""
-
-#: builtin/name-rev.c:588
-msgid "ignore refs matching <pattern>"
-msgstr ""
-
-#: builtin/name-rev.c:590
-msgid "list all commits reachable from all refs"
-msgstr ""
-
-#: builtin/name-rev.c:591
-msgid "deprecated: use annotate-stdin instead"
-msgstr ""
-
-#: builtin/name-rev.c:592
-msgid "annotate text from stdin"
-msgstr ""
-
-#: builtin/name-rev.c:593
-msgid "allow to print `undefined` names (default)"
-msgstr ""
-
-#: builtin/name-rev.c:599
-msgid "dereference tags in the input (internal use)"
-msgstr ""
-
-#: builtin/notes.c:28
-msgid "git notes [--ref <notes-ref>] [list [<object>]]"
-msgstr ""
-
-#: builtin/notes.c:29
-msgid ""
-"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> "
-"| (-c | -C) <object>] [<object>]"
-msgstr ""
-
-#: builtin/notes.c:30
-msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"
-msgstr ""
-
-#: builtin/notes.c:31
-msgid ""
-"git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | "
-"(-c | -C) <object>] [<object>]"
-msgstr ""
-
-#: builtin/notes.c:32
-msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"
-msgstr ""
-
-#: builtin/notes.c:33
-msgid "git notes [--ref <notes-ref>] show [<object>]"
-msgstr ""
-
-#: builtin/notes.c:34
-msgid ""
-"git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"
-msgstr ""
-
-#: builtin/notes.c:37
-msgid "git notes [--ref <notes-ref>] remove [<object>...]"
-msgstr ""
-
-#: builtin/notes.c:38
-msgid "git notes [--ref <notes-ref>] prune [-n] [-v]"
-msgstr ""
-
-#: builtin/notes.c:39
-msgid "git notes [--ref <notes-ref>] get-ref"
-msgstr ""
-
-#: builtin/notes.c:44
-msgid "git notes [list [<object>]]"
-msgstr ""
-
-#: builtin/notes.c:49
-msgid "git notes add [<options>] [<object>]"
-msgstr ""
-
-#: builtin/notes.c:54
-msgid "git notes copy [<options>] <from-object> <to-object>"
-msgstr ""
-
-#: builtin/notes.c:55
-msgid "git notes copy --stdin [<from-object> <to-object>]..."
-msgstr ""
-
-#: builtin/notes.c:60
-msgid "git notes append [<options>] [<object>]"
-msgstr ""
-
-#: builtin/notes.c:65
-msgid "git notes edit [<object>]"
-msgstr ""
-
-#: builtin/notes.c:70
-msgid "git notes show [<object>]"
-msgstr ""
-
-#: builtin/notes.c:75
-msgid "git notes merge [<options>] <notes-ref>"
-msgstr ""
-
-#: builtin/notes.c:76
-msgid "git notes merge --commit [<options>]"
-msgstr ""
-
-#: builtin/notes.c:77
-msgid "git notes merge --abort [<options>]"
-msgstr ""
-
-#: builtin/notes.c:82
-msgid "git notes remove [<object>]"
-msgstr ""
-
-#: builtin/notes.c:87
-msgid "git notes prune [<options>]"
-msgstr ""
-
-#: builtin/notes.c:97
-msgid "Write/edit the notes for the following object:"
-msgstr ""
-
-#: builtin/notes.c:149
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr ""
-
-#: builtin/notes.c:153
-msgid "could not read 'show' output"
-msgstr ""
-
-#: builtin/notes.c:161
-#, c-format
-msgid "failed to finish 'show' for object '%s'"
-msgstr ""
-
-#: builtin/notes.c:194
-msgid "please supply the note contents using either -m or -F option"
-msgstr ""
-
-#: builtin/notes.c:203
-msgid "unable to write note object"
-msgstr ""
-
-#: builtin/notes.c:206
-#, c-format
-msgid "the note contents have been left in %s"
-msgstr ""
-
-#: builtin/notes.c:240 builtin/tag.c:582
-#, c-format
-msgid "could not open or read '%s'"
-msgstr ""
-
-#: builtin/notes.c:261 builtin/notes.c:311 builtin/notes.c:313
-#: builtin/notes.c:381 builtin/notes.c:436 builtin/notes.c:524
-#: builtin/notes.c:529 builtin/notes.c:608 builtin/notes.c:670
-#, c-format
-msgid "failed to resolve '%s' as a valid ref."
-msgstr ""
-
-#: builtin/notes.c:263
-#, c-format
-msgid "failed to read object '%s'."
-msgstr ""
-
-#: builtin/notes.c:266
-#, c-format
-msgid "cannot read note data from non-blob object '%s'."
-msgstr ""
-
-#: builtin/notes.c:307
-#, c-format
-msgid "malformed input line: '%s'."
-msgstr ""
-
-#: builtin/notes.c:322
-#, c-format
-msgid "failed to copy notes from '%s' to '%s'"
-msgstr ""
-
-#. TRANSLATORS: the first %s will be replaced by a git
-#. notes command: 'add', 'merge', 'remove', etc.
-#.
-#: builtin/notes.c:354
-#, c-format
-msgid "refusing to %s notes in %s (outside of refs/notes/)"
-msgstr ""
-
-#: builtin/notes.c:387 builtin/notes.c:676
-#, c-format
-msgid "no note found for object %s."
-msgstr ""
-
-#: builtin/notes.c:408 builtin/notes.c:574
-msgid "note contents as a string"
-msgstr ""
-
-#: builtin/notes.c:411 builtin/notes.c:577
-msgid "note contents in a file"
-msgstr ""
-
-#: builtin/notes.c:414 builtin/notes.c:580
-msgid "reuse and edit specified note object"
-msgstr ""
-
-#: builtin/notes.c:417 builtin/notes.c:583
-msgid "reuse specified note object"
-msgstr ""
-
-#: builtin/notes.c:420 builtin/notes.c:586
-msgid "allow storing empty note"
-msgstr ""
-
-#: builtin/notes.c:421 builtin/notes.c:494
-msgid "replace existing notes"
-msgstr ""
-
-#: builtin/notes.c:446
-#, c-format
-msgid ""
-"Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite "
-"existing notes"
-msgstr ""
-
-#: builtin/notes.c:461 builtin/notes.c:542
-#, c-format
-msgid "Overwriting existing notes for object %s\n"
-msgstr ""
-
-#: builtin/notes.c:473 builtin/notes.c:635 builtin/notes.c:904
-#, c-format
-msgid "Removing note for object %s\n"
-msgstr ""
-
-#: builtin/notes.c:495
-msgid "read objects from stdin"
-msgstr ""
-
-#: builtin/notes.c:497
-msgid "load rewriting config for <command> (implies --stdin)"
-msgstr ""
-
-#: builtin/notes.c:515
-msgid "too few arguments"
-msgstr ""
-
-#: builtin/notes.c:536
-#, c-format
-msgid ""
-"Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite "
-"existing notes"
-msgstr ""
-
-#: builtin/notes.c:548
-#, c-format
-msgid "missing notes on source object %s. Cannot copy."
-msgstr ""
-
-#: builtin/notes.c:601
-#, c-format
-msgid ""
-"The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
-"Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
-msgstr ""
-
-#: builtin/notes.c:696
-msgid "failed to delete ref NOTES_MERGE_PARTIAL"
-msgstr ""
-
-#: builtin/notes.c:698
-msgid "failed to delete ref NOTES_MERGE_REF"
-msgstr ""
-
-#: builtin/notes.c:700
-msgid "failed to remove 'git notes merge' worktree"
-msgstr ""
-
-#: builtin/notes.c:720
-msgid "failed to read ref NOTES_MERGE_PARTIAL"
-msgstr ""
-
-#: builtin/notes.c:722
-msgid "could not find commit from NOTES_MERGE_PARTIAL."
-msgstr ""
-
-#: builtin/notes.c:724
-msgid "could not parse commit from NOTES_MERGE_PARTIAL."
-msgstr ""
-
-#: builtin/notes.c:737
-msgid "failed to resolve NOTES_MERGE_REF"
-msgstr ""
-
-#: builtin/notes.c:740
-msgid "failed to finalize notes merge"
-msgstr ""
-
-#: builtin/notes.c:766
-#, c-format
-msgid "unknown notes merge strategy %s"
-msgstr ""
-
-#: builtin/notes.c:782
-msgid "General options"
-msgstr ""
-
-#: builtin/notes.c:784
-msgid "Merge options"
-msgstr ""
-
-#: builtin/notes.c:786
-msgid ""
-"resolve notes conflicts using the given strategy (manual/ours/theirs/union/"
-"cat_sort_uniq)"
-msgstr ""
-
-#: builtin/notes.c:788
-msgid "Committing unmerged notes"
-msgstr ""
-
-#: builtin/notes.c:790
-msgid "finalize notes merge by committing unmerged notes"
-msgstr ""
-
-#: builtin/notes.c:792
-msgid "Aborting notes merge resolution"
-msgstr ""
-
-#: builtin/notes.c:794
-msgid "abort notes merge"
-msgstr ""
-
-#: builtin/notes.c:805
-msgid "cannot mix --commit, --abort or -s/--strategy"
-msgstr ""
-
-#: builtin/notes.c:810
-msgid "must specify a notes ref to merge"
-msgstr ""
-
-#: builtin/notes.c:834
-#, c-format
-msgid "unknown -s/--strategy: %s"
-msgstr ""
-
-#: builtin/notes.c:874
-#, c-format
-msgid "a notes merge into %s is already in-progress at %s"
-msgstr ""
-
-#: builtin/notes.c:878
-#, c-format
-msgid "failed to store link to current notes ref (%s)"
-msgstr ""
-
-#: builtin/notes.c:880
-#, c-format
-msgid ""
-"Automatic notes merge failed. Fix conflicts in %s and commit the result with "
-"'git notes merge --commit', or abort the merge with 'git notes merge --"
-"abort'.\n"
-msgstr ""
-
-#: builtin/notes.c:899 builtin/tag.c:595
-#, c-format
-msgid "Failed to resolve '%s' as a valid ref."
-msgstr ""
-
-#: builtin/notes.c:902
-#, c-format
-msgid "Object %s has no note\n"
-msgstr ""
-
-#: builtin/notes.c:914
-msgid "attempt to remove non-existent note is not an error"
-msgstr ""
-
-#: builtin/notes.c:917
-msgid "read object names from the standard input"
-msgstr ""
-
-#: builtin/notes.c:956 builtin/prune.c:144 builtin/worktree.c:148
-msgid "do not remove, show only"
-msgstr ""
-
-#: builtin/notes.c:957
-msgid "report pruned notes"
-msgstr ""
-
-#: builtin/notes.c:1000
-msgid "notes-ref"
-msgstr ""
-
-#: builtin/notes.c:1001
-msgid "use notes from <notes-ref>"
-msgstr ""
-
-#: builtin/notes.c:1036 builtin/stash.c:1802
-#, c-format
-msgid "unknown subcommand: %s"
-msgstr ""
-
-#: builtin/pack-objects.c:182
-msgid ""
-"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
-msgstr ""
-
-#: builtin/pack-objects.c:183
-msgid ""
-"git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
-msgstr ""
-
-#: builtin/pack-objects.c:570
-#, c-format
-msgid ""
-"write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in "
-"pack %s"
-msgstr ""
-
-#: builtin/pack-objects.c:578
-#, c-format
-msgid "bad packed object CRC for %s"
-msgstr ""
-
-#: builtin/pack-objects.c:589
-#, c-format
-msgid "corrupt packed object for %s"
-msgstr ""
-
-#: builtin/pack-objects.c:720
-#, c-format
-msgid "recursive delta detected for object %s"
-msgstr ""
-
-#: builtin/pack-objects.c:939
-#, c-format
-msgid "ordered %u objects, expected %<PRIu32>"
-msgstr ""
-
-#: builtin/pack-objects.c:1034
-#, c-format
-msgid "expected object at offset %<PRIuMAX> in pack %s"
-msgstr ""
-
-#: builtin/pack-objects.c:1158
-msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
-msgstr ""
-
-#: builtin/pack-objects.c:1171
-msgid "Writing objects"
-msgstr ""
-
-#: builtin/pack-objects.c:1243 builtin/update-index.c:90
-#, c-format
-msgid "failed to stat %s"
-msgstr ""
-
-#: builtin/pack-objects.c:1276
-msgid "failed to write bitmap index"
-msgstr ""
-
-#: builtin/pack-objects.c:1302
-#, c-format
-msgid "wrote %<PRIu32> objects while expecting %<PRIu32>"
-msgstr ""
-
-#: builtin/pack-objects.c:1544
-msgid "disabling bitmap writing, as some objects are not being packed"
-msgstr ""
-
-#: builtin/pack-objects.c:1992
-#, c-format
-msgid "delta base offset overflow in pack for %s"
-msgstr ""
-
-#: builtin/pack-objects.c:2001
-#, c-format
-msgid "delta base offset out of bound for %s"
-msgstr ""
-
-#: builtin/pack-objects.c:2282
-msgid "Counting objects"
-msgstr ""
-
-#: builtin/pack-objects.c:2447
-#, c-format
-msgid "unable to parse object header of %s"
-msgstr ""
-
-#: builtin/pack-objects.c:2517 builtin/pack-objects.c:2533
-#: builtin/pack-objects.c:2543
-#, c-format
-msgid "object %s cannot be read"
-msgstr ""
-
-#: builtin/pack-objects.c:2520 builtin/pack-objects.c:2547
-#, c-format
-msgid "object %s inconsistent object length (%<PRIuMAX> vs %<PRIuMAX>)"
-msgstr ""
-
-#: builtin/pack-objects.c:2557
-msgid "suboptimal pack - out of memory"
-msgstr ""
-
-#: builtin/pack-objects.c:2872
-#, c-format
-msgid "Delta compression using up to %d threads"
-msgstr ""
-
-#: builtin/pack-objects.c:3011
-#, c-format
-msgid "unable to pack objects reachable from tag %s"
-msgstr ""
-
-#: builtin/pack-objects.c:3097
-msgid "Compressing objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3103
-msgid "inconsistency with delta count"
-msgstr ""
-
-#: builtin/pack-objects.c:3182
-#, c-format
-msgid ""
-"value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
-"hash> <uri>' (got '%s')"
-msgstr ""
-
-#: builtin/pack-objects.c:3185
-#, c-format
-msgid ""
-"object already configured in another uploadpack.blobpackfileuri (got '%s')"
-msgstr ""
-
-#: builtin/pack-objects.c:3220
-#, c-format
-msgid "could not get type of object %s in pack %s"
-msgstr ""
-
-#: builtin/pack-objects.c:3348 builtin/pack-objects.c:3359
-#: builtin/pack-objects.c:3373
-#, c-format
-msgid "could not find pack '%s'"
-msgstr ""
-
-#: builtin/pack-objects.c:3416
-#, c-format
-msgid ""
-"expected edge object ID, got garbage:\n"
-" %s"
-msgstr ""
-
-#: builtin/pack-objects.c:3422
-#, c-format
-msgid ""
-"expected object ID, got garbage:\n"
-" %s"
-msgstr ""
-
-#: builtin/pack-objects.c:3540 builtin/pack-objects.c:3627
-msgid "cannot open pack index"
-msgstr ""
-
-#: builtin/pack-objects.c:3549
-#, c-format
-msgid "loose object at %s could not be examined"
-msgstr ""
-
-#: builtin/pack-objects.c:3635
-msgid "unable to force loose object"
-msgstr ""
-
-#: builtin/pack-objects.c:3763
-#, c-format
-msgid "not a rev '%s'"
-msgstr ""
-
-#: builtin/pack-objects.c:3766 builtin/rev-parse.c:1061
-#, c-format
-msgid "bad revision '%s'"
-msgstr ""
-
-#: builtin/pack-objects.c:3794
-msgid "unable to add recent objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3847
-#, c-format
-msgid "unsupported index version %s"
-msgstr ""
-
-#: builtin/pack-objects.c:3851
-#, c-format
-msgid "bad index version '%s'"
-msgstr ""
-
-#: builtin/pack-objects.c:3907
-msgid "<version>[,<offset>]"
-msgstr ""
-
-#: builtin/pack-objects.c:3908
-msgid "write the pack index file in the specified idx format version"
-msgstr ""
-
-#: builtin/pack-objects.c:3911
-msgid "maximum size of each output pack file"
-msgstr ""
-
-#: builtin/pack-objects.c:3913
-msgid "ignore borrowed objects from alternate object store"
-msgstr ""
-
-#: builtin/pack-objects.c:3915
-msgid "ignore packed objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3917
-msgid "limit pack window by objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3919
-msgid "limit pack window by memory in addition to object limit"
-msgstr ""
-
-#: builtin/pack-objects.c:3921
-msgid "maximum length of delta chain allowed in the resulting pack"
-msgstr ""
-
-#: builtin/pack-objects.c:3923
-msgid "reuse existing deltas"
-msgstr ""
-
-#: builtin/pack-objects.c:3925
-msgid "reuse existing objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3927
-msgid "use OFS_DELTA objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3929
-msgid "use threads when searching for best delta matches"
-msgstr ""
-
-#: builtin/pack-objects.c:3931
-msgid "do not create an empty pack output"
-msgstr ""
-
-#: builtin/pack-objects.c:3933
-msgid "read revision arguments from standard input"
-msgstr ""
-
-#: builtin/pack-objects.c:3935
-msgid "limit the objects to those that are not yet packed"
-msgstr ""
-
-#: builtin/pack-objects.c:3938
-msgid "include objects reachable from any reference"
-msgstr ""
-
-#: builtin/pack-objects.c:3941
-msgid "include objects referred by reflog entries"
-msgstr ""
-
-#: builtin/pack-objects.c:3944
-msgid "include objects referred to by the index"
-msgstr ""
-
-#: builtin/pack-objects.c:3947
-msgid "read packs from stdin"
-msgstr ""
-
-#: builtin/pack-objects.c:3949
-msgid "output pack to stdout"
-msgstr ""
-
-#: builtin/pack-objects.c:3951
-msgid "include tag objects that refer to objects to be packed"
-msgstr ""
-
-#: builtin/pack-objects.c:3953
-msgid "keep unreachable objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3955
-msgid "pack loose unreachable objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3957
-msgid "unpack unreachable objects newer than <time>"
-msgstr ""
-
-#: builtin/pack-objects.c:3960
-msgid "use the sparse reachability algorithm"
-msgstr ""
-
-#: builtin/pack-objects.c:3962
-msgid "create thin packs"
-msgstr ""
-
-#: builtin/pack-objects.c:3964
-msgid "create packs suitable for shallow fetches"
-msgstr ""
-
-#: builtin/pack-objects.c:3966
-msgid "ignore packs that have companion .keep file"
-msgstr ""
-
-#: builtin/pack-objects.c:3968
-msgid "ignore this pack"
-msgstr ""
-
-#: builtin/pack-objects.c:3970
-msgid "pack compression level"
-msgstr ""
-
-#: builtin/pack-objects.c:3972
-msgid "do not hide commits by grafts"
-msgstr ""
-
-#: builtin/pack-objects.c:3974
-msgid "use a bitmap index if available to speed up counting objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3976
-msgid "write a bitmap index together with the pack index"
-msgstr ""
-
-#: builtin/pack-objects.c:3980
-msgid "write a bitmap index if possible"
-msgstr ""
-
-#: builtin/pack-objects.c:3984
-msgid "handling for missing objects"
-msgstr ""
-
-#: builtin/pack-objects.c:3987
-msgid "do not pack objects in promisor packfiles"
-msgstr ""
-
-#: builtin/pack-objects.c:3989
-msgid "respect islands during delta compression"
-msgstr ""
-
-#: builtin/pack-objects.c:3991
-msgid "protocol"
-msgstr ""
-
-#: builtin/pack-objects.c:3992
-msgid "exclude any configured uploadpack.blobpackfileuri with this protocol"
-msgstr ""
-
-#: builtin/pack-objects.c:4027
-#, c-format
-msgid "delta chain depth %d is too deep, forcing %d"
-msgstr ""
-
-#: builtin/pack-objects.c:4032
-#, c-format
-msgid "pack.deltaCacheLimit is too high, forcing %d"
-msgstr ""
-
-#: builtin/pack-objects.c:4088
-msgid "--max-pack-size cannot be used to build a pack for transfer"
-msgstr ""
-
-#: builtin/pack-objects.c:4090
-msgid "minimum pack size limit is 1 MiB"
-msgstr ""
-
-#: builtin/pack-objects.c:4095
-msgid "--thin cannot be used to build an indexable pack"
-msgstr ""
-
-#: builtin/pack-objects.c:4104
-msgid "cannot use --filter without --stdout"
-msgstr ""
-
-#: builtin/pack-objects.c:4106
-msgid "cannot use --filter with --stdin-packs"
-msgstr ""
-
-#: builtin/pack-objects.c:4110
-msgid "cannot use internal rev list with --stdin-packs"
-msgstr ""
-
-#: builtin/pack-objects.c:4169
-msgid "Enumerating objects"
-msgstr ""
-
-#: builtin/pack-objects.c:4210
-#, c-format
-msgid ""
-"Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
-msgstr ""
-
-#: builtin/pack-redundant.c:601
-msgid ""
-"'git pack-redundant' is nominated for removal.\n"
-"If you still use this command, please add an extra\n"
-"option, '--i-still-use-this', on the command line\n"
-"and let us know you still use it by sending an e-mail\n"
-"to <git@vger.kernel.org>.  Thanks.\n"
-msgstr ""
-
-#: builtin/pack-refs.c:8
-msgid "git pack-refs [<options>]"
-msgstr ""
-
-#: builtin/pack-refs.c:16
-msgid "pack everything"
-msgstr ""
-
-#: builtin/pack-refs.c:17
-msgid "prune loose refs (default)"
-msgstr ""
-
-#: builtin/prune.c:14
-msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
-msgstr ""
-
-#: builtin/prune.c:145
-msgid "report pruned objects"
-msgstr ""
-
-#: builtin/prune.c:148
-msgid "expire objects older than <time>"
-msgstr ""
-
-#: builtin/prune.c:150
-msgid "limit traversal to objects outside promisor packfiles"
-msgstr ""
-
-#: builtin/prune.c:163
-msgid "cannot prune in a precious-objects repo"
-msgstr ""
-
-#: builtin/pull.c:67
-msgid "git pull [<options>] [<repository> [<refspec>...]]"
-msgstr ""
-
-#: builtin/pull.c:124
-msgid "control for recursive fetching of submodules"
-msgstr ""
-
-#: builtin/pull.c:128
-msgid "Options related to merging"
-msgstr ""
-
-#: builtin/pull.c:131
-msgid "incorporate changes by rebasing rather than merging"
-msgstr ""
-
-#: builtin/pull.c:159 builtin/revert.c:126
-msgid "allow fast-forward"
-msgstr ""
-
-#: builtin/pull.c:165
-msgid "control use of pre-merge-commit and commit-msg hooks"
-msgstr ""
-
-#: builtin/pull.c:171 parse-options.h:371
-msgid "automatically stash/stash pop before and after"
-msgstr ""
-
-#: builtin/pull.c:187
-msgid "Options related to fetching"
-msgstr ""
-
-#: builtin/pull.c:197
-msgid "force overwrite of local branch"
-msgstr ""
-
-#: builtin/pull.c:205
-msgid "number of submodules pulled in parallel"
-msgstr ""
-
-#: builtin/pull.c:449
-msgid ""
-"There is no candidate for rebasing against among the refs that you just "
-"fetched."
-msgstr ""
-
-#: builtin/pull.c:451
-msgid ""
-"There are no candidates for merging among the refs that you just fetched."
-msgstr ""
-
-#: builtin/pull.c:452
-msgid ""
-"Generally this means that you provided a wildcard refspec which had no\n"
-"matches on the remote end."
-msgstr ""
-
-#: builtin/pull.c:455
-#, c-format
-msgid ""
-"You asked to pull from the remote '%s', but did not specify\n"
-"a branch. Because this is not the default configured remote\n"
-"for your current branch, you must specify a branch on the command line."
-msgstr ""
-
-#: builtin/pull.c:460 builtin/rebase.c:978
-msgid "You are not currently on a branch."
-msgstr ""
-
-#: builtin/pull.c:462 builtin/pull.c:477
-msgid "Please specify which branch you want to rebase against."
-msgstr ""
-
-#: builtin/pull.c:464 builtin/pull.c:479
-msgid "Please specify which branch you want to merge with."
-msgstr ""
-
-#: builtin/pull.c:465 builtin/pull.c:480
-msgid "See git-pull(1) for details."
-msgstr ""
-
-#: builtin/pull.c:467 builtin/pull.c:473 builtin/pull.c:482
-#: builtin/rebase.c:984
-msgid "<remote>"
-msgstr ""
-
-#: builtin/pull.c:467 builtin/pull.c:482 builtin/pull.c:487
-#: contrib/scalar/scalar.c:374
-msgid "<branch>"
-msgstr ""
-
-#: builtin/pull.c:475 builtin/rebase.c:976
-msgid "There is no tracking information for the current branch."
-msgstr ""
-
-#: builtin/pull.c:484
-msgid ""
-"If you wish to set tracking information for this branch you can do so with:"
-msgstr ""
-
-#: builtin/pull.c:489
-#, c-format
-msgid ""
-"Your configuration specifies to merge with the ref '%s'\n"
-"from the remote, but no such ref was fetched."
-msgstr ""
-
-#: builtin/pull.c:600
-#, c-format
-msgid "unable to access commit %s"
-msgstr ""
-
-#: builtin/pull.c:908
-msgid "ignoring --verify-signatures for rebase"
-msgstr ""
-
-#: builtin/pull.c:969
-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"
-"your next pull:\n"
-"\n"
-"  git config pull.rebase false  # merge\n"
-"  git config pull.rebase true   # rebase\n"
-"  git config pull.ff only       # fast-forward only\n"
-"\n"
-"You can replace \"git config\" with \"git config --global\" to set a "
-"default\n"
-"preference for all repositories. You can also pass --rebase, --no-rebase,\n"
-"or --ff-only on the command line to override the configured default per\n"
-"invocation.\n"
-msgstr ""
-
-#: builtin/pull.c:1047
-msgid "Updating an unborn branch with changes added to the index."
-msgstr ""
-
-#: builtin/pull.c:1051
-msgid "pull with rebase"
-msgstr ""
-
-#: builtin/pull.c:1052
-msgid "please commit or stash them."
-msgstr ""
-
-#: builtin/pull.c:1077
-#, c-format
-msgid ""
-"fetch updated the current branch head.\n"
-"fast-forwarding your working tree from\n"
-"commit %s."
-msgstr ""
-
-#: builtin/pull.c:1083
-#, c-format
-msgid ""
-"Cannot fast-forward your working tree.\n"
-"After making sure that you saved anything precious from\n"
-"$ git diff %s\n"
-"output, run\n"
-"$ git reset --hard\n"
-"to recover."
-msgstr ""
-
-#: builtin/pull.c:1098
-msgid "Cannot merge multiple branches into empty head."
-msgstr ""
-
-#: builtin/pull.c:1103
-msgid "Cannot rebase onto multiple branches."
-msgstr ""
-
-#: builtin/pull.c:1105
-msgid "Cannot fast-forward to multiple branches."
-msgstr ""
-
-#: builtin/pull.c:1120
-msgid "Need to specify how to reconcile divergent branches."
-msgstr ""
-
-#: builtin/pull.c:1134
-msgid "cannot rebase with locally recorded submodule modifications"
-msgstr ""
-
-#: builtin/push.c:19
-msgid "git push [<options>] [<repository> [<refspec>...]]"
-msgstr ""
-
-#: builtin/push.c:111
-msgid "tag shorthand without <tag>"
-msgstr ""
-
-#: builtin/push.c:119
-msgid "--delete only accepts plain target ref names"
-msgstr ""
-
-#: builtin/push.c:164
-msgid ""
-"\n"
-"To choose either option permanently, see push.default in 'git help config'."
-msgstr ""
-
-#: builtin/push.c:167
-#, 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"
-"on the remote, use\n"
-"\n"
-"    git push %s HEAD:%s\n"
-"\n"
-"To push to the branch of the same name on the remote, use\n"
-"\n"
-"    git push %s HEAD\n"
-"%s"
-msgstr ""
-
-#: builtin/push.c:182
-#, c-format
-msgid ""
-"You are not currently on a branch.\n"
-"To push the history leading to the current (detached HEAD)\n"
-"state now, use\n"
-"\n"
-"    git push %s HEAD:<name-of-remote-branch>\n"
-msgstr ""
-
-#: builtin/push.c:191
-#, 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"
-"\n"
-"    git push --set-upstream %s %s\n"
-msgstr ""
-
-#: builtin/push.c:199
-#, c-format
-msgid "The current branch %s has multiple upstream branches, refusing to push."
-msgstr ""
-
-#: builtin/push.c:217
-msgid ""
-"You didn't specify any refspecs to push, and push.default is \"nothing\"."
-msgstr ""
-
-#: builtin/push.c:243
-#, c-format
-msgid ""
-"You are pushing to remote '%s', which is not the upstream of\n"
-"your current branch '%s', without telling me what to push\n"
-"to update which remote branch."
-msgstr ""
-
-#: builtin/push.c:258
-msgid ""
-"Updates were rejected because the tip of your current branch is behind\n"
-"its remote counterpart. Integrate the remote changes (e.g.\n"
-"'git pull ...') before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
-msgstr ""
-
-#: builtin/push.c:264
-msgid ""
-"Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. Check out this branch and integrate the remote changes\n"
-"(e.g. 'git pull ...') before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
-msgstr ""
-
-#: builtin/push.c:270
-msgid ""
-"Updates were rejected because the remote contains work that you do\n"
-"not have locally. This is usually caused by another repository pushing\n"
-"to the same ref. You may want to first integrate the remote changes\n"
-"(e.g., 'git pull ...') before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
-msgstr ""
-
-#: builtin/push.c:277
-msgid "Updates were rejected because the tag already exists in the remote."
-msgstr ""
-
-#: builtin/push.c:280
-msgid ""
-"You cannot update a remote ref that points at a non-commit object,\n"
-"or update a remote ref to make it point at a non-commit object,\n"
-"without using the '--force' option.\n"
-msgstr ""
-
-#: builtin/push.c:285
-msgid ""
-"Updates were rejected because the tip of the remote-tracking\n"
-"branch has been updated since the last checkout. You may want\n"
-"to integrate those changes locally (e.g., 'git pull ...')\n"
-"before forcing an update.\n"
-msgstr ""
-
-#: builtin/push.c:355
-#, c-format
-msgid "Pushing to %s\n"
-msgstr ""
-
-#: builtin/push.c:362
-#, c-format
-msgid "failed to push some refs to '%s'"
-msgstr ""
-
-#: builtin/push.c:544 builtin/submodule--helper.c:3377
-msgid "repository"
-msgstr ""
-
-#: builtin/push.c:545 builtin/send-pack.c:193
-msgid "push all refs"
-msgstr ""
-
-#: builtin/push.c:546 builtin/send-pack.c:195
-msgid "mirror all refs"
-msgstr ""
-
-#: builtin/push.c:548
-msgid "delete refs"
-msgstr ""
-
-#: builtin/push.c:549
-msgid "push tags (can't be used with --all or --mirror)"
-msgstr ""
-
-#: builtin/push.c:552 builtin/send-pack.c:196
-msgid "force updates"
-msgstr ""
-
-#: builtin/push.c:553 builtin/send-pack.c:208
-msgid "<refname>:<expect>"
-msgstr ""
-
-#: builtin/push.c:554 builtin/send-pack.c:209
-msgid "require old value of ref to be at this value"
-msgstr ""
-
-#: builtin/push.c:557 builtin/send-pack.c:212
-msgid "require remote updates to be integrated locally"
-msgstr ""
-
-#: builtin/push.c:560
-msgid "control recursive pushing of submodules"
-msgstr ""
-
-#: builtin/push.c:561 builtin/send-pack.c:203
-msgid "use thin pack"
-msgstr ""
-
-#: builtin/push.c:562 builtin/push.c:563 builtin/send-pack.c:190
-#: builtin/send-pack.c:191
-msgid "receive pack program"
-msgstr ""
-
-#: builtin/push.c:564
-msgid "set upstream for git pull/status"
-msgstr ""
-
-#: builtin/push.c:567
-msgid "prune locally removed refs"
-msgstr ""
-
-#: builtin/push.c:569
-msgid "bypass pre-push hook"
-msgstr ""
-
-#: builtin/push.c:570
-msgid "push missing but relevant tags"
-msgstr ""
-
-#: builtin/push.c:572 builtin/send-pack.c:197
-msgid "GPG sign the push"
-msgstr ""
-
-#: builtin/push.c:574 builtin/send-pack.c:204
-msgid "request atomic transaction on remote side"
-msgstr ""
-
-#: builtin/push.c:594
-msgid "--delete doesn't make sense without any refs"
-msgstr ""
-
-#: builtin/push.c:614
-#, c-format
-msgid "bad repository '%s'"
-msgstr ""
-
-#: builtin/push.c:615
-msgid ""
-"No configured push destination.\n"
-"Either specify the URL from the command-line or configure a remote "
-"repository using\n"
-"\n"
-"    git remote add <name> <url>\n"
-"\n"
-"and then push using the remote name\n"
-"\n"
-"    git push <name>\n"
-msgstr ""
-
-#: builtin/push.c:632
-msgid "--all can't be combined with refspecs"
-msgstr ""
-
-#: builtin/push.c:638
-msgid "--mirror can't be combined with refspecs"
-msgstr ""
-
-#: builtin/push.c:648
-msgid "push options must not have new line characters"
-msgstr ""
-
-#: builtin/range-diff.c:9
-msgid "git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"
-msgstr ""
-
-#: builtin/range-diff.c:10
-msgid "git range-diff [<options>] <old-tip>...<new-tip>"
-msgstr ""
-
-#: builtin/range-diff.c:11
-msgid "git range-diff [<options>] <base> <old-tip> <new-tip>"
-msgstr ""
-
-#: builtin/range-diff.c:30
-msgid "use simple diff colors"
-msgstr ""
-
-#: builtin/range-diff.c:32
-msgid "notes"
-msgstr ""
-
-#: builtin/range-diff.c:32
-msgid "passed to 'git log'"
-msgstr ""
-
-#: builtin/range-diff.c:35
-msgid "only emit output related to the first range"
-msgstr ""
-
-#: builtin/range-diff.c:37
-msgid "only emit output related to the second range"
-msgstr ""
-
-#: builtin/range-diff.c:60 builtin/range-diff.c:64
-#, c-format
-msgid "not a commit range: '%s'"
-msgstr ""
-
-#: builtin/range-diff.c:74
-msgid "single arg format must be symmetric range"
-msgstr ""
-
-#: builtin/range-diff.c:89
-msgid "need two commit ranges"
-msgstr ""
-
-#: builtin/read-tree.c:41
-msgid ""
-"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) "
-"[-u | -i]] [--no-sparse-checkout] [--index-output=<file>] (--empty | <tree-"
-"ish1> [<tree-ish2> [<tree-ish3>]])"
-msgstr ""
-
-#: builtin/read-tree.c:116
-msgid "write resulting index to <file>"
-msgstr ""
-
-#: builtin/read-tree.c:119
-msgid "only empty the index"
-msgstr ""
-
-#: builtin/read-tree.c:121
-msgid "Merging"
-msgstr ""
-
-#: builtin/read-tree.c:123
-msgid "perform a merge in addition to a read"
-msgstr ""
-
-#: builtin/read-tree.c:125
-msgid "3-way merge if no file level merging required"
-msgstr ""
-
-#: builtin/read-tree.c:127
-msgid "3-way merge in presence of adds and removes"
-msgstr ""
-
-#: builtin/read-tree.c:129
-msgid "same as -m, but discard unmerged entries"
-msgstr ""
-
-#: builtin/read-tree.c:130
-msgid "<subdirectory>/"
-msgstr ""
-
-#: builtin/read-tree.c:131
-msgid "read the tree into the index under <subdirectory>/"
-msgstr ""
-
-#: builtin/read-tree.c:134
-msgid "update working tree with merge result"
-msgstr ""
-
-#: builtin/read-tree.c:136
-msgid "gitignore"
-msgstr ""
-
-#: builtin/read-tree.c:137
-msgid "allow explicitly ignored files to be overwritten"
-msgstr ""
-
-#: builtin/read-tree.c:140
-msgid "don't check the working tree after merging"
-msgstr ""
-
-#: builtin/read-tree.c:141
-msgid "don't update the index or the work tree"
-msgstr ""
-
-#: builtin/read-tree.c:143
-msgid "skip applying sparse checkout filter"
-msgstr ""
-
-#: builtin/read-tree.c:145
-msgid "debug unpack-trees"
-msgstr ""
-
-#: builtin/read-tree.c:149
-msgid "suppress feedback messages"
-msgstr ""
-
-#: builtin/read-tree.c:190
-msgid "You need to resolve your current index first"
-msgstr ""
-
-#: builtin/rebase.c:36
-msgid ""
-"git rebase [-i] [options] [--exec <cmd>] [--onto <newbase> | --keep-base] "
-"[<upstream> [<branch>]]"
-msgstr ""
-
-#: builtin/rebase.c:38
-msgid ""
-"git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]"
-msgstr ""
-
-#: builtin/rebase.c:231
-#, c-format
-msgid "could not create temporary %s"
-msgstr ""
-
-#: builtin/rebase.c:237
-msgid "could not mark as interactive"
-msgstr ""
-
-#: builtin/rebase.c:290
-msgid "could not generate todo list"
-msgstr ""
-
-#: builtin/rebase.c:332
-msgid "a base commit must be provided with --upstream or --onto"
-msgstr ""
-
-#: builtin/rebase.c:391
-#, c-format
-msgid "%s requires the merge backend"
-msgstr ""
-
-#: builtin/rebase.c:433
-#, c-format
-msgid "could not get 'onto': '%s'"
-msgstr ""
-
-#: builtin/rebase.c:450
-#, c-format
-msgid "invalid orig-head: '%s'"
-msgstr ""
-
-#: builtin/rebase.c:475
-#, c-format
-msgid "ignoring invalid allow_rerere_autoupdate: '%s'"
-msgstr ""
-
-#: builtin/rebase.c:600
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-
-#: builtin/rebase.c:685
-#, c-format
-msgid ""
-"\n"
-"git encountered an error while preparing the patches to replay\n"
-"these revisions:\n"
-"\n"
-"    %s\n"
-"\n"
-"As a result, git cannot rebase them."
-msgstr ""
-
-#: builtin/rebase.c:836
-#, c-format
-msgid "could not switch to %s"
-msgstr ""
-
-#: builtin/rebase.c:952
-#, c-format
-msgid ""
-"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask"
-"\"."
-msgstr ""
-
-#: builtin/rebase.c:970
-#, c-format
-msgid ""
-"%s\n"
-"Please specify which branch you want to rebase against.\n"
-"See git-rebase(1) for details.\n"
-"\n"
-"    git rebase '<branch>'\n"
-"\n"
-msgstr ""
-
-#: builtin/rebase.c:986
-#, c-format
-msgid ""
-"If you wish to set tracking information for this branch you can do so with:\n"
-"\n"
-"    git branch --set-upstream-to=%s/<branch> %s\n"
-"\n"
-msgstr ""
-
-#: builtin/rebase.c:1016
-msgid "exec commands cannot contain newlines"
-msgstr ""
-
-#: builtin/rebase.c:1020
-msgid "empty exec command"
-msgstr ""
-
-#: builtin/rebase.c:1051
-msgid "rebase onto given branch instead of upstream"
-msgstr ""
-
-#: builtin/rebase.c:1053
-msgid "use the merge-base of upstream and branch as the current base"
-msgstr ""
-
-#: builtin/rebase.c:1055
-msgid "allow pre-rebase hook to run"
-msgstr ""
-
-#: builtin/rebase.c:1057
-msgid "be quiet. implies --no-stat"
-msgstr ""
-
-#: builtin/rebase.c:1060
-msgid "display a diffstat of what changed upstream"
-msgstr ""
-
-#: builtin/rebase.c:1063
-msgid "do not show diffstat of what changed upstream"
-msgstr ""
-
-#: builtin/rebase.c:1066
-msgid "add a Signed-off-by trailer to each commit"
-msgstr ""
-
-#: builtin/rebase.c:1069
-msgid "make committer date match author date"
-msgstr ""
-
-#: builtin/rebase.c:1071
-msgid "ignore author date and use current date"
-msgstr ""
-
-#: builtin/rebase.c:1073
-msgid "synonym of --reset-author-date"
-msgstr ""
-
-#: builtin/rebase.c:1075 builtin/rebase.c:1079
-msgid "passed to 'git apply'"
-msgstr ""
-
-#: builtin/rebase.c:1077
-msgid "ignore changes in whitespace"
-msgstr ""
-
-#: builtin/rebase.c:1081 builtin/rebase.c:1084
-msgid "cherry-pick all commits, even if unchanged"
-msgstr ""
-
-#: builtin/rebase.c:1086
-msgid "continue"
-msgstr ""
-
-#: builtin/rebase.c:1089
-msgid "skip current patch and continue"
-msgstr ""
-
-#: builtin/rebase.c:1091
-msgid "abort and check out the original branch"
-msgstr ""
-
-#: builtin/rebase.c:1094
-msgid "abort but keep HEAD where it is"
-msgstr ""
-
-#: builtin/rebase.c:1095
-msgid "edit the todo list during an interactive rebase"
-msgstr ""
-
-#: builtin/rebase.c:1098
-msgid "show the patch file being applied or merged"
-msgstr ""
-
-#: builtin/rebase.c:1101
-msgid "use apply strategies to rebase"
-msgstr ""
-
-#: builtin/rebase.c:1105
-msgid "use merging strategies to rebase"
-msgstr ""
-
-#: builtin/rebase.c:1109
-msgid "let the user edit the list of commits to rebase"
-msgstr ""
-
-#: builtin/rebase.c:1113
-msgid "(DEPRECATED) try to recreate merges instead of ignoring them"
-msgstr ""
-
-#: builtin/rebase.c:1118
-msgid "how to handle commits that become empty"
-msgstr ""
-
-#: builtin/rebase.c:1121
-msgid "keep commits which start empty"
-msgstr ""
-
-#: builtin/rebase.c:1125
-msgid "move commits that begin with squash!/fixup! under -i"
-msgstr ""
-
-#: builtin/rebase.c:1132
-msgid "add exec lines after each commit of the editable list"
-msgstr ""
-
-#: builtin/rebase.c:1136
-msgid "allow rebasing commits with empty messages"
-msgstr ""
-
-#: builtin/rebase.c:1140
-msgid "try to rebase merges instead of skipping them"
-msgstr ""
-
-#: builtin/rebase.c:1143
-msgid "use 'merge-base --fork-point' to refine upstream"
-msgstr ""
-
-#: builtin/rebase.c:1145
-msgid "use the given merge strategy"
-msgstr ""
-
-#: builtin/rebase.c:1147 builtin/revert.c:115
-msgid "option"
-msgstr ""
-
-#: builtin/rebase.c:1148
-msgid "pass the argument through to the merge strategy"
-msgstr ""
-
-#: builtin/rebase.c:1151
-msgid "rebase all reachable commits up to the root(s)"
-msgstr ""
-
-#: builtin/rebase.c:1154
-msgid "automatically re-schedule any `exec` that fails"
-msgstr ""
-
-#: builtin/rebase.c:1156
-msgid "apply all changes, even those already present upstream"
-msgstr ""
-
-#: builtin/rebase.c:1177
-msgid "It looks like 'git am' is in progress. Cannot rebase."
-msgstr ""
-
-#: builtin/rebase.c:1208
-msgid "--preserve-merges was replaced by --rebase-merges"
-msgstr ""
-
-#: builtin/rebase.c:1230
-msgid "No rebase in progress?"
-msgstr ""
-
-#: builtin/rebase.c:1234
-msgid "The --edit-todo action can only be used during interactive rebase."
-msgstr ""
-
-#: builtin/rebase.c:1257 t/helper/test-fast-rebase.c:122
-msgid "Cannot read HEAD"
-msgstr ""
-
-#: builtin/rebase.c:1269
-msgid ""
-"You must edit all merge conflicts and then\n"
-"mark them as resolved using git add"
-msgstr ""
-
-#: builtin/rebase.c:1287
-msgid "could not discard worktree changes"
-msgstr ""
-
-#: builtin/rebase.c:1308
-#, c-format
-msgid "could not move back to %s"
-msgstr ""
-
-#: builtin/rebase.c:1354
-#, c-format
-msgid ""
-"It seems that there is already a %s directory, and\n"
-"I wonder if you are in the middle of another rebase.  If that is the\n"
-"case, please try\n"
-"\t%s\n"
-"If that is not the case, please\n"
-"\t%s\n"
-"and run me again.  I am stopping in case you still have something\n"
-"valuable there.\n"
-msgstr ""
-
-#: builtin/rebase.c:1382
-msgid "switch `C' expects a numerical value"
-msgstr ""
-
-#: builtin/rebase.c:1424
-#, c-format
-msgid "Unknown mode: %s"
-msgstr ""
-
-#: builtin/rebase.c:1463
-msgid "--strategy requires --merge or --interactive"
-msgstr ""
-
-#: builtin/rebase.c:1492
-msgid "apply options and merge options cannot be used together"
-msgstr ""
-
-#: builtin/rebase.c:1505
-#, c-format
-msgid "Unknown rebase backend: %s"
-msgstr ""
-
-#: builtin/rebase.c:1534
-msgid "--reschedule-failed-exec requires --exec or --interactive"
-msgstr ""
-
-#: builtin/rebase.c:1565
-#, c-format
-msgid "invalid upstream '%s'"
-msgstr ""
-
-#: builtin/rebase.c:1571
-msgid "Could not create new root commit"
-msgstr ""
-
-#: builtin/rebase.c:1597
-#, c-format
-msgid "'%s': need exactly one merge base with branch"
-msgstr ""
-
-#: builtin/rebase.c:1600
-#, c-format
-msgid "'%s': need exactly one merge base"
-msgstr ""
-
-#: builtin/rebase.c:1609
-#, c-format
-msgid "Does not point to a valid commit '%s'"
-msgstr ""
-
-#: builtin/rebase.c:1636
-#, c-format
-msgid "no such branch/commit '%s'"
-msgstr ""
-
-#: builtin/rebase.c:1647 builtin/submodule--helper.c:43
-#: builtin/submodule--helper.c:2477
-#, c-format
-msgid "No such ref: %s"
-msgstr ""
-
-#: builtin/rebase.c:1658
-msgid "Could not resolve HEAD to a revision"
-msgstr ""
-
-#: builtin/rebase.c:1679
-msgid "Please commit or stash them."
-msgstr ""
-
-#: builtin/rebase.c:1714
-msgid "HEAD is up to date."
-msgstr ""
-
-#: builtin/rebase.c:1716
-#, c-format
-msgid "Current branch %s is up to date.\n"
-msgstr ""
-
-#: builtin/rebase.c:1724
-msgid "HEAD is up to date, rebase forced."
-msgstr ""
-
-#: builtin/rebase.c:1726
-#, c-format
-msgid "Current branch %s is up to date, rebase forced.\n"
-msgstr ""
-
-#: builtin/rebase.c:1734
-msgid "The pre-rebase hook refused to rebase."
-msgstr ""
-
-#: builtin/rebase.c:1741
-#, c-format
-msgid "Changes to %s:\n"
-msgstr ""
-
-#: builtin/rebase.c:1744
-#, c-format
-msgid "Changes from %s to %s:\n"
-msgstr ""
-
-#: builtin/rebase.c:1769
-#, c-format
-msgid "First, rewinding head to replay your work on top of it...\n"
-msgstr ""
-
-#: builtin/rebase.c:1781
-msgid "Could not detach HEAD"
-msgstr ""
-
-#: builtin/rebase.c:1790
-#, c-format
-msgid "Fast-forwarded %s to %s.\n"
-msgstr ""
-
-#: builtin/receive-pack.c:35
-msgid "git receive-pack <git-dir>"
-msgstr ""
-
-#: builtin/receive-pack.c:1263
-msgid ""
-"By default, updating the current branch in a non-bare repository\n"
-"is denied, because it will make the index and work tree inconsistent\n"
-"with what you pushed, and will require 'git reset --hard' to match\n"
-"the work tree to HEAD.\n"
-"\n"
-"You can set the 'receive.denyCurrentBranch' configuration variable\n"
-"to 'ignore' or 'warn' in the remote repository to allow pushing into\n"
-"its current branch; however, this is not recommended unless you\n"
-"arranged to update its work tree to match what you pushed in some\n"
-"other way.\n"
-"\n"
-"To squelch this message and still keep the default behaviour, set\n"
-"'receive.denyCurrentBranch' configuration variable to 'refuse'."
-msgstr ""
-
-#: builtin/receive-pack.c:1283
-msgid ""
-"By default, deleting the current branch is denied, because the next\n"
-"'git clone' won't result in any file checked out, causing confusion.\n"
-"\n"
-"You can set 'receive.denyDeleteCurrent' configuration variable to\n"
-"'warn' or 'ignore' in the remote repository to allow deleting the\n"
-"current branch, with or without a warning message.\n"
-"\n"
-"To squelch this message, you can set it to 'refuse'."
-msgstr ""
-
-#: builtin/receive-pack.c:2476
-msgid "quiet"
-msgstr ""
-
-#: builtin/receive-pack.c:2491
-msgid "you must specify a directory"
-msgstr ""
-
-#: builtin/reflog.c:9
-msgid "git reflog [show] [<log-options>] [<ref>]"
-msgstr ""
-
-#: builtin/reflog.c:12
-msgid ""
-"git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
-"                  [--rewrite] [--updateref] [--stale-fix]\n"
-"                  [--dry-run | -n] [--verbose] [--all [--single-worktree] | "
-"<refs>...]"
-msgstr ""
-
-#: builtin/reflog.c:17
-msgid ""
-"git reflog delete [--rewrite] [--updateref]\n"
-"                  [--dry-run | -n] [--verbose] <ref>@{<specifier>}..."
-msgstr ""
-
-#: builtin/reflog.c:21
-msgid "git reflog exists <ref>"
-msgstr ""
-
-#: builtin/reflog.c:197 builtin/reflog.c:211
-#, c-format
-msgid "invalid timestamp '%s' given to '--%s'"
-msgstr ""
-
-#: builtin/reflog.c:240 builtin/reflog.c:359
-msgid "do not actually prune any entries"
-msgstr ""
-
-#: builtin/reflog.c:243 builtin/reflog.c:362
-msgid ""
-"rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"
-msgstr ""
-
-#: builtin/reflog.c:246 builtin/reflog.c:365
-msgid "update the reference to the value of the top reflog entry"
-msgstr ""
-
-#: builtin/reflog.c:248 builtin/reflog.c:367
-msgid "print extra information on screen"
-msgstr ""
-
-#: builtin/reflog.c:249 builtin/reflog.c:253
-msgid "timestamp"
-msgstr ""
-
-#: builtin/reflog.c:250
-msgid "prune entries older than the specified time"
-msgstr ""
-
-#: builtin/reflog.c:254
-msgid ""
-"prune entries older than <time> that are not reachable from the current tip "
-"of the branch"
-msgstr ""
-
-#: builtin/reflog.c:258
-msgid "prune any reflog entries that point to broken commits"
-msgstr ""
-
-#: builtin/reflog.c:259
-msgid "process the reflogs of all references"
-msgstr ""
-
-#: builtin/reflog.c:261
-msgid "limits processing to reflogs from the current worktree only"
-msgstr ""
-
-#: builtin/reflog.c:294
-#, c-format
-msgid "Marking reachable objects..."
-msgstr ""
-
-#: builtin/reflog.c:338
-#, c-format
-msgid "%s points nowhere!"
-msgstr ""
-
-#: builtin/reflog.c:374
-msgid "no reflog specified to delete"
-msgstr ""
-
-#: builtin/reflog.c:396
-#, c-format
-msgid "invalid ref format: %s"
-msgstr ""
-
-#: builtin/remote.c:19
-msgid ""
-"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
-"mirror=<fetch|push>] <name> <url>"
-msgstr ""
-
-#: builtin/remote.c:20 builtin/remote.c:40
-msgid "git remote rename [--[no-]progress] <old> <new>"
-msgstr ""
-
-#: builtin/remote.c:21 builtin/remote.c:45
-msgid "git remote remove <name>"
-msgstr ""
-
-#: builtin/remote.c:22 builtin/remote.c:50
-msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
-msgstr ""
-
-#: builtin/remote.c:23
-msgid "git remote [-v | --verbose] show [-n] <name>"
-msgstr ""
-
-#: builtin/remote.c:24
-msgid "git remote prune [-n | --dry-run] <name>"
-msgstr ""
-
-#: builtin/remote.c:25
-msgid ""
-"git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
-msgstr ""
-
-#: builtin/remote.c:26
-msgid "git remote set-branches [--add] <name> <branch>..."
-msgstr ""
-
-#: builtin/remote.c:27 builtin/remote.c:76
-msgid "git remote get-url [--push] [--all] <name>"
-msgstr ""
-
-#: builtin/remote.c:28 builtin/remote.c:81
-msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
-msgstr ""
-
-#: builtin/remote.c:29 builtin/remote.c:82
-msgid "git remote set-url --add <name> <newurl>"
-msgstr ""
-
-#: builtin/remote.c:30 builtin/remote.c:83
-msgid "git remote set-url --delete <name> <url>"
-msgstr ""
-
-#: builtin/remote.c:35
-msgid "git remote add [<options>] <name> <url>"
-msgstr ""
-
-#: builtin/remote.c:55
-msgid "git remote set-branches <name> <branch>..."
-msgstr ""
-
-#: builtin/remote.c:56
-msgid "git remote set-branches --add <name> <branch>..."
-msgstr ""
-
-#: builtin/remote.c:61
-msgid "git remote show [<options>] <name>"
-msgstr ""
-
-#: builtin/remote.c:66
-msgid "git remote prune [<options>] <name>"
-msgstr ""
-
-#: builtin/remote.c:71
-msgid "git remote update [<options>] [<group> | <remote>]..."
-msgstr ""
-
-#: builtin/remote.c:100
-#, c-format
-msgid "Updating %s"
-msgstr ""
-
-#: builtin/remote.c:102
-#, c-format
-msgid "Could not fetch %s"
-msgstr ""
-
-#: builtin/remote.c:132
-msgid ""
-"--mirror is dangerous and deprecated; please\n"
-"\t use --mirror=fetch or --mirror=push instead"
-msgstr ""
-
-#: builtin/remote.c:149
-#, c-format
-msgid "unknown mirror argument: %s"
-msgstr ""
-
-#: builtin/remote.c:165
-msgid "fetch the remote branches"
-msgstr ""
-
-#: builtin/remote.c:167
-msgid "import all tags and associated objects when fetching"
-msgstr ""
-
-#: builtin/remote.c:170
-msgid "or do not fetch any tag at all (--no-tags)"
-msgstr ""
-
-#: builtin/remote.c:172
-msgid "branch(es) to track"
-msgstr ""
-
-#: builtin/remote.c:173
-msgid "master branch"
-msgstr ""
-
-#: builtin/remote.c:175
-msgid "set up remote as a mirror to push to or fetch from"
-msgstr ""
-
-#: builtin/remote.c:187
-msgid "specifying a master branch makes no sense with --mirror"
-msgstr ""
-
-#: builtin/remote.c:189
-msgid "specifying branches to track makes sense only with fetch mirrors"
-msgstr ""
-
-#: builtin/remote.c:196 builtin/remote.c:716
-#, c-format
-msgid "remote %s already exists."
-msgstr ""
-
-#: builtin/remote.c:241
-#, c-format
-msgid "Could not setup master '%s'"
-msgstr ""
-
-#: builtin/remote.c:323
-#, c-format
-msgid "unhandled branch.%s.rebase=%s; assuming 'true'"
-msgstr ""
-
-#: builtin/remote.c:367
-#, c-format
-msgid "Could not get fetch map for refspec %s"
-msgstr ""
-
-#: builtin/remote.c:461 builtin/remote.c:469
-msgid "(matching)"
-msgstr ""
-
-#: builtin/remote.c:473
-msgid "(delete)"
-msgstr ""
-
-#: builtin/remote.c:664
-#, c-format
-msgid "could not set '%s'"
-msgstr ""
-
-#: builtin/remote.c:669
-#, c-format
-msgid ""
-"The %s configuration remote.pushDefault in:\n"
-"\t%s:%d\n"
-"now names the non-existent remote '%s'"
-msgstr ""
-
-#: builtin/remote.c:707 builtin/remote.c:866 builtin/remote.c:973
-#, c-format
-msgid "No such remote: '%s'"
-msgstr ""
-
-#: builtin/remote.c:726
-#, c-format
-msgid "Could not rename config section '%s' to '%s'"
-msgstr ""
-
-#: builtin/remote.c:746
-#, c-format
-msgid ""
-"Not updating non-default fetch refspec\n"
-"\t%s\n"
-"\tPlease update the configuration manually if necessary."
-msgstr ""
-
-#: builtin/remote.c:783
-msgid "Renaming remote references"
-msgstr ""
-
-#: builtin/remote.c:794
-#, c-format
-msgid "deleting '%s' failed"
-msgstr ""
-
-#: builtin/remote.c:832
-#, c-format
-msgid "creating '%s' failed"
-msgstr ""
-
-#: builtin/remote.c:912
-msgid ""
-"Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
-"to delete it, use:"
-msgid_plural ""
-"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
-"to delete them, use:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/remote.c:926
-#, c-format
-msgid "Could not remove config section '%s'"
-msgstr ""
-
-#: builtin/remote.c:1034
-#, c-format
-msgid " new (next fetch will store in remotes/%s)"
-msgstr ""
-
-#: builtin/remote.c:1037
-msgid " tracked"
-msgstr ""
-
-#: builtin/remote.c:1039
-msgid " stale (use 'git remote prune' to remove)"
-msgstr ""
-
-#: builtin/remote.c:1041
-msgid " ???"
-msgstr ""
-
-#: builtin/remote.c:1082
-#, c-format
-msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
-msgstr ""
-
-#: builtin/remote.c:1091
-#, c-format
-msgid "rebases interactively onto remote %s"
-msgstr ""
-
-#: builtin/remote.c:1093
-#, c-format
-msgid "rebases interactively (with merges) onto remote %s"
-msgstr ""
-
-#: builtin/remote.c:1096
-#, c-format
-msgid "rebases onto remote %s"
-msgstr ""
-
-#: builtin/remote.c:1100
-#, c-format
-msgid " merges with remote %s"
-msgstr ""
-
-#: builtin/remote.c:1103
-#, c-format
-msgid "merges with remote %s"
-msgstr ""
-
-#: builtin/remote.c:1106
-#, c-format
-msgid "%-*s    and with remote %s\n"
-msgstr ""
-
-#: builtin/remote.c:1149
-msgid "create"
-msgstr ""
-
-#: builtin/remote.c:1152
-msgid "delete"
-msgstr ""
-
-#: builtin/remote.c:1156
-msgid "up to date"
-msgstr ""
-
-#: builtin/remote.c:1159
-msgid "fast-forwardable"
-msgstr ""
-
-#: builtin/remote.c:1162
-msgid "local out of date"
-msgstr ""
-
-#: builtin/remote.c:1169
-#, c-format
-msgid "    %-*s forces to %-*s (%s)"
-msgstr ""
-
-#: builtin/remote.c:1172
-#, c-format
-msgid "    %-*s pushes to %-*s (%s)"
-msgstr ""
-
-#: builtin/remote.c:1176
-#, c-format
-msgid "    %-*s forces to %s"
-msgstr ""
-
-#: builtin/remote.c:1179
-#, c-format
-msgid "    %-*s pushes to %s"
-msgstr ""
-
-#: builtin/remote.c:1247
-msgid "do not query remotes"
-msgstr ""
-
-#: builtin/remote.c:1268
-#, c-format
-msgid "* remote %s"
-msgstr ""
-
-#: builtin/remote.c:1269
-#, c-format
-msgid "  Fetch URL: %s"
-msgstr ""
-
-#: builtin/remote.c:1270 builtin/remote.c:1286 builtin/remote.c:1423
-msgid "(no URL)"
-msgstr ""
-
-#. TRANSLATORS: the colon ':' should align
-#. with the one in " Fetch URL: %s"
-#. translation.
-#.
-#: builtin/remote.c:1284 builtin/remote.c:1286
-#, c-format
-msgid "  Push  URL: %s"
-msgstr ""
-
-#: builtin/remote.c:1288 builtin/remote.c:1290 builtin/remote.c:1292
-#, c-format
-msgid "  HEAD branch: %s"
-msgstr ""
-
-#: builtin/remote.c:1288
-msgid "(not queried)"
-msgstr ""
-
-#: builtin/remote.c:1290
-msgid "(unknown)"
-msgstr ""
-
-#: builtin/remote.c:1294
-#, c-format
-msgid ""
-"  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
-msgstr ""
-
-#: builtin/remote.c:1306
-#, c-format
-msgid "  Remote branch:%s"
-msgid_plural "  Remote branches:%s"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/remote.c:1309 builtin/remote.c:1335
-msgid " (status not queried)"
-msgstr ""
-
-#: builtin/remote.c:1318
-msgid "  Local branch configured for 'git pull':"
-msgid_plural "  Local branches configured for 'git pull':"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/remote.c:1326
-msgid "  Local refs will be mirrored by 'git push'"
-msgstr ""
-
-#: builtin/remote.c:1332
-#, c-format
-msgid "  Local ref configured for 'git push'%s:"
-msgid_plural "  Local refs configured for 'git push'%s:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/remote.c:1353
-msgid "set refs/remotes/<name>/HEAD according to remote"
-msgstr ""
-
-#: builtin/remote.c:1355
-msgid "delete refs/remotes/<name>/HEAD"
-msgstr ""
-
-#: builtin/remote.c:1369
-msgid "Cannot determine remote HEAD"
-msgstr ""
-
-#: builtin/remote.c:1371
-msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
-msgstr ""
-
-#: builtin/remote.c:1381
-#, c-format
-msgid "Could not delete %s"
-msgstr ""
-
-#: builtin/remote.c:1389
-#, c-format
-msgid "Not a valid ref: %s"
-msgstr ""
-
-#: builtin/remote.c:1391
-#, c-format
-msgid "Could not setup %s"
-msgstr ""
-
-#: builtin/remote.c:1409
-#, c-format
-msgid " %s will become dangling!"
-msgstr ""
-
-#: builtin/remote.c:1410
-#, c-format
-msgid " %s has become dangling!"
-msgstr ""
-
-#: builtin/remote.c:1419
-#, c-format
-msgid "Pruning %s"
-msgstr ""
-
-#: builtin/remote.c:1420
-#, c-format
-msgid "URL: %s"
-msgstr ""
-
-#: builtin/remote.c:1436
-#, c-format
-msgid " * [would prune] %s"
-msgstr ""
-
-#: builtin/remote.c:1439
-#, c-format
-msgid " * [pruned] %s"
-msgstr ""
-
-#: builtin/remote.c:1484
-msgid "prune remotes after fetching"
-msgstr ""
-
-#: builtin/remote.c:1548 builtin/remote.c:1604 builtin/remote.c:1674
-#, c-format
-msgid "No such remote '%s'"
-msgstr ""
-
-#: builtin/remote.c:1566
-msgid "add branch"
-msgstr ""
-
-#: builtin/remote.c:1573
-msgid "no remote specified"
-msgstr ""
-
-#: builtin/remote.c:1590
-msgid "query push URLs rather than fetch URLs"
-msgstr ""
-
-#: builtin/remote.c:1592
-msgid "return all URLs"
-msgstr ""
-
-#: builtin/remote.c:1622
-#, c-format
-msgid "no URLs configured for remote '%s'"
-msgstr ""
-
-#: builtin/remote.c:1648
-msgid "manipulate push URLs"
-msgstr ""
-
-#: builtin/remote.c:1650
-msgid "add URL"
-msgstr ""
-
-#: builtin/remote.c:1652
-msgid "delete URLs"
-msgstr ""
-
-#: builtin/remote.c:1659
-msgid "--add --delete doesn't make sense"
-msgstr ""
-
-#: builtin/remote.c:1700
-#, c-format
-msgid "Invalid old URL pattern: %s"
-msgstr ""
-
-#: builtin/remote.c:1708
-#, c-format
-msgid "No such URL found: %s"
-msgstr ""
-
-#: builtin/remote.c:1710
-msgid "Will not delete all non-push URLs"
-msgstr ""
-
-#: builtin/remote.c:1727
-msgid "be verbose; must be placed before a subcommand"
-msgstr ""
-
-#: builtin/repack.c:29
-msgid "git repack [<options>]"
-msgstr ""
-
-#: builtin/repack.c:34
-msgid ""
-"Incremental repacks are incompatible with bitmap indexes.  Use\n"
-"--no-write-bitmap-index or disable the pack.writebitmaps configuration."
-msgstr ""
-
-#: builtin/repack.c:206
-msgid "could not start pack-objects to repack promisor objects"
-msgstr ""
-
-#: builtin/repack.c:280 builtin/repack.c:824
-msgid "repack: Expecting full hex object ID lines only from pack-objects."
-msgstr ""
-
-#: builtin/repack.c:304
-msgid "could not finish pack-objects to repack promisor objects"
-msgstr ""
-
-#: builtin/repack.c:319
-#, c-format
-msgid "cannot open index for %s"
-msgstr ""
-
-#: builtin/repack.c:378
-#, c-format
-msgid "pack %s too large to consider in geometric progression"
-msgstr ""
-
-#: builtin/repack.c:411 builtin/repack.c:418 builtin/repack.c:423
-#, c-format
-msgid "pack %s too large to roll up"
-msgstr ""
-
-#: builtin/repack.c:503
-#, c-format
-msgid "could not open tempfile %s for writing"
-msgstr ""
-
-#: builtin/repack.c:521
-msgid "could not close refs snapshot tempfile"
-msgstr ""
-
-#: builtin/repack.c:634
-msgid "pack everything in a single pack"
-msgstr ""
-
-#: builtin/repack.c:636
-msgid "same as -a, and turn unreachable objects loose"
-msgstr ""
-
-#: builtin/repack.c:639
-msgid "remove redundant packs, and run git-prune-packed"
-msgstr ""
-
-#: builtin/repack.c:641
-msgid "pass --no-reuse-delta to git-pack-objects"
-msgstr ""
-
-#: builtin/repack.c:643
-msgid "pass --no-reuse-object to git-pack-objects"
-msgstr ""
-
-#: builtin/repack.c:645
-msgid "do not run git-update-server-info"
-msgstr ""
-
-#: builtin/repack.c:648
-msgid "pass --local to git-pack-objects"
-msgstr ""
-
-#: builtin/repack.c:650
-msgid "write bitmap index"
-msgstr ""
-
-#: builtin/repack.c:652
-msgid "pass --delta-islands to git-pack-objects"
-msgstr ""
-
-#: builtin/repack.c:653
-msgid "approxidate"
-msgstr ""
-
-#: builtin/repack.c:654
-msgid "with -A, do not loosen objects older than this"
-msgstr ""
-
-#: builtin/repack.c:656
-msgid "with -a, repack unreachable objects"
-msgstr ""
-
-#: builtin/repack.c:658
-msgid "size of the window used for delta compression"
-msgstr ""
-
-#: builtin/repack.c:659 builtin/repack.c:665
-msgid "bytes"
-msgstr ""
-
-#: builtin/repack.c:660
-msgid "same as the above, but limit memory size instead of entries count"
-msgstr ""
-
-#: builtin/repack.c:662
-msgid "limits the maximum delta depth"
-msgstr ""
-
-#: builtin/repack.c:664
-msgid "limits the maximum number of threads"
-msgstr ""
-
-#: builtin/repack.c:666
-msgid "maximum size of each packfile"
-msgstr ""
-
-#: builtin/repack.c:668
-msgid "repack objects in packs marked with .keep"
-msgstr ""
-
-#: builtin/repack.c:670
-msgid "do not repack this pack"
-msgstr ""
-
-#: builtin/repack.c:672
-msgid "find a geometric progression with factor <N>"
-msgstr ""
-
-#: builtin/repack.c:674
-msgid "write a multi-pack index of the resulting packs"
-msgstr ""
-
-#: builtin/repack.c:684
-msgid "cannot delete packs in a precious-objects repo"
-msgstr ""
-
-#: builtin/repack.c:833
-msgid "Nothing new to pack."
-msgstr ""
-
-#: builtin/repack.c:863
-#, c-format
-msgid "missing required file: %s"
-msgstr ""
-
-#: builtin/repack.c:865
-#, c-format
-msgid "could not unlink: %s"
-msgstr ""
-
-#: builtin/replace.c:22
-msgid "git replace [-f] <object> <replacement>"
-msgstr ""
-
-#: builtin/replace.c:23
-msgid "git replace [-f] --edit <object>"
-msgstr ""
-
-#: builtin/replace.c:24
-msgid "git replace [-f] --graft <commit> [<parent>...]"
-msgstr ""
-
-#: builtin/replace.c:26
-msgid "git replace -d <object>..."
-msgstr ""
-
-#: builtin/replace.c:27
-msgid "git replace [--format=<format>] [-l [<pattern>]]"
-msgstr ""
-
-#: builtin/replace.c:90
-#, c-format
-msgid ""
-"invalid replace format '%s'\n"
-"valid formats are 'short', 'medium' and 'long'"
-msgstr ""
-
-#: builtin/replace.c:125
-#, c-format
-msgid "replace ref '%s' not found"
-msgstr ""
-
-#: builtin/replace.c:141
-#, c-format
-msgid "Deleted replace ref '%s'"
-msgstr ""
-
-#: builtin/replace.c:153
-#, c-format
-msgid "'%s' is not a valid ref name"
-msgstr ""
-
-#: builtin/replace.c:158
-#, c-format
-msgid "replace ref '%s' already exists"
-msgstr ""
-
-#: builtin/replace.c:178
-#, c-format
-msgid ""
-"Objects must be of the same type.\n"
-"'%s' points to a replaced object of type '%s'\n"
-"while '%s' points to a replacement object of type '%s'."
-msgstr ""
-
-#: builtin/replace.c:229
-#, c-format
-msgid "unable to open %s for writing"
-msgstr ""
-
-#: builtin/replace.c:242
-msgid "cat-file reported failure"
-msgstr ""
-
-#: builtin/replace.c:258
-#, c-format
-msgid "unable to open %s for reading"
-msgstr ""
-
-#: builtin/replace.c:271
-msgid "unable to spawn mktree"
-msgstr ""
-
-#: builtin/replace.c:275
-msgid "unable to read from mktree"
-msgstr ""
-
-#: builtin/replace.c:284
-msgid "mktree reported failure"
-msgstr ""
-
-#: builtin/replace.c:288
-msgid "mktree did not return an object name"
-msgstr ""
-
-#: builtin/replace.c:297
-#, c-format
-msgid "unable to fstat %s"
-msgstr ""
-
-#: builtin/replace.c:302
-msgid "unable to write object to database"
-msgstr ""
-
-#: builtin/replace.c:325
-#, c-format
-msgid "unable to get object type for %s"
-msgstr ""
-
-#: builtin/replace.c:341
-msgid "editing object file failed"
-msgstr ""
-
-#: builtin/replace.c:350
-#, c-format
-msgid "new object is the same as the old one: '%s'"
-msgstr ""
-
-#: builtin/replace.c:383
-#, c-format
-msgid "could not parse %s as a commit"
-msgstr ""
-
-#: builtin/replace.c:415
-#, c-format
-msgid "bad mergetag in commit '%s'"
-msgstr ""
-
-#: builtin/replace.c:417
-#, c-format
-msgid "malformed mergetag in commit '%s'"
-msgstr ""
-
-#: builtin/replace.c:429
-#, c-format
-msgid ""
-"original commit '%s' contains mergetag '%s' that is discarded; use --edit "
-"instead of --graft"
-msgstr ""
-
-#: builtin/replace.c:468
-#, c-format
-msgid "the original commit '%s' has a gpg signature"
-msgstr ""
-
-#: builtin/replace.c:469
-msgid "the signature will be removed in the replacement commit!"
-msgstr ""
-
-#: builtin/replace.c:479
-#, c-format
-msgid "could not write replacement commit for: '%s'"
-msgstr ""
-
-#: builtin/replace.c:487
-#, c-format
-msgid "graft for '%s' unnecessary"
-msgstr ""
-
-#: builtin/replace.c:491
-#, c-format
-msgid "new commit is the same as the old one: '%s'"
-msgstr ""
-
-#: builtin/replace.c:526
-#, c-format
-msgid ""
-"could not convert the following graft(s):\n"
-"%s"
-msgstr ""
-
-#: builtin/replace.c:547
-msgid "list replace refs"
-msgstr ""
-
-#: builtin/replace.c:548
-msgid "delete replace refs"
-msgstr ""
-
-#: builtin/replace.c:549
-msgid "edit existing object"
-msgstr ""
-
-#: builtin/replace.c:550
-msgid "change a commit's parents"
-msgstr ""
-
-#: builtin/replace.c:551
-msgid "convert existing graft file"
-msgstr ""
-
-#: builtin/replace.c:552
-msgid "replace the ref if it exists"
-msgstr ""
-
-#: builtin/replace.c:554
-msgid "do not pretty-print contents for --edit"
-msgstr ""
-
-#: builtin/replace.c:555
-msgid "use this format"
-msgstr ""
-
-#: builtin/replace.c:568
-msgid "--format cannot be used when not listing"
-msgstr ""
-
-#: builtin/replace.c:576
-msgid "-f only makes sense when writing a replacement"
-msgstr ""
-
-#: builtin/replace.c:580
-msgid "--raw only makes sense with --edit"
-msgstr ""
-
-#: builtin/replace.c:586
-msgid "-d needs at least one argument"
-msgstr ""
-
-#: builtin/replace.c:592
-msgid "bad number of arguments"
-msgstr ""
-
-#: builtin/replace.c:598
-msgid "-e needs exactly one argument"
-msgstr ""
-
-#: builtin/replace.c:604
-msgid "-g needs at least one argument"
-msgstr ""
-
-#: builtin/replace.c:610
-msgid "--convert-graft-file takes no argument"
-msgstr ""
-
-#: builtin/replace.c:616
-msgid "only one pattern can be given with -l"
-msgstr ""
-
-#: builtin/rerere.c:13
-msgid "git rerere [clear | forget <path>... | status | remaining | diff | gc]"
-msgstr ""
-
-#: builtin/rerere.c:58
-msgid "register clean resolutions in index"
-msgstr ""
-
-#: builtin/rerere.c:77
-msgid "'git rerere forget' without paths is deprecated"
-msgstr ""
-
-#: builtin/rerere.c:111
-#, c-format
-msgid "unable to generate diff for '%s'"
-msgstr ""
-
-#: builtin/reset.c:33
-msgid ""
-"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
-msgstr ""
-
-#: builtin/reset.c:34
-msgid "git reset [-q] [<tree-ish>] [--] <pathspec>..."
-msgstr ""
-
-#: builtin/reset.c:35
-msgid ""
-"git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]"
-msgstr ""
-
-#: builtin/reset.c:36
-msgid "git reset --patch [<tree-ish>] [--] [<pathspec>...]"
-msgstr ""
-
-#: builtin/reset.c:42
-msgid "mixed"
-msgstr ""
-
-#: builtin/reset.c:42
-msgid "soft"
-msgstr ""
-
-#: builtin/reset.c:42
-msgid "hard"
-msgstr ""
-
-#: builtin/reset.c:42
-msgid "merge"
-msgstr ""
-
-#: builtin/reset.c:42
-msgid "keep"
-msgstr ""
-
-#: builtin/reset.c:90
-msgid "You do not have a valid HEAD."
-msgstr ""
-
-#: builtin/reset.c:92
-msgid "Failed to find tree of HEAD."
-msgstr ""
-
-#: builtin/reset.c:98
-#, c-format
-msgid "Failed to find tree of %s."
-msgstr ""
-
-#: builtin/reset.c:123
-#, c-format
-msgid "HEAD is now at %s"
-msgstr ""
-
-#: builtin/reset.c:304
-#, c-format
-msgid "Cannot do a %s reset in the middle of a merge."
-msgstr ""
-
-#: builtin/reset.c:402 builtin/stash.c:606 builtin/stash.c:669
-#: builtin/stash.c:693
-msgid "be quiet, only report errors"
-msgstr ""
-
-#: builtin/reset.c:404
-msgid "skip refreshing the index after reset"
-msgstr ""
-
-#: builtin/reset.c:406
-msgid "reset HEAD and index"
-msgstr ""
-
-#: builtin/reset.c:407
-msgid "reset only HEAD"
-msgstr ""
-
-#: builtin/reset.c:409 builtin/reset.c:411
-msgid "reset HEAD, index and working tree"
-msgstr ""
-
-#: builtin/reset.c:413
-msgid "reset HEAD but keep local changes"
-msgstr ""
-
-#: builtin/reset.c:419
-msgid "record only the fact that removed paths will be added later"
-msgstr ""
-
-#: builtin/reset.c:452
-#, c-format
-msgid "Failed to resolve '%s' as a valid revision."
-msgstr ""
-
-#: builtin/reset.c:460
-#, c-format
-msgid "Failed to resolve '%s' as a valid tree."
-msgstr ""
-
-#: builtin/reset.c:479
-msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
-msgstr ""
-
-#: builtin/reset.c:481
-#, c-format
-msgid "Cannot do %s reset with paths."
-msgstr ""
-
-#: builtin/reset.c:496
-#, c-format
-msgid "%s reset is not allowed in a bare repository"
-msgstr ""
-
-#: builtin/reset.c:527
-msgid "Unstaged changes after reset:"
-msgstr ""
-
-#: builtin/reset.c:530
-#, c-format
-msgid ""
-"It took %.2f seconds to refresh the index after reset.  You can use\n"
-"'--no-refresh' to avoid this."
-msgstr ""
-
-#: builtin/reset.c:547
-#, c-format
-msgid "Could not reset index file to revision '%s'."
-msgstr ""
-
-#: builtin/reset.c:552
-msgid "Could not write new index file."
-msgstr ""
-
-#: builtin/rev-list.c:659
-msgid "rev-list does not support display of notes"
-msgstr ""
-
-#: builtin/rev-list.c:664
-#, c-format
-msgid "marked counting and '%s' cannot be used together"
-msgstr ""
-
-#: builtin/rev-parse.c:409
-msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
-msgstr ""
-
-#: builtin/rev-parse.c:414
-msgid "keep the `--` passed as an arg"
-msgstr ""
-
-#: builtin/rev-parse.c:416
-msgid "stop parsing after the first non-option argument"
-msgstr ""
-
-#: builtin/rev-parse.c:419
-msgid "output in stuck long form"
-msgstr ""
-
-#: builtin/rev-parse.c:438
-msgid "premature end of input"
-msgstr ""
-
-#: builtin/rev-parse.c:442
-msgid "no usage string given before the `--' separator"
-msgstr ""
-
-#: builtin/rev-parse.c:548
-msgid "Needed a single revision"
-msgstr ""
-
-#: builtin/rev-parse.c:552
-msgid ""
-"git rev-parse --parseopt [<options>] -- [<args>...]\n"
-"   or: git rev-parse --sq-quote [<arg>...]\n"
-"   or: git rev-parse [<options>] [<arg>...]\n"
-"\n"
-"Run \"git rev-parse --parseopt -h\" for more information on the first usage."
-msgstr ""
-
-#: builtin/rev-parse.c:712
-msgid "--resolve-git-dir requires an argument"
-msgstr ""
-
-#: builtin/rev-parse.c:715
-#, c-format
-msgid "not a gitdir '%s'"
-msgstr ""
-
-#: builtin/rev-parse.c:739
-msgid "--git-path requires an argument"
-msgstr ""
-
-#: builtin/rev-parse.c:749
-msgid "-n requires an argument"
-msgstr ""
-
-#: builtin/rev-parse.c:763
-msgid "--path-format requires an argument"
-msgstr ""
-
-#: builtin/rev-parse.c:769
-#, c-format
-msgid "unknown argument to --path-format: %s"
-msgstr ""
-
-#: builtin/rev-parse.c:776
-msgid "--default requires an argument"
-msgstr ""
-
-#: builtin/rev-parse.c:782
-msgid "--prefix requires an argument"
-msgstr ""
-
-#: builtin/rev-parse.c:851
-#, c-format
-msgid "unknown mode for --abbrev-ref: %s"
-msgstr ""
-
-#: builtin/rev-parse.c:1023
-#, c-format
-msgid "unknown mode for --show-object-format: %s"
-msgstr ""
-
-#: builtin/revert.c:24
-msgid "git revert [<options>] <commit-ish>..."
-msgstr ""
-
-#: builtin/revert.c:25
-msgid "git revert <subcommand>"
-msgstr ""
-
-#: builtin/revert.c:30
-msgid "git cherry-pick [<options>] <commit-ish>..."
-msgstr ""
-
-#: builtin/revert.c:31
-msgid "git cherry-pick <subcommand>"
-msgstr ""
-
-#: builtin/revert.c:72
-#, c-format
-msgid "option `%s' expects a number greater than zero"
-msgstr ""
-
-#: builtin/revert.c:92
-#, c-format
-msgid "%s: %s cannot be used with %s"
-msgstr ""
-
-#: builtin/revert.c:102
-msgid "end revert or cherry-pick sequence"
-msgstr ""
-
-#: builtin/revert.c:103
-msgid "resume revert or cherry-pick sequence"
-msgstr ""
-
-#: builtin/revert.c:104
-msgid "cancel revert or cherry-pick sequence"
-msgstr ""
-
-#: builtin/revert.c:105
-msgid "skip current commit and continue"
-msgstr ""
-
-#: builtin/revert.c:107
-msgid "don't automatically commit"
-msgstr ""
-
-#: builtin/revert.c:108
-msgid "edit the commit message"
-msgstr ""
-
-#: builtin/revert.c:111
-msgid "parent-number"
-msgstr ""
-
-#: builtin/revert.c:112
-msgid "select mainline parent"
-msgstr ""
-
-#: builtin/revert.c:114
-msgid "merge strategy"
-msgstr ""
-
-#: builtin/revert.c:116
-msgid "option for merge strategy"
-msgstr ""
-
-#: builtin/revert.c:125
-msgid "append commit name"
-msgstr ""
-
-#: builtin/revert.c:127
-msgid "preserve initially empty commits"
-msgstr ""
-
-#: builtin/revert.c:128
-msgid "allow commits with empty messages"
-msgstr ""
-
-#: builtin/revert.c:129
-msgid "keep redundant, empty commits"
-msgstr ""
-
-#: builtin/revert.c:241
-msgid "revert failed"
-msgstr ""
-
-#: builtin/revert.c:254
-msgid "cherry-pick failed"
-msgstr ""
-
-#: builtin/rm.c:20
-msgid "git rm [<options>] [--] <file>..."
-msgstr ""
-
-#: builtin/rm.c:208
-msgid ""
-"the following file has staged content different from both the\n"
-"file and the HEAD:"
-msgid_plural ""
-"the following files have staged content different from both the\n"
-"file and the HEAD:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/rm.c:213
-msgid ""
-"\n"
-"(use -f to force removal)"
-msgstr ""
-
-#: builtin/rm.c:217
-msgid "the following file has changes staged in the index:"
-msgid_plural "the following files have changes staged in the index:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/rm.c:221 builtin/rm.c:230
-msgid ""
-"\n"
-"(use --cached to keep the file, or -f to force removal)"
-msgstr ""
-
-#: builtin/rm.c:227
-msgid "the following file has local modifications:"
-msgid_plural "the following files have local modifications:"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/rm.c:245
-msgid "do not list removed files"
-msgstr ""
-
-#: builtin/rm.c:246
-msgid "only remove from the index"
-msgstr ""
-
-#: builtin/rm.c:247
-msgid "override the up-to-date check"
-msgstr ""
-
-#: builtin/rm.c:248
-msgid "allow recursive removal"
-msgstr ""
-
-#: builtin/rm.c:250
-msgid "exit with a zero status even if nothing matched"
-msgstr ""
-
-#: builtin/rm.c:285
-msgid "No pathspec was given. Which files should I remove?"
-msgstr ""
-
-#: builtin/rm.c:315
-msgid "please stage your changes to .gitmodules or stash them to proceed"
-msgstr ""
-
-#: builtin/rm.c:337
-#, c-format
-msgid "not removing '%s' recursively without -r"
-msgstr ""
-
-#: builtin/rm.c:385
-#, c-format
-msgid "git rm: unable to remove %s"
-msgstr ""
-
-#: builtin/send-pack.c:20
-msgid ""
-"git send-pack [--mirror] [--dry-run] [--force]\n"
-"              [--receive-pack=<git-receive-pack>]\n"
-"              [--verbose] [--thin] [--atomic]\n"
-"              [<host>:]<directory> (--all | <ref>...)"
-msgstr ""
-
-#: builtin/send-pack.c:192
-msgid "remote name"
-msgstr ""
-
-#: builtin/send-pack.c:205
-msgid "use stateless RPC protocol"
-msgstr ""
-
-#: builtin/send-pack.c:206
-msgid "read refs from stdin"
-msgstr ""
-
-#: builtin/send-pack.c:207
-msgid "print status from remote helper"
-msgstr ""
-
-#: builtin/shortlog.c:16
-msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
-msgstr ""
-
-#: builtin/shortlog.c:17
-msgid "git log --pretty=short | git shortlog [<options>]"
-msgstr ""
-
-#: builtin/shortlog.c:123
-msgid "using multiple --group options with stdin is not supported"
-msgstr ""
-
-#: builtin/shortlog.c:133
-msgid "using --group=trailer with stdin is not supported"
-msgstr ""
-
-#: builtin/shortlog.c:323
-#, c-format
-msgid "unknown group type: %s"
-msgstr ""
-
-#: builtin/shortlog.c:351
-msgid "group by committer rather than author"
-msgstr ""
-
-#: builtin/shortlog.c:354
-msgid "sort output according to the number of commits per author"
-msgstr ""
-
-#: builtin/shortlog.c:356
-msgid "suppress commit descriptions, only provides commit count"
-msgstr ""
-
-#: builtin/shortlog.c:358
-msgid "show the email address of each author"
-msgstr ""
-
-#: builtin/shortlog.c:359
-msgid "<w>[,<i1>[,<i2>]]"
-msgstr ""
-
-#: builtin/shortlog.c:360
-msgid "linewrap output"
-msgstr ""
-
-#: builtin/shortlog.c:362
-msgid "field"
-msgstr ""
-
-#: builtin/shortlog.c:363
-msgid "group by field"
-msgstr ""
-
-#: builtin/shortlog.c:395
-msgid "too many arguments given outside repository"
-msgstr ""
-
-#: builtin/show-branch.c:14
-msgid ""
-"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>)...]"
-msgstr ""
-
-#: builtin/show-branch.c:18
-msgid "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]"
-msgstr ""
-
-#: builtin/show-branch.c:396
-#, c-format
-msgid "ignoring %s; cannot handle more than %d ref"
-msgid_plural "ignoring %s; cannot handle more than %d refs"
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/show-branch.c:548
-#, c-format
-msgid "no matching refs with %s"
-msgstr ""
-
-#: builtin/show-branch.c:645
-msgid "show remote-tracking and local branches"
-msgstr ""
-
-#: builtin/show-branch.c:647
-msgid "show remote-tracking branches"
-msgstr ""
-
-#: builtin/show-branch.c:649
-msgid "color '*!+-' corresponding to the branch"
-msgstr ""
-
-#: builtin/show-branch.c:651
-msgid "show <n> more commits after the common ancestor"
-msgstr ""
-
-#: builtin/show-branch.c:653
-msgid "synonym to more=-1"
-msgstr ""
-
-#: builtin/show-branch.c:654
-msgid "suppress naming strings"
-msgstr ""
-
-#: builtin/show-branch.c:656
-msgid "include the current branch"
-msgstr ""
-
-#: builtin/show-branch.c:658
-msgid "name commits with their object names"
-msgstr ""
-
-#: builtin/show-branch.c:660
-msgid "show possible merge bases"
-msgstr ""
-
-#: builtin/show-branch.c:662
-msgid "show refs unreachable from any other ref"
-msgstr ""
-
-#: builtin/show-branch.c:664
-msgid "show commits in topological order"
-msgstr ""
-
-#: builtin/show-branch.c:667
-msgid "show only commits not on the first branch"
-msgstr ""
-
-#: builtin/show-branch.c:669
-msgid "show merges reachable from only one tip"
-msgstr ""
-
-#: builtin/show-branch.c:671
-msgid "topologically sort, maintaining date order where possible"
-msgstr ""
-
-#: builtin/show-branch.c:674
-msgid "<n>[,<base>]"
-msgstr ""
-
-#: builtin/show-branch.c:675
-msgid "show <n> most recent ref-log entries starting at base"
-msgstr ""
-
-#: builtin/show-branch.c:735
-msgid "no branches given, and HEAD is not valid"
-msgstr ""
-
-#: builtin/show-branch.c:738
-msgid "--reflog option needs one branch name"
-msgstr ""
-
-#: builtin/show-branch.c:741
-#, c-format
-msgid "only %d entry can be shown at one time."
-msgid_plural "only %d entries can be shown at one time."
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/show-branch.c:745
-#, c-format
-msgid "no such ref %s"
-msgstr ""
-
-#: builtin/show-branch.c:831
-#, c-format
-msgid "cannot handle more than %d rev."
-msgid_plural "cannot handle more than %d revs."
-msgstr[0] ""
-msgstr[1] ""
-
-#: builtin/show-branch.c:835
-#, c-format
-msgid "'%s' is not a valid ref."
-msgstr ""
-
-#: builtin/show-branch.c:838
-#, c-format
-msgid "cannot find commit %s (%s)"
-msgstr ""
-
-#: builtin/show-index.c:21
-msgid "hash-algorithm"
-msgstr ""
-
-#: builtin/show-index.c:31
-msgid "Unknown hash algorithm"
-msgstr ""
-
-#: builtin/show-ref.c:12
-msgid ""
-"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --"
-"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]"
-msgstr ""
-
-#: builtin/show-ref.c:13
-msgid "git show-ref --exclude-existing[=<pattern>]"
-msgstr ""
-
-#: builtin/show-ref.c:162
-msgid "only show tags (can be combined with heads)"
-msgstr ""
-
-#: builtin/show-ref.c:163
-msgid "only show heads (can be combined with tags)"
-msgstr ""
-
-#: builtin/show-ref.c:164
-msgid "stricter reference checking, requires exact ref path"
-msgstr ""
-
-#: builtin/show-ref.c:167 builtin/show-ref.c:169
-msgid "show the HEAD reference, even if it would be filtered out"
-msgstr ""
-
-#: builtin/show-ref.c:171
-msgid "dereference tags into object IDs"
-msgstr ""
-
-#: builtin/show-ref.c:173
-msgid "only show SHA1 hash using <n> digits"
-msgstr ""
-
-#: builtin/show-ref.c:177
-msgid "do not print results to stdout (useful with --verify)"
-msgstr ""
-
-#: builtin/show-ref.c:179
-msgid "show refs from stdin that aren't in local repository"
-msgstr ""
-
-#: builtin/sparse-checkout.c:23
-msgid "git sparse-checkout (init|list|set|add|reapply|disable) <options>"
-msgstr ""
-
-#: builtin/sparse-checkout.c:61
-msgid "this worktree is not sparse"
-msgstr ""
-
-#: builtin/sparse-checkout.c:76
-msgid "this worktree is not sparse (sparse-checkout file may not exist)"
-msgstr ""
-
-#: builtin/sparse-checkout.c:177
-#, c-format
-msgid ""
-"directory '%s' contains untracked files, but is not in the sparse-checkout "
-"cone"
-msgstr ""
-
-#: builtin/sparse-checkout.c:185
-#, c-format
-msgid "failed to remove directory '%s'"
-msgstr ""
-
-#: builtin/sparse-checkout.c:327
-msgid "failed to create directory for sparse-checkout file"
-msgstr ""
-
-#: builtin/sparse-checkout.c:366
-msgid "failed to initialize worktree config"
-msgstr ""
-
-#: builtin/sparse-checkout.c:411
-msgid "failed to modify sparse-index config"
-msgstr ""
-
-#: builtin/sparse-checkout.c:441 builtin/sparse-checkout.c:793
-#: builtin/sparse-checkout.c:847
-msgid "initialize the sparse-checkout in cone mode"
-msgstr ""
-
-#: builtin/sparse-checkout.c:443 builtin/sparse-checkout.c:795
-#: builtin/sparse-checkout.c:849
-msgid "toggle the use of a sparse index"
-msgstr ""
-
-#: builtin/sparse-checkout.c:479
-#, c-format
-msgid "failed to open '%s'"
-msgstr ""
-
-#: builtin/sparse-checkout.c:531
-#, c-format
-msgid "could not normalize path %s"
-msgstr ""
-
-#: builtin/sparse-checkout.c:560
-#, c-format
-msgid "unable to unquote C-style string '%s'"
-msgstr ""
-
-#: builtin/sparse-checkout.c:615 builtin/sparse-checkout.c:643
-msgid "unable to load existing sparse-checkout patterns"
-msgstr ""
-
-#: builtin/sparse-checkout.c:619
-msgid "existing sparse-checkout patterns do not use cone mode"
-msgstr ""
-
-#: builtin/sparse-checkout.c:707
-msgid "please run from the toplevel directory in non-cone mode"
-msgstr ""
-
-#: builtin/sparse-checkout.c:712
-msgid "specify directories rather than patterns (no leading slash)"
-msgstr ""
-
-#: builtin/sparse-checkout.c:714
-msgid ""
-"specify directories rather than patterns.  If your directory starts with a "
-"'!', pass --skip-checks"
-msgstr ""
-
-#: builtin/sparse-checkout.c:716
-msgid ""
-"specify directories rather than patterns.  If your directory really has any "
-"of '*?[]\\' in it, pass --skip-checks"
-msgstr ""
-
-#: builtin/sparse-checkout.c:732
-#, c-format
-msgid ""
-"'%s' is not a directory; to treat it as a directory anyway, rerun with --"
-"skip-checks"
-msgstr ""
-
-#: builtin/sparse-checkout.c:734
-#, 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 ""
-
-#: builtin/sparse-checkout.c:739
-msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"
-msgstr ""
-
-#: builtin/sparse-checkout.c:752 builtin/sparse-checkout.c:797
-msgid ""
-"skip some sanity checks on the given paths that might give false positives"
-msgstr ""
-
-#: builtin/sparse-checkout.c:755 builtin/sparse-checkout.c:800
-msgid "read patterns from standard in"
-msgstr ""
-
-#: builtin/sparse-checkout.c:760
-msgid "no sparse-checkout to add to"
-msgstr ""
-
-#: builtin/sparse-checkout.c:775
-msgid ""
-"git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] "
-"(--stdin | <patterns>)"
-msgstr ""
-
-#: builtin/sparse-checkout.c:854
-msgid "must be in a sparse-checkout to reapply sparsity patterns"
-msgstr ""
-
-#: builtin/sparse-checkout.c:914
-msgid "error while refreshing working directory"
-msgstr ""
-
-#: builtin/stash.c:24 builtin/stash.c:40
-msgid "git stash list [<options>]"
-msgstr ""
-
-#: builtin/stash.c:25 builtin/stash.c:45
-msgid "git stash show [<options>] [<stash>]"
-msgstr ""
-
-#: builtin/stash.c:26 builtin/stash.c:50
-msgid "git stash drop [-q|--quiet] [<stash>]"
-msgstr ""
-
-#: builtin/stash.c:27
-msgid "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]"
-msgstr ""
-
-#: builtin/stash.c:28 builtin/stash.c:65
-msgid "git stash branch <branchname> [<stash>]"
-msgstr ""
-
-#: builtin/stash.c:30
-msgid ""
-"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>...]]"
-msgstr ""
-
-#: builtin/stash.c:34
-msgid ""
-"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
-"quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [<message>]"
-msgstr ""
-
-#: builtin/stash.c:55
-msgid "git stash pop [--index] [-q|--quiet] [<stash>]"
-msgstr ""
-
-#: builtin/stash.c:60
-msgid "git stash apply [--index] [-q|--quiet] [<stash>]"
-msgstr ""
-
-#: builtin/stash.c:75
-msgid "git stash store [-m|--message <message>] [-q|--quiet] <commit>"
-msgstr ""
-
-#: builtin/stash.c:80
-msgid ""
-"git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
-"          [--] [<pathspec>...]]"
-msgstr ""
-
-#: builtin/stash.c:87
-msgid ""
-"git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
-"               [-u|--include-untracked] [-a|--all] [<message>]"
-msgstr ""
-
-#: builtin/stash.c:130
-#, c-format
-msgid "'%s' is not a stash-like commit"
-msgstr ""
-
-#: builtin/stash.c:150
-#, c-format
-msgid "Too many revisions specified:%s"
-msgstr ""
-
-#: builtin/stash.c:164
-msgid "No stash entries found."
-msgstr ""
-
-#: builtin/stash.c:178
-#, c-format
-msgid "%s is not a valid reference"
-msgstr ""
-
-#: builtin/stash.c:227
-msgid "git stash clear with arguments is unimplemented"
-msgstr ""
-
-#: builtin/stash.c:447
-#, c-format
-msgid ""
-"WARNING: Untracked file in way of tracked file!  Renaming\n"
-"            %s -> %s\n"
-"         to make room.\n"
-msgstr ""
-
-#: builtin/stash.c:508
-msgid "cannot apply a stash in the middle of a merge"
-msgstr ""
-
-#: builtin/stash.c:519
-#, c-format
-msgid "could not generate diff %s^!."
-msgstr ""
-
-#: builtin/stash.c:526
-msgid "conflicts in index. Try without --index."
-msgstr ""
-
-#: builtin/stash.c:532
-msgid "could not save index tree"
-msgstr ""
-
-#: builtin/stash.c:552
-#, c-format
-msgid "Merging %s with %s"
-msgstr ""
-
-#: builtin/stash.c:562
-msgid "Index was not unstashed."
-msgstr ""
-
-#: builtin/stash.c:576
-msgid "could not restore untracked files from stash"
-msgstr ""
-
-#: builtin/stash.c:608 builtin/stash.c:695
-msgid "attempt to recreate the index"
-msgstr ""
-
-#: builtin/stash.c:641
-#, c-format
-msgid "Dropped %s (%s)"
-msgstr ""
-
-#: builtin/stash.c:644
-#, c-format
-msgid "%s: Could not drop stash entry"
-msgstr ""
-
-#: builtin/stash.c:657
-#, c-format
-msgid "'%s' is not a stash reference"
-msgstr ""
-
-#: builtin/stash.c:707
-msgid "The stash entry is kept in case you need it again."
-msgstr ""
-
-#: builtin/stash.c:730
-msgid "No branch name specified"
-msgstr ""
-
-#: builtin/stash.c:809
-msgid "failed to parse tree"
-msgstr ""
-
-#: builtin/stash.c:820
-msgid "failed to unpack trees"
-msgstr ""
-
-#: builtin/stash.c:840
-msgid "include untracked files in the stash"
-msgstr ""
-
-#: builtin/stash.c:843
-msgid "only show untracked files in the stash"
-msgstr ""
-
-#: builtin/stash.c:930 builtin/stash.c:967
-#, c-format
-msgid "Cannot update %s with %s"
-msgstr ""
-
-#: builtin/stash.c:948 builtin/stash.c:1667 builtin/stash.c:1739
-msgid "stash message"
-msgstr ""
-
-#: builtin/stash.c:958
-msgid "\"git stash store\" requires one <commit> argument"
-msgstr ""
-
-#: builtin/stash.c:1143
-msgid "No staged changes"
-msgstr ""
-
-#: builtin/stash.c:1204
-msgid "No changes selected"
-msgstr ""
-
-#: builtin/stash.c:1304
-msgid "You do not have the initial commit yet"
-msgstr ""
-
-#: builtin/stash.c:1331
-msgid "Cannot save the current index state"
-msgstr ""
-
-#: builtin/stash.c:1340
-msgid "Cannot save the untracked files"
-msgstr ""
-
-#: builtin/stash.c:1351 builtin/stash.c:1370
-msgid "Cannot save the current worktree state"
-msgstr ""
-
-#: builtin/stash.c:1361
-msgid "Cannot save the current staged state"
-msgstr ""
-
-#: builtin/stash.c:1398
-msgid "Cannot record working tree state"
-msgstr ""
-
-#: builtin/stash.c:1447
-msgid "Can't use --patch and --include-untracked or --all at the same time"
-msgstr ""
-
-#: builtin/stash.c:1458
-msgid "Can't use --staged and --include-untracked or --all at the same time"
-msgstr ""
-
-#: builtin/stash.c:1476
-msgid "Did you forget to 'git add'?"
-msgstr ""
-
-#: builtin/stash.c:1491
-msgid "No local changes to save"
-msgstr ""
-
-#: builtin/stash.c:1498
-msgid "Cannot initialize stash"
-msgstr ""
-
-#: builtin/stash.c:1513
-msgid "Cannot save the current status"
-msgstr ""
-
-#: builtin/stash.c:1518
-#, c-format
-msgid "Saved working directory and index state %s"
-msgstr ""
-
-#: builtin/stash.c:1615
-msgid "Cannot remove worktree changes"
-msgstr ""
-
-#: builtin/stash.c:1656 builtin/stash.c:1728
-msgid "keep index"
-msgstr ""
-
-#: builtin/stash.c:1658 builtin/stash.c:1730
-msgid "stash staged changes only"
-msgstr ""
-
-#: builtin/stash.c:1660 builtin/stash.c:1732
-msgid "stash in patch mode"
-msgstr ""
-
-#: builtin/stash.c:1661 builtin/stash.c:1733
-msgid "quiet mode"
-msgstr ""
-
-#: builtin/stash.c:1663 builtin/stash.c:1735
-msgid "include untracked files in stash"
-msgstr ""
-
-#: builtin/stash.c:1665 builtin/stash.c:1737
-msgid "include ignore files"
-msgstr ""
-
-#: builtin/stripspace.c:37
-msgid "skip and remove all lines starting with comment character"
-msgstr ""
-
-#: builtin/stripspace.c:40
-msgid "prepend comment character and space to each line"
-msgstr ""
-
-#: builtin/submodule--helper.c:50 builtin/submodule--helper.c:2486
-#, c-format
-msgid "Expecting a full ref name, got %s"
-msgstr ""
-
-#: builtin/submodule--helper.c:103
-#, c-format
-msgid "cannot strip one component off url '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:213
-#, c-format
-msgid ""
-"could not look up configuration '%s'. Assuming this repository is its own "
-"authoritative upstream."
-msgstr ""
-
-#: builtin/submodule--helper.c:413 builtin/submodule--helper.c:1873
-msgid "alternative anchor for relative paths"
-msgstr ""
-
-#: builtin/submodule--helper.c:418
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr ""
-
-#: builtin/submodule--helper.c:476 builtin/submodule--helper.c:617
-#: builtin/submodule--helper.c:640
-#, c-format
-msgid "No url found for submodule path '%s' in .gitmodules"
-msgstr ""
-
-#: builtin/submodule--helper.c:528
-#, c-format
-msgid "Entering '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:531
-#, c-format
-msgid ""
-"run_command returned non-zero status for %s\n"
-"."
-msgstr ""
-
-#: builtin/submodule--helper.c:553
-#, c-format
-msgid ""
-"run_command returned non-zero status while recursing in the nested "
-"submodules of %s\n"
-"."
-msgstr ""
-
-#: builtin/submodule--helper.c:569
-msgid "suppress output of entering each submodule command"
-msgstr ""
-
-#: builtin/submodule--helper.c:571 builtin/submodule--helper.c:876
-#: builtin/submodule--helper.c:1458
-msgid "recurse into nested submodules"
-msgstr ""
-
-#: builtin/submodule--helper.c:576
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr ""
-
-#: builtin/submodule--helper.c:654
-#, c-format
-msgid "Failed to register url for submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:658
-#, c-format
-msgid "Submodule '%s' (%s) registered for path '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:668
-#, c-format
-msgid "warning: command update mode suggested for submodule '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:675
-#, c-format
-msgid "Failed to register update mode for submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:697
-msgid "suppress output for initializing a submodule"
-msgstr ""
-
-#: builtin/submodule--helper.c:702
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr ""
-
-#: builtin/submodule--helper.c:775 builtin/submodule--helper.c:910
-#, c-format
-msgid "no submodule mapping found in .gitmodules for path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:823
-#, c-format
-msgid "could not resolve HEAD ref inside the submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:850 builtin/submodule--helper.c:1428
-#, c-format
-msgid "failed to recurse into submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:874 builtin/submodule--helper.c:1595
-msgid "suppress submodule status output"
-msgstr ""
-
-#: builtin/submodule--helper.c:875
-msgid ""
-"use commit stored in the index instead of the one stored in the submodule "
-"HEAD"
-msgstr ""
-
-#: builtin/submodule--helper.c:881
-msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
-msgstr ""
-
-#: builtin/submodule--helper.c:905
-msgid "git submodule--helper name <path>"
-msgstr ""
-
-#: builtin/submodule--helper.c:977
-#, c-format
-msgid "* %s %s(blob)->%s(submodule)"
-msgstr ""
-
-#: builtin/submodule--helper.c:980
-#, c-format
-msgid "* %s %s(submodule)->%s(blob)"
-msgstr ""
-
-#: builtin/submodule--helper.c:993
-#, c-format
-msgid "%s"
-msgstr ""
-
-#: builtin/submodule--helper.c:1043
-#, c-format
-msgid "couldn't hash object from '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1047
-#, c-format
-msgid "unexpected mode %o\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:1288
-msgid "use the commit stored in the index instead of the submodule HEAD"
-msgstr ""
-
-#: builtin/submodule--helper.c:1290
-msgid "compare the commit in the index with that in the submodule HEAD"
-msgstr ""
-
-#: builtin/submodule--helper.c:1292
-msgid "skip submodules with 'ignore_config' value set to 'all'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1294
-msgid "limit the summary size"
-msgstr ""
-
-#: builtin/submodule--helper.c:1299
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
-msgstr ""
-
-#: builtin/submodule--helper.c:1323
-msgid "could not fetch a revision for HEAD"
-msgstr ""
-
-#: builtin/submodule--helper.c:1384
-#, c-format
-msgid "Synchronizing submodule url for '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:1390
-#, c-format
-msgid "failed to register url for submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1399
-#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1409
-#, c-format
-msgid "failed to update remote for submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1456
-msgid "suppress output of synchronizing submodule url"
-msgstr ""
-
-#: builtin/submodule--helper.c:1463
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr ""
-
-#: builtin/submodule--helper.c:1513
-#, c-format
-msgid ""
-"Submodule work tree '%s' contains a .git directory. This will be replaced "
-"with a .git file by using absorbgitdirs."
-msgstr ""
-
-#: builtin/submodule--helper.c:1530
-#, c-format
-msgid ""
-"Submodule work tree '%s' contains local modifications; use '-f' to discard "
-"them"
-msgstr ""
-
-#: builtin/submodule--helper.c:1538
-#, c-format
-msgid "Cleared directory '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:1540
-#, c-format
-msgid "Could not remove submodule work tree '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:1551
-#, c-format
-msgid "could not create empty submodule directory %s"
-msgstr ""
-
-#: builtin/submodule--helper.c:1567
-#, c-format
-msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:1596
-msgid "remove submodule working trees even if they contain local changes"
-msgstr ""
-
-#: builtin/submodule--helper.c:1597
-msgid "unregister all submodules"
-msgstr ""
-
-#: builtin/submodule--helper.c:1602
-msgid ""
-"git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
-msgstr ""
-
-#: builtin/submodule--helper.c:1616
-msgid "Use '--all' if you really want to deinitialize all submodules"
-msgstr ""
-
-#: builtin/submodule--helper.c:1665
-msgid ""
-"An alternate computed from a superproject's alternate is invalid.\n"
-"To allow Git to clone without an alternate in such a case, set\n"
-"submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
-"'--reference-if-able' instead of '--reference'."
-msgstr ""
-
-#: builtin/submodule--helper.c:1710 builtin/submodule--helper.c:1713
-#, c-format
-msgid "submodule '%s' cannot add alternate: %s"
-msgstr ""
-
-#: builtin/submodule--helper.c:1749
-#, c-format
-msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
-msgstr ""
-
-#: builtin/submodule--helper.c:1756
-#, c-format
-msgid "Value '%s' for submodule.alternateLocation is not recognized"
-msgstr ""
-
-#: builtin/submodule--helper.c:1781
-#, c-format
-msgid "refusing to create/use '%s' in another submodule's git dir"
-msgstr ""
-
-#: builtin/submodule--helper.c:1826
-#, c-format
-msgid "clone of '%s' into submodule path '%s' failed"
-msgstr ""
-
-#: builtin/submodule--helper.c:1831
-#, c-format
-msgid "directory not empty: '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1843
-#, c-format
-msgid "could not get submodule directory for '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1876
-msgid "where the new submodule will be cloned to"
-msgstr ""
-
-#: builtin/submodule--helper.c:1879
-msgid "name of the new submodule"
-msgstr ""
-
-#: builtin/submodule--helper.c:1882
-msgid "url where to clone the submodule from"
-msgstr ""
-
-#: builtin/submodule--helper.c:1890 builtin/submodule--helper.c:3383
-msgid "depth for shallow clones"
-msgstr ""
-
-#: builtin/submodule--helper.c:1893 builtin/submodule--helper.c:2731
-#: builtin/submodule--helper.c:3376
-msgid "force cloning progress"
-msgstr ""
-
-#: builtin/submodule--helper.c:1895 builtin/submodule--helper.c:2733
-msgid "disallow cloning into non-empty directory"
-msgstr ""
-
-#: builtin/submodule--helper.c:1903
-msgid ""
-"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
-"<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter "
-"<filter-spec>] --url <url> --path <path>"
-msgstr ""
-
-#: builtin/submodule--helper.c:1943
-#, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:1947
-#, c-format
-msgid "Invalid update mode '%s' configured for submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2041
-#, c-format
-msgid "Submodule path '%s' not initialized"
-msgstr ""
-
-#: builtin/submodule--helper.c:2045
-msgid "Maybe you want to use 'update --init'?"
-msgstr ""
-
-#: builtin/submodule--helper.c:2075
-#, c-format
-msgid "Skipping unmerged submodule %s"
-msgstr ""
-
-#: builtin/submodule--helper.c:2104
-#, c-format
-msgid "Skipping submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2257
-#, c-format
-msgid "Failed to clone '%s'. Retry scheduled"
-msgstr ""
-
-#: builtin/submodule--helper.c:2268
-#, c-format
-msgid "Failed to clone '%s' a second time, aborting"
-msgstr ""
-
-#: builtin/submodule--helper.c:2371
-#, c-format
-msgid "Unable to checkout '%s' in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2375
-#, c-format
-msgid "Unable to rebase '%s' in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2379
-#, c-format
-msgid "Unable to merge '%s' in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2383
-#, c-format
-msgid "Execution of '%s %s' failed in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2402
-#, c-format
-msgid "Submodule path '%s': checked out '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:2406
-#, c-format
-msgid "Submodule path '%s': rebased into '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:2410
-#, c-format
-msgid "Submodule path '%s': merged in '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:2414
-#, c-format
-msgid "Submodule path '%s': '%s %s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:2438
-#, c-format
-msgid "Unable to fetch in submodule path '%s'; trying to directly fetch %s:"
-msgstr ""
-
-#: builtin/submodule--helper.c:2447
-#, c-format
-msgid ""
-"Fetched in submodule path '%s', but it did not contain %s. Direct fetching "
-"of that commit failed."
-msgstr ""
-
-#: builtin/submodule--helper.c:2481
-#, c-format
-msgid ""
-"Submodule (%s) branch configured to inherit branch from superproject, but "
-"the superproject is not on any branch"
-msgstr ""
-
-#: builtin/submodule--helper.c:2499
-#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2588
-#, c-format
-msgid "Unable to find current revision in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2599
-#, c-format
-msgid "Unable to fetch in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2604
-#, c-format
-msgid "Unable to find %s revision in submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2640
-#, c-format
-msgid "Failed to recurse into submodule path '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:2699
-msgid "force checkout updates"
-msgstr ""
-
-#: builtin/submodule--helper.c:2701
-msgid "initialize uninitialized submodules before update"
-msgstr ""
-
-#: builtin/submodule--helper.c:2703
-msgid "use SHA-1 of submodule's remote tracking branch"
-msgstr ""
-
-#: builtin/submodule--helper.c:2705
-msgid "traverse submodules recursively"
-msgstr ""
-
-#: builtin/submodule--helper.c:2707
-msgid "don't fetch new objects from the remote site"
-msgstr ""
-
-#: builtin/submodule--helper.c:2710 builtin/submodule--helper.c:2892
-msgid "path into the working tree"
-msgstr ""
-
-#: builtin/submodule--helper.c:2713
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr ""
-
-#: builtin/submodule--helper.c:2717
-msgid "rebase, merge, checkout or none"
-msgstr ""
-
-#: builtin/submodule--helper.c:2723
-msgid "create a shallow clone truncated to the specified number of revisions"
-msgstr ""
-
-#: builtin/submodule--helper.c:2726
-msgid "parallel jobs"
-msgstr ""
-
-#: builtin/submodule--helper.c:2728
-msgid "whether the initial clone should follow the shallow recommendation"
-msgstr ""
-
-#: builtin/submodule--helper.c:2729
-msgid "don't print cloning progress"
-msgstr ""
-
-#: builtin/submodule--helper.c:2741
-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 ""
-
-#: builtin/submodule--helper.c:2767
-msgid "bad value for update parameter"
-msgstr ""
-
-#: builtin/submodule--helper.c:2893
-msgid "recurse into submodules"
-msgstr ""
-
-#: builtin/submodule--helper.c:2899
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr ""
-
-#: builtin/submodule--helper.c:2955
-msgid "check if it is safe to write to the .gitmodules file"
-msgstr ""
-
-#: builtin/submodule--helper.c:2958
-msgid "unset the config in the .gitmodules file"
-msgstr ""
-
-#: builtin/submodule--helper.c:2963
-msgid "git submodule--helper config <name> [<value>]"
-msgstr ""
-
-#: builtin/submodule--helper.c:2964
-msgid "git submodule--helper config --unset <name>"
-msgstr ""
-
-#: builtin/submodule--helper.c:2984 builtin/submodule--helper.c:3238
-#: builtin/submodule--helper.c:3395
-msgid "please make sure that the .gitmodules file is in the working tree"
-msgstr ""
-
-#: builtin/submodule--helper.c:3000
-msgid "suppress output for setting url of a submodule"
-msgstr ""
-
-#: builtin/submodule--helper.c:3004
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr ""
-
-#: builtin/submodule--helper.c:3037
-msgid "set the default tracking branch to master"
-msgstr ""
-
-#: builtin/submodule--helper.c:3039
-msgid "set the default tracking branch"
-msgstr ""
-
-#: builtin/submodule--helper.c:3043
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr ""
-
-#: builtin/submodule--helper.c:3044
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
-msgstr ""
-
-#: builtin/submodule--helper.c:3051
-msgid "--branch or --default required"
-msgstr ""
-
-#: builtin/submodule--helper.c:3072 builtin/submodule--helper.c:3375
-msgid "print only error messages"
-msgstr ""
-
-#: builtin/submodule--helper.c:3073
-msgid "force creation"
-msgstr ""
-
-#: builtin/submodule--helper.c:3081
-msgid "show whether the branch would be created"
-msgstr ""
-
-#: builtin/submodule--helper.c:3085
-msgid ""
-"git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--"
-"quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"
-msgstr ""
-
-#: builtin/submodule--helper.c:3097
-#, c-format
-msgid "creating branch '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:3155
-#, c-format
-msgid "Adding existing repo at '%s' to the index\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:3158
-#, c-format
-msgid "'%s' already exists and is not a valid git repo"
-msgstr ""
-
-#: builtin/submodule--helper.c:3171
-#, c-format
-msgid "A git directory for '%s' is found locally with remote(s):\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:3178
-#, c-format
-msgid ""
-"If you want to reuse this local git directory instead of cloning again from\n"
-"  %s\n"
-"use the '--force' option. If the local git directory is not the correct "
-"repo\n"
-"or you are unsure what this means choose another name with the '--name' "
-"option."
-msgstr ""
-
-#: builtin/submodule--helper.c:3190
-#, c-format
-msgid "Reactivating local git directory for submodule '%s'\n"
-msgstr ""
-
-#: builtin/submodule--helper.c:3227
-#, c-format
-msgid "unable to checkout submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:3266
-#, c-format
-msgid "Failed to add submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:3270 builtin/submodule--helper.c:3275
-#: builtin/submodule--helper.c:3283
-#, c-format
-msgid "Failed to register submodule '%s'"
-msgstr ""
-
-#: builtin/submodule--helper.c:3339
-#, c-format
-msgid "'%s' already exists in the index"
-msgstr ""
-
-#: builtin/submodule--helper.c:3342
-#, c-format
-msgid "'%s' already exists in the index and is not a submodule"
-msgstr ""
-
-#: builtin/submodule--helper.c:3372
-msgid "branch of repository to add as submodule"
-msgstr ""
-
-#: builtin/submodule--helper.c:3373
-msgid "allow adding an otherwise ignored submodule path"
-msgstr ""
-
-#: builtin/submodule--helper.c:3379
-msgid "borrow the objects from reference repositories"
-msgstr ""
-
-#: builtin/submodule--helper.c:3381
-msgid ""
-"sets the submodule’s name to the given string instead of defaulting to its "
-"path"
-msgstr ""
-
-#: builtin/submodule--helper.c:3388
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr ""
-
-#: builtin/submodule--helper.c:3416
-msgid "Relative path can only be used from the toplevel of the working tree"
-msgstr ""
-
-#: builtin/submodule--helper.c:3425
-#, c-format
-msgid "repo URL: '%s' must be absolute or begin with ./|../"
-msgstr ""
-
-#: builtin/submodule--helper.c:3460
-#, c-format
-msgid "'%s' is not a valid submodule name"
-msgstr ""
-
-#: builtin/submodule--helper.c:3520 git.c:453 git.c:729
-#, c-format
-msgid "%s doesn't support --super-prefix"
-msgstr ""
-
-#: builtin/submodule--helper.c:3526
-#, c-format
-msgid "'%s' is not a valid submodule--helper subcommand"
-msgstr ""
-
-#: builtin/symbolic-ref.c:8
-msgid "git symbolic-ref [<options>] <name> [<ref>]"
-msgstr ""
-
-#: builtin/symbolic-ref.c:9
-msgid "git symbolic-ref -d [-q] <name>"
-msgstr ""
-
-#: builtin/symbolic-ref.c:42
-msgid "suppress error message for non-symbolic (detached) refs"
-msgstr ""
-
-#: builtin/symbolic-ref.c:43
-msgid "delete symbolic ref"
-msgstr ""
-
-#: builtin/symbolic-ref.c:44
-msgid "shorten ref output"
-msgstr ""
-
-#: builtin/symbolic-ref.c:45 builtin/update-ref.c:505
-msgid "reason"
-msgstr ""
-
-#: builtin/symbolic-ref.c:45 builtin/update-ref.c:505
-msgid "reason of the update"
-msgstr ""
-
-#: builtin/tag.c:26
-msgid ""
-"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n"
-"        <tagname> [<head>]"
-msgstr ""
-
-#: builtin/tag.c:28
-msgid "git tag -d <tagname>..."
-msgstr ""
-
-#: builtin/tag.c:29
-msgid ""
-"git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--"
-"points-at <object>]\n"
-"        [--format=<format>] [--merged <commit>] [--no-merged <commit>] "
-"[<pattern>...]"
-msgstr ""
-
-#: builtin/tag.c:31
-msgid "git tag -v [--format=<format>] <tagname>..."
-msgstr ""
-
-#: builtin/tag.c:101
-#, c-format
-msgid "tag '%s' not found."
-msgstr ""
-
-#: builtin/tag.c:136
-#, c-format
-msgid "Deleted tag '%s' (was %s)\n"
-msgstr ""
-
-#: builtin/tag.c:171
-#, c-format
-msgid ""
-"\n"
-"Write a message for tag:\n"
-"  %s\n"
-"Lines starting with '%c' will be ignored.\n"
-msgstr ""
-
-#: builtin/tag.c:175
-#, c-format
-msgid ""
-"\n"
-"Write a message for tag:\n"
-"  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
-"want to.\n"
-msgstr ""
-
-#: builtin/tag.c:241
-msgid "unable to sign the tag"
-msgstr ""
-
-#: builtin/tag.c:259
-#, c-format
-msgid ""
-"You have created a nested tag. The object referred to by your new tag is\n"
-"already a tag. If you meant to tag the object that it points to, use:\n"
-"\n"
-"\tgit tag -f %s %s^{}"
-msgstr ""
-
-#: builtin/tag.c:275
-msgid "bad object type."
-msgstr ""
-
-#: builtin/tag.c:326
-msgid "no tag message?"
-msgstr ""
-
-#: builtin/tag.c:333
-#, c-format
-msgid "The tag message has been left in %s\n"
-msgstr ""
-
-#: builtin/tag.c:445
-msgid "list tag names"
-msgstr ""
-
-#: builtin/tag.c:447
-msgid "print <n> lines of each tag message"
-msgstr ""
-
-#: builtin/tag.c:449
-msgid "delete tags"
-msgstr ""
-
-#: builtin/tag.c:450
-msgid "verify tags"
-msgstr ""
-
-#: builtin/tag.c:452
-msgid "Tag creation options"
-msgstr ""
-
-#: builtin/tag.c:454
-msgid "annotated tag, needs a message"
-msgstr ""
-
-#: builtin/tag.c:456
-msgid "tag message"
-msgstr ""
-
-#: builtin/tag.c:458
-msgid "force edit of tag message"
-msgstr ""
-
-#: builtin/tag.c:459
-msgid "annotated and GPG-signed tag"
-msgstr ""
-
-#: builtin/tag.c:462
-msgid "use another key to sign the tag"
-msgstr ""
-
-#: builtin/tag.c:463
-msgid "replace the tag if exists"
-msgstr ""
-
-#: builtin/tag.c:464 builtin/update-ref.c:511
-msgid "create a reflog"
-msgstr ""
-
-#: builtin/tag.c:466
-msgid "Tag listing options"
-msgstr ""
-
-#: builtin/tag.c:467
-msgid "show tag list in columns"
-msgstr ""
-
-#: builtin/tag.c:468 builtin/tag.c:470
-msgid "print only tags that contain the commit"
-msgstr ""
-
-#: builtin/tag.c:469 builtin/tag.c:471
-msgid "print only tags that don't contain the commit"
-msgstr ""
-
-#: builtin/tag.c:472
-msgid "print only tags that are merged"
-msgstr ""
-
-#: builtin/tag.c:473
-msgid "print only tags that are not merged"
-msgstr ""
-
-#: builtin/tag.c:477
-msgid "print only tags of the object"
-msgstr ""
-
-#: builtin/tag.c:559
-#, c-format
-msgid "the '%s' option is only allowed in list mode"
-msgstr ""
-
-#: builtin/tag.c:598
-#, c-format
-msgid "'%s' is not a valid tag name."
-msgstr ""
-
-#: builtin/tag.c:603
-#, c-format
-msgid "tag '%s' already exists"
-msgstr ""
-
-#: builtin/tag.c:634
-#, c-format
-msgid "Updated tag '%s' (was %s)\n"
-msgstr ""
-
-#: builtin/unpack-objects.c:95
-msgid "pack exceeds maximum allowed size"
-msgstr ""
-
-#: builtin/unpack-objects.c:504
-msgid "Unpacking objects"
-msgstr ""
-
-#: builtin/update-index.c:84
-#, c-format
-msgid "failed to create directory %s"
-msgstr ""
-
-#: builtin/update-index.c:106
-#, c-format
-msgid "failed to delete file %s"
-msgstr ""
-
-#: builtin/update-index.c:113 builtin/update-index.c:219
-#, c-format
-msgid "failed to delete directory %s"
-msgstr ""
-
-#: builtin/update-index.c:138
-#, c-format
-msgid "Testing mtime in '%s' "
-msgstr ""
-
-#: builtin/update-index.c:152
-msgid "directory stat info does not change after adding a new file"
-msgstr ""
-
-#: builtin/update-index.c:165
-msgid "directory stat info does not change after adding a new directory"
-msgstr ""
-
-#: builtin/update-index.c:178
-msgid "directory stat info changes after updating a file"
-msgstr ""
-
-#: builtin/update-index.c:189
-msgid "directory stat info changes after adding a file inside subdirectory"
-msgstr ""
-
-#: builtin/update-index.c:200
-msgid "directory stat info does not change after deleting a file"
-msgstr ""
-
-#: builtin/update-index.c:213
-msgid "directory stat info does not change after deleting a directory"
-msgstr ""
-
-#: builtin/update-index.c:220
-msgid " OK"
-msgstr ""
-
-#: builtin/update-index.c:589
-msgid "git update-index [<options>] [--] [<file>...]"
-msgstr ""
-
-#: builtin/update-index.c:993
-msgid "continue refresh even when index needs update"
-msgstr ""
-
-#: builtin/update-index.c:996
-msgid "refresh: ignore submodules"
-msgstr ""
-
-#: builtin/update-index.c:999
-msgid "do not ignore new files"
-msgstr ""
-
-#: builtin/update-index.c:1001
-msgid "let files replace directories and vice-versa"
-msgstr ""
-
-#: builtin/update-index.c:1003
-msgid "notice files missing from worktree"
-msgstr ""
-
-#: builtin/update-index.c:1005
-msgid "refresh even if index contains unmerged entries"
-msgstr ""
-
-#: builtin/update-index.c:1008
-msgid "refresh stat information"
-msgstr ""
-
-#: builtin/update-index.c:1012
-msgid "like --refresh, but ignore assume-unchanged setting"
-msgstr ""
-
-#: builtin/update-index.c:1016
-msgid "<mode>,<object>,<path>"
-msgstr ""
-
-#: builtin/update-index.c:1017
-msgid "add the specified entry to the index"
-msgstr ""
-
-#: builtin/update-index.c:1027
-msgid "mark files as \"not changing\""
-msgstr ""
-
-#: builtin/update-index.c:1030
-msgid "clear assumed-unchanged bit"
-msgstr ""
-
-#: builtin/update-index.c:1033
-msgid "mark files as \"index-only\""
-msgstr ""
-
-#: builtin/update-index.c:1036
-msgid "clear skip-worktree bit"
-msgstr ""
-
-#: builtin/update-index.c:1039
-msgid "do not touch index-only entries"
-msgstr ""
-
-#: builtin/update-index.c:1041
-msgid "add to index only; do not add content to object database"
-msgstr ""
-
-#: builtin/update-index.c:1043
-msgid "remove named paths even if present in worktree"
-msgstr ""
-
-#: builtin/update-index.c:1045
-msgid "with --stdin: input lines are terminated by null bytes"
-msgstr ""
-
-#: builtin/update-index.c:1047
-msgid "read list of paths to be updated from standard input"
-msgstr ""
-
-#: builtin/update-index.c:1051
-msgid "add entries from standard input to the index"
-msgstr ""
-
-#: builtin/update-index.c:1055
-msgid "repopulate stages #2 and #3 for the listed paths"
-msgstr ""
-
-#: builtin/update-index.c:1059
-msgid "only update entries that differ from HEAD"
-msgstr ""
-
-#: builtin/update-index.c:1063
-msgid "ignore files missing from worktree"
-msgstr ""
-
-#: builtin/update-index.c:1066
-msgid "report actions to standard output"
-msgstr ""
-
-#: builtin/update-index.c:1068
-msgid "(for porcelains) forget saved unresolved conflicts"
-msgstr ""
-
-#: builtin/update-index.c:1072
-msgid "write index in this format"
-msgstr ""
-
-#: builtin/update-index.c:1074
-msgid "enable or disable split index"
-msgstr ""
-
-#: builtin/update-index.c:1076
-msgid "enable/disable untracked cache"
-msgstr ""
-
-#: builtin/update-index.c:1078
-msgid "test if the filesystem supports untracked cache"
-msgstr ""
-
-#: builtin/update-index.c:1080
-msgid "enable untracked cache without testing the filesystem"
-msgstr ""
-
-#: builtin/update-index.c:1082
-msgid "write out the index even if is not flagged as changed"
-msgstr ""
-
-#: builtin/update-index.c:1084
-msgid "enable or disable file system monitor"
-msgstr ""
-
-#: builtin/update-index.c:1086
-msgid "mark files as fsmonitor valid"
-msgstr ""
-
-#: builtin/update-index.c:1089
-msgid "clear fsmonitor valid bit"
-msgstr ""
-
-#: builtin/update-index.c:1195
-msgid ""
-"core.splitIndex is set to false; remove or change it, if you really want to "
-"enable split index"
-msgstr ""
-
-#: builtin/update-index.c:1204
-msgid ""
-"core.splitIndex is set to true; remove or change it, if you really want to "
-"disable split index"
-msgstr ""
-
-#: builtin/update-index.c:1216
-msgid ""
-"core.untrackedCache is set to true; remove or change it, if you really want "
-"to disable the untracked cache"
-msgstr ""
-
-#: builtin/update-index.c:1220
-msgid "Untracked cache disabled"
-msgstr ""
-
-#: builtin/update-index.c:1228
-msgid ""
-"core.untrackedCache is set to false; remove or change it, if you really want "
-"to enable the untracked cache"
-msgstr ""
-
-#: builtin/update-index.c:1232
-#, c-format
-msgid "Untracked cache enabled for '%s'"
-msgstr ""
-
-#: builtin/update-index.c:1241
-msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
-msgstr ""
-
-#: builtin/update-index.c:1246
-msgid "fsmonitor enabled"
-msgstr ""
-
-#: builtin/update-index.c:1250
-msgid ""
-"core.fsmonitor is set; remove it if you really want to disable fsmonitor"
-msgstr ""
-
-#: builtin/update-index.c:1254
-msgid "fsmonitor disabled"
-msgstr ""
-
-#: builtin/update-ref.c:10
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr ""
-
-#: builtin/update-ref.c:11
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr ""
-
-#: builtin/update-ref.c:12
-msgid "git update-ref [<options>] --stdin [-z]"
-msgstr ""
-
-#: builtin/update-ref.c:506
-msgid "delete the reference"
-msgstr ""
-
-#: builtin/update-ref.c:508
-msgid "update <refname> not the one it points to"
-msgstr ""
-
-#: builtin/update-ref.c:509
-msgid "stdin has NUL-terminated arguments"
-msgstr ""
-
-#: builtin/update-ref.c:510
-msgid "read updates from stdin"
-msgstr ""
-
-#: builtin/update-server-info.c:15
-msgid "update the info files from scratch"
-msgstr ""
-
-#: builtin/upload-pack.c:11
-msgid "git upload-pack [<options>] <dir>"
-msgstr ""
-
-#: builtin/upload-pack.c:24 t/helper/test-serve-v2.c:17
-msgid "quit after a single request/response exchange"
-msgstr ""
-
-#: builtin/upload-pack.c:26
-msgid "serve up the info/refs for git-http-backend"
-msgstr ""
-
-#: builtin/upload-pack.c:29
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr ""
-
-#: builtin/upload-pack.c:31
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr ""
-
-#: builtin/verify-commit.c:19
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr ""
-
-#: builtin/verify-commit.c:68
-msgid "print commit contents"
-msgstr ""
-
-#: builtin/verify-commit.c:69 builtin/verify-tag.c:37
-msgid "print raw gpg status output"
-msgstr ""
-
-#: builtin/verify-pack.c:59
-msgid "git verify-pack [-v | --verbose] [-s | --stat-only] <pack>..."
-msgstr ""
-
-#: builtin/verify-pack.c:70
-msgid "verbose"
-msgstr ""
-
-#: builtin/verify-pack.c:72
-msgid "show statistics only"
-msgstr ""
-
-#: builtin/verify-tag.c:18
-msgid "git verify-tag [-v | --verbose] [--format=<format>] <tag>..."
-msgstr ""
-
-#: builtin/verify-tag.c:36
-msgid "print tag contents"
-msgstr ""
-
-#: builtin/worktree.c:19
-msgid "git worktree add [<options>] <path> [<commit-ish>]"
-msgstr ""
-
-#: builtin/worktree.c:20
-msgid "git worktree list [<options>]"
-msgstr ""
-
-#: builtin/worktree.c:21
-msgid "git worktree lock [<options>] <path>"
-msgstr ""
-
-#: builtin/worktree.c:22
-msgid "git worktree move <worktree> <new-path>"
-msgstr ""
-
-#: builtin/worktree.c:23
-msgid "git worktree prune [<options>]"
-msgstr ""
-
-#: builtin/worktree.c:24
-msgid "git worktree remove [<options>] <worktree>"
-msgstr ""
-
-#: builtin/worktree.c:25
-msgid "git worktree repair [<path>...]"
-msgstr ""
-
-#: builtin/worktree.c:26
-msgid "git worktree unlock <path>"
-msgstr ""
-
-#: builtin/worktree.c:76
-#, c-format
-msgid "Removing %s/%s: %s"
-msgstr ""
-
-#: builtin/worktree.c:149
-msgid "report pruned working trees"
-msgstr ""
-
-#: builtin/worktree.c:151
-msgid "expire working trees older than <time>"
-msgstr ""
-
-#: builtin/worktree.c:221
-#, c-format
-msgid "'%s' already exists"
-msgstr ""
-
-#: builtin/worktree.c:230
-#, c-format
-msgid "unusable worktree destination '%s'"
-msgstr ""
-
-#: builtin/worktree.c:235
-#, c-format
-msgid ""
-"'%s' is a missing but locked worktree;\n"
-"use '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"
-msgstr ""
-
-#: builtin/worktree.c:237
-#, c-format
-msgid ""
-"'%s' is a missing but already registered worktree;\n"
-"use '%s -f' to override, or 'prune' or 'remove' to clear"
-msgstr ""
-
-#: builtin/worktree.c:248
-#, c-format
-msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly"
-msgstr ""
-
-#: builtin/worktree.c:268
-#, c-format
-msgid "failed to copy worktree config from '%s' to '%s'"
-msgstr ""
-
-#: builtin/worktree.c:280 builtin/worktree.c:285
-#, c-format
-msgid "failed to unset '%s' in '%s'"
-msgstr ""
-
-#: builtin/worktree.c:356
-#, c-format
-msgid "could not create directory of '%s'"
-msgstr ""
-
-#: builtin/worktree.c:378
-msgid "initializing"
-msgstr ""
-
-#: builtin/worktree.c:492 builtin/worktree.c:498
-#, c-format
-msgid "Preparing worktree (new branch '%s')"
-msgstr ""
-
-#: builtin/worktree.c:494
-#, c-format
-msgid "Preparing worktree (resetting branch '%s'; was at %s)"
-msgstr ""
-
-#: builtin/worktree.c:503
-#, c-format
-msgid "Preparing worktree (checking out '%s')"
-msgstr ""
-
-#: builtin/worktree.c:509
-#, c-format
-msgid "Preparing worktree (detached HEAD %s)"
-msgstr ""
-
-#: builtin/worktree.c:554
-msgid "checkout <branch> even if already checked out in other worktree"
-msgstr ""
-
-#: builtin/worktree.c:557
-msgid "create a new branch"
-msgstr ""
-
-#: builtin/worktree.c:559
-msgid "create or reset a branch"
-msgstr ""
-
-#: builtin/worktree.c:561
-msgid "populate the new working tree"
-msgstr ""
-
-#: builtin/worktree.c:562
-msgid "keep the new working tree locked"
-msgstr ""
-
-#: builtin/worktree.c:564 builtin/worktree.c:809
-msgid "reason for locking"
-msgstr ""
-
-#: builtin/worktree.c:567
-msgid "set up tracking mode (see git-branch(1))"
-msgstr ""
-
-#: builtin/worktree.c:570
-msgid "try to match the new branch name with a remote-tracking branch"
-msgstr ""
-
-#: builtin/worktree.c:584
-msgid "added with --lock"
-msgstr ""
-
-#: builtin/worktree.c:646
-msgid "--[no-]track can only be used if a new branch is created"
-msgstr ""
-
-#: builtin/worktree.c:766
-msgid "show extended annotations and reasons, if available"
-msgstr ""
-
-#: builtin/worktree.c:768
-msgid "add 'prunable' annotation to worktrees older than <time>"
-msgstr ""
-
-#: builtin/worktree.c:770
-msgid "terminate records with a NUL character"
-msgstr ""
-
-#: builtin/worktree.c:821 builtin/worktree.c:854 builtin/worktree.c:928
-#: builtin/worktree.c:1052
-#, c-format
-msgid "'%s' is not a working tree"
-msgstr ""
-
-#: builtin/worktree.c:823 builtin/worktree.c:856
-msgid "The main working tree cannot be locked or unlocked"
-msgstr ""
-
-#: builtin/worktree.c:828
-#, c-format
-msgid "'%s' is already locked, reason: %s"
-msgstr ""
-
-#: builtin/worktree.c:830
-#, c-format
-msgid "'%s' is already locked"
-msgstr ""
-
-#: builtin/worktree.c:858
-#, c-format
-msgid "'%s' is not locked"
-msgstr ""
-
-#: builtin/worktree.c:899
-msgid "working trees containing submodules cannot be moved or removed"
-msgstr ""
-
-#: builtin/worktree.c:907
-msgid "force move even if worktree is dirty or locked"
-msgstr ""
-
-#: builtin/worktree.c:930 builtin/worktree.c:1054
-#, c-format
-msgid "'%s' is a main working tree"
-msgstr ""
-
-#: builtin/worktree.c:935
-#, c-format
-msgid "could not figure out destination name from '%s'"
-msgstr ""
-
-#: builtin/worktree.c:948
-#, c-format
-msgid ""
-"cannot move a locked working tree, lock reason: %s\n"
-"use 'move -f -f' to override or unlock first"
-msgstr ""
-
-#: builtin/worktree.c:950
-msgid ""
-"cannot move a locked working tree;\n"
-"use 'move -f -f' to override or unlock first"
-msgstr ""
-
-#: builtin/worktree.c:953
-#, c-format
-msgid "validation failed, cannot move working tree: %s"
-msgstr ""
-
-#: builtin/worktree.c:958
-#, c-format
-msgid "failed to move '%s' to '%s'"
-msgstr ""
-
-#: builtin/worktree.c:1004
-#, c-format
-msgid "failed to run 'git status' on '%s'"
-msgstr ""
-
-#: builtin/worktree.c:1008
-#, c-format
-msgid "'%s' contains modified or untracked files, use --force to delete it"
-msgstr ""
-
-#: builtin/worktree.c:1013
-#, c-format
-msgid "failed to run 'git status' on '%s', code %d"
-msgstr ""
-
-#: builtin/worktree.c:1036
-msgid "force removal even if worktree is dirty or locked"
-msgstr ""
-
-#: builtin/worktree.c:1059
-#, c-format
-msgid ""
-"cannot remove a locked working tree, lock reason: %s\n"
-"use 'remove -f -f' to override or unlock first"
-msgstr ""
-
-#: builtin/worktree.c:1061
-msgid ""
-"cannot remove a locked working tree;\n"
-"use 'remove -f -f' to override or unlock first"
-msgstr ""
-
-#: builtin/worktree.c:1064
-#, c-format
-msgid "validation failed, cannot remove working tree: %s"
-msgstr ""
-
-#: builtin/worktree.c:1088
-#, c-format
-msgid "repair: %s: %s"
-msgstr ""
-
-#: builtin/worktree.c:1091
-#, c-format
-msgid "error: %s: %s"
-msgstr ""
-
-#: builtin/write-tree.c:15
-msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]"
-msgstr ""
-
-#: builtin/write-tree.c:28
-msgid "<prefix>/"
-msgstr ""
-
-#: builtin/write-tree.c:29
-msgid "write tree object for a subdirectory <prefix>"
-msgstr ""
-
-#: builtin/write-tree.c:31
-msgid "only useful for debugging"
-msgstr ""
-
-#: git.c:28
-msgid ""
-"git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
-"           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
-"bare]\n"
-"           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-"           [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
-"           <command> [<args>]"
-msgstr ""
-
-#: git.c:36
-msgid ""
-"'git help -a' and 'git help -g' list available subcommands and some\n"
-"concept guides. See 'git help <command>' or 'git help <concept>'\n"
-"to read about a specific subcommand or concept.\n"
-"See 'git help git' for an overview of the system."
-msgstr ""
-
-#: git.c:188 git.c:216 git.c:300
-#, c-format
-msgid "no directory given for '%s' option\n"
-msgstr ""
-
-#: git.c:202
-#, c-format
-msgid "no namespace given for --namespace\n"
-msgstr ""
-
-#: git.c:230
-#, c-format
-msgid "no prefix given for --super-prefix\n"
-msgstr ""
-
-#: git.c:252
-#, c-format
-msgid "-c expects a configuration string\n"
-msgstr ""
-
-#: git.c:260
-#, c-format
-msgid "no config key given for --config-env\n"
-msgstr ""
-
-#: git.c:326
-#, c-format
-msgid "unknown option: %s\n"
-msgstr ""
-
-#: git.c:375
-#, c-format
-msgid "while expanding alias '%s': '%s'"
-msgstr ""
-
-#: git.c:384
-#, c-format
-msgid ""
-"alias '%s' changes environment variables.\n"
-"You can use '!git' in the alias to do this"
-msgstr ""
-
-#: git.c:391
-#, c-format
-msgid "empty alias for %s"
-msgstr ""
-
-#: git.c:394
-#, c-format
-msgid "recursive alias: %s"
-msgstr ""
-
-#: git.c:480
-msgid "write failure on standard output"
-msgstr ""
-
-#: git.c:482
-msgid "unknown write failure on standard output"
-msgstr ""
-
-#: git.c:484
-msgid "close failed on standard output"
-msgstr ""
-
-#: git.c:838
-#, c-format
-msgid "alias loop detected: expansion of '%s' does not terminate:%s"
-msgstr ""
-
-#: git.c:888
-#, c-format
-msgid "cannot handle %s as a builtin"
-msgstr ""
-
-#: git.c:901
-#, c-format
-msgid ""
-"usage: %s\n"
-"\n"
-msgstr ""
-
-#: git.c:921
-#, c-format
-msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
-msgstr ""
-
-#: git.c:933
-#, c-format
-msgid "failed to run command '%s': %s\n"
-msgstr ""
-
-#: http-fetch.c:128
-#, c-format
-msgid "argument to --packfile must be a valid hash (got '%s')"
-msgstr ""
-
-#: http-fetch.c:138
-msgid "not a git repository"
-msgstr ""
-
-#: t/helper/test-fast-rebase.c:141
-msgid "unhandled options"
-msgstr ""
-
-#: t/helper/test-fast-rebase.c:146
-msgid "error preparing revisions"
-msgstr ""
-
-#: t/helper/test-reach.c:154
-#, c-format
-msgid "commit %s is not marked reachable"
-msgstr ""
-
-#: t/helper/test-reach.c:164
-msgid "too many commits marked reachable"
-msgstr ""
-
-#: t/helper/test-serve-v2.c:7
-msgid "test-tool serve-v2 [<options>]"
-msgstr ""
-
-#: t/helper/test-serve-v2.c:19
-msgid "exit immediately after advertising capabilities"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:581
-msgid "test-helper simple-ipc is-active    [<name>] [<options>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:582
-msgid "test-helper simple-ipc run-daemon   [<name>] [<threads>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:583
-msgid "test-helper simple-ipc start-daemon [<name>] [<threads>] [<max-wait>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:584
-msgid "test-helper simple-ipc stop-daemon  [<name>] [<max-wait>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:585
-msgid "test-helper simple-ipc send         [<name>] [<token>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:586
-msgid "test-helper simple-ipc sendbytes    [<name>] [<bytecount>] [<byte>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:587
-msgid ""
-"test-helper simple-ipc multiple     [<name>] [<threads>] [<bytecount>] "
-"[<batchsize>]"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:595
-msgid "name or pathname of unix domain socket"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:597
-msgid "named-pipe name"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:599
-msgid "number of threads in server thread pool"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:600
-msgid "seconds to wait for daemon to start or stop"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:602
-msgid "number of bytes"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:603
-msgid "number of requests per thread"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:605
-msgid "byte"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:605
-msgid "ballast character"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:606
-msgid "token"
-msgstr ""
-
-#: t/helper/test-simple-ipc.c:606
-msgid "command token to send to the server"
-msgstr ""
-
-#: http.c:350
-#, c-format
-msgid "negative value for http.postbuffer; defaulting to %d"
-msgstr ""
-
-#: http.c:371
-msgid "Delegation control is not supported with cURL < 7.22.0"
-msgstr ""
-
-#: http.c:380
-msgid "Public key pinning not supported with cURL < 7.39.0"
-msgstr ""
-
-#: http.c:812
-msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"
-msgstr ""
-
-#: http.c:1016
-#, c-format
-msgid "Unsupported SSL backend '%s'. Supported SSL backends:"
-msgstr ""
-
-#: http.c:1023
-#, c-format
-msgid "Could not set SSL backend to '%s': cURL was built without SSL backends"
-msgstr ""
-
-#: http.c:1027
-#, c-format
-msgid "Could not set SSL backend to '%s': already set"
-msgstr ""
-
-#: http.c:1876
-#, c-format
-msgid ""
-"unable to update url base from redirection:\n"
-"  asked for: %s\n"
-"   redirect: %s"
-msgstr ""
-
-#: remote-curl.c:184
-#, c-format
-msgid "invalid quoting in push-option value: '%s'"
-msgstr ""
-
-#: remote-curl.c:308
-#, c-format
-msgid "%sinfo/refs not valid: is this a git repository?"
-msgstr ""
-
-#: remote-curl.c:409
-msgid "invalid server response; expected service, got flush packet"
-msgstr ""
-
-#: remote-curl.c:440
-#, c-format
-msgid "invalid server response; got '%s'"
-msgstr ""
-
-#: remote-curl.c:500
-#, c-format
-msgid "repository '%s' not found"
-msgstr ""
-
-#: remote-curl.c:504
-#, c-format
-msgid "Authentication failed for '%s'"
-msgstr ""
-
-#: remote-curl.c:508
-#, c-format
-msgid "unable to access '%s' with http.pinnedPubkey configuration: %s"
-msgstr ""
-
-#: remote-curl.c:512
-#, c-format
-msgid "unable to access '%s': %s"
-msgstr ""
-
-#: remote-curl.c:518
-#, c-format
-msgid "redirecting to %s"
-msgstr ""
-
-#: remote-curl.c:649
-msgid "shouldn't have EOF when not gentle on EOF"
-msgstr ""
-
-#: remote-curl.c:661
-msgid "remote server sent unexpected response end packet"
-msgstr ""
-
-#: remote-curl.c:730
-msgid "unable to rewind rpc post data - try increasing http.postBuffer"
-msgstr ""
-
-#: remote-curl.c:759
-#, c-format
-msgid "remote-curl: bad line length character: %.4s"
-msgstr ""
-
-#: remote-curl.c:761
-msgid "remote-curl: unexpected response end packet"
-msgstr ""
-
-#: remote-curl.c:837
-#, c-format
-msgid "RPC failed; %s"
-msgstr ""
-
-#: remote-curl.c:877
-msgid "cannot handle pushes this big"
-msgstr ""
-
-#: remote-curl.c:990
-#, c-format
-msgid "cannot deflate request; zlib deflate error %d"
-msgstr ""
-
-#: remote-curl.c:994
-#, c-format
-msgid "cannot deflate request; zlib end error %d"
-msgstr ""
-
-#: remote-curl.c:1044
-#, c-format
-msgid "%d bytes of length header were received"
-msgstr ""
-
-#: remote-curl.c:1046
-#, c-format
-msgid "%d bytes of body are still expected"
-msgstr ""
-
-#: remote-curl.c:1135
-msgid "dumb http transport does not support shallow capabilities"
-msgstr ""
-
-#: remote-curl.c:1150
-msgid "fetch failed."
-msgstr ""
-
-#: remote-curl.c:1198
-msgid "cannot fetch by sha1 over smart http"
-msgstr ""
-
-#: remote-curl.c:1242 remote-curl.c:1248
-#, c-format
-msgid "protocol error: expected sha/ref, got '%s'"
-msgstr ""
-
-#: remote-curl.c:1260 remote-curl.c:1378
-#, c-format
-msgid "http transport does not support %s"
-msgstr ""
-
-#: remote-curl.c:1296
-msgid "git-http-push failed"
-msgstr ""
-
-#: remote-curl.c:1485
-msgid "remote-curl: usage: git remote-curl <remote> [<url>]"
-msgstr ""
-
-#: remote-curl.c:1517
-msgid "remote-curl: error reading command stream from git"
-msgstr ""
-
-#: remote-curl.c:1524
-msgid "remote-curl: fetch attempted without a local repo"
-msgstr ""
-
-#: remote-curl.c:1565
-#, c-format
-msgid "remote-curl: unknown command '%s' from git"
-msgstr ""
-
-#: contrib/scalar/scalar.c:49
-msgid "need a working directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c:86
-msgid "could not find enlistment root"
-msgstr ""
-
-#: contrib/scalar/scalar.c:89 contrib/scalar/scalar.c:350
-#: contrib/scalar/scalar.c:435 contrib/scalar/scalar.c:578
-#, c-format
-msgid "could not switch to '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:179
-#, c-format
-msgid "could not configure %s=%s"
-msgstr ""
-
-#: contrib/scalar/scalar.c:197
-msgid "could not configure log.excludeDecoration"
-msgstr ""
-
-#: contrib/scalar/scalar.c:218
-msgid "Scalar enlistments require a worktree"
-msgstr ""
-
-#: contrib/scalar/scalar.c:310
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:316
-msgid "failed to get default branch name from remote; using local default"
-msgstr ""
-
-#: contrib/scalar/scalar.c:329
-msgid "failed to get default branch name"
-msgstr ""
-
-#: contrib/scalar/scalar.c:340
-msgid "failed to unregister repository"
-msgstr ""
-
-#: contrib/scalar/scalar.c:355
-msgid "failed to delete enlistment directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c:375
-msgid "branch to checkout after clone"
-msgstr ""
-
-#: contrib/scalar/scalar.c:377
-msgid "when cloning, create full working directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c:379
-msgid "only download metadata for the branch that will be checked out"
-msgstr ""
-
-#: contrib/scalar/scalar.c:384
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c:409
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:418
-#, c-format
-msgid "directory '%s' exists already"
-msgstr ""
-
-#: contrib/scalar/scalar.c:445
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:456
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:465
-#, c-format
-msgid "could not configure '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:468
-msgid "partial clone failed; attempting full clone"
-msgstr ""
-
-#: contrib/scalar/scalar.c:472
-msgid "could not configure for full clone"
-msgstr ""
-
-#: contrib/scalar/scalar.c:504
-msgid "`scalar list` does not take arguments"
-msgstr ""
-
-#: contrib/scalar/scalar.c:517
-msgid "scalar register [<enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c:544
-msgid "reconfigure all registered enlistments"
-msgstr ""
-
-#: contrib/scalar/scalar.c:548
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c:566
-msgid "--all or <enlistment>, but not both"
-msgstr ""
-
-#: contrib/scalar/scalar.c:581
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:621
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-
-#: contrib/scalar/scalar.c:639
-#, c-format
-msgid "no such task: '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:689
-msgid "scalar unregister [<enlistment>]"
-msgstr ""
-
-#: contrib/scalar/scalar.c:736
-msgid "scalar delete <enlistment>"
-msgstr ""
-
-#: contrib/scalar/scalar.c:751
-msgid "refusing to delete current working directory"
-msgstr ""
-
-#: contrib/scalar/scalar.c:766
-msgid "include Git version"
-msgstr ""
-
-#: contrib/scalar/scalar.c:768
-msgid "include Git's build options"
-msgstr ""
-
-#: contrib/scalar/scalar.c:772
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr ""
-
-#: contrib/scalar/scalar.c:813
-msgid "-C requires a <directory>"
-msgstr ""
-
-#: contrib/scalar/scalar.c:815
-#, c-format
-msgid "could not change to '%s'"
-msgstr ""
-
-#: contrib/scalar/scalar.c:821
-msgid "-c requires a <key>=<value> argument"
-msgstr ""
-
-#: contrib/scalar/scalar.c:839
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-
-#: compat/compiler.h:26
-msgid "no compiler information available\n"
-msgstr ""
-
-#: compat/compiler.h:38
-msgid "no libc information available\n"
-msgstr ""
-
-#: list-objects-filter-options.h:126
-msgid "args"
-msgstr ""
-
-#: list-objects-filter-options.h:127
-msgid "object filtering"
-msgstr ""
-
-#: parse-options.h:188
-msgid "expiry-date"
-msgstr ""
-
-#: parse-options.h:202
-msgid "no-op (backward compatibility)"
-msgstr ""
-
-#: parse-options.h:341
-msgid "be more verbose"
-msgstr ""
-
-#: parse-options.h:343
-msgid "be more quiet"
-msgstr ""
-
-#: parse-options.h:349
-msgid "use <n> digits to display object names"
-msgstr ""
-
-#: parse-options.h:368
-msgid "how to strip spaces and #comments from message"
-msgstr ""
-
-#: parse-options.h:369
-msgid "read pathspec from file"
-msgstr ""
-
-#: parse-options.h:370
-msgid ""
-"with --pathspec-from-file, pathspec elements are separated with NUL character"
-msgstr ""
-
-#: ref-filter.h:98
-msgid "key"
-msgstr ""
-
-#: ref-filter.h:98
-msgid "field name to sort on"
-msgstr ""
-
-#: rerere.h:44
-msgid "update the index with reused conflict resolution if possible"
-msgstr ""
-
-#: command-list.h:50
-msgid "Add file contents to the index"
-msgstr ""
-
-#: command-list.h:51
-msgid "Apply a series of patches from a mailbox"
-msgstr ""
-
-#: command-list.h:52
-msgid "Annotate file lines with commit information"
-msgstr ""
-
-#: command-list.h:53
-msgid "Apply a patch to files and/or to the index"
-msgstr ""
-
-#: command-list.h:54
-msgid "Import a GNU Arch repository into Git"
-msgstr ""
-
-#: command-list.h:55
-msgid "Create an archive of files from a named tree"
-msgstr ""
-
-#: command-list.h:56
-msgid "Use binary search to find the commit that introduced a bug"
-msgstr ""
-
-#: command-list.h:57
-msgid "Show what revision and author last modified each line of a file"
-msgstr ""
-
-#: command-list.h:58
-msgid "List, create, or delete branches"
-msgstr ""
-
-#: command-list.h:59
-msgid "Collect information for user to file a bug report"
-msgstr ""
-
-#: command-list.h:60
-msgid "Move objects and refs by archive"
-msgstr ""
-
-#: command-list.h:61
-msgid "Provide content or type and size information for repository objects"
-msgstr ""
-
-#: command-list.h:62
-msgid "Display gitattributes information"
-msgstr ""
-
-#: command-list.h:63
-msgid "Debug gitignore / exclude files"
-msgstr ""
-
-#: command-list.h:64
-msgid "Show canonical names and email addresses of contacts"
-msgstr ""
-
-#: command-list.h:65
-msgid "Ensures that a reference name is well formed"
-msgstr ""
-
-#: command-list.h:66
-msgid "Switch branches or restore working tree files"
-msgstr ""
-
-#: command-list.h:67
-msgid "Copy files from the index to the working tree"
-msgstr ""
-
-#: command-list.h:68
-msgid "Find commits yet to be applied to upstream"
-msgstr ""
-
-#: command-list.h:69
-msgid "Apply the changes introduced by some existing commits"
-msgstr ""
-
-#: command-list.h:70
-msgid "Graphical alternative to git-commit"
-msgstr ""
-
-#: command-list.h:71
-msgid "Remove untracked files from the working tree"
-msgstr ""
-
-#: command-list.h:72
-msgid "Clone a repository into a new directory"
-msgstr ""
-
-#: command-list.h:73
-msgid "Display data in columns"
-msgstr ""
-
-#: command-list.h:74
-msgid "Record changes to the repository"
-msgstr ""
-
-#: command-list.h:75
-msgid "Write and verify Git commit-graph files"
-msgstr ""
-
-#: command-list.h:76
-msgid "Create a new commit object"
-msgstr ""
-
-#: command-list.h:77
-msgid "Get and set repository or global options"
-msgstr ""
-
-#: command-list.h:78
-msgid "Count unpacked number of objects and their disk consumption"
-msgstr ""
-
-#: command-list.h:79
-msgid "Retrieve and store user credentials"
-msgstr ""
-
-#: command-list.h:80
-msgid "Helper to temporarily store passwords in memory"
-msgstr ""
-
-#: command-list.h:81
-msgid "Helper to store credentials on disk"
-msgstr ""
-
-#: command-list.h:82
-msgid "Export a single commit to a CVS checkout"
-msgstr ""
-
-#: command-list.h:83
-msgid "Salvage your data out of another SCM people love to hate"
-msgstr ""
-
-#: command-list.h:84
-msgid "A CVS server emulator for Git"
-msgstr ""
-
-#: command-list.h:85
-msgid "A really simple server for Git repositories"
-msgstr ""
-
-#: command-list.h:86
-msgid "Give an object a human readable name based on an available ref"
-msgstr ""
-
-#: command-list.h:87
-msgid "Show changes between commits, commit and working tree, etc"
-msgstr ""
-
-#: command-list.h:88
-msgid "Compares files in the working tree and the index"
-msgstr ""
-
-#: command-list.h:89
-msgid "Compare a tree to the working tree or index"
-msgstr ""
-
-#: command-list.h:90
-msgid "Compares the content and mode of blobs found via two tree objects"
-msgstr ""
-
-#: command-list.h:91
-msgid "Show changes using common diff tools"
-msgstr ""
-
-#: command-list.h:92
-msgid "Git data exporter"
-msgstr ""
-
-#: command-list.h:93
-msgid "Backend for fast Git data importers"
-msgstr ""
-
-#: command-list.h:94
-msgid "Download objects and refs from another repository"
-msgstr ""
-
-#: command-list.h:95
-msgid "Receive missing objects from another repository"
-msgstr ""
-
-#: command-list.h:96
-msgid "Rewrite branches"
-msgstr ""
-
-#: command-list.h:97
-msgid "Produce a merge commit message"
-msgstr ""
-
-#: command-list.h:98
-msgid "Output information on each ref"
-msgstr ""
-
-#: command-list.h:99
-msgid "Run a Git command on a list of repositories"
-msgstr ""
-
-#: command-list.h:100
-msgid "Prepare patches for e-mail submission"
-msgstr ""
-
-#: command-list.h:101
-msgid "Verifies the connectivity and validity of the objects in the database"
-msgstr ""
-
-#: command-list.h:102
-msgid "Cleanup unnecessary files and optimize the local repository"
-msgstr ""
-
-#: command-list.h:103
-msgid "Extract commit ID from an archive created using git-archive"
-msgstr ""
-
-#: command-list.h:104
-msgid "Print lines matching a pattern"
-msgstr ""
-
-#: command-list.h:105
-msgid "A portable graphical interface to Git"
-msgstr ""
-
-#: command-list.h:106
-msgid "Compute object ID and optionally creates a blob from a file"
-msgstr ""
-
-#: command-list.h:107
-msgid "Display help information about Git"
-msgstr ""
-
-#: command-list.h:108
-msgid "Run git hooks"
-msgstr ""
-
-#: command-list.h:109
-msgid "Server side implementation of Git over HTTP"
-msgstr ""
-
-#: command-list.h:110
-msgid "Download from a remote Git repository via HTTP"
-msgstr ""
-
-#: command-list.h:111
-msgid "Push objects over HTTP/DAV to another repository"
-msgstr ""
-
-#: command-list.h:112
-msgid "Send a collection of patches from stdin to an IMAP folder"
-msgstr ""
-
-#: command-list.h:113
-msgid "Build pack index file for an existing packed archive"
-msgstr ""
-
-#: command-list.h:114
-msgid "Create an empty Git repository or reinitialize an existing one"
-msgstr ""
-
-#: command-list.h:115
-msgid "Instantly browse your working repository in gitweb"
-msgstr ""
-
-#: command-list.h:116
-msgid "Add or parse structured information in commit messages"
-msgstr ""
-
-#: command-list.h:117
-msgid "Show commit logs"
-msgstr ""
-
-#: command-list.h:118
-msgid "Show information about files in the index and the working tree"
-msgstr ""
-
-#: command-list.h:119
-msgid "List references in a remote repository"
-msgstr ""
-
-#: command-list.h:120
-msgid "List the contents of a tree object"
-msgstr ""
-
-#: command-list.h:121
-msgid "Extracts patch and authorship from a single e-mail message"
-msgstr ""
-
-#: command-list.h:122
-msgid "Simple UNIX mbox splitter program"
-msgstr ""
-
-#: command-list.h:123
-msgid "Run tasks to optimize Git repository data"
-msgstr ""
-
-#: command-list.h:124
-msgid "Join two or more development histories together"
-msgstr ""
-
-#: command-list.h:125
-msgid "Find as good common ancestors as possible for a merge"
-msgstr ""
-
-#: command-list.h:126
-msgid "Run a three-way file merge"
-msgstr ""
-
-#: command-list.h:127
-msgid "Run a merge for files needing merging"
-msgstr ""
-
-#: command-list.h:128
-msgid "The standard helper program to use with git-merge-index"
-msgstr ""
-
-#: command-list.h:129
-msgid "Show three-way merge without touching index"
-msgstr ""
-
-#: command-list.h:130
-msgid "Run merge conflict resolution tools to resolve merge conflicts"
-msgstr ""
-
-#: command-list.h:131
-msgid "Creates a tag object with extra validation"
-msgstr ""
-
-#: command-list.h:132
-msgid "Build a tree-object from ls-tree formatted text"
-msgstr ""
-
-#: command-list.h:133
-msgid "Write and verify multi-pack-indexes"
-msgstr ""
-
-#: command-list.h:134
-msgid "Move or rename a file, a directory, or a symlink"
-msgstr ""
-
-#: command-list.h:135
-msgid "Find symbolic names for given revs"
-msgstr ""
-
-#: command-list.h:136
-msgid "Add or inspect object notes"
-msgstr ""
-
-#: command-list.h:137
-msgid "Import from and submit to Perforce repositories"
-msgstr ""
-
-#: command-list.h:138
-msgid "Create a packed archive of objects"
-msgstr ""
-
-#: command-list.h:139
-msgid "Find redundant pack files"
-msgstr ""
-
-#: command-list.h:140
-msgid "Pack heads and tags for efficient repository access"
-msgstr ""
-
-#: command-list.h:141
-msgid "Compute unique ID for a patch"
-msgstr ""
-
-#: command-list.h:142
-msgid "Prune all unreachable objects from the object database"
-msgstr ""
-
-#: command-list.h:143
-msgid "Remove extra objects that are already in pack files"
-msgstr ""
-
-#: command-list.h:144
-msgid "Fetch from and integrate with another repository or a local branch"
-msgstr ""
-
-#: command-list.h:145
-msgid "Update remote refs along with associated objects"
-msgstr ""
-
-#: command-list.h:146
-msgid "Applies a quilt patchset onto the current branch"
-msgstr ""
-
-#: command-list.h:147
-msgid "Compare two commit ranges (e.g. two versions of a branch)"
-msgstr ""
-
-#: command-list.h:148
-msgid "Reads tree information into the index"
-msgstr ""
-
-#: command-list.h:149
-msgid "Reapply commits on top of another base tip"
-msgstr ""
-
-#: command-list.h:150
-msgid "Receive what is pushed into the repository"
-msgstr ""
-
-#: command-list.h:151
-msgid "Manage reflog information"
-msgstr ""
-
-#: command-list.h:152
-msgid "Manage set of tracked repositories"
-msgstr ""
-
-#: command-list.h:153
-msgid "Pack unpacked objects in a repository"
-msgstr ""
-
-#: command-list.h:154
-msgid "Create, list, delete refs to replace objects"
-msgstr ""
-
-#: command-list.h:155
-msgid "Generates a summary of pending changes"
-msgstr ""
-
-#: command-list.h:156
-msgid "Reuse recorded resolution of conflicted merges"
-msgstr ""
-
-#: command-list.h:157
-msgid "Reset current HEAD to the specified state"
-msgstr ""
-
-#: command-list.h:158
-msgid "Restore working tree files"
-msgstr ""
-
-#: command-list.h:159
-msgid "Lists commit objects in reverse chronological order"
-msgstr ""
-
-#: command-list.h:160
-msgid "Pick out and massage parameters"
-msgstr ""
-
-#: command-list.h:161
-msgid "Revert some existing commits"
-msgstr ""
-
-#: command-list.h:162
-msgid "Remove files from the working tree and from the index"
-msgstr ""
-
-#: command-list.h:163
-msgid "Send a collection of patches as emails"
-msgstr ""
-
-#: command-list.h:164
-msgid "Push objects over Git protocol to another repository"
-msgstr ""
-
-#: command-list.h:165
-msgid "Git's i18n setup code for shell scripts"
-msgstr ""
-
-#: command-list.h:166
-msgid "Common Git shell script setup code"
-msgstr ""
-
-#: command-list.h:167
-msgid "Restricted login shell for Git-only SSH access"
-msgstr ""
-
-#: command-list.h:168
-msgid "Summarize 'git log' output"
-msgstr ""
-
-#: command-list.h:169
-msgid "Show various types of objects"
-msgstr ""
-
-#: command-list.h:170
-msgid "Show branches and their commits"
-msgstr ""
-
-#: command-list.h:171
-msgid "Show packed archive index"
-msgstr ""
-
-#: command-list.h:172
-msgid "List references in a local repository"
-msgstr ""
-
-#: command-list.h:173
-msgid "Reduce your working tree to a subset of tracked files"
-msgstr ""
-
-#: command-list.h:174
-msgid "Add file contents to the staging area"
-msgstr ""
-
-#: command-list.h:175
-msgid "Stash the changes in a dirty working directory away"
-msgstr ""
-
-#: command-list.h:176
-msgid "Show the working tree status"
-msgstr ""
-
-#: command-list.h:177
-msgid "Remove unnecessary whitespace"
-msgstr ""
-
-#: command-list.h:178
-msgid "Initialize, update or inspect submodules"
-msgstr ""
-
-#: command-list.h:179
-msgid "Bidirectional operation between a Subversion repository and Git"
-msgstr ""
-
-#: command-list.h:180
-msgid "Switch branches"
-msgstr ""
-
-#: command-list.h:181
-msgid "Read, modify and delete symbolic refs"
-msgstr ""
-
-#: command-list.h:182
-msgid "Create, list, delete or verify a tag object signed with GPG"
-msgstr ""
-
-#: command-list.h:183
-msgid "Creates a temporary file with a blob's contents"
-msgstr ""
-
-#: command-list.h:184
-msgid "Unpack objects from a packed archive"
-msgstr ""
-
-#: command-list.h:185
-msgid "Register file contents in the working tree to the index"
-msgstr ""
-
-#: command-list.h:186
-msgid "Update the object name stored in a ref safely"
-msgstr ""
-
-#: command-list.h:187
-msgid "Update auxiliary info file to help dumb servers"
-msgstr ""
-
-#: command-list.h:188
-msgid "Send archive back to git-archive"
-msgstr ""
-
-#: command-list.h:189
-msgid "Send objects packed back to git-fetch-pack"
-msgstr ""
-
-#: command-list.h:190
-msgid "Show a Git logical variable"
-msgstr ""
-
-#: command-list.h:191
-msgid "Check the GPG signature of commits"
-msgstr ""
-
-#: command-list.h:192
-msgid "Validate packed Git archive files"
-msgstr ""
-
-#: command-list.h:193
-msgid "Check the GPG signature of tags"
-msgstr ""
-
-#: command-list.h:194
-msgid "Show logs with difference each commit introduces"
-msgstr ""
-
-#: command-list.h:195
-msgid "Manage multiple working trees"
-msgstr ""
-
-#: command-list.h:196
-msgid "Create a tree object from the current index"
-msgstr ""
-
-#: command-list.h:197
-msgid "Defining attributes per path"
-msgstr ""
-
-#: command-list.h:198
-msgid "Git command-line interface and conventions"
-msgstr ""
-
-#: command-list.h:199
-msgid "A Git core tutorial for developers"
-msgstr ""
-
-#: command-list.h:200
-msgid "Providing usernames and passwords to Git"
-msgstr ""
-
-#: command-list.h:201
-msgid "Git for CVS users"
-msgstr ""
-
-#: command-list.h:202
-msgid "Tweaking diff output"
-msgstr ""
-
-#: command-list.h:203
-msgid "A useful minimum set of commands for Everyday Git"
-msgstr ""
-
-#: command-list.h:204
-msgid "Frequently asked questions about using Git"
-msgstr ""
-
-#: command-list.h:205
-msgid "A Git Glossary"
-msgstr ""
-
-#: command-list.h:206
-msgid "Hooks used by Git"
-msgstr ""
-
-#: command-list.h:207
-msgid "Specifies intentionally untracked files to ignore"
-msgstr ""
-
-#: command-list.h:208
-msgid "The Git repository browser"
-msgstr ""
-
-#: command-list.h:209
-msgid "Map author/committer names and/or E-Mail addresses"
-msgstr ""
-
-#: command-list.h:210
-msgid "Defining submodule properties"
-msgstr ""
-
-#: command-list.h:211
-msgid "Git namespaces"
-msgstr ""
-
-#: command-list.h:212
-msgid "Helper programs to interact with remote repositories"
-msgstr ""
-
-#: command-list.h:213
-msgid "Git Repository Layout"
-msgstr ""
-
-#: command-list.h:214
-msgid "Specifying revisions and ranges for Git"
-msgstr ""
-
-#: command-list.h:215
-msgid "Mounting one repository inside another"
-msgstr ""
-
-#: command-list.h:216
-msgid "A tutorial introduction to Git"
-msgstr ""
-
-#: command-list.h:217
-msgid "A tutorial introduction to Git: part two"
-msgstr ""
-
-#: command-list.h:218
-msgid "Git web interface (web frontend to Git repositories)"
-msgstr ""
-
-#: command-list.h:219
-msgid "An overview of recommended workflows with Git"
-msgstr ""
-
-#: git-merge-octopus.sh:46
-msgid ""
-"Error: Your local changes to the following files would be overwritten by "
-"merge"
-msgstr ""
-
-#: git-merge-octopus.sh:61
-msgid "Automated merge did not work."
-msgstr ""
-
-#: git-merge-octopus.sh:62
-msgid "Should not be doing an octopus."
-msgstr ""
-
-#: git-merge-octopus.sh:73
-#, sh-format
-msgid "Unable to find common commit with $pretty_name"
-msgstr ""
-
-#: git-merge-octopus.sh:77
-#, sh-format
-msgid "Already up to date with $pretty_name"
-msgstr ""
-
-#: git-merge-octopus.sh:89
-#, sh-format
-msgid "Fast-forwarding to: $pretty_name"
-msgstr ""
-
-#: git-merge-octopus.sh:97
-#, sh-format
-msgid "Trying simple merge with $pretty_name"
-msgstr ""
-
-#: git-merge-octopus.sh:102
-msgid "Simple merge did not work, trying automatic merge."
-msgstr ""
-
-#: git-sh-setup.sh:89 git-sh-setup.sh:94
-#, sh-format
-msgid "usage: $dashless $USAGE"
-msgstr ""
-
-#: git-sh-setup.sh:182
-#, sh-format
-msgid "Cannot chdir to $cdup, the toplevel of the working tree"
-msgstr ""
-
-#: git-sh-setup.sh:191 git-sh-setup.sh:198
-#, sh-format
-msgid "fatal: $program_name cannot be used without a working tree."
-msgstr ""
-
-#: git-sh-setup.sh:212
-msgid "Cannot rewrite branches: You have unstaged changes."
-msgstr ""
-
-#: git-sh-setup.sh:215
-#, sh-format
-msgid "Cannot $action: You have unstaged changes."
-msgstr ""
-
-#: git-sh-setup.sh:226
-#, sh-format
-msgid "Cannot $action: Your index contains uncommitted changes."
-msgstr ""
-
-#: git-sh-setup.sh:228
-msgid "Additionally, your index contains uncommitted changes."
-msgstr ""
-
-#: git-sh-setup.sh:348
-msgid "You need to run this command from the toplevel of the working tree."
-msgstr ""
-
-#: git-sh-setup.sh:353
-msgid "Unable to determine absolute path of git directory"
-msgstr ""
-
-#. TRANSLATORS: you can adjust this to align "git add -i" status menu
-#: git-add--interactive.perl:212
-#, perl-format
-msgid "%12s %12s %s"
-msgstr ""
-
-#: git-add--interactive.perl:632
-#, perl-format
-msgid "touched %d path\n"
-msgid_plural "touched %d paths\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: git-add--interactive.perl:1056
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for staging."
-msgstr ""
-
-#: git-add--interactive.perl:1059
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for stashing."
-msgstr ""
-
-#: git-add--interactive.perl:1062
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for unstaging."
-msgstr ""
-
-#: git-add--interactive.perl:1065 git-add--interactive.perl:1074
-#: git-add--interactive.perl:1080
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for applying."
-msgstr ""
-
-#: git-add--interactive.perl:1068 git-add--interactive.perl:1071
-#: git-add--interactive.perl:1077
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for discarding."
-msgstr ""
-
-#: git-add--interactive.perl:1114
-#, perl-format
-msgid "failed to open hunk edit file for writing: %s"
-msgstr ""
-
-#: git-add--interactive.perl:1121
-#, perl-format
-msgid ""
-"---\n"
-"To remove '%s' lines, make them ' ' lines (context).\n"
-"To remove '%s' lines, delete them.\n"
-"Lines starting with %s will be removed.\n"
-msgstr ""
-
-#: git-add--interactive.perl:1143
-#, perl-format
-msgid "failed to open hunk edit file for reading: %s"
-msgstr ""
-
-#: git-add--interactive.perl:1253
-msgid ""
-"y - stage this hunk\n"
-"n - do not stage this hunk\n"
-"q - quit; do not stage this hunk or any of the remaining ones\n"
-"a - stage this hunk and all later hunks in the file\n"
-"d - do not stage this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1259
-msgid ""
-"y - stash this hunk\n"
-"n - do not stash this hunk\n"
-"q - quit; do not stash this hunk or any of the remaining ones\n"
-"a - stash this hunk and all later hunks in the file\n"
-"d - do not stash this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1265
-msgid ""
-"y - unstage this hunk\n"
-"n - do not unstage this hunk\n"
-"q - quit; do not unstage this hunk or any of the remaining ones\n"
-"a - unstage this hunk and all later hunks in the file\n"
-"d - do not unstage this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1271
-msgid ""
-"y - apply this hunk to index\n"
-"n - do not apply this hunk to index\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1277 git-add--interactive.perl:1295
-msgid ""
-"y - discard this hunk from worktree\n"
-"n - do not discard this hunk from worktree\n"
-"q - quit; do not discard this hunk or any of the remaining ones\n"
-"a - discard this hunk and all later hunks in the file\n"
-"d - do not discard this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1283
-msgid ""
-"y - discard this hunk from index and worktree\n"
-"n - do not discard this hunk from index and worktree\n"
-"q - quit; do not discard this hunk or any of the remaining ones\n"
-"a - discard this hunk and all later hunks in the file\n"
-"d - do not discard this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1289
-msgid ""
-"y - apply this hunk to index and worktree\n"
-"n - do not apply this hunk to index and worktree\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1301
-msgid ""
-"y - apply this hunk to worktree\n"
-"n - do not apply this hunk to worktree\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file"
-msgstr ""
-
-#: git-add--interactive.perl:1316
-msgid ""
-"g - select a hunk to go to\n"
-"/ - search for a hunk matching the given regex\n"
-"j - leave this hunk undecided, see next undecided hunk\n"
-"J - leave this hunk undecided, see next hunk\n"
-"k - leave this hunk undecided, see previous undecided hunk\n"
-"K - leave this hunk undecided, see previous hunk\n"
-"s - split the current hunk into smaller hunks\n"
-"e - manually edit the current hunk\n"
-"? - print help\n"
-msgstr ""
-
-#: git-add--interactive.perl:1347
-msgid "The selected hunks do not apply to the index!\n"
-msgstr ""
-
-#: git-add--interactive.perl:1362
-#, perl-format
-msgid "ignoring unmerged: %s\n"
-msgstr ""
-
-#: git-add--interactive.perl:1481
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl:1482
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl:1483
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl:1484
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr ""
-
-#: git-add--interactive.perl:1601
-msgid "No other hunks to goto\n"
-msgstr ""
-
-#: git-add--interactive.perl:1619
-#, perl-format
-msgid "Invalid number: '%s'\n"
-msgstr ""
-
-#: git-add--interactive.perl:1624
-#, perl-format
-msgid "Sorry, only %d hunk available.\n"
-msgid_plural "Sorry, only %d hunks available.\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: git-add--interactive.perl:1659
-msgid "No other hunks to search\n"
-msgstr ""
-
-#: git-add--interactive.perl:1676
-#, perl-format
-msgid "Malformed search regexp %s: %s\n"
-msgstr ""
-
-#: git-add--interactive.perl:1686
-msgid "No hunk matches the given pattern\n"
-msgstr ""
-
-#: git-add--interactive.perl:1698 git-add--interactive.perl:1720
-msgid "No previous hunk\n"
-msgstr ""
-
-#: git-add--interactive.perl:1707 git-add--interactive.perl:1726
-msgid "No next hunk\n"
-msgstr ""
-
-#: git-add--interactive.perl:1732
-msgid "Sorry, cannot split this hunk\n"
-msgstr ""
-
-#: git-add--interactive.perl:1738
-#, perl-format
-msgid "Split into %d hunk.\n"
-msgid_plural "Split into %d hunks.\n"
-msgstr[0] ""
-msgstr[1] ""
-
-#: git-add--interactive.perl:1748
-msgid "Sorry, cannot edit this hunk\n"
-msgstr ""
-
-#. TRANSLATORS: please do not translate the command names
-#. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1813
-msgid ""
-"status        - show paths with changes\n"
-"update        - add working tree state to the staged set of changes\n"
-"revert        - revert staged set of changes back to the HEAD version\n"
-"patch         - pick hunks and update selectively\n"
-"diff          - view diff between HEAD and index\n"
-"add untracked - add contents of untracked files to the staged set of "
-"changes\n"
-msgstr ""
-
-#: git-add--interactive.perl:1830 git-add--interactive.perl:1842
-#: git-add--interactive.perl:1845 git-add--interactive.perl:1852
-#: git-add--interactive.perl:1855 git-add--interactive.perl:1862
-#: git-add--interactive.perl:1866 git-add--interactive.perl:1872
-msgid "missing --"
-msgstr ""
-
-#: git-add--interactive.perl:1868
-#, perl-format
-msgid "unknown --patch mode: %s"
-msgstr ""
-
-#: git-add--interactive.perl:1874 git-add--interactive.perl:1880
-#, perl-format
-msgid "invalid argument %s, expecting --"
-msgstr ""
-
-#: git-send-email.perl:159
-msgid "local zone differs from GMT by a non-minute interval\n"
-msgstr ""
-
-#: git-send-email.perl:166 git-send-email.perl:172
-msgid "local time offset greater than or equal to 24 hours\n"
-msgstr ""
-
-#: git-send-email.perl:244
-#, perl-format
-msgid "fatal: command '%s' died with exit code %d"
-msgstr ""
-
-#: git-send-email.perl:257
-msgid "the editor exited uncleanly, aborting everything"
-msgstr ""
-
-#: git-send-email.perl:346
-#, perl-format
-msgid ""
-"'%s' contains an intermediate version of the email you were composing.\n"
-msgstr ""
-
-#: git-send-email.perl:351
-#, perl-format
-msgid "'%s.final' contains the composed email.\n"
-msgstr ""
-
-#: git-send-email.perl:484
-msgid "--dump-aliases incompatible with other options\n"
-msgstr ""
-
-#: git-send-email.perl:561
-msgid ""
-"fatal: found configuration options for 'sendmail'\n"
-"git-send-email is configured with the sendemail.* options - note the 'e'.\n"
-"Set sendemail.forbidSendmailVariables to false to disable this check.\n"
-msgstr ""
-
-#: git-send-email.perl:566 git-send-email.perl:782
-msgid "Cannot run git format-patch from outside a repository\n"
-msgstr ""
-
-#: git-send-email.perl:569
-msgid ""
-"`batch-size` and `relogin` must be specified together (via command-line or "
-"configuration option)\n"
-msgstr ""
-
-#: git-send-email.perl:582
-#, perl-format
-msgid "Unknown --suppress-cc field: '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:613
-#, perl-format
-msgid "Unknown --confirm setting: '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:653
-#, perl-format
-msgid "warning: sendmail alias with quotes is not supported: %s\n"
-msgstr ""
-
-#: git-send-email.perl:655
-#, perl-format
-msgid "warning: `:include:` not supported: %s\n"
-msgstr ""
-
-#: git-send-email.perl:657
-#, perl-format
-msgid "warning: `/file` or `|pipe` redirection not supported: %s\n"
-msgstr ""
-
-#: git-send-email.perl:662
-#, perl-format
-msgid "warning: sendmail line is not recognized: %s\n"
-msgstr ""
-
-#: git-send-email.perl:747
-#, perl-format
-msgid ""
-"File '%s' exists but it could also be the range of commits\n"
-"to produce patches for.  Please disambiguate by...\n"
-"\n"
-"    * Saying \"./%s\" if you mean a file; or\n"
-"    * Giving --format-patch option if you mean a range.\n"
-msgstr ""
-
-#: git-send-email.perl:768
-#, perl-format
-msgid "Failed to opendir %s: %s"
-msgstr ""
-
-#: git-send-email.perl:803
-msgid ""
-"\n"
-"No patch files specified!\n"
-"\n"
-msgstr ""
-
-#: git-send-email.perl:816
-#, perl-format
-msgid "No subject line in %s?"
-msgstr ""
-
-#: git-send-email.perl:827
-#, perl-format
-msgid "Failed to open for writing %s: %s"
-msgstr ""
-
-#: git-send-email.perl:838
-msgid ""
-"Lines beginning in \"GIT:\" will be removed.\n"
-"Consider including an overall diffstat or table of contents\n"
-"for the patch you are writing.\n"
-"\n"
-"Clear the body content if you don't wish to send a summary.\n"
-msgstr ""
-
-#: git-send-email.perl:862
-#, perl-format
-msgid "Failed to open %s: %s"
-msgstr ""
-
-#: git-send-email.perl:879
-#, perl-format
-msgid "Failed to open %s.final: %s"
-msgstr ""
-
-#: git-send-email.perl:922
-msgid "Summary email is empty, skipping it\n"
-msgstr ""
-
-#. TRANSLATORS: please keep [y/N] as is.
-#: git-send-email.perl:971
-#, perl-format
-msgid "Are you sure you want to use <%s> [y/N]? "
-msgstr ""
-
-#: git-send-email.perl:1026
-msgid ""
-"The following files are 8bit, but do not declare a Content-Transfer-"
-"Encoding.\n"
-msgstr ""
-
-#: git-send-email.perl:1031
-msgid "Which 8bit encoding should I declare [UTF-8]? "
-msgstr ""
-
-#: git-send-email.perl:1039
-#, perl-format
-msgid ""
-"Refusing to send because the patch\n"
-"\t%s\n"
-"has the template subject '*** SUBJECT HERE ***'. Pass --force if you really "
-"want to send.\n"
-msgstr ""
-
-#: git-send-email.perl:1058
-msgid "To whom should the emails be sent (if anyone)?"
-msgstr ""
-
-#: git-send-email.perl:1076
-#, perl-format
-msgid "fatal: alias '%s' expands to itself\n"
-msgstr ""
-
-#: git-send-email.perl:1088
-msgid "Message-ID to be used as In-Reply-To for the first email (if any)? "
-msgstr ""
-
-#: git-send-email.perl:1150 git-send-email.perl:1158
-#, perl-format
-msgid "error: unable to extract a valid address from: %s\n"
-msgstr ""
-
-#. TRANSLATORS: Make sure to include [q] [d] [e] in your
-#. translation. The program will only accept English input
-#. at this point.
-#: git-send-email.perl:1162
-msgid "What to do with this address? ([q]uit|[d]rop|[e]dit): "
-msgstr ""
-
-#: git-send-email.perl:1482
-#, perl-format
-msgid "CA path \"%s\" does not exist"
-msgstr ""
-
-#: git-send-email.perl:1565
-msgid ""
-"    The Cc list above has been expanded by additional\n"
-"    addresses found in the patch commit message. By default\n"
-"    send-email prompts before sending whenever this occurs.\n"
-"    This behavior is controlled by the sendemail.confirm\n"
-"    configuration setting.\n"
-"\n"
-"    For additional information, run 'git send-email --help'.\n"
-"    To retain the current behavior, but squelch this message,\n"
-"    run 'git config --global sendemail.confirm auto'.\n"
-"\n"
-msgstr ""
-
-#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
-#. translation. The program will only accept English input
-#. at this point.
-#: git-send-email.perl:1580
-msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
-msgstr ""
-
-#: git-send-email.perl:1583
-msgid "Send this email reply required"
-msgstr ""
-
-#: git-send-email.perl:1617
-msgid "The required SMTP server is not properly defined."
-msgstr ""
-
-#: git-send-email.perl:1664
-#, perl-format
-msgid "Server does not support STARTTLS! %s"
-msgstr ""
-
-#: git-send-email.perl:1669 git-send-email.perl:1673
-#, perl-format
-msgid "STARTTLS failed! %s"
-msgstr ""
-
-#: git-send-email.perl:1682
-msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
-msgstr ""
-
-#: git-send-email.perl:1700
-#, perl-format
-msgid "Failed to send %s\n"
-msgstr ""
-
-#: git-send-email.perl:1703
-#, perl-format
-msgid "Dry-Sent %s\n"
-msgstr ""
-
-#: git-send-email.perl:1703
-#, perl-format
-msgid "Sent %s\n"
-msgstr ""
-
-#: git-send-email.perl:1705
-msgid "Dry-OK. Log says:\n"
-msgstr ""
-
-#: git-send-email.perl:1705
-msgid "OK. Log says:\n"
-msgstr ""
-
-#: git-send-email.perl:1724
-msgid "Result: "
-msgstr ""
-
-#: git-send-email.perl:1727
-msgid "Result: OK\n"
-msgstr ""
-
-#: git-send-email.perl:1744
-#, perl-format
-msgid "can't open file %s"
-msgstr ""
-
-#: git-send-email.perl:1792 git-send-email.perl:1812
-#, perl-format
-msgid "(mbox) Adding cc: %s from line '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:1798
-#, perl-format
-msgid "(mbox) Adding to: %s from line '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:1855
-#, perl-format
-msgid "(non-mbox) Adding cc: %s from line '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:1890
-#, perl-format
-msgid "(body) Adding cc: %s from line '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:2009
-#, perl-format
-msgid "(%s) Could not execute '%s'"
-msgstr ""
-
-#: git-send-email.perl:2016
-#, perl-format
-msgid "(%s) Adding %s: %s from: '%s'\n"
-msgstr ""
-
-#: git-send-email.perl:2020
-#, perl-format
-msgid "(%s) failed to close pipe to '%s'"
-msgstr ""
-
-#: git-send-email.perl:2050
-msgid "cannot send message as 7bit"
-msgstr ""
-
-#: git-send-email.perl:2058
-msgid "invalid transfer encoding"
-msgstr ""
-
-#: git-send-email.perl:2100
-#, perl-format
-msgid ""
-"fatal: %s: rejected by %s hook\n"
-"%s\n"
-"warning: no patches were sent\n"
-msgstr ""
-
-#: git-send-email.perl:2110 git-send-email.perl:2163 git-send-email.perl:2173
-#, perl-format
-msgid "unable to open %s: %s\n"
-msgstr ""
-
-#: git-send-email.perl:2113
-#, perl-format
-msgid ""
-"fatal: %s:%d is longer than 998 characters\n"
-"warning: no patches were sent\n"
-msgstr ""
-
-#: git-send-email.perl:2131
-#, perl-format
-msgid "Skipping %s with backup suffix '%s'.\n"
-msgstr ""
-
-#. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:2135
-#, perl-format
-msgid "Do you really want to send %s? [y|N]: "
-msgstr ""
index d3f488cb05f29bc90e4e03810d9bf4b972d0834f..d31b48e725083654222842049e121a35fe8d511b 100644 (file)
@@ -19,7 +19,7 @@ void prio_queue_reverse(struct prio_queue *queue)
 {
        int i, j;
 
-       if (queue->compare != NULL)
+       if (queue->compare)
                BUG("prio_queue_reverse() on non-LIFO queue");
        for (i = 0; i < (j = (queue->nr - 1) - i); i++)
                swap(queue, i, j);
index db2ebdc66ef2fe465456e39c4d33c6e5f6bd36de..8d6695681c1040aa2c1941228f325607c0c81e6b 100644 (file)
@@ -84,7 +84,7 @@ static void promisor_remote_move_to_tail(struct promisor_remote_config *config,
                                         struct promisor_remote *r,
                                         struct promisor_remote *previous)
 {
-       if (r->next == NULL)
+       if (!r->next)
                return;
 
        if (previous)
index b72eb9fdbee8d8d7473c973973e88eb09e15f723..39cc010c628f5670b045f9e433d8fc016daa55ad 100644 (file)
@@ -596,6 +596,6 @@ int is_range_diff_range(const char *arg)
        }
 
        free(copy);
-       object_array_clear(&revs.pending);
+       release_revisions(&revs);
        return negative > 0 && positive > 0;
 }
index b9f4ad886eff72f75eaa45c40d8a75c6ae2d2008..aba63ebeb3be784a1fba95e13070e8bd847315c1 100644 (file)
@@ -13,6 +13,7 @@
 #include "worktree.h"
 #include "object-store.h"
 #include "pack-bitmap.h"
+#include "pack-mtimes.h"
 
 struct connectivity_progress {
        struct progress *progress;
@@ -60,9 +61,13 @@ static void mark_commit(struct commit *c, void *data)
 struct recent_data {
        struct rev_info *revs;
        timestamp_t timestamp;
+       report_recent_object_fn *cb;
+       int ignore_in_core_kept_packs;
 };
 
 static void add_recent_object(const struct object_id *oid,
+                             struct packed_git *pack,
+                             off_t offset,
                              timestamp_t mtime,
                              struct recent_data *data)
 {
@@ -103,13 +108,29 @@ static void add_recent_object(const struct object_id *oid,
                die("unable to lookup %s", oid_to_hex(oid));
 
        add_pending_object(data->revs, obj, "");
+       if (data->cb)
+               data->cb(obj, pack, offset, mtime);
+}
+
+static int want_recent_object(struct recent_data *data,
+                             const struct object_id *oid)
+{
+       if (data->ignore_in_core_kept_packs &&
+           has_object_kept_pack(oid, IN_CORE_KEEP_PACKS))
+               return 0;
+       return 1;
 }
 
 static int add_recent_loose(const struct object_id *oid,
                            const char *path, void *data)
 {
        struct stat st;
-       struct object *obj = lookup_object(the_repository, oid);
+       struct object *obj;
+
+       if (!want_recent_object(data, oid))
+               return 0;
+
+       obj = lookup_object(the_repository, oid);
 
        if (obj && obj->flags & SEEN)
                return 0;
@@ -126,7 +147,7 @@ static int add_recent_loose(const struct object_id *oid,
                return error_errno("unable to stat %s", oid_to_hex(oid));
        }
 
-       add_recent_object(oid, st.st_mtime, data);
+       add_recent_object(oid, NULL, 0, st.st_mtime, data);
        return 0;
 }
 
@@ -134,29 +155,49 @@ static int add_recent_packed(const struct object_id *oid,
                             struct packed_git *p, uint32_t pos,
                             void *data)
 {
-       struct object *obj = lookup_object(the_repository, oid);
+       struct object *obj;
+       timestamp_t mtime = p->mtime;
+
+       if (!want_recent_object(data, oid))
+               return 0;
+
+       obj = lookup_object(the_repository, oid);
 
        if (obj && obj->flags & SEEN)
                return 0;
-       add_recent_object(oid, p->mtime, data);
+       if (p->is_cruft) {
+               if (load_pack_mtimes(p) < 0)
+                       die(_("could not load cruft pack .mtimes"));
+               mtime = nth_packed_mtime(p, pos);
+       }
+       add_recent_object(oid, p, nth_packed_object_offset(p, pos), mtime, data);
        return 0;
 }
 
 int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
-                                          timestamp_t timestamp)
+                                          timestamp_t timestamp,
+                                          report_recent_object_fn *cb,
+                                          int ignore_in_core_kept_packs)
 {
        struct recent_data data;
+       enum for_each_object_flags flags;
        int r;
 
        data.revs = revs;
        data.timestamp = timestamp;
+       data.cb = cb;
+       data.ignore_in_core_kept_packs = ignore_in_core_kept_packs;
 
        r = for_each_loose_object(add_recent_loose, &data,
                                  FOR_EACH_OBJECT_LOCAL_ONLY);
        if (r)
                return r;
-       return for_each_packed_object(add_recent_packed, &data,
-                                     FOR_EACH_OBJECT_LOCAL_ONLY);
+
+       flags = FOR_EACH_OBJECT_LOCAL_ONLY | FOR_EACH_OBJECT_PACK_ORDER;
+       if (ignore_in_core_kept_packs)
+               flags |= FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS;
+
+       return for_each_packed_object(add_recent_packed, &data, flags);
 }
 
 static int mark_object_seen(const struct object_id *oid,
@@ -217,7 +258,8 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
 
        if (mark_recent) {
                revs->ignore_missing_links = 1;
-               if (add_unseen_recent_objects_to_traversal(revs, mark_recent))
+               if (add_unseen_recent_objects_to_traversal(revs, mark_recent,
+                                                          NULL, 0))
                        die("unable to mark recent objects");
                if (prepare_revision_walk(revs))
                        die("revision walk setup failed");
index 5df932ad8f54418927d30117ee0209ba91459bde..020a887b99ce106618a9657c52ef7111b58022d1 100644 (file)
@@ -3,9 +3,16 @@
 
 struct progress;
 struct rev_info;
+struct object;
+struct packed_git;
+
+typedef void report_recent_object_fn(const struct object *, struct packed_git *,
+                                    off_t, time_t);
 
 int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
-                                          timestamp_t timestamp);
+                                          timestamp_t timestamp,
+                                          report_recent_object_fn cb,
+                                          int ignore_in_core_kept_packs);
 void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
                            timestamp_t mark_recent, struct progress *);
 
index 4df97e185e9c80cd061ab1d00143eceed81a0242..96ce489c7c5f04895783979debede4266ff99fa3 100644 (file)
@@ -112,7 +112,7 @@ static const char *alternate_index_output;
 static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
 {
        if (S_ISSPARSEDIR(ce->ce_mode))
-               istate->sparse_index = 1;
+               istate->sparse_index = INDEX_COLLAPSED;
 
        istate->cache[nr] = ce;
        add_name_hash(istate, ce);
@@ -1856,7 +1856,7 @@ static int read_index_extension(struct index_state *istate,
                break;
        case CACHE_EXT_SPARSE_DIRECTORIES:
                /* no content, only an indicator */
-               istate->sparse_index = 1;
+               istate->sparse_index = INDEX_COLLAPSED;
                break;
        default:
                if (*ext < 'A' || 'Z' < *ext)
@@ -2260,6 +2260,20 @@ static unsigned long load_cache_entries_threaded(struct index_state *istate, con
        return consumed;
 }
 
+static void set_new_index_sparsity(struct index_state *istate)
+{
+       /*
+        * If the index's repo exists, mark it sparse according to
+        * repo settings.
+        */
+       if (istate->repo) {
+               prepare_repo_settings(istate->repo);
+               if (!istate->repo->settings.command_requires_full_index &&
+                   is_sparse_index_allowed(istate, 0))
+                       istate->sparse_index = 1;
+       }
+}
+
 /* remember to discard_cache() before reading a different cache! */
 int do_read_index(struct index_state *istate, const char *path, int must_exist)
 {
@@ -2281,8 +2295,10 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        istate->timestamp.nsec = 0;
        fd = open(path, O_RDONLY);
        if (fd < 0) {
-               if (!must_exist && errno == ENOENT)
+               if (!must_exist && errno == ENOENT) {
+                       set_new_index_sparsity(istate);
                        return 0;
+               }
                die_errno(_("%s: index file open failed"), path);
        }
 
@@ -3149,7 +3165,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
                                 unsigned flags)
 {
        int ret;
-       int was_full = !istate->sparse_index;
+       int was_full = istate->sparse_index == INDEX_EXPANDED;
 
        ret = convert_to_sparse(istate, 0);
 
index 7838bd22b8db1bd52859361a4f3b7789c2cf4b5b..d3c90e5dbe2fdb4cdbad6b93290e27b46e205fbb 100644 (file)
@@ -1261,7 +1261,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
         * ":" means no format is specified, and use the default.
         */
        formatp = strchr(atomname, ':');
-       if (formatp != NULL) {
+       if (formatp) {
                formatp++;
                parse_date_format(formatp, &date_mode);
        }
@@ -1509,7 +1509,7 @@ static void fill_missing_values(struct atom_value *val)
        int i;
        for (i = 0; i < used_atom_cnt; i++) {
                struct atom_value *v = &val[i];
-               if (v->s == NULL)
+               if (!v->s)
                        v->s = xstrdup("");
        }
 }
@@ -1619,7 +1619,7 @@ static const char *rstrip_ref_components(const char *refname, int len)
 
        while (remaining-- > 0) {
                char *p = strrchr(start, '/');
-               if (p == NULL) {
+               if (!p) {
                        free((char *)to_free);
                        return xstrdup("");
                } else
@@ -2392,6 +2392,7 @@ static void reach_filter(struct ref_array *array,
                clear_commit_marks(merge_commit, ALL_REV_FLAGS);
        }
 
+       release_revisions(&revs);
        free(to_clear);
 }
 
index 8ac4b284b6b6857a0a6d1f79eed563135771a291..7aa6595a51f757ec2d25ed5d96c805ff1dbf13d2 100644 (file)
@@ -8,7 +8,7 @@
 
 struct complete_reflogs {
        char *ref;
-       const char *short_ref;
+       char *short_ref;
        struct reflog_info {
                struct object_id ooid, noid;
                char *email;
@@ -51,9 +51,16 @@ static void free_complete_reflog(struct complete_reflogs *array)
        }
        free(array->items);
        free(array->ref);
+       free(array->short_ref);
        free(array);
 }
 
+static void complete_reflogs_clear(void *util, const char *str)
+{
+       struct complete_reflogs *array = util;
+       free_complete_reflog(array);
+}
+
 static struct complete_reflogs *read_complete_reflog(const char *ref)
 {
        struct complete_reflogs *reflogs =
@@ -116,6 +123,21 @@ void init_reflog_walk(struct reflog_walk_info **info)
        (*info)->complete_reflogs.strdup_strings = 1;
 }
 
+void reflog_walk_info_release(struct reflog_walk_info *info)
+{
+       size_t i;
+
+       if (!info)
+               return;
+
+       for (i = 0; i < info->nr; i++)
+               free(info->logs[i]);
+       string_list_clear_func(&info->complete_reflogs,
+                              complete_reflogs_clear);
+       free(info->logs);
+       free(info);
+}
+
 int add_reflog_for_walk(struct reflog_walk_info *info,
                struct commit *commit, const char *name)
 {
index e9e00ffd479475a6a887b04ae685a64d3b251db7..8076f10d9fbc0dd5588582f5bfec105416037233 100644 (file)
@@ -8,6 +8,7 @@ struct reflog_walk_info;
 struct date_mode;
 
 void init_reflog_walk(struct reflog_walk_info **info);
+void reflog_walk_info_release(struct reflog_walk_info *info);
 int add_reflog_for_walk(struct reflog_walk_info *info,
                        struct commit *commit, const char *name);
 void show_reflog_message(struct reflog_walk_info *info, int,
diff --git a/refs.c b/refs.c
index 9db66e995518c9f85acd0de0c5fa44658fdcf523..90bcb2716873592864e2496951f913618521cb45 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1109,8 +1109,10 @@ int ref_transaction_create(struct ref_transaction *transaction,
                           unsigned int flags, const char *msg,
                           struct strbuf *err)
 {
-       if (!new_oid || is_null_oid(new_oid))
-               BUG("create called without valid new_oid");
+       if (!new_oid || is_null_oid(new_oid)) {
+               strbuf_addf(err, "'%s' has a null OID", refname);
+               return 1;
+       }
        return ref_transaction_update(transaction, refname, new_oid,
                                      null_oid(), flags, msg, err);
 }
index 3080ef944d998f87c7a42d1e2be33d5c97d8cfaf..32afd8a40b0faf22d1ef2de5bb2a2990fa6eebb3 100644 (file)
@@ -134,7 +134,7 @@ int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len)
        r = bsearch(&key, dir->entries, dir->nr, sizeof(*dir->entries),
                    ref_entry_cmp_sslice);
 
-       if (r == NULL)
+       if (!r)
                return -1;
 
        return r - dir->entries;
index 2605371c28d86f638dcd5079466e038e3eb7a38a..8331b34e82300630b68c574e4f68071f3ebf261a 100644 (file)
@@ -15,7 +15,8 @@ https://developers.google.com/open-source/licenses/bsd
 
 static void strbuf_return_block(void *b, struct reftable_block *dest)
 {
-       memset(dest->data, 0xff, dest->len);
+       if (dest->len)
+               memset(dest->data, 0xff, dest->len);
        reftable_free(dest->data);
 }
 
@@ -56,7 +57,8 @@ void block_source_from_strbuf(struct reftable_block_source *bs,
 
 static void malloc_return_block(void *b, struct reftable_block *dest)
 {
-       memset(dest->data, 0xff, dest->len);
+       if (dest->len)
+               memset(dest->data, 0xff, dest->len);
        reftable_free(dest->data);
 }
 
@@ -85,7 +87,8 @@ static uint64_t file_size(void *b)
 
 static void file_return_block(void *b, struct reftable_block *dest)
 {
-       memset(dest->data, 0xff, dest->len);
+       if (dest->len)
+               memset(dest->data, 0xff, dest->len);
        reftable_free(dest->data);
 }
 
index 19fe4e200859683b13b1f0b0a21c8b1685ad4a08..d0b717510fa7d6dd8832bf77490630964e33b23b 100644 (file)
@@ -35,7 +35,7 @@ static int count_dir_entries(const char *dirname)
        DIR *dir = opendir(dirname);
        int len = 0;
        struct dirent *d;
-       if (dir == NULL)
+       if (!dir)
                return 0;
 
        while ((d = readdir(dir))) {
index 82db7995dd68ec9f8f8b7756582d9be749f13a9b..b8899e060abdd6629d73510a8b126b0c00c90b8d 100644 (file)
@@ -16,7 +16,7 @@ struct tree_node *tree_search(void *key, struct tree_node **rootp,
                              int insert)
 {
        int res;
-       if (*rootp == NULL) {
+       if (!*rootp) {
                if (!insert) {
                        return NULL;
                } else {
@@ -50,7 +50,7 @@ void infix_walk(struct tree_node *t, void (*action)(void *arg, void *key),
 
 void tree_free(struct tree_node *t)
 {
-       if (t == NULL) {
+       if (!t) {
                return;
        }
        if (t->left) {
index 427f1317c6be6121a733fa206ce6e27ab5e029b8..2e322a5683d081eea60fc85dfc4d792ce89b7a93 100644 (file)
@@ -183,7 +183,7 @@ static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
        struct tree_node *node = tree_search(&want, &w->obj_index_tree,
                                             &obj_index_tree_node_compare, 0);
        struct obj_index_tree_node *key = NULL;
-       if (node == NULL) {
+       if (!node) {
                struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT;
                key = reftable_malloc(sizeof(struct obj_index_tree_node));
                *key = empty;
@@ -222,7 +222,7 @@ static int writer_add_record(struct reftable_writer *w,
 
        strbuf_reset(&w->last_key);
        strbuf_addbuf(&w->last_key, &key);
-       if (w->block_writer == NULL) {
+       if (!w->block_writer) {
                writer_reinit_block_writer(w, reftable_record_type(rec));
        }
 
@@ -263,7 +263,7 @@ int reftable_writer_add_ref(struct reftable_writer *w,
        };
        int err = 0;
 
-       if (ref->refname == NULL)
+       if (!ref->refname)
                return REFTABLE_API_ERROR;
        if (ref->update_index < w->min_update_index ||
            ref->update_index > w->max_update_index)
@@ -336,7 +336,7 @@ int reftable_writer_add_log(struct reftable_writer *w,
        if (log->value_type == REFTABLE_LOG_DELETION)
                return reftable_writer_add_log_verbatim(w, log);
 
-       if (log->refname == NULL)
+       if (!log->refname)
                return REFTABLE_API_ERROR;
 
        input_log_message = log->value.update.message;
@@ -545,7 +545,7 @@ static int writer_finish_public_section(struct reftable_writer *w)
        uint8_t typ = 0;
        int err = 0;
 
-       if (w->block_writer == NULL)
+       if (!w->block_writer)
                return 0;
 
        typ = block_writer_type(w->block_writer);
@@ -694,7 +694,7 @@ static int writer_flush_nonempty_block(struct reftable_writer *w)
 
 static int writer_flush_block(struct reftable_writer *w)
 {
-       if (w->block_writer == NULL)
+       if (!w->block_writer)
                return 0;
        if (w->block_writer->entries == 0)
                return 0;
index 42a4e7106e1255af5b79d32ff7d86170827582b1..dc270379e4d6393881d3731c60fd78cc59402802 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -14,6 +14,7 @@
 #include "strvec.h"
 #include "commit-reach.h"
 #include "advice.h"
+#include "connect.h"
 
 enum map_direction { FROM_SRC, FROM_DST };
 
@@ -543,6 +544,8 @@ static const char *remotes_remote_for_branch(struct remote_state *remote_state,
        }
        if (explicit)
                *explicit = 0;
+       if (remote_state->remotes_nr == 1)
+               return remote_state->remotes[0]->name;
        return "origin";
 }
 
@@ -2172,6 +2175,7 @@ static int stat_branch_pair(const char *branch_name, const char *base,
        clear_commit_marks(theirs, ALL_REV_FLAGS);
 
        strvec_clear(&argv);
+       release_revisions(&revs);
        return 1;
 }
 
@@ -2727,3 +2731,101 @@ void remote_state_clear(struct remote_state *remote_state)
        hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent);
        hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent);
 }
+
+/*
+ * Returns 1 if it was the last chop before ':'.
+ */
+static int chop_last_dir(char **remoteurl, int is_relative)
+{
+       char *rfind = find_last_dir_sep(*remoteurl);
+       if (rfind) {
+               *rfind = '\0';
+               return 0;
+       }
+
+       rfind = strrchr(*remoteurl, ':');
+       if (rfind) {
+               *rfind = '\0';
+               return 1;
+       }
+
+       if (is_relative || !strcmp(".", *remoteurl))
+               die(_("cannot strip one component off url '%s'"),
+                       *remoteurl);
+
+       free(*remoteurl);
+       *remoteurl = xstrdup(".");
+       return 0;
+}
+
+char *relative_url(const char *remote_url, const char *url,
+                  const char *up_path)
+{
+       int is_relative = 0;
+       int colonsep = 0;
+       char *out;
+       char *remoteurl;
+       struct strbuf sb = STRBUF_INIT;
+       size_t len;
+
+       if (!url_is_local_not_ssh(url) || is_absolute_path(url))
+               return xstrdup(url);
+
+       len = strlen(remote_url);
+       if (!len)
+               BUG("invalid empty remote_url");
+
+       remoteurl = xstrdup(remote_url);
+       if (is_dir_sep(remoteurl[len-1]))
+               remoteurl[len-1] = '\0';
+
+       if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl))
+               is_relative = 0;
+       else {
+               is_relative = 1;
+               /*
+                * Prepend a './' to ensure all relative
+                * remoteurls start with './' or '../'
+                */
+               if (!starts_with_dot_slash_native(remoteurl) &&
+                   !starts_with_dot_dot_slash_native(remoteurl)) {
+                       strbuf_reset(&sb);
+                       strbuf_addf(&sb, "./%s", remoteurl);
+                       free(remoteurl);
+                       remoteurl = strbuf_detach(&sb, NULL);
+               }
+       }
+       /*
+        * When the url starts with '../', remove that and the
+        * last directory in remoteurl.
+        */
+       while (url) {
+               if (starts_with_dot_dot_slash_native(url)) {
+                       url += 3;
+                       colonsep |= chop_last_dir(&remoteurl, is_relative);
+               } else if (starts_with_dot_slash_native(url))
+                       url += 2;
+               else
+                       break;
+       }
+       strbuf_reset(&sb);
+       strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url);
+       if (ends_with(url, "/"))
+               strbuf_setlen(&sb, sb.len - 1);
+       free(remoteurl);
+
+       if (starts_with_dot_slash_native(sb.buf))
+               out = xstrdup(sb.buf + 2);
+       else
+               out = xstrdup(sb.buf);
+
+       if (!up_path || !is_relative) {
+               strbuf_release(&sb);
+               return out;
+       }
+
+       strbuf_reset(&sb);
+       strbuf_addf(&sb, "%s%s", up_path, out);
+       free(out);
+       return strbuf_detach(&sb, NULL);
+}
index 4a1209ae2c800d1fc07b7905b26d615d28eee924..dd4402436f1f2e1bb06d37c932ca8f9e3afcf48a 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -409,4 +409,36 @@ int parseopt_push_cas_option(const struct option *, const char *arg, int unset);
 int is_empty_cas(const struct push_cas_option *);
 void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);
 
+/*
+ * The `url` argument is the URL that navigates to the submodule origin
+ * repo. When relative, this URL is relative to the superproject origin
+ * URL repo. The `up_path` argument, if specified, is the relative
+ * path that navigates from the submodule working tree to the superproject
+ * working tree. Returns the origin URL of the submodule.
+ *
+ * Return either an absolute URL or filesystem path (if the superproject
+ * origin URL is an absolute URL or filesystem path, respectively) or a
+ * relative file system path (if the superproject origin URL is a relative
+ * file system path).
+ *
+ * When the output is a relative file system path, the path is either
+ * relative to the submodule working tree, if up_path is specified, or to
+ * the superproject working tree otherwise.
+ *
+ * NEEDSWORK: This works incorrectly on the domain and protocol part.
+ * remote_url      url              outcome          expectation
+ * http://a.com/b  ../c             http://a.com/c   as is
+ * http://a.com/b/ ../c             http://a.com/c   same as previous line, but
+ *                                                   ignore trailing slash in url
+ * http://a.com/b  ../../c          http://c         error out
+ * http://a.com/b  ../../../c       http:/c          error out
+ * http://a.com/b  ../../../../c    http:c           error out
+ * http://a.com/b  ../../../../../c    .:c           error out
+ * http://a.com/b  http://d.org/e   http://d.org/e   as is
+ * NEEDSWORK: Given how chop_last_dir() works, this function is broken
+ * when a local part has a colon in its path component, too.
+ */
+char *relative_url(const char *remote_url, const char *url,
+                  const char *up_path);
+
 #endif
index d26627c59329151ef196e26444a64cb44ad699d4..876ab435da949c8359c315636225d9fd7fd962ab 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -591,7 +591,7 @@ int rerere_remaining(struct repository *r, struct string_list *merge_rr)
                else if (conflict_type == RESOLVED) {
                        struct string_list_item *it;
                        it = string_list_lookup(merge_rr, (const char *)e->name);
-                       if (it != NULL) {
+                       if (it) {
                                free_rerere_id(it);
                                it->util = RERERE_RESOLVED;
                        }
index 7d435f80480ef1b7684fdc43b51057d20e79966f..211352795c5529a7ee7efed0162b65ed85158c5b 100644 (file)
@@ -606,6 +606,10 @@ static struct commit *one_relevant_parent(const struct rev_info *revs,
  *
  *   2. We saw anything except REV_TREE_NEW.
  */
+#define REV_TREE_SAME          0
+#define REV_TREE_NEW           1       /* Only new files */
+#define REV_TREE_OLD           2       /* Only files removed */
+#define REV_TREE_DIFFERENT     3       /* Mixed changes */
 static int tree_difference = REV_TREE_SAME;
 
 static void file_add_remove(struct diff_options *options,
@@ -1440,6 +1444,9 @@ static int limit_list(struct rev_info *revs)
                if (revs->min_age != -1 && (commit->date > revs->min_age) &&
                    !revs->line_level_traverse)
                        continue;
+               if (revs->max_age_as_filter != -1 &&
+                       (commit->date < revs->max_age_as_filter) && !revs->line_level_traverse)
+                       continue;
                date = commit->date;
                p = &commit_list_insert(commit, p)->next;
 
@@ -1456,10 +1463,9 @@ static int limit_list(struct rev_info *revs)
        if (revs->left_only || revs->right_only)
                limit_left_right(newlist, revs);
 
-       if (bottom) {
+       if (bottom)
                limit_to_ancestry(bottom, newlist);
-               free_commit_list(bottom);
-       }
+       free_commit_list(bottom);
 
        /*
         * Check if any commits have become TREESAME by some of their parents
@@ -1838,6 +1844,7 @@ void repo_init_revisions(struct repository *r,
        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;
@@ -2218,6 +2225,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
        } else if ((argcount = parse_long_opt("since", argv, &optarg))) {
                revs->max_age = approxidate(optarg);
                return argcount;
+       } else if ((argcount = parse_long_opt("since-as-filter", argv, &optarg))) {
+               revs->max_age_as_filter = approxidate(optarg);
+               return argcount;
        } else if ((argcount = parse_long_opt("after", argv, &optarg))) {
                revs->max_age = approxidate(optarg);
                return argcount;
@@ -2833,7 +2843,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
        }
        strvec_clear(&prune_data);
 
-       if (revs->def == NULL)
+       if (!revs->def)
                revs->def = opt ? opt->def : NULL;
        if (opt && opt->tweak)
                opt->tweak(revs, opt);
@@ -2923,6 +2933,42 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
        return left;
 }
 
+static void release_revisions_cmdline(struct rev_cmdline_info *cmdline)
+{
+       unsigned int i;
+
+       for (i = 0; i < cmdline->nr; i++)
+               free((char *)cmdline->rev[i].name);
+       free(cmdline->rev);
+}
+
+static void release_revisions_mailmap(struct string_list *mailmap)
+{
+       if (!mailmap)
+               return;
+       clear_mailmap(mailmap);
+       free(mailmap);
+}
+
+static void release_revisions_topo_walk_info(struct topo_walk_info *info);
+
+void release_revisions(struct rev_info *revs)
+{
+       free_commit_list(revs->commits);
+       object_array_clear(&revs->pending);
+       object_array_clear(&revs->boundary_commits);
+       release_revisions_cmdline(&revs->cmdline);
+       list_objects_filter_release(&revs->filter);
+       clear_pathspec(&revs->prune_data);
+       date_mode_release(&revs->date_mode);
+       release_revisions_mailmap(revs->mailmap);
+       free_grep_patterns(&revs->grep_filter);
+       /* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */
+       diff_free(&revs->pruning);
+       reflog_walk_info_release(revs->reflog_info);
+       release_revisions_topo_walk_info(revs->topo_walk_info);
+}
+
 static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child)
 {
        struct commit_list *l = xcalloc(1, sizeof(*l));
@@ -3433,17 +3479,22 @@ static void compute_indegrees_to_depth(struct rev_info *revs,
                indegree_walk_step(revs);
 }
 
-static void reset_topo_walk(struct rev_info *revs)
+static void release_revisions_topo_walk_info(struct topo_walk_info *info)
 {
-       struct topo_walk_info *info = revs->topo_walk_info;
-
+       if (!info)
+               return;
        clear_prio_queue(&info->explore_queue);
        clear_prio_queue(&info->indegree_queue);
        clear_prio_queue(&info->topo_queue);
        clear_indegree_slab(&info->indegree);
        clear_author_date_slab(&info->author_date);
+       free(info);
+}
 
-       FREE_AND_NULL(revs->topo_walk_info);
+static void reset_topo_walk(struct rev_info *revs)
+{
+       release_revisions_topo_walk_info(revs->topo_walk_info);
+       revs->topo_walk_info = NULL;
 }
 
 static void init_topo_walk(struct rev_info *revs)
@@ -3652,7 +3703,7 @@ static enum rewrite_result rewrite_one_1(struct rev_info *revs,
                        return rewrite_one_ok;
                if (!p->parents)
                        return rewrite_one_noparents;
-               if ((p = one_relevant_parent(revs, p->parents)) == NULL)
+               if (!(p = one_relevant_parent(revs, p->parents)))
                        return rewrite_one_ok;
                *pp = p;
        }
@@ -3862,6 +3913,9 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
        if (revs->min_age != -1 &&
            comparison_date(revs, commit) > revs->min_age)
                        return commit_ignore;
+       if (revs->max_age_as_filter != -1 &&
+           comparison_date(revs, commit) < revs->max_age_as_filter)
+                       return commit_ignore;
        if (revs->min_parents || (revs->max_parents >= 0)) {
                int n = commit_list_count(commit->parents);
                if ((n < revs->min_parents) ||
@@ -4080,10 +4134,8 @@ static void create_boundary_commit_list(struct rev_info *revs)
         * boundary commits anyway.  (This is what the code has always
         * done.)
         */
-       if (revs->commits) {
-               free_commit_list(revs->commits);
-               revs->commits = NULL;
-       }
+       free_commit_list(revs->commits);
+       revs->commits = NULL;
 
        /*
         * Put all of the actual boundary commits from revs->boundary_commits
@@ -4220,10 +4272,8 @@ struct commit *get_revision(struct rev_info *revs)
                graph_update(revs->graph, c);
        if (!c) {
                free_saved_parents(revs);
-               if (revs->previous_parents) {
-                       free_commit_list(revs->previous_parents);
-                       revs->previous_parents = NULL;
-               }
+               free_commit_list(revs->previous_parents);
+               revs->previous_parents = NULL;
        }
        return c;
 }
index 5bc59c7bfe1e35efe7fb24e93f9a093baa28b658..e576845cdd103731f3e8d3ea1a4b0eefb21e2063 100644 (file)
@@ -263,6 +263,7 @@ struct rev_info {
        int skip_count;
        int max_count;
        timestamp_t max_age;
+       timestamp_t max_age_as_filter;
        timestamp_t min_age;
        int min_parents;
        int max_parents;
@@ -329,31 +330,24 @@ struct rev_info {
        struct tmp_objdir *remerge_objdir;
 };
 
-int ref_excluded(struct string_list *, const char *path);
-void clear_ref_exclusion(struct string_list **);
-void add_ref_exclusion(struct string_list **, const char *exclude);
-
-
-#define REV_TREE_SAME          0
-#define REV_TREE_NEW           1       /* Only new files */
-#define REV_TREE_OLD           2       /* Only files removed */
-#define REV_TREE_DIFFERENT     3       /* Mixed changes */
-
-/* revision.c */
-typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *);
-extern volatile show_early_output_fn_t show_early_output;
-
-struct setup_revision_opt {
-       const char *def;
-       void (*tweak)(struct rev_info *, struct setup_revision_opt *);
-       unsigned int    assume_dashdash:1,
-                       allow_exclude_promisor_objects:1;
-       unsigned revarg_opt;
-};
-
-#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
-#define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix)
-#endif
+/**
+ * Initialize the "struct rev_info" structure with a macro.
+ *
+ * This will not fully initialize a "struct rev_info", the
+ * repo_init_revisions() function needs to be called before
+ * setup_revisions() and any revision walking takes place.
+ *
+ * Use REV_INFO_INIT to make the "struct rev_info" safe for passing to
+ * release_revisions() when it's inconvenient (e.g. due to a "goto
+ * cleanup" pattern) to arrange for repo_init_revisions() to be called
+ * before release_revisions() is called.
+ *
+ * Initializing with this REV_INFO_INIT is redundant to invoking
+ * repo_init_revisions(). If repo_init_revisions() is guaranteed to be
+ * called before release_revisions() the "struct rev_info" can be left
+ * uninitialized.
+ */
+#define REV_INFO_INIT { 0 }
 
 /**
  * Initialize a rev_info structure with default values. The third parameter may
@@ -366,6 +360,9 @@ struct setup_revision_opt {
 void repo_init_revisions(struct repository *r,
                         struct rev_info *revs,
                         const char *prefix);
+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
+#define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix)
+#endif
 
 /**
  * Parse revision information, filling in the `rev_info` structure, and
@@ -374,9 +371,22 @@ void repo_init_revisions(struct repository *r,
  * head of the argument list. The last parameter is used in case no
  * parameter given by the first two arguments.
  */
+struct setup_revision_opt {
+       const char *def;
+       void (*tweak)(struct rev_info *, struct setup_revision_opt *);
+       unsigned int    assume_dashdash:1,
+                       allow_exclude_promisor_objects:1;
+       unsigned revarg_opt;
+};
 int setup_revisions(int argc, const char **argv, struct rev_info *revs,
                    struct setup_revision_opt *);
 
+/**
+ * Free data allocated in a "struct rev_info" after it's been
+ * initialized with repo_init_revisions() or REV_INFO_INIT.
+ */
+void release_revisions(struct rev_info *revs);
+
 void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
                        const struct option *options,
                        const char * const usagestr[]);
@@ -417,6 +427,14 @@ void mark_trees_uninteresting_sparse(struct repository *r, struct oidset *trees)
 
 void show_object_with_name(FILE *, struct object *, const char *);
 
+/**
+ * Helpers to check if a "struct string_list" item matches with
+ * wildmatch().
+ */
+int ref_excluded(struct string_list *, const char *path);
+void clear_ref_exclusion(struct string_list **);
+void add_ref_exclusion(struct string_list **, const char *exclude);
+
 /**
  * This function can be used if you want to add commit objects as revision
  * information. You can use the `UNINTERESTING` object flag to indicate if
@@ -472,4 +490,10 @@ int rewrite_parents(struct rev_info *revs,
  */
 struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit);
 
+/**
+ * Global for the (undocumented) "--early-output" flag for "git log".
+ */
+typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *);
+extern volatile show_early_output_fn_t show_early_output;
+
 #endif
index 07bed6c31b4e9f065b9ae0a4490cfd56adada0c7..5bd0c933e80291264abb537b7cd39b761e964a82 100644 (file)
@@ -142,7 +142,6 @@ struct child_process {
        unsigned clean_on_exit:1;
        unsigned wait_after_clean:1;
        void (*clean_on_exit_handler)(struct child_process *process);
-       void *clean_on_exit_handler_cbdata;
 };
 
 #define CHILD_PROCESS_INIT { \
index a5f678f4529b1953af8dd7b6e168a4a03333e2e9..bb4046aab33ddd0bdba960a0edf8732cc2bdf372 100644 (file)
@@ -1327,7 +1327,6 @@ void print_commit_summary(struct repository *r,
        get_commit_format(format.buf, &rev);
        rev.always_show_header = 0;
        rev.diffopt.detect_rename = DIFF_DETECT_RENAME;
-       rev.diffopt.break_opt = 0;
        diff_setup_done(&rev.diffopt);
 
        refs = get_main_ref_store(the_repository);
@@ -1347,6 +1346,7 @@ void print_commit_summary(struct repository *r,
                log_tree_commit(&rev, commit);
        }
 
+       release_revisions(&rev);
        strbuf_release(&format);
 }
 
@@ -3415,6 +3415,7 @@ static int make_patch(struct repository *r,
                unuse_commit_buffer(commit, commit_buffer);
        }
        strbuf_release(&buf);
+       release_revisions(&log_tree_opt);
 
        return res;
 }
@@ -4525,6 +4526,7 @@ cleanup_head_ref:
                                              &log_tree_opt.diffopt);
                                log_tree_diff_flush(&log_tree_opt);
                        }
+                       release_revisions(&log_tree_opt);
                }
                flush_rewritten_pending();
                if (!stat(rebase_path_rewritten_list(), &st) &&
@@ -5351,6 +5353,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
        int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
        int reapply_cherry_picks = flags & TODO_LIST_REAPPLY_CHERRY_PICKS;
        int skipped_commit = 0;
+       int ret = 0;
 
        repo_init_revisions(r, &revs, NULL);
        revs.verbose_header = 1;
@@ -5374,14 +5377,20 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
        pp.fmt = revs.commit_format;
        pp.output_encoding = get_log_output_encoding();
 
-       if (setup_revisions(argc, argv, &revs, NULL) > 1)
-               return error(_("make_script: unhandled options"));
+       if (setup_revisions(argc, argv, &revs, NULL) > 1) {
+               ret = error(_("make_script: unhandled options"));
+               goto cleanup;
+       }
 
-       if (prepare_revision_walk(&revs) < 0)
-               return error(_("make_script: error preparing revisions"));
+       if (prepare_revision_walk(&revs) < 0) {
+               ret = error(_("make_script: error preparing revisions"));
+               goto cleanup;
+       }
 
-       if (rebase_merges)
-               return make_script_with_merges(&pp, &revs, out, flags);
+       if (rebase_merges) {
+               ret = make_script_with_merges(&pp, &revs, out, flags);
+               goto cleanup;
+       }
 
        while ((commit = get_revision(&revs))) {
                int is_empty = is_original_commit_empty(commit);
@@ -5405,7 +5414,9 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
        if (skipped_commit)
                advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,
                                  _("use --reapply-cherry-picks to include skipped commits"));
-       return 0;
+cleanup:
+       release_revisions(&revs);
+       return ret;
 }
 
 /*
diff --git a/serve.c b/serve.c
index b3fe9b5126a3347784d501e296102ab87cc4c5ab..733347f602aa1ede3e45fee94050163790d65bf9 100644 (file)
--- a/serve.c
+++ b/serve.c
@@ -3,7 +3,6 @@
 #include "config.h"
 #include "pkt-line.h"
 #include "version.h"
-#include "strvec.h"
 #include "ls-refs.h"
 #include "protocol-caps.h"
 #include "serve.h"
diff --git a/setup.c b/setup.c
index a7b36f3ffbfbf272a319005828961d9f7db8afe8..faf5095e44de5d7a51048d8b501ea124fe89159f 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -459,7 +459,16 @@ static void setup_original_cwd(void)
         */
 
        /* Normalize the directory */
-       strbuf_realpath(&tmp, tmp_original_cwd, 1);
+       if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {
+               trace2_data_string("setup", the_repository,
+                                  "realpath-path", tmp_original_cwd);
+               trace2_data_string("setup", the_repository,
+                                  "realpath-failure", strerror(errno));
+               free((char*)tmp_original_cwd);
+               tmp_original_cwd = NULL;
+               return;
+       }
+
        free((char*)tmp_original_cwd);
        tmp_original_cwd = NULL;
        startup_info->original_cwd = strbuf_detach(&tmp, NULL);
@@ -1470,7 +1479,7 @@ int git_config_perm(const char *var, const char *value)
        int i;
        char *endptr;
 
-       if (value == NULL)
+       if (!value)
                return PERM_GROUP;
 
        if (!strcmp(value, "umask"))
index 6cd307ac2c65a2825e467aeb9c1e6abfe8cc7e70..133496bd4d9f2979dfe2765e98a50186463dde1d 100644 (file)
@@ -397,7 +397,7 @@ subst_from_stdin (void)
                  /* Substitute the variable's value from the environment.  */
                  const char *env_value = getenv (buffer);
 
-                 if (env_value != NULL)
+                 if (env_value)
                    fputs (env_value, stdout);
                }
              else
index e158be58b05591820d645a6a44423d2da97097e1..4270471586e62cbab3f3c9da6897b0f423fbf586 100644 (file)
--- a/shallow.c
+++ b/shallow.c
@@ -262,6 +262,7 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
                if ((o->flags & both_flags) == both_flags)
                        o->flags &= ~not_shallow_flag;
        }
+       release_revisions(&revs);
        return result;
 }
 
@@ -560,7 +561,7 @@ static void paint_down(struct paint_info *info, const struct object_id *oid,
                else
                        c->object.flags |= SEEN;
 
-               if (*refs == NULL)
+               if (!*refs)
                        *refs = bitmap;
                else {
                        memcpy(tmp, *refs, bitmap_size);
index 50d4596f0d6084b8537c31a89fb2932565aa800a..4330192e9c363df8103e27d5ccb06769adfbc0b8 100644 (file)
@@ -62,7 +62,9 @@ ifndef V
        QUIET_BUILT_IN = @echo '   ' BUILTIN $@;
        QUIET_LNCP     = @echo '   ' LN/CP $@;
        QUIET_XGETTEXT = @echo '   ' XGETTEXT $@;
+       QUIET_MSGINIT  = @echo '   ' MSGINIT $@;
        QUIET_MSGFMT   = @echo '   ' MSGFMT $@;
+       QUIET_MSGMERGE = @echo '   ' MSGMERGE $@;
        QUIET_GCOV     = @echo '   ' GCOV $@;
        QUIET_SP       = @echo '   ' SP $<;
        QUIET_HDR      = @echo '   ' HDR $(<:hcc=h);
index 8636af72de59f38ff9de871c34bd44f8aab75286..e4a54ce19433dd0cdd553996762af642ace0d9b8 100644 (file)
@@ -9,6 +9,11 @@
 #include "dir.h"
 #include "fsmonitor.h"
 
+struct modify_index_context {
+       struct index_state *write;
+       struct pattern_list *pl;
+};
+
 static struct cache_entry *construct_sparse_dir_entry(
                                struct index_state *istate,
                                const char *sparse_dir,
@@ -118,7 +123,7 @@ static int index_has_unmerged_entries(struct index_state *istate)
        return 0;
 }
 
-static int is_sparse_index_allowed(struct index_state *istate, int flags)
+int is_sparse_index_allowed(struct index_state *istate, int flags)
 {
        if (!core_apply_sparse_checkout || !core_sparse_checkout_cone)
                return 0;
@@ -173,7 +178,7 @@ int convert_to_sparse(struct index_state *istate, int flags)
         * If the index is already sparse, empty, or otherwise
         * cannot be converted to sparse, do not convert.
         */
-       if (istate->sparse_index || !istate->cache_nr ||
+       if (istate->sparse_index == INDEX_COLLAPSED || !istate->cache_nr ||
            !is_sparse_index_allowed(istate, flags))
                return 0;
 
@@ -214,7 +219,7 @@ int convert_to_sparse(struct index_state *istate, int flags)
        FREE_AND_NULL(istate->fsmonitor_dirty);
        FREE_AND_NULL(istate->fsmonitor_last_update);
 
-       istate->sparse_index = 1;
+       istate->sparse_index = INDEX_COLLAPSED;
        trace2_region_leave("index", "convert_to_sparse", istate->repo);
        return 0;
 }
@@ -231,56 +236,148 @@ static int add_path_to_index(const struct object_id *oid,
                             struct strbuf *base, const char *path,
                             unsigned int mode, void *context)
 {
-       struct index_state *istate = (struct index_state *)context;
+       struct modify_index_context *ctx = (struct modify_index_context *)context;
        struct cache_entry *ce;
        size_t len = base->len;
 
-       if (S_ISDIR(mode))
-               return READ_TREE_RECURSIVE;
+       if (S_ISDIR(mode)) {
+               int dtype;
+               size_t baselen = base->len;
+               if (!ctx->pl)
+                       return READ_TREE_RECURSIVE;
+
+               /*
+                * Have we expanded to a point outside of the sparse-checkout?
+                *
+                * Artificially pad the path name with a slash "/" to
+                * indicate it as a directory, and add an arbitrary file
+                * name ("-") so we can consider base->buf as a file name
+                * to match against the cone-mode patterns.
+                *
+                * If we compared just "path", then we would expand more
+                * than we should. Since every file at root is always
+                * included, we would expand every directory at root at
+                * least one level deep instead of using sparse directory
+                * entries.
+                */
+               strbuf_addstr(base, path);
+               strbuf_add(base, "/-", 2);
+
+               if (path_matches_pattern_list(base->buf, base->len,
+                                             NULL, &dtype,
+                                             ctx->pl, ctx->write)) {
+                       strbuf_setlen(base, baselen);
+                       return READ_TREE_RECURSIVE;
+               }
 
-       strbuf_addstr(base, path);
+               /*
+                * The path "{base}{path}/" is a sparse directory. Create the correct
+                * name for inserting the entry into the index.
+                */
+               strbuf_setlen(base, base->len - 1);
+       } else {
+               strbuf_addstr(base, path);
+       }
 
-       ce = make_cache_entry(istate, mode, oid, base->buf, 0, 0);
+       ce = make_cache_entry(ctx->write, mode, oid, base->buf, 0, 0);
        ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED;
-       set_index_entry(istate, istate->cache_nr++, ce);
+       set_index_entry(ctx->write, ctx->write->cache_nr++, ce);
 
        strbuf_setlen(base, len);
        return 0;
 }
 
-void ensure_full_index(struct index_state *istate)
+void expand_index(struct index_state *istate, struct pattern_list *pl)
 {
        int i;
        struct index_state *full;
        struct strbuf base = STRBUF_INIT;
+       const char *tr_region;
+       struct modify_index_context ctx;
 
-       if (!istate || !istate->sparse_index)
+       /*
+        * If the index is already full, then keep it full. We will convert
+        * it to a sparse index on write, if possible.
+        */
+       if (!istate || istate->sparse_index == INDEX_EXPANDED)
                return;
 
+       /*
+        * If our index is sparse, but our new pattern set does not use
+        * cone mode patterns, then we need to expand the index before we
+        * continue. A NULL pattern set indicates a full expansion to a
+        * full index.
+        */
+       if (pl && !pl->use_cone_patterns) {
+               pl = NULL;
+       } else {
+               /*
+                * We might contract file entries into sparse-directory
+                * entries, and for that we will need the cache tree to
+                * be recomputed.
+                */
+               cache_tree_free(&istate->cache_tree);
+
+               /*
+                * If there is a problem creating the cache tree, then we
+                * need to expand to a full index since we cannot satisfy
+                * the current request as a sparse index.
+                */
+               if (cache_tree_update(istate, 0))
+                       pl = NULL;
+       }
+
        if (!istate->repo)
                istate->repo = the_repository;
 
-       trace2_region_enter("index", "ensure_full_index", istate->repo);
+       /*
+        * A NULL pattern set indicates we are expanding a full index, so
+        * we use a special region name that indicates the full expansion.
+        * This is used by test cases, but also helps to differentiate the
+        * two cases.
+        */
+       tr_region = pl ? "expand_index" : "ensure_full_index";
+       trace2_region_enter("index", tr_region, istate->repo);
 
        /* initialize basics of new index */
        full = xcalloc(1, sizeof(struct index_state));
        memcpy(full, istate, sizeof(struct index_state));
 
+       /*
+        * This slightly-misnamed 'full' index might still be sparse if we
+        * are only modifying the list of sparse directories. This hinges
+        * on whether we have a non-NULL pattern list.
+        */
+       full->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
+
        /* then change the necessary things */
-       full->sparse_index = 0;
        full->cache_alloc = (3 * istate->cache_alloc) / 2;
        full->cache_nr = 0;
        ALLOC_ARRAY(full->cache, full->cache_alloc);
 
+       ctx.write = full;
+       ctx.pl = pl;
+
        for (i = 0; i < istate->cache_nr; i++) {
                struct cache_entry *ce = istate->cache[i];
                struct tree *tree;
                struct pathspec ps;
+               int dtype;
 
                if (!S_ISSPARSEDIR(ce->ce_mode)) {
                        set_index_entry(full, full->cache_nr++, ce);
                        continue;
                }
+
+               /* We now have a sparse directory entry. Should we expand? */
+               if (pl &&
+                   path_matches_pattern_list(ce->name, ce->ce_namelen,
+                                             NULL, &dtype,
+                                             pl, istate) == NOT_MATCHED) {
+                       set_index_entry(full, full->cache_nr++, ce);
+                       continue;
+               }
+
                if (!(ce->ce_flags & CE_SKIP_WORKTREE))
                        warning(_("index entry is a directory, but not sparse (%08x)"),
                                ce->ce_flags);
@@ -297,7 +394,7 @@ void ensure_full_index(struct index_state *istate)
                strbuf_add(&base, ce->name, strlen(ce->name));
 
                read_tree_at(istate->repo, tree, &base, &ps,
-                            add_path_to_index, full);
+                            add_path_to_index, &ctx);
 
                /* free directory entries. full entries are re-used */
                discard_cache_entry(ce);
@@ -306,7 +403,7 @@ void ensure_full_index(struct index_state *istate)
        /* Copy back into original index. */
        memcpy(&istate->name_hash, &full->name_hash, sizeof(full->name_hash));
        memcpy(&istate->dir_hash, &full->dir_hash, sizeof(full->dir_hash));
-       istate->sparse_index = 0;
+       istate->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
        free(istate->cache);
        istate->cache = full->cache;
        istate->cache_nr = full->cache_nr;
@@ -322,7 +419,12 @@ void ensure_full_index(struct index_state *istate)
        cache_tree_free(&istate->cache_tree);
        cache_tree_update(istate, 0);
 
-       trace2_region_leave("index", "ensure_full_index", istate->repo);
+       trace2_region_leave("index", tr_region, istate->repo);
+}
+
+void ensure_full_index(struct index_state *istate)
+{
+       expand_index(istate, NULL);
 }
 
 void ensure_correct_sparsity(struct index_state *istate)
index 633d4fb7e318afcd69257e5d85850138da9d7348..59a92d819ecdac1430b69db081b79cfc7e8ca84a 100644 (file)
@@ -3,6 +3,7 @@
 
 struct index_state;
 #define SPARSE_INDEX_MEMORY_ONLY (1 << 0)
+int is_sparse_index_allowed(struct index_state *istate, int flags);
 int convert_to_sparse(struct index_state *istate, int flags);
 void ensure_correct_sparsity(struct index_state *istate);
 void clear_skip_worktree_from_present_files(struct index_state *istate);
@@ -23,4 +24,17 @@ void expand_to_path(struct index_state *istate,
 struct repository;
 int set_sparse_index_config(struct repository *repo, int enable);
 
+struct pattern_list;
+
+/**
+ * Scan the given index and compare its entries to the given pattern list.
+ * If the index is sparse and the pattern list uses cone mode patterns,
+ * then modify the index to contain the all of the file entries within that
+ * new pattern list. This expands sparse directories only as far as needed.
+ *
+ * If the pattern list is NULL or does not use cone mode patterns, then the
+ * index is expanded to a full index.
+ */
+void expand_index(struct index_state *istate, struct pattern_list *pl);
+
 #endif
index 29668b0620dd91458b27d61d9a8498f752aa3a1c..ce3beaf5d4f0d648310acc39a76e31d67a3a40c8 100644 (file)
@@ -204,17 +204,17 @@ int check_submodule_name(const char *name)
                return -1;
 
        /*
-        * Look for '..' as a path component. Check both '/' and '\\' as
+        * Look for '..' as a path component. Check is_xplatform_dir_sep() as
         * separators rather than is_dir_sep(), because we want the name rules
         * to be consistent across platforms.
         */
        goto in_component; /* always start inside component */
        while (*name) {
                char c = *name++;
-               if (c == '/' || c == '\\') {
+               if (is_xplatform_dir_sep(c)) {
 in_component:
                        if (name[0] == '.' && name[1] == '.' &&
-                           (!name[2] || name[2] == '/' || name[2] == '\\'))
+                           (!name[2] || is_xplatform_dir_sep(name[2])))
                                return -1;
                }
        }
index fa229a8b97a12ab4bd354db6ed0de5eddd098af5..28a8ca6bf46845906cb4bc2071a594a383eefc72 100644 (file)
@@ -38,7 +38,7 @@ struct submodule {
        const char *path;
        const char *name;
        const char *url;
-       int fetch_recurse;
+       enum submodule_recurse_mode fetch_recurse;
        const char *ignore;
        const char *branch;
        struct submodule_update_strategy update_strategy;
index 86c8f0f89dbdb0e82cb18054392a884c70a71811..7923e951e1c1ba9429ab2e35e23cd89d94ab3d3e 100644 (file)
@@ -619,7 +619,7 @@ void show_submodule_diff_summary(struct diff_options *o, const char *path,
                struct object_id *one, struct object_id *two,
                unsigned dirty_submodule)
 {
-       struct rev_info rev;
+       struct rev_info rev = REV_INFO_INIT;
        struct commit *left = NULL, *right = NULL;
        struct commit_list *merge_bases = NULL;
        struct repository *sub;
@@ -645,8 +645,8 @@ void show_submodule_diff_summary(struct diff_options *o, const char *path,
        print_submodule_diff_summary(sub, &rev, o);
 
 out:
-       if (merge_bases)
-               free_commit_list(merge_bases);
+       free_commit_list(merge_bases);
+       release_revisions(&rev);
        clear_commit_marks(left, ~0);
        clear_commit_marks(right, ~0);
        if (sub) {
@@ -735,8 +735,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 
 done:
        strbuf_release(&sb);
-       if (merge_bases)
-               free_commit_list(merge_bases);
+       free_commit_list(merge_bases);
        if (left)
                clear_commit_marks(left, ~0);
        if (right)
@@ -925,9 +924,11 @@ static void collect_changed_submodules(struct repository *r,
                diff_rev.diffopt.format_callback_data = &data;
                diff_rev.dense_combined_merges = 1;
                diff_tree_combined_merge(commit, &diff_rev);
+               release_revisions(&diff_rev);
        }
 
        reset_revision_walk();
+       release_revisions(&rev);
 }
 
 static void free_submodules_data(struct string_list *submodules)
index 40c14452377521b9ca46b44e64e3580539c2d1cc..437bc96e05eb2fe3845b998be584737c6d67147d 100644 (file)
@@ -13,7 +13,7 @@ struct repository;
 struct string_list;
 struct strbuf;
 
-enum {
+enum submodule_recurse_mode {
        RECURSE_SUBMODULES_ONLY = -5,
        RECURSE_SUBMODULES_CHECK = -4,
        RECURSE_SUBMODULES_ERROR = -3,
index 9ffea1d31478029a62fd60bdc1041001706a3bea..309a31133c6126eefc37f0397ab3706dff905825 100644 (file)
--- a/t/README
+++ b/t/README
@@ -419,7 +419,7 @@ the --sparse command-line argument.
 GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
 by overriding the minimum number of cache entries required per thread.
 
-GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when true, enables the
+GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when false, disables the
 built-in version of git add -i. See 'add.interactive.useBuiltin' in
 git-config(1).
 
index 09e86f9ba0804f70d6561b5bda03d69535f11dcf..cc01d891504eb117eb9c367ebc4e89b516157012 100644 (file)
@@ -56,6 +56,10 @@ check_count () {
        ' "$@" <actual
 }
 
+get_progress_result () {
+       tr '\015' '\012' | tail -n 1
+}
+
 test_expect_success 'setup A lines' '
        echo "1A quick brown fox jumps over the" >file &&
        echo "lazy dog" >>file &&
@@ -604,3 +608,39 @@ test_expect_success 'blame -L X,-N (non-numeric N)' '
 test_expect_success 'blame -L ,^/RE/' '
        test_must_fail $PROG -L1,^/99/ file
 '
+
+test_expect_success 'blame progress on a full file' '
+       cat >expect <<-\EOF &&
+       Blaming lines: 100% (10/10), done.
+       EOF
+
+       GIT_PROGRESS_DELAY=0 \
+       git blame --progress hello.c 2>stderr &&
+
+       get_progress_result <stderr >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'blame progress on a single range' '
+       cat >expect <<-\EOF &&
+       Blaming lines: 100% (4/4), done.
+       EOF
+
+       GIT_PROGRESS_DELAY=0 \
+       git blame --progress -L 3,6 hello.c 2>stderr &&
+
+       get_progress_result <stderr >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'blame progress on multiple ranges' '
+       cat >expect <<-\EOF &&
+       Blaming lines: 100% (7/7), done.
+       EOF
+
+       GIT_PROGRESS_DELAY=0 \
+       git blame --progress -L 3,6 -L 8,10 hello.c 2>stderr &&
+
+       get_progress_result <stderr >actual &&
+       test_cmp expect actual
+'
index fc2d460904340a782bfb4a20baa41108099fefef..4e5553e20249debf36a76296f18599300ee91af5 100644 (file)
@@ -99,6 +99,7 @@ int cmd__fast_rebase(int argc, const char **argv)
        struct merge_result result;
        struct strbuf reflog_msg = STRBUF_INIT;
        struct strbuf branch_name = STRBUF_INIT;
+       int ret = 0;
 
        /*
         * test-tool stuff doesn't set up the git directory by default; need to
@@ -137,13 +138,17 @@ int cmd__fast_rebase(int argc, const char **argv)
        revs.topo_order = 1;
        strvec_pushl(&rev_walk_args, "", argv[4], "--not", argv[3], NULL);
 
-       if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1)
-               return error(_("unhandled options"));
+       if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) {
+               ret = error(_("unhandled options"));
+               goto cleanup;
+       }
 
        strvec_clear(&rev_walk_args);
 
-       if (prepare_revision_walk(&revs) < 0)
-               return error(_("error preparing revisions"));
+       if (prepare_revision_walk(&revs) < 0) {
+               ret = error(_("error preparing revisions"));
+               goto cleanup;
+       }
 
        init_merge_options(&merge_opt, the_repository);
        memset(&result, 0, sizeof(result));
@@ -201,8 +206,6 @@ int cmd__fast_rebase(int argc, const char **argv)
                }
                if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0)
                        die(_("unable to update HEAD"));
-               strbuf_release(&reflog_msg);
-               strbuf_release(&branch_name);
 
                prime_cache_tree(the_repository, the_repository->index,
                                 result.tree);
@@ -221,5 +224,11 @@ int cmd__fast_rebase(int argc, const char **argv)
        if (write_locked_index(&the_index, &lock,
                               COMMIT_LOCK | SKIP_IF_UNCHANGED))
                die(_("unable to write %s"), get_index_file());
-       return (result.clean == 0);
+
+       ret = (result.clean == 0);
+cleanup:
+       strbuf_release(&reflog_msg);
+       strbuf_release(&branch_name);
+       release_revisions(&revs);
+       return ret;
 }
diff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c
new file mode 100644 (file)
index 0000000..f7b79da
--- /dev/null
@@ -0,0 +1,56 @@
+#include "git-compat-util.h"
+#include "test-tool.h"
+#include "strbuf.h"
+#include "object-store.h"
+#include "packfile.h"
+#include "pack-mtimes.h"
+
+static void dump_mtimes(struct packed_git *p)
+{
+       uint32_t i;
+       if (load_pack_mtimes(p) < 0)
+               die("could not load pack .mtimes");
+
+       for (i = 0; i < p->num_objects; i++) {
+               struct object_id oid;
+               if (nth_packed_object_id(&oid, p, i) < 0)
+                       die("could not load object id at position %"PRIu32, i);
+
+               printf("%s %"PRIu32"\n",
+                      oid_to_hex(&oid), nth_packed_mtime(p, i));
+       }
+}
+
+static const char *pack_mtimes_usage = "\n"
+"  test-tool pack-mtimes <pack-name.mtimes>";
+
+int cmd__pack_mtimes(int argc, const char **argv)
+{
+       struct strbuf buf = STRBUF_INIT;
+       struct packed_git *p;
+
+       setup_git_directory();
+
+       if (argc != 2)
+               usage(pack_mtimes_usage);
+
+       for (p = get_all_packs(the_repository); p; p = p->next) {
+               strbuf_addstr(&buf, basename(p->pack_name));
+               strbuf_strip_suffix(&buf, ".pack");
+               strbuf_addstr(&buf, ".mtimes");
+
+               if (!strcmp(buf.buf, argv[1]))
+                       break;
+
+               strbuf_reset(&buf);
+       }
+
+       strbuf_release(&buf);
+
+       if (!p)
+               die("could not find pack '%s'", argv[1]);
+
+       dump_mtimes(p);
+
+       return 0;
+}
index 625b2dbf8226fee261c52b3cf74f24187e0ca68e..4a45d5bac2af5678eda5ad8b49c7747a3973878e 100644 (file)
@@ -43,6 +43,7 @@ static int run_revision_walk(void)
        }
 
        reset_revision_walk();
+       release_revisions(&rev);
        return got_revision;
 }
 
index 0424f7adf5d69cc2596a58ee3ef33f1826dfc621..d2eacd302d60910f60cc538a17f9854691e299f2 100644 (file)
@@ -48,6 +48,7 @@ static struct test_cmd cmds[] = {
        { "oidmap", cmd__oidmap },
        { "oidtree", cmd__oidtree },
        { "online-cpus", cmd__online_cpus },
+       { "pack-mtimes", cmd__pack_mtimes },
        { "parse-options", cmd__parse_options },
        { "parse-pathspec-file", cmd__parse_pathspec_file },
        { "partial-clone", cmd__partial_clone },
index c876e8246fbdff9ddf43e5b4ec46944406f9d33d..960cc27ef7cfc4d7b73d9fcd672166066a2161d4 100644 (file)
@@ -38,6 +38,7 @@ int cmd__mktemp(int argc, const char **argv);
 int cmd__oidmap(int argc, const char **argv);
 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_pathspec_file(int argc, const char** argv);
 int cmd__partial_clone(int argc, const char **argv);
index 5aff2abe8b5490156e7745beb5ad01d9cacc0d58..2a5b8738ea37da950b65cd8a3357b9ebdb59363e 100644 (file)
@@ -142,10 +142,11 @@ start_p4d () {
 
 p4_add_user () {
        name=$1 &&
+       fullname="${2:-Dr. $1}"
        p4 user -f -i <<-EOF
        User: $name
        Email: $name@example.com
-       FullName: Dr. $name
+       FullName: $fullname
        EOF
 }
 
index 2fde2353fd38356548fd40e4808984618b0d9585..ea28971e8ee6abfcd3c0394c6d8b143c75ac12dd 100644 (file)
@@ -1,3 +1,7 @@
+if test -z "$TEST_FAILS_SANITIZE_LEAK"
+then
+       TEST_PASSES_SANITIZE_LEAK=true
+fi
 . ./test-lib.sh
 
 if test -n "$NO_SVN_TESTS"
diff --git a/t/lib-sudo.sh b/t/lib-sudo.sh
new file mode 100644 (file)
index 0000000..b4d7788
--- /dev/null
@@ -0,0 +1,15 @@
+# Helpers for running git commands under sudo.
+
+# Runs a scriplet passed through stdin under sudo.
+run_with_sudo () {
+       local ret
+       local RUN="$TEST_DIRECTORY/$$.sh"
+       write_script "$RUN" "$TEST_SHELL_PATH"
+       # avoid calling "$RUN" directly so sudo doesn't get a chance to
+       # override the shell, add aditional restrictions or even reject
+       # running the script because its security policy deem it unsafe
+       sudo "$TEST_SHELL_PATH" -c "\"$RUN\""
+       ret=$?
+       rm -f "$RUN"
+       return $ret
+}
diff --git a/t/lib-unique-files.sh b/t/lib-unique-files.sh
new file mode 100644 (file)
index 0000000..a14080f
--- /dev/null
@@ -0,0 +1,34 @@
+# Helper to create files with unique contents
+
+# Create multiple files with unique contents within this test run. Takes the
+# number of directories, the number of files in each directory, and the base
+# directory.
+#
+# test_create_unique_files 2 3 my_dir -- Creates 2 directories with 3 files
+#                                       each in my_dir, all with contents
+#                                       different from previous invocations
+#                                       of this command in this run.
+
+test_create_unique_files () {
+       test "$#" -ne 3 && BUG "3 param"
+
+       local dirs="$1" &&
+       local files="$2" &&
+       local basedir="$3" &&
+       local counter="0" &&
+       local i &&
+       local j &&
+       test_tick &&
+       local basedata="$basedir$test_tick" &&
+       rm -rf "$basedir" &&
+       for i in $(test_seq $dirs)
+       do
+               local dir="$basedir/dir$i" &&
+               mkdir -p "$dir" &&
+               for j in $(test_seq $files)
+               do
+                       counter=$((counter + 1)) &&
+                       echo "$basedata.$counter">"$dir/file$j.txt"
+               done
+       done
+}
diff --git a/t/perf/p0008-odb-fsync.sh b/t/perf/p0008-odb-fsync.sh
new file mode 100755 (executable)
index 0000000..b3a90f3
--- /dev/null
@@ -0,0 +1,82 @@
+#!/bin/sh
+#
+# This test measures the performance of adding new files to the object
+# database. The test was originally added to measure the effect of the
+# core.fsyncMethod=batch mode, which is why we are testing different values of
+# that setting explicitly and creating a lot of unique objects.
+
+test_description="Tests performance of adding things to the object database"
+
+. ./perf-lib.sh
+
+. $TEST_DIRECTORY/lib-unique-files.sh
+
+test_perf_fresh_repo
+test_checkout_worktree
+
+dir_count=10
+files_per_dir=50
+total_files=$((dir_count * files_per_dir))
+
+populate_files () {
+       test_create_unique_files $dir_count $files_per_dir files
+}
+
+setup_repo () {
+       (rm -rf .git || 1) &&
+       git init &&
+       test_commit first &&
+       populate_files
+}
+
+test_perf_fsync_cfgs () {
+       local method &&
+       local cfg &&
+       for method in none fsync batch writeout-only
+       do
+               case $method in
+               none)
+                       cfg="-c core.fsync=none"
+                       ;;
+               *)
+                       cfg="-c core.fsync=loose-object -c core.fsyncMethod=$method"
+               esac &&
+
+               # Set GIT_TEST_FSYNC=1 explicitly since fsync is normally
+               # disabled by t/test-lib.sh.
+               if ! test_perf "$1 (fsyncMethod=$method)" \
+                                               --setup "$2" \
+                                               "GIT_TEST_FSYNC=1 git $cfg $3"
+               then
+                       break
+               fi
+       done
+}
+
+test_perf_fsync_cfgs "add $total_files files" \
+       "setup_repo" \
+       "add -- files"
+
+test_perf_fsync_cfgs "stash $total_files files" \
+       "setup_repo" \
+       "stash push -u -- files"
+
+test_perf_fsync_cfgs "unpack $total_files files" \
+       "
+       setup_repo &&
+       git -c core.fsync=none add -- files &&
+       git -c core.fsync=none commit -q -m second &&
+       echo HEAD | git pack-objects -q --stdout --revs >test_pack.pack &&
+       setup_repo
+       " \
+       "unpack-objects -q <test_pack.pack"
+
+test_perf_fsync_cfgs "commit $total_files files" \
+       "
+       setup_repo &&
+       git -c core.fsync=none add -- files &&
+       populate_files
+       " \
+       "commit -q -a -m test"
+
+test_done
index 382716cfca909e82c0bc5bf04e3bb3726dc2f9f1..c181110a43931fb2a8131270a4d8bdcb0a2e7a4b 100755 (executable)
@@ -106,10 +106,13 @@ test_perf_on_all () {
 }
 
 test_perf_on_all git status
+test_perf_on_all 'git stash && git stash pop'
+test_perf_on_all 'echo >>new && git stash -u && git stash pop'
 test_perf_on_all git add -A
 test_perf_on_all git add .
 test_perf_on_all git commit -a -m A
 test_perf_on_all git checkout -f -
+test_perf_on_all "git sparse-checkout add f2/f3/f1 && git sparse-checkout set $SPARSE_CONE"
 test_perf_on_all git reset
 test_perf_on_all git reset --hard
 test_perf_on_all git reset -- does-not-exist
index 2bc47ded4d11f95a1711b442dbb8a363c1fb531f..03fbfbb85d34142713787997009be48b97ec03fc 100755 (executable)
@@ -36,7 +36,8 @@ do
                else
                        prereq=""
                fi
-               test_perf $prereq "$engine log$GIT_PERF_4220_LOG_OPTS --grep='$pattern'" "
+               test_perf "$engine log$GIT_PERF_4220_LOG_OPTS --grep='$pattern'" \
+                       --prereq "$prereq" "
                        git -c grep.patternType=$engine log --pretty=format:%h$GIT_PERF_4220_LOG_OPTS --grep='$pattern' >'out.$engine' || :
                "
        done
index 060971265a9c852c608d97d5059172f14a7c3395..0a6d6dfc2198f7bbf0fec141575ff25306eda423 100755 (executable)
@@ -26,7 +26,8 @@ do
                else
                        prereq=""
                fi
-               test_perf $prereq "$engine log$GIT_PERF_4221_LOG_OPTS --grep='$pattern'" "
+               test_perf "$engine log$GIT_PERF_4221_LOG_OPTS --grep='$pattern'" \
+                       --prereq "$prereq" "
                        git -c grep.patternType=$engine log --pretty=format:%h$GIT_PERF_4221_LOG_OPTS --grep='$pattern' >'out.$engine' || :
                "
        done
index c16f6a3ff698c088db427ae9d7b0a8f16f59a8c6..14c601bbf860aa67087e5b9a0bb421f938f9ff3c 100755 (executable)
@@ -26,9 +26,8 @@ test_expect_success 'set up thread-counting tests' '
        done
 '
 
-test_perf PERF_EXTRA 'index-pack 0 threads' '
-       rm -rf repo.git &&
-       git init --bare repo.git &&
+test_perf 'index-pack 0 threads' --prereq PERF_EXTRA \
+       --setup 'rm -rf repo.git && git init --bare repo.git' '
        GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK
 '
 
@@ -36,17 +35,15 @@ for t in $threads
 do
        THREADS=$t
        export THREADS
-       test_perf PERF_EXTRA "index-pack $t threads" '
-               rm -rf repo.git &&
-               git init --bare repo.git &&
+       test_perf "index-pack $t threads" --prereq PERF_EXTRA \
+               --setup 'rm -rf repo.git && git init --bare repo.git' '
                GIT_DIR=repo.git GIT_FORCE_THREADS=1 \
                git index-pack --threads=$THREADS --stdin <$PACK
        '
 done
 
-test_perf 'index-pack default number of threads' '
-       rm -rf repo.git &&
-       git init --bare repo.git &&
+test_perf 'index-pack default number of threads' \
+       --setup 'rm -rf repo.git && git init --bare repo.git' '
        GIT_DIR=repo.git git index-pack --stdin < $PACK
 '
 
index 0b9129ca7bc55a61d3692834fe44940214669244..b1cb23880fb2bf44faad8745d58f392ceff17a94 100755 (executable)
@@ -60,18 +60,6 @@ then
        esac
 fi
 
-if test -n "$GIT_PERF_7519_DROP_CACHE"
-then
-       # When using GIT_PERF_7519_DROP_CACHE, GIT_PERF_REPEAT_COUNT must be 1 to
-       # generate valid results. Otherwise the caching that happens for the nth
-       # run will negate the validity of the comparisons.
-       if test "$GIT_PERF_REPEAT_COUNT" -ne 1
-       then
-               echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2
-               GIT_PERF_REPEAT_COUNT=1
-       fi
-fi
-
 trace_start () {
        if test -n "$GIT_PERF_7519_TRACE"
        then
@@ -175,10 +163,10 @@ setup_for_fsmonitor_hook () {
 
 test_perf_w_drop_caches () {
        if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-               test-tool drop-caches
+               test_perf "$1" --setup "test-tool drop-caches" "$2"
+       else
+               test_perf "$@"
        fi
-
-       test_perf "$@"
 }
 
 test_fsmonitor_suite () {
index 8b09c5bf328b880b7bbe10f37c7356b785473384..9bfb86842a90df812c7a9260e153830668408483 100755 (executable)
@@ -49,13 +49,15 @@ do
                fi
                if ! test_have_prereq PERF_GREP_ENGINES_THREADS
                then
-                       test_perf $prereq "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern'" "
+                       test_perf "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern'" \
+                               --prereq "$prereq" "
                                git -c grep.patternType=$engine grep$GIT_PERF_7820_GREP_OPTS -- '$pattern' >'out.$engine' || :
                        "
                else
                        for threads in $GIT_PERF_GREP_THREADS
                        do
-                               test_perf PTHREADS,$prereq "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern' with $threads threads" "
+                               test_perf "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern' with $threads threads"
+                                       --prereq PTHREADS,$prereq "
                                        git -c grep.patternType=$engine -c grep.threads=$threads grep$GIT_PERF_7820_GREP_OPTS -- '$pattern' >'out.$engine.$threads' || :
                                "
                        done
index 932105cd12c9331362e86030df6d3b10af7f2dac..ab3687c28d449136f4d5331e5bcbd2d6103d8d5f 100644 (file)
@@ -189,19 +189,39 @@ exit $ret' >&3 2>&4
 }
 
 test_wrapper_ () {
-       test_wrapper_func_=$1; shift
+       local test_wrapper_func_="$1"; shift
+       local test_title_="$1"; shift
        test_start_
-       test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
-       test "$#" = 2 ||
-       BUG "not 2 or 3 parameters to test-expect-success"
+       test_prereq=
+       test_perf_setup_=
+       while test $# != 0
+       do
+               case $1 in
+               --prereq)
+                       test_prereq=$2
+                       shift
+                       ;;
+               --setup)
+                       test_perf_setup_=$2
+                       shift
+                       ;;
+               *)
+                       break
+                       ;;
+               esac
+               shift
+       done
+       test "$#" = 1 || BUG "test_wrapper_ needs 2 positional parameters"
        export test_prereq
-       if ! test_skip "$@"
+       export test_perf_setup_
+
+       if ! test_skip "$test_title_" "$@"
        then
                base=$(basename "$0" .sh)
                echo "$test_count" >>"$perf_results_dir"/$base.subtests
                echo "$1" >"$perf_results_dir"/$base.$test_count.descr
                base="$perf_results_dir"/"$PERF_RESULTS_PREFIX$(basename "$0" .sh)"."$test_count"
-               "$test_wrapper_func_" "$@"
+               "$test_wrapper_func_" "$test_title_" "$@"
        fi
 
        test_finish_
@@ -214,6 +234,16 @@ test_perf_ () {
                echo "perf $test_count - $1:"
        fi
        for i in $(test_seq 1 $GIT_PERF_REPEAT_COUNT); do
+               if test -n "$test_perf_setup_"
+               then
+                       say >&3 "setup: $test_perf_setup_"
+                       if ! test_eval_ $test_perf_setup_
+                       then
+                               test_failure_ "$test_perf_setup_"
+                               break
+                       fi
+
+               fi
                say >&3 "running: $2"
                if test_run_perf_ "$2"
                then
@@ -237,11 +267,24 @@ test_perf_ () {
        rm test_time.*
 }
 
+# Usage: test_perf 'title' [options] 'perf-test'
+#      Run the performance test script specified in perf-test with
+#      optional prerequisite and setup steps.
+# Options:
+#      --prereq prerequisites: Skip the test if prequisites aren't met
+#      --setup "setup-steps": Run setup steps prior to each measured iteration
+#
 test_perf () {
        test_wrapper_ test_perf_ "$@"
 }
 
 test_size_ () {
+       if test -n "$test_perf_setup_"
+       then
+               say >&3 "setup: $test_perf_setup_"
+               test_eval_ $test_perf_setup_
+       fi
+
        say >&3 "running: $2"
        if test_eval_ "$2" 3>"$base".result; then
                test_ok_ "$1"
@@ -250,6 +293,14 @@ test_size_ () {
        fi
 }
 
+# Usage: test_size 'title' [options] 'size-test'
+#      Run the size test script specified in size-test with optional
+#      prerequisites and setup steps. Returns the numeric value
+#      returned by size-test.
+# Options:
+#      --prereq prerequisites: Skip the test if prequisites aren't met
+#      --setup "setup-steps": Run setup steps prior to the size measurement
+
 test_size () {
        test_wrapper_ test_size_ "$@"
 }
index 6c3e1f7159d4dcc6a2e61228fa7c4f3cec42ef3b..6c33a4369015c813a73384ff68149463c5189105 100755 (executable)
@@ -181,7 +181,7 @@ for cmd in git "git help"
 do
        test_expect_success "'$cmd' section spacing" '
                test_section_spacing_trailer git help <<-\EOF &&
-               usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
+               usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
 
                These are common Git commands used in various situations:
 
index 0feb41a23f2c27db155fc49b6fb3ff7f9106cc53..7f80f463930407410c6d3f671fb1f7833ec3b01e 100755 (executable)
@@ -77,12 +77,12 @@ create_NNO_MIX_files () {
 
 check_warning () {
        case "$1" in
-       LF_CRLF) echo "warning: LF will be replaced by CRLF" >"$2".expect ;;
-       CRLF_LF) echo "warning: CRLF will be replaced by LF" >"$2".expect ;;
-       '')                                                      >"$2".expect ;;
+       LF_CRLF) echo "LF will be replaced by CRLF" >"$2".expect ;;
+       CRLF_LF) echo "CRLF will be replaced by LF" >"$2".expect ;;
+       '')                                         >"$2".expect ;;
        *) echo >&2 "Illegal 1": "$1" ; return false ;;
        esac
-       grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" | uniq  >"$2".actual
+       sed -e "s/^.* \([^ ]* will be replaced by [^ ]*\) .*$/\1/" "$2" | uniq  >"$2".actual
        test_cmp "$2".expect "$2".actual
 }
 
index 239d93f4d21141f5991f9fb409a4675ece0f98bd..238b25f91a34d745016045a9570063086a5eec1f 100755 (executable)
@@ -9,13 +9,41 @@ export GIT_TEST_ASSUME_DIFFERENT_OWNER
 
 expect_rejected_dir () {
        test_must_fail git status 2>err &&
-       grep "safe.directory" err
+       grep "unsafe repository" err
 }
 
 test_expect_success 'safe.directory is not set' '
        expect_rejected_dir
 '
 
+test_expect_success 'ignoring safe.directory on the command line' '
+       test_must_fail git -c safe.directory="$(pwd)" status 2>err &&
+       grep "unsafe repository" err
+'
+
+test_expect_success 'ignoring safe.directory in the environment' '
+       test_must_fail env GIT_CONFIG_COUNT=1 \
+               GIT_CONFIG_KEY_0="safe.directory" \
+               GIT_CONFIG_VALUE_0="$(pwd)" \
+               git status 2>err &&
+       grep "unsafe repository" err
+'
+
+test_expect_success 'ignoring safe.directory in GIT_CONFIG_PARAMETERS' '
+       test_must_fail env \
+               GIT_CONFIG_PARAMETERS="${SQ}safe.directory${SQ}=${SQ}$(pwd)${SQ}" \
+               git status 2>err &&
+       grep "unsafe repository" err
+'
+
+test_expect_success 'ignoring safe.directory in repo config' '
+       (
+               unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+               git config safe.directory "$(pwd)"
+       ) &&
+       expect_rejected_dir
+'
+
 test_expect_success 'safe.directory does not match' '
        git config --global safe.directory bogus &&
        expect_rejected_dir
diff --git a/t/t0034-root-safe-directory.sh b/t/t0034-root-safe-directory.sh
new file mode 100755 (executable)
index 0000000..a621f1e
--- /dev/null
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+test_description='verify safe.directory checks while running as root'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-sudo.sh
+
+if [ "$GIT_TEST_ALLOW_SUDO" != "YES" ]
+then
+       skip_all="You must set env var GIT_TEST_ALLOW_SUDO=YES in order to run this test"
+       test_done
+fi
+
+if ! test_have_prereq NOT_ROOT
+then
+       skip_all="These tests do not support running as root"
+       test_done
+fi
+
+test_lazy_prereq SUDO '
+       sudo -n id -u >u &&
+       id -u root >r &&
+       test_cmp u r &&
+       command -v git >u &&
+       sudo command -v git >r &&
+       test_cmp u r
+'
+
+if ! test_have_prereq SUDO
+then
+       skip_all="Your sudo/system configuration is either too strict or unsupported"
+       test_done
+fi
+
+test_expect_success SUDO 'setup' '
+       sudo rm -rf root &&
+       mkdir -p root/r &&
+       (
+               cd root/r &&
+               git init
+       )
+'
+
+test_expect_success SUDO 'sudo git status as original owner' '
+       (
+               cd root/r &&
+               git status &&
+               sudo git status
+       )
+'
+
+test_expect_success SUDO 'setup root owned repository' '
+       sudo mkdir -p root/p &&
+       sudo git init root/p
+'
+
+test_expect_success 'cannot access if owned by root' '
+       (
+               cd root/p &&
+               test_must_fail git status
+       )
+'
+
+test_expect_success 'can access if addressed explicitly' '
+       (
+               cd root/p &&
+               GIT_DIR=.git GIT_WORK_TREE=. git status
+       )
+'
+
+test_expect_failure SUDO 'can access with sudo if root' '
+       (
+               cd root/p &&
+               sudo git status
+       )
+'
+
+test_expect_success SUDO 'can access with sudo if root by removing SUDO_UID' '
+       (
+               cd root/p &&
+               run_with_sudo <<-END
+                       unset SUDO_UID &&
+                       git status
+               END
+       )
+'
+
+test_lazy_prereq SUDO_SUDO '
+       sudo sudo id -u >u &&
+       id -u root >r &&
+       test_cmp u r
+'
+
+test_expect_success SUDO_SUDO 'can access with sudo abusing SUDO_UID' '
+       (
+               cd root/p &&
+               sudo sudo git status
+       )
+'
+
+# this MUST be always the last test
+test_expect_success SUDO 'cleanup' '
+       sudo rm -rf root
+'
+
+test_done
index 2630e756dab7322a5360a67766a648a80a5a7222..752aa8c945431b909e580f557ef738a455fa8132 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='"-C <path>" option and its effects on other path-related options'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success '"git -C <path>" runs git from the directory <path>' '
index 2fe6ae6a4e544cb4f58ad96e22ee6b24c076de94..aa35350b6f396f562463a16ffcba364ab94ed5d5 100755 (executable)
@@ -542,7 +542,7 @@ test_lazy_prereq CAN_EXEC_IN_PWD '
        ./git rev-parse
 '
 
-test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
+test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
        mkdir -p pretend/bin pretend/libexec/git-core &&
        echo "echo HERE" | write_script pretend/libexec/git-core/git-here &&
        cp "$GIT_EXEC_PATH"/git$X pretend/bin/ &&
@@ -550,7 +550,7 @@ test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
        echo HERE >expect &&
        test_cmp expect actual'
 
-test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' '
+test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' '
        mkdir -p pretend/bin &&
        cp "$GIT_EXEC_PATH"/git$X pretend/bin/ &&
        git config yes.path "%(prefix)/yes" &&
index 8e215867b8c197dedef32c569e1d1f632d22b631..b9480c8178193e4eba46dd2d581e1aa4eaa5dae6 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='Test revision walking api'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 cat >run_twice_expected <<-EOF
index 69beb59f627faab6b9bd7c197a3335a88d12e368..a16cc3d298357be89e58514db83c1d3f04b3ad4d 100755 (executable)
@@ -5,6 +5,7 @@ test_description='previous branch syntax @{-n}'
 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 'branch -d @{-1}' '
index a1998b558f96bb956b4ddce500d9447ded49a54d..878aadd64c9517dc1891031bd8bee0b298cfccb6 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='various @{whatever} syntax tests'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index 0710b1fb1e945b4d15d989f65f83050076e592cf..516a6112fdcf1907fb3827cc23e7ad0b24b39099 100755 (executable)
@@ -21,6 +21,7 @@ In the test, these paths are used:
        yomin   - not in H or M
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-read-tree.sh
 
index 46cbd5514a68e135222b5dbec77a21e170ccaa2b..bd5313caec9240b52bf9e8d663fd0c515d321064 100755 (executable)
@@ -9,6 +9,7 @@ This is identical to t1001, but uses -u to update the work tree as well.
 
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-read-tree.sh
 
index 1b8520769446d217c757d8286e8c46c54dcafb97..dadf3b14583bec460a51cbf69362a875dd3cc867 100755 (executable)
@@ -681,7 +681,7 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' '
 
                # Setup and create the empty blob and its path
                empty_path=$(git rev-parse --git-path objects/$(test_oid_to_path "$EMPTY_BLOB")) &&
-               git hash-object -w --stdin </dev/null &&
+               empty_blob=$(git hash-object -w --stdin </dev/null) &&
 
                # Create another blob and its path
                echo other >other.blob &&
@@ -722,7 +722,13 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' '
                # content out as-is. Try to make it zlib-invalid.
                mv -f other.blob "$empty_path" &&
                test_must_fail git fsck 2>err.fsck &&
-               grep "^error: inflate: data stream error (" err.fsck
+               cat >expect <<-EOF &&
+               error: inflate: data stream error (incorrect header check)
+               error: unable to unpack header of ./$empty_path
+               error: $empty_blob: object corrupt or missing: ./$empty_path
+               EOF
+               grep "^error: " err.fsck >actual &&
+               test_cmp expect actual
        )
 '
 
index dd957be1b78c5690fc79495f501eea52e4467600..63a553d7b32224550a48008772e396e88455af11 100755 (executable)
@@ -57,8 +57,8 @@ test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' '
        read_tree_u_must_succeed -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt result &&
-       test -f init.t &&
-       test -f sub/added
+       test_path_is_file init.t &&
+       test_path_is_file sub/added
 '
 
 test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-checkout and enabled' '
@@ -67,8 +67,8 @@ test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-
        read_tree_u_must_succeed --no-sparse-checkout -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt result &&
-       test -f init.t &&
-       test -f sub/added
+       test_path_is_file init.t &&
+       test_path_is_file sub/added
 '
 
 test_expect_success 'read-tree with empty .git/info/sparse-checkout' '
@@ -85,8 +85,8 @@ test_expect_success 'read-tree with empty .git/info/sparse-checkout' '
        S subsub/added
        EOF
        test_cmp expected.swt result &&
-       ! test -f init.t &&
-       ! test -f sub/added
+       test_path_is_missing init.t &&
+       test_path_is_missing sub/added
 '
 
 test_expect_success 'match directories with trailing slash' '
@@ -101,8 +101,8 @@ test_expect_success 'match directories with trailing slash' '
        read_tree_u_must_succeed -m -u HEAD &&
        git ls-files -t > result &&
        test_cmp expected.swt-noinit result &&
-       test ! -f init.t &&
-       test -f sub/added
+       test_path_is_missing init.t &&
+       test_path_is_file sub/added
 '
 
 test_expect_success 'match directories without trailing slash' '
@@ -110,8 +110,8 @@ test_expect_success 'match directories without trailing slash' '
        read_tree_u_must_succeed -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt-noinit result &&
-       test ! -f init.t &&
-       test -f sub/added
+       test_path_is_missing init.t &&
+       test_path_is_file sub/added
 '
 
 test_expect_success 'match directories with negated patterns' '
@@ -129,9 +129,9 @@ EOF
        git read-tree -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt-negation result &&
-       test ! -f init.t &&
-       test ! -f sub/added &&
-       test -f sub/addedtoo
+       test_path_is_missing init.t &&
+       test_path_is_missing sub/added &&
+       test_path_is_file sub/addedtoo
 '
 
 test_expect_success 'match directories with negated patterns (2)' '
@@ -150,9 +150,9 @@ EOF
        git read-tree -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt-negation2 result &&
-       test -f init.t &&
-       test -f sub/added &&
-       test ! -f sub/addedtoo
+       test_path_is_file init.t &&
+       test_path_is_file sub/added &&
+       test_path_is_missing sub/addedtoo
 '
 
 test_expect_success 'match directory pattern' '
@@ -160,8 +160,8 @@ test_expect_success 'match directory pattern' '
        read_tree_u_must_succeed -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt-noinit result &&
-       test ! -f init.t &&
-       test -f sub/added
+       test_path_is_missing init.t &&
+       test_path_is_file sub/added
 '
 
 test_expect_success 'checkout area changes' '
@@ -176,15 +176,15 @@ test_expect_success 'checkout area changes' '
        read_tree_u_must_succeed -m -u HEAD &&
        git ls-files -t >result &&
        test_cmp expected.swt-nosub result &&
-       test -f init.t &&
-       test ! -f sub/added
+       test_path_is_file init.t &&
+       test_path_is_missing sub/added
 '
 
 test_expect_success 'read-tree updates worktree, absent case' '
        echo sub/added >.git/info/sparse-checkout &&
        git checkout -f top &&
        read_tree_u_must_succeed -m -u HEAD^ &&
-       test ! -f init.t
+       test_path_is_missing init.t
 '
 
 test_expect_success 'read-tree will not throw away dirty changes, non-sparse' '
@@ -229,7 +229,7 @@ test_expect_success 'read-tree adds to worktree, absent case' '
        echo init.t >.git/info/sparse-checkout &&
        git checkout -f removed &&
        read_tree_u_must_succeed -u -m HEAD^ &&
-       test ! -f sub/added
+       test_path_is_missing sub/added
 '
 
 test_expect_success 'read-tree adds to worktree, dirty case' '
@@ -248,7 +248,7 @@ test_expect_success 'index removal and worktree narrowing at the same time' '
        echo init.t >.git/info/sparse-checkout &&
        git checkout removed &&
        git ls-files sub/added >result &&
-       test ! -f sub/added &&
+       test_path_is_missing sub/added &&
        test_must_be_empty result
 '
 
index bc89371f53436dbf3427f231f560ef1b1f8683f6..5b8e47e346c710ac4ddb4592d707c9b9fdf358a7 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='see how we handle various forms of corruption'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # convert "1234abcd" to ".git/objects/12/34abcd"
index 9a900310186d3876f873d5da5ff94dca4a3da35c..de1ec89007d787ff828405b1f6225477efe68235 100755 (executable)
@@ -72,7 +72,7 @@ test_expect_success 'git sparse-checkout list (populated)' '
 '
 
 test_expect_success 'git sparse-checkout init' '
-       git -C repo sparse-checkout init &&
+       git -C repo sparse-checkout init --no-cone &&
        cat >expect <<-\EOF &&
        /*
        !/*/
@@ -111,6 +111,7 @@ test_expect_success 'init with existing sparse-checkout' '
 
 test_expect_success 'clone --sparse' '
        git clone --sparse "file://$(pwd)/repo" clone &&
+       git -C clone sparse-checkout reapply --no-cone &&
        git -C clone sparse-checkout list >actual &&
        cat >expect <<-\EOF &&
        /*
@@ -124,7 +125,7 @@ test_expect_success 'switching to cone mode with non-cone mode patterns' '
        git init bad-patterns &&
        (
                cd bad-patterns &&
-               git sparse-checkout init &&
+               git sparse-checkout init --no-cone &&
                git sparse-checkout add dir &&
                git config --worktree core.sparseCheckoutCone true &&
                test_must_fail git sparse-checkout add dir 2>err &&
@@ -402,7 +403,7 @@ test_expect_success 'revert to old sparse-checkout on empty update' '
                git sparse-checkout set nothing 2>err &&
                test_i18ngrep ! "Sparse checkout leaves no entry on working directory" err &&
                test_i18ngrep ! ".git/index.lock" err &&
-               git sparse-checkout set file
+               git sparse-checkout set --no-cone file
        )
 '
 
@@ -424,7 +425,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status'
        git clone repo dirty &&
        echo dirty >dirty/folder1/a &&
 
-       git -C dirty sparse-checkout init 2>err &&
+       git -C dirty sparse-checkout init --no-cone 2>err &&
        test_i18ngrep "warning.*The following paths are not up to date" err &&
 
        git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&
@@ -435,7 +436,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status'
        test_must_be_empty err &&
 
        git -C dirty reset --hard &&
-       git -C dirty sparse-checkout init &&
+       git -C dirty sparse-checkout init --no-cone &&
        git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
        test_path_is_missing dirty/folder1/a &&
        git -C dirty sparse-checkout disable &&
@@ -451,7 +452,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat
        EOF
        git -C unmerged update-index --index-info <input &&
 
-       git -C unmerged sparse-checkout init 2>err &&
+       git -C unmerged sparse-checkout init --no-cone 2>err &&
        test_i18ngrep "warning.*The following paths are unmerged" err &&
 
        git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&
@@ -462,7 +463,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat
        test_i18ngrep "warning.*The following paths are unmerged" err &&
 
        git -C unmerged reset --hard &&
-       git -C unmerged sparse-checkout init &&
+       git -C unmerged sparse-checkout init --no-cone &&
        git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* &&
        git -C unmerged sparse-checkout disable
 '
index 236ab5302844b21d5688ddaca5e98625c33406fa..f9f8c988bb4905939824903b3c59620450238350 100755 (executable)
@@ -205,36 +205,68 @@ test_sparse_unstaged () {
        done
 }
 
-test_expect_success 'sparse-index contents' '
-       init_repos &&
-
+# Usage: test_sprase_checkout_set "<c1> ... <cN>" "<s1> ... <sM>"
+# Verifies that "git sparse-checkout set <c1> ... <cN>" succeeds and
+# leaves the sparse index in a state where <s1> ... <sM> are sparse
+# directories (and <c1> ... <cN> are not).
+test_sparse_checkout_set () {
+       CONE_DIRS=$1 &&
+       SPARSE_DIRS=$2 &&
+       git -C sparse-index sparse-checkout set --skip-checks $CONE_DIRS &&
        git -C sparse-index ls-files --sparse --stage >cache &&
-       for dir in folder1 folder2 x
+
+       # Check that the directories outside of the sparse-checkout cone
+       # have sparse directory entries.
+       for dir in $SPARSE_DIRS
        do
                TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
                grep "040000 $TREE 0    $dir/" cache \
                        || return 1
        done &&
 
-       git -C sparse-index sparse-checkout set folder1 &&
-
-       git -C sparse-index ls-files --sparse --stage >cache &&
-       for dir in deep folder2 x
+       # Check that the directories in the sparse-checkout cone
+       # are not sparse directory entries.
+       for dir in $CONE_DIRS
        do
-               TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
-               grep "040000 $TREE 0    $dir/" cache \
+               # Allow TREE to not exist because
+               # $dir does not exist at HEAD.
+               TREE=$(git -C sparse-index rev-parse HEAD:$dir) ||
+               ! grep "040000 $TREE 0  $dir/" cache \
                        || return 1
-       done &&
+       done
+}
 
-       git -C sparse-index sparse-checkout set deep/deeper1 &&
+test_expect_success 'sparse-index contents' '
+       init_repos &&
 
-       git -C sparse-index ls-files --sparse --stage >cache &&
-       for dir in deep/deeper2 folder1 folder2 x
-       do
-               TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
-               grep "040000 $TREE 0    $dir/" cache \
-                       || return 1
-       done &&
+       # Remove deep, add three other directories.
+       test_sparse_checkout_set \
+               "folder1 folder2 x" \
+               "before deep" &&
+
+       # Remove folder1, add deep
+       test_sparse_checkout_set \
+               "deep folder2 x" \
+               "before folder1" &&
+
+       # Replace deep with deep/deeper2 (dropping deep/deeper1)
+       # Add folder1
+       test_sparse_checkout_set \
+               "deep/deeper2 folder1 folder2 x" \
+               "before deep/deeper1" &&
+
+       # Replace deep/deeper2 with deep/deeper1
+       # Replace folder1 with folder1/0/0
+       # Replace folder2 with non-existent folder2/2/3
+       # Add non-existent "bogus"
+       test_sparse_checkout_set \
+               "bogus deep/deeper1 folder1/0/0 folder2/2/3 x" \
+               "before deep/deeper2 folder2/0" &&
+
+       # Drop down to only files at root
+       test_sparse_checkout_set \
+               "" \
+               "before deep folder1 folder2 x" &&
 
        # Disabling the sparse-index replaces tree entries with full ones
        git -C sparse-index sparse-checkout init --no-sparse-index &&
@@ -1034,6 +1066,55 @@ test_expect_success 'cherry-pick with conflicts' '
        test_all_match test_must_fail git cherry-pick to-cherry-pick
 '
 
+test_expect_success 'stash' '
+       init_repos &&
+
+       write_script edit-contents <<-\EOF &&
+       echo text >>$1
+       EOF
+
+       # Stash a sparse directory (folder1)
+       test_all_match git checkout -b test-branch rename-base &&
+       test_all_match git reset --soft rename-out-to-out &&
+       test_all_match git stash &&
+       test_all_match git status --porcelain=v2 &&
+
+       # Apply the sparse directory stash without reinstating the index
+       test_all_match git stash apply -q &&
+       test_all_match git status --porcelain=v2 &&
+
+       # Reset to state where stash can be applied
+       test_sparse_match git sparse-checkout reapply &&
+       test_all_match git reset --hard rename-out-to-out &&
+
+       # Apply the sparse directory stash *with* reinstating the index
+       test_all_match git stash apply --index -q &&
+       test_all_match git status --porcelain=v2 &&
+
+       # Reset to state where we will get a conflict applying the stash
+       test_sparse_match git sparse-checkout reapply &&
+       test_all_match git reset --hard update-folder1 &&
+
+       # Apply the sparse directory stash with conflicts
+       test_all_match test_must_fail git stash apply --index -q &&
+       test_all_match test_must_fail git stash apply -q &&
+       test_all_match git status --porcelain=v2 &&
+
+       # Reset to base branch
+       test_sparse_match git sparse-checkout reapply &&
+       test_all_match git reset --hard base &&
+
+       # Stash & unstash an untracked file outside of the sparse checkout
+       # definition.
+       run_on_sparse mkdir -p folder1 &&
+       run_on_all ../edit-contents folder1/new &&
+       test_all_match git stash -u &&
+       test_all_match git status --porcelain=v2 &&
+
+       test_all_match git stash pop -q &&
+       test_all_match git status --porcelain=v2
+'
+
 test_expect_success 'checkout-index inside sparse definition' '
        init_repos &&
 
@@ -1151,6 +1232,33 @@ test_expect_success 'clean' '
        test_sparse_match test_path_is_dir folder1
 '
 
+for builtin in show rev-parse
+do
+       test_expect_success "$builtin (cached blobs/trees)" "
+               init_repos &&
+
+               test_all_match git $builtin :a &&
+               test_all_match git $builtin :deep/a &&
+               test_sparse_match git $builtin :folder1/a &&
+
+               # The error message differs depending on whether
+               # the directory exists in the worktree.
+               test_all_match test_must_fail git $builtin :deep/ &&
+               test_must_fail git -C full-checkout $builtin :folder1/ &&
+               test_sparse_match test_must_fail git $builtin :folder1/ &&
+
+               # Change the sparse cone for an extra case:
+               run_on_sparse git sparse-checkout set deep/deeper1 &&
+
+               # deep/deeper2 is a sparse directory in the sparse index.
+               test_sparse_match test_must_fail git $builtin :deep/deeper2/ &&
+
+               # deep/deeper2/deepest is not in the sparse index, but
+               # will trigger an index expansion.
+               test_sparse_match test_must_fail git $builtin :deep/deeper2/deepest/
+       "
+done
+
 test_expect_success 'submodule handling' '
        init_repos &&
 
@@ -1222,7 +1330,10 @@ test_expect_success 'index.sparse disabled inline uses full index' '
 
 ensure_not_expanded () {
        rm -f trace2.txt &&
-       echo >>sparse-index/untracked.txt &&
+       if test -z "$WITHOUT_UNTRACKED_TXT"
+       then
+               echo >>sparse-index/untracked.txt
+       fi &&
 
        if test "$1" = "!"
        then
@@ -1326,6 +1437,30 @@ test_expect_success 'sparse-index is not expanded: merge conflict in cone' '
        )
 '
 
+test_expect_success 'sparse-index is not expanded: stash' '
+       init_repos &&
+
+       echo >>sparse-index/a &&
+       ensure_not_expanded stash &&
+       ensure_not_expanded stash list &&
+       ensure_not_expanded stash show stash@{0} &&
+       ensure_not_expanded stash apply stash@{0} &&
+       ensure_not_expanded stash drop stash@{0} &&
+
+       echo >>sparse-index/deep/new &&
+       ensure_not_expanded stash -u &&
+       (
+               WITHOUT_UNTRACKED_TXT=1 &&
+               ensure_not_expanded stash pop
+       ) &&
+
+       ensure_not_expanded stash create &&
+       oid=$(git -C sparse-index stash create) &&
+       ensure_not_expanded stash store -m "test" $oid &&
+       ensure_not_expanded reset --hard &&
+       ensure_not_expanded stash pop
+'
+
 test_expect_success 'sparse index is not expanded: diff' '
        init_repos &&
 
@@ -1372,6 +1507,15 @@ test_expect_success 'sparse index is not expanded: diff' '
        ensure_not_expanded diff --cached
 '
 
+test_expect_success 'sparse index is not expanded: show and rev-parse' '
+       init_repos &&
+
+       ensure_not_expanded show :a &&
+       ensure_not_expanded show :deep/a &&
+       ensure_not_expanded rev-parse :a &&
+       ensure_not_expanded rev-parse :deep/a
+'
+
 test_expect_success 'sparse index is not expanded: update-index' '
        init_repos &&
 
@@ -1516,6 +1660,31 @@ test_expect_success 'ls-files' '
        ensure_not_expanded ls-files --sparse
 '
 
+test_expect_success 'sparse index is not expanded: sparse-checkout' '
+       init_repos &&
+
+       ensure_not_expanded sparse-checkout set deep/deeper2 &&
+       ensure_not_expanded sparse-checkout set deep/deeper1 &&
+       ensure_not_expanded sparse-checkout set deep &&
+       ensure_not_expanded sparse-checkout add folder1 &&
+       ensure_not_expanded sparse-checkout set deep/deeper1 &&
+       ensure_not_expanded sparse-checkout set folder2 &&
+
+       # Demonstrate that the checks that "folder1/a" is a file
+       # do not cause a sparse-index expansion (since it is in the
+       # sparse-checkout cone).
+       echo >>sparse-index/folder2/a &&
+       git -C sparse-index add folder2/a &&
+
+       ensure_not_expanded sparse-checkout add folder1 &&
+
+       # Skip checks here, since deep/deeper1 is inside a sparse directory
+       # that must be expanded to check whether `deep/deeper1` is a file
+       # or not.
+       ensure_not_expanded sparse-checkout set --skip-checks deep/deeper1 &&
+       ensure_not_expanded sparse-checkout set
+'
+
 # NEEDSWORK: a sparse-checkout behaves differently from a full checkout
 # in this scenario, but it shouldn't.
 test_expect_success 'reset mixed and checkout orphan' '
index 132a1b885acbce46cb9f8a1b52fc2833fc8a7990..9fb0b90f252aa17a04a52678eb48a3a9bf9883ee 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='basic symbolic-ref tests'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # If the tests munging HEAD fail, they can break detection of
index 975c4ea83a877b2dfaf6059c320c71c0282fee0c..da581ec19ac619cef717a4a3b4dc34f55c0142b8 100755 (executable)
@@ -4,6 +4,7 @@ test_description='Test reflog display routines'
 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' '
index 977603f7f1ca9efb781c5743f1e730246e6d1963..ff30874f940439fe979e3857400c54b944194dcb 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='reflog walk shows repeated commits again'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup commits' '
index a3e6ea08088b15ee461c53e2baebe7d0dfb19664..3b531842dd4c864b45bfd89c36e14f9327d6b29e 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='per-worktree refs'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index de50c0ea018cfa981312c9f146f8265544e64711..ab7f31f1dcd5b5b7224ded4099f8316171bdea7d 100755 (executable)
@@ -774,10 +774,19 @@ test_expect_success 'fsck finds problems in duplicate loose objects' '
                # no "-d" here, so we end up with duplicates
                git repack &&
                # now corrupt the loose copy
-               file=$(sha1_file "$(git rev-parse HEAD)") &&
+               oid="$(git rev-parse HEAD)" &&
+               file=$(sha1_file "$oid") &&
                rm "$file" &&
                echo broken >"$file" &&
-               test_must_fail git fsck
+               test_must_fail git fsck 2>err &&
+
+               cat >expect <<-EOF &&
+               error: inflate: data stream error (incorrect header check)
+               error: unable to unpack header of $file
+               error: $oid: object corrupt or missing: $file
+               EOF
+               grep "^error: " err >actual &&
+               test_cmp expect actual
        )
 '
 
index a9721215fab540ccf6ce1e12f2c5066b620cac6b..9425aae6395838b3d0fd57b8cf8fe228d1db335f 100755 (executable)
@@ -4,6 +4,7 @@ test_description='checkout from unborn branch'
 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' '
index abfd586c32b017e7f00d9cfc1a85cddb4f150d43..bc3f69b4b1d2fdbb942498a3f4826655de22a1ee 100755 (executable)
@@ -4,7 +4,13 @@ test_description='git checkout --patch'
 
 . ./lib-patch-mode.sh
 
-test_expect_success PERL 'setup' '
+if ! test_bool_env GIT_TEST_ADD_I_USE_BUILTIN true && ! test_have_prereq PERL
+then
+       skip_all='skipping interactive add tests, PERL not set'
+       test_done
+fi
+
+test_expect_success 'setup' '
        mkdir dir &&
        echo parent > dir/foo &&
        echo dummy > bar &&
@@ -18,44 +24,40 @@ test_expect_success PERL 'setup' '
 
 # note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar'
 
-# NEEDSWORK: Since the builtin add-p is used when $GIT_TEST_ADD_I_USE_BUILTIN
-# is given, we should replace the PERL prerequisite with an ADD_I prerequisite
-# which first checks if $GIT_TEST_ADD_I_USE_BUILTIN is defined before checking
-# PERL.
-test_expect_success PERL 'saying "n" does nothing' '
+test_expect_success 'saying "n" does nothing' '
        set_and_save_state dir/foo work head &&
        test_write_lines n n | git checkout -p &&
        verify_saved_state bar &&
        verify_saved_state dir/foo
 '
 
-test_expect_success PERL 'git checkout -p' '
+test_expect_success 'git checkout -p' '
        test_write_lines n y | git checkout -p &&
        verify_saved_state bar &&
        verify_state dir/foo head head
 '
 
-test_expect_success PERL 'git checkout -p with staged changes' '
+test_expect_success 'git checkout -p with staged changes' '
        set_state dir/foo work index &&
        test_write_lines n y | git checkout -p &&
        verify_saved_state bar &&
        verify_state dir/foo index index
 '
 
-test_expect_success PERL 'git checkout -p HEAD with NO staged changes: abort' '
+test_expect_success 'git checkout -p HEAD with NO staged changes: abort' '
        set_and_save_state dir/foo work head &&
        test_write_lines n y n | git checkout -p HEAD &&
        verify_saved_state bar &&
        verify_saved_state dir/foo
 '
 
-test_expect_success PERL 'git checkout -p HEAD with NO staged changes: apply' '
+test_expect_success 'git checkout -p HEAD with NO staged changes: apply' '
        test_write_lines n y y | git checkout -p HEAD &&
        verify_saved_state bar &&
        verify_state dir/foo head head
 '
 
-test_expect_success PERL 'git checkout -p HEAD with change already staged' '
+test_expect_success 'git checkout -p HEAD with change already staged' '
        set_state dir/foo index index &&
        # the third n is to get out in case it mistakenly does not apply
        test_write_lines n y n | git checkout -p HEAD &&
@@ -63,21 +65,21 @@ test_expect_success PERL 'git checkout -p HEAD with change already staged' '
        verify_state dir/foo head head
 '
 
-test_expect_success PERL 'git checkout -p HEAD^...' '
+test_expect_success 'git checkout -p HEAD^...' '
        # the third n is to get out in case it mistakenly does not apply
        test_write_lines n y n | git checkout -p HEAD^... &&
        verify_saved_state bar &&
        verify_state dir/foo parent parent
 '
 
-test_expect_success PERL 'git checkout -p HEAD^' '
+test_expect_success 'git checkout -p HEAD^' '
        # the third n is to get out in case it mistakenly does not apply
        test_write_lines n y n | git checkout -p HEAD^ &&
        verify_saved_state bar &&
        verify_state dir/foo parent parent
 '
 
-test_expect_success PERL 'git checkout -p handles deletion' '
+test_expect_success 'git checkout -p handles deletion' '
        set_state dir/foo work index &&
        rm dir/foo &&
        test_write_lines n y | git checkout -p &&
@@ -90,28 +92,28 @@ test_expect_success PERL 'git checkout -p handles deletion' '
 # dir/foo.  There's always an extra 'n' to reject edits to dir/foo in
 # the failure case (and thus get out of the loop).
 
-test_expect_success PERL 'path limiting works: dir' '
+test_expect_success 'path limiting works: dir' '
        set_state dir/foo work head &&
        test_write_lines y n | git checkout -p dir &&
        verify_saved_state bar &&
        verify_state dir/foo head head
 '
 
-test_expect_success PERL 'path limiting works: -- dir' '
+test_expect_success 'path limiting works: -- dir' '
        set_state dir/foo work head &&
        test_write_lines y n | git checkout -p -- dir &&
        verify_saved_state bar &&
        verify_state dir/foo head head
 '
 
-test_expect_success PERL 'path limiting works: HEAD^ -- dir' '
+test_expect_success 'path limiting works: HEAD^ -- dir' '
        # the third n is to get out in case it mistakenly does not apply
        test_write_lines y n n | git checkout -p HEAD^ -- dir &&
        verify_saved_state bar &&
        verify_state dir/foo parent parent
 '
 
-test_expect_success PERL 'path limiting works: foo inside dir' '
+test_expect_success 'path limiting works: foo inside dir' '
        set_state dir/foo work head &&
        # the third n is to get out in case it mistakenly does not apply
        test_write_lines y n n | (cd dir && git checkout -p foo) &&
@@ -119,11 +121,11 @@ test_expect_success PERL 'path limiting works: foo inside dir' '
        verify_state dir/foo head head
 '
 
-test_expect_success PERL 'none of this moved HEAD' '
+test_expect_success 'none of this moved HEAD' '
        verify_saved_head
 '
 
-test_expect_success PERL 'empty tree can be handled' '
+test_expect_success 'empty tree can be handled' '
        test_when_finished "git reset --hard" &&
        git checkout -p $(test_oid empty_tree) --
 '
index 0c38f8e35695745c8eb02fe090c0d15b6d1666c8..be394f1131ac191476dfa228be6fc6f35e0cecd0 100755 (executable)
@@ -14,6 +14,7 @@ only the updates to dir/sub.
 Also tested are "git add -u" without limiting, and "git add -u"
 without contents changes, and other conditions'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index db7ca55998666138f3580fe430dfe53ece43be13..ebf58db2d1827209464c94ac621f16f1693367d5 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='Intent to add'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'intent to add' '
index e12db5936155453ea86a9b84ce0321e588d955b4..9723c2827ccddc84824035e600d90d28aed0e1eb 100755 (executable)
@@ -886,6 +886,41 @@ test_expect_success 'branch from tag w/--track causes failure' '
        test_must_fail git branch --track my11 foobar
 '
 
+test_expect_success 'simple tracking works when remote branch name matches' '
+       test_when_finished "rm -rf otherserver" &&
+       git init otherserver &&
+       test_commit -C otherserver my_commit 1 &&
+       git -C otherserver branch feature &&
+       test_config branch.autosetupmerge simple &&
+       test_config remote.otherserver.url otherserver &&
+       test_config remote.otherserver.fetch refs/heads/*:refs/remotes/otherserver/* &&
+       git fetch otherserver &&
+       git branch feature otherserver/feature &&
+       test_cmp_config otherserver branch.feature.remote &&
+       test_cmp_config refs/heads/feature branch.feature.merge
+'
+
+test_expect_success 'simple tracking skips when remote branch name does not match' '
+       test_config branch.autosetupmerge simple &&
+       test_config remote.local.url . &&
+       test_config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+       git fetch local &&
+       git branch my-other local/main &&
+       test_cmp_config "" --default "" branch.my-other.remote &&
+       test_cmp_config "" --default "" branch.my-other.merge
+'
+
+test_expect_success 'simple tracking skips when remote ref is not a branch' '
+       test_config branch.autosetupmerge simple &&
+       test_config remote.localtags.url . &&
+       test_config remote.localtags.fetch refs/tags/*:refs/remotes/localtags/* &&
+       git tag mytag12 main &&
+       git fetch localtags &&
+       git branch mytag12 localtags/mytag12 &&
+       test_cmp_config "" --default "" branch.mytag12.remote &&
+       test_cmp_config "" --default "" branch.mytag12.merge
+'
+
 test_expect_success '--set-upstream-to fails on multiple branches' '
        echo "fatal: too many arguments to set new upstream" >expect &&
        test_must_fail git branch --set-upstream-to main a b c 2>err &&
index 7a1be73ce8771b851dfc2c7a95d80dece4c2b5cb..f2b9199007752eded932a8da541e1a86e350d10a 100755 (executable)
@@ -161,4 +161,18 @@ test_expect_success 'show branch --reflog=2' '
        test_cmp actual expect
 '
 
+# incompatible options
+while read combo
+do
+       test_expect_success "show-branch $combo (should fail)" '
+               test_must_fail git show-branch $combo 2>error &&
+               grep -e "cannot be used together" -e "usage:" error
+       '
+done <<\EOF
+--all --reflog
+--merge-base --reflog
+--list --merge-base
+--reflog --current
+EOF
+
 test_done
index bb5fea02a03a563a23e806d80dbb88a673c40802..d0c4d38b4d485d0b3faef4cdc7acbeb42b3c929c 100755 (executable)
@@ -8,6 +8,7 @@ test_description='Test commit notes index (expensive!)'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 create_repo () {
index eac193757bf1a5cd27ed4d54249a41de7b302bde..bc9b791d1b9ed2a780de4544232f769e093072b1 100755 (executable)
@@ -5,6 +5,7 @@ test_description='Test commit notes organized in subtrees'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 number_of_commits=100
index 9976d787f4721c898d52eb0211399b145c9e1872..64a9915761a82a6ea8d640dabfe3811db6450a5a 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='Test that adding/removing many notes triggers automatic fanout restructuring'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 path_has_fanout() {
index cde3562e3a64f756544763107d9c607eaa4f38ca..7b4607d72f2748df9d0800a5e471e4af1d6ae32a 100755 (executable)
@@ -5,6 +5,7 @@ test_description='rebasing a commit with multi-line first paragraph.'
 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 '
index 3716a42e81284f562cef9ba951edbbd1ff6701d6..3e04802cb003b027c0d70319465af4363877de06 100755 (executable)
@@ -129,6 +129,20 @@ test_expect_success 'rebase --keep-base main from topic' '
        test_cmp expect actual
 '
 
+test_expect_success 'rebase --keep-base main topic from main' '
+       git checkout main &&
+       git branch -f topic G &&
+
+       git rebase --keep-base main topic &&
+       git rev-parse C >base.expect &&
+       git merge-base main HEAD >base.actual &&
+       test_cmp base.expect base.actual &&
+
+       git rev-parse HEAD~2 >actual &&
+       git rev-parse C^0 >expect &&
+       test_cmp expect actual
+'
+
 test_expect_success 'rebase --keep-base main from side' '
        git reset --hard &&
        git checkout side &&
@@ -153,6 +167,21 @@ test_expect_success 'rebase -i --keep-base main from topic' '
        test_cmp expect actual
 '
 
+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 &&
+       git rev-parse C >base.expect &&
+       git merge-base main HEAD >base.actual &&
+       test_cmp base.expect base.actual &&
+
+       git rev-parse HEAD~2 >actual &&
+       git rev-parse C^0 >expect &&
+       test_cmp expect actual
+'
+
 test_expect_success 'rebase -i --keep-base main from side' '
        git reset --hard &&
        git checkout side &&
index 8617efaaf1e66f6f5d8246a817085ebd2d43c477..9eb19204ac7e3167511aca8c8ae8583928be3692 100755 (executable)
@@ -66,8 +66,7 @@ test_expect_success 'cherry-pick after renaming branch' '
 
        git checkout rename2 &&
        git cherry-pick added &&
-       test $(git rev-parse HEAD^) = $(git rev-parse rename2) &&
-       test -f opos &&
+       test_cmp_rev rename2 HEAD^ &&
        grep "Add extra line at the end" opos &&
        git reflog -1 | grep cherry-pick
 
@@ -77,9 +76,9 @@ test_expect_success 'revert after renaming branch' '
 
        git checkout rename1 &&
        git revert added &&
-       test $(git rev-parse HEAD^) = $(git rev-parse rename1) &&
-       test -f spoo &&
-       ! grep "Add extra line at the end" spoo &&
+       test_cmp_rev rename1 HEAD^ &&
+       test_path_is_file spoo &&
+       test_cmp_rev initial:oops HEAD:spoo &&
        git reflog -1 | grep revert
 
 '
index 034ec010910c167eef2dcc791d0895742086bf3b..08580fd3dccb73bea98c787271ba49c362a55b6b 100755 (executable)
@@ -30,7 +30,7 @@ test_expect_success 'setup' "
 for opt in "" -f --dry-run
 do
        test_expect_success "rm${opt:+ $opt} does not remove sparse entries" '
-               git sparse-checkout set a &&
+               git sparse-checkout set --no-cone a &&
                test_must_fail git rm $opt b 2>stderr &&
                test_cmp b_error_and_hint stderr &&
                git ls-files --error-unmatch b
@@ -118,7 +118,7 @@ test_expect_success 'can remove files from non-sparse dir' '
        test_commit w/f &&
        test_commit x/y/f &&
 
-       git sparse-checkout set w !/x y/ &&
+       git sparse-checkout set --no-cone w !/x y/ &&
        git rm w/f.t x/y/f.t 2>stderr &&
        test_must_be_empty stderr
 '
@@ -128,7 +128,7 @@ test_expect_success 'refuse to remove non-skip-worktree file from sparse dir' '
        git sparse-checkout disable &&
        mkdir -p x/y/z &&
        test_commit x/y/z/f &&
-       git sparse-checkout set !/x y/ !x/y/z &&
+       git sparse-checkout set --no-cone !/x y/ !x/y/z &&
 
        git update-index --no-skip-worktree x/y/z/f.t &&
        test_must_fail git rm x/y/z/f.t 2>stderr &&
index b1f90ba3250fa39863f6fe58e85b27613e303df4..8979c8a5f03e4ca14c2eef5443cd2064ccb79557 100755 (executable)
@@ -8,6 +8,8 @@ test_description='Test of git add, including the -- option.'
 TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
+. $TEST_DIRECTORY/lib-unique-files.sh
+
 # Test the file mode "$1" of the file "$2" in the index.
 test_mode_in_index () {
        case "$(git ls-files -s "$2")" in
@@ -34,6 +36,32 @@ test_expect_success \
     'Test that "git add -- -q" works' \
     'touch -- -q && git add -- -q'
 
+BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch'
+
+test_expect_success 'git add: core.fsyncmethod=batch' "
+       test_create_unique_files 2 4 files_base_dir1 &&
+       GIT_TEST_FSYNC=1 git $BATCH_CONFIGURATION add -- ./files_base_dir1/ &&
+       git ls-files --stage files_base_dir1/ |
+       test_parse_ls_files_stage_oids >added_files_oids &&
+
+       # We created 2 subdirs with 4 files each (8 files total) above
+       test_line_count = 8 added_files_oids &&
+       git cat-file --batch-check='%(objectname)' <added_files_oids >added_files_actual &&
+       test_cmp added_files_oids added_files_actual
+"
+
+test_expect_success 'git update-index: core.fsyncmethod=batch' "
+       test_create_unique_files 2 4 files_base_dir2 &&
+       find files_base_dir2 ! -type d -print | xargs git $BATCH_CONFIGURATION update-index --add -- &&
+       git ls-files --stage files_base_dir2 |
+       test_parse_ls_files_stage_oids >added_files2_oids &&
+
+       # We created 2 subdirs with 4 files each (8 files total) above
+       test_line_count = 8 added_files2_oids &&
+       git cat-file --batch-check='%(objectname)' <added_files2_oids >added_files2_actual &&
+       test_cmp added_files2_oids added_files2_actual
+"
+
 test_expect_success \
        'git add: Test that executable bit is not used if core.filemode=0' \
        'git config core.filemode 0 &&
index 95609046c61d3711244524d48061df4dae8cc343..2bade9e804fcfc74df7d5629bbd409fda1c4a302 100755 (executable)
@@ -166,7 +166,7 @@ test_expect_success 'do not warn when pathspec matches dense entries' '
 test_expect_success 'git add fails outside of sparse-checkout definition' '
        test_when_finished git sparse-checkout disable &&
        test_commit a &&
-       git sparse-checkout init &&
+       git sparse-checkout init --no-cone &&
        git sparse-checkout set a &&
        echo >>sparse_entry &&
 
@@ -208,7 +208,7 @@ test_expect_success 'add obeys advice.updateSparsePath' '
 '
 
 test_expect_success 'add allows sparse entries with --sparse' '
-       git sparse-checkout set a &&
+       git sparse-checkout set --no-cone a &&
        echo modified >sparse_entry &&
        test_must_fail git add sparse_entry &&
        test_sparse_entry_unchanged &&
index 4abbc8fccae78c69358970644320a3a114793083..20e94881964d5535e86d0332114d6fcb3495e0ba 100755 (executable)
@@ -9,6 +9,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
 . ./test-lib.sh
+. $TEST_DIRECTORY/lib-unique-files.sh
 
 test_expect_success 'usage on cmd and subcommand invalid option' '
        test_expect_code 129 git stash --invalid-option 2>usage &&
@@ -1410,6 +1411,25 @@ test_expect_success 'stash handles skip-worktree entries nicely' '
        git rev-parse --verify refs/stash:A.t
 '
 
+
+BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch'
+
+test_expect_success 'stash with core.fsyncmethod=batch' "
+       test_create_unique_files 2 4 files_base_dir &&
+       GIT_TEST_FSYNC=1 git $BATCH_CONFIGURATION stash push -u -- ./files_base_dir/ &&
+
+       # The files were untracked, so use the third parent,
+       # which contains the untracked files
+       git ls-tree -r stash^3 -- ./files_base_dir/ |
+       test_parse_ls_tree_oids >stashed_files_oids &&
+
+       # We created 2 dirs with 4 files each (8 files total) above
+       test_line_count = 8 stashed_files_oids &&
+       git cat-file --batch-check='%(objectname)' <stashed_files_oids >stashed_files_actual &&
+       test_cmp stashed_files_oids stashed_files_actual
+"
+
+
 test_expect_success 'git stash succeeds despite directory/file change' '
        test_create_repo directory_file_switch_v1 &&
        (
index 1219f8bd4c05f69ca159717c9b2e92f9510e76da..858a5522f96b63b971daf85f20e5d66aaebc48e6 100755 (executable)
@@ -206,17 +206,17 @@ test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' '
 '
 
 test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
+       test_when_finished "git rm -f file.ext" &&
        touch file.ext &&
        git add file.ext &&
        echo with extension > file.ext &&
 
        cat >expect <<-EOF &&
-       file.ext file $(git rev-parse --verify HEAD:file) 100644 file.ext $(test_oid zero) 100644
+       file.ext
        EOF
        GIT_EXTERNAL_DIFF=echo git diff file.ext >out &&
-       cut -d" " -f1,3- <out >actual &&
-       git update-index --force-remove file.ext &&
-       rm file.ext
+       basename $(cut -d" " -f2 <out) >actual &&
+       test_cmp expect actual
 '
 
 echo "#!$SHELL_PATH" >fake-diff.sh
index 9be65fd4440a68af70e6630c8ded872d7be41f5d..1219aa226dc7259172dba38da3f7354870e0929b 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='Format-patch numbering options'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 295da987cce5c8141b96d35944b73fb3f86f7e64..40164ae07d2c06d9ef5fc67b16e5ad8421b2875e 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='difference in submodules'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-diff.sh
 
index 204ba673cb58f905f2f35ff5b83294b2a2943f48..60cb819c42e4bc3b5fcc2a771b1b4bb876674cff 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='format-patch mime headers and extra headers do not conflict'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'create commit with utf-8 body' '
index 98d9713d8b2454eb1dfc4f137133a7cb0174bd0d..48655bcc789eef6f08896b064440ea25a36c6e47 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='format-patch -s should force MIME encoding as needed'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 0eb0314a8b35daecd3a442592bac4de1c480ffe0..78090e6852d5a8362e53414a1b4fc3302a24d874 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='diff with assume-unchanged entries'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # external diff has been tested in t4020-diff-external.sh
index 741e0803c1ac0a418c98c7eee9cb449a7c60da06..73048d0a52683bed2d56de3b0be77680cecaaf5a 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='diff.context configuration'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index a1de63b77f8b41ba0513f626d196129cf3ea4f09..0ecb3915412fcd70a62dc9acfba3054240767177 100755 (executable)
@@ -4,6 +4,7 @@ test_description='test combined/stat/moved interaction'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # This test covers a weird 3-way interaction between "--cc -p", which will run
index aa52de401b96ec1e6c7f2c2c6ec87ef4d0d393e7..96965373036a6944971b28cbf5c9f42e2c9abdb2 100755 (executable)
@@ -4,6 +4,7 @@ test_description='apply to deeper directory without getting fooled with symlink'
 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 '
index 33860d3829085211d5a5aa4da9468fa52cae4d9b..ece9fae207dbdbcc28a4ac999a351bd059c0968a 100755 (executable)
@@ -2,7 +2,6 @@
 
 test_description='apply empty'
 
-
 TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
index f6db5a79dd9d356c93a935374c4c27520ecf6593..ed94c90204e9c2eab135a1c2dcdeb15cf33e214c 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='apply same filename'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index be07407f855597ca276deccfbc17c3b692aa0642..6e66352558212e9a40404ef892a0944ab3d09db3 100755 (executable)
@@ -1992,10 +1992,13 @@ test_expect_success GPG 'log --show-signature for merged tag with GPG failure' '
        git tag -s -m signed_tag_msg signed_tag_fail &&
        git checkout plain-fail &&
        git merge --no-ff -m msg signed_tag_fail &&
-       TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual &&
-       grep "^merged tag" actual &&
-       grep "^No signature" actual &&
-       ! grep "^gpg: Signature made" actual
+       if ! test_have_prereq VALGRIND
+       then
+               TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual &&
+               grep "^merged tag" actual &&
+               grep "^No signature" actual &&
+               ! grep "^gpg: Signature made" actual
+       fi
 '
 
 test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '
index 4871a5dc92f0d586715728d667eefcf8c7644e00..33ecf82c7f98d3b9fb59422e614eb47cfe54fecb 100755 (executable)
@@ -6,6 +6,8 @@
 test_description='Test --follow should always find copies hard in git log.
 
 '
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-diff.sh
 
index b8709424981e92b84f754f520faafe7c4751bf46..36ac6aff1e40dd8ebc1bc894bf63d2228bcd32a3 100755 (executable)
@@ -8,6 +8,7 @@ test_description='Test for "git log --decorate" colors'
 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 '
index 0244888a5a7a8939276b0425b9144a8e262a2c8f..30a219894bb45f2655596fe02e8a7d001a35eabd 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='git log with invalid commit headers'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
diff --git a/t/t4217-log-limit.sh b/t/t4217-log-limit.sh
new file mode 100755 (executable)
index 0000000..6e01e26
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+test_description='git log with filter options limiting the output'
+
+. ./test-lib.sh
+
+test_expect_success 'setup test' '
+       git init &&
+       echo a >file &&
+       git add file &&
+       GIT_COMMITTER_DATE="2021-02-01 00:00" git commit -m init &&
+       echo a >>file &&
+       git add file &&
+       GIT_COMMITTER_DATE="2022-02-01 00:00" git commit -m first &&
+       echo a >>file &&
+       git add file &&
+       GIT_COMMITTER_DATE="2021-03-01 00:00" git commit -m second &&
+       echo a >>file &&
+       git add file &&
+       GIT_COMMITTER_DATE="2022-03-01 00:00" git commit -m third
+'
+
+test_expect_success 'git log --since-as-filter=...' '
+       git log --since-as-filter="2022-01-01" --format=%s >actual &&
+       cat >expect <<-\EOF &&
+       third
+       first
+       EOF
+       test_cmp expect actual
+'
+
+test_expect_success 'git log --children --since-as-filter=...' '
+       git log --children --since-as-filter="2022-01-01" --format=%s >actual &&
+       cat >expect <<-\EOF &&
+       third
+       first
+       EOF
+       test_cmp expect actual
+'
+
+test_done
index a11d61206addc4deaf4e8887bb23a7e9fc83cdd7..f8a0f309e2dec0f2ab864851730446bdc7102818 100755 (executable)
@@ -161,22 +161,27 @@ test_expect_success 'pack-objects with bogus arguments' '
 '
 
 check_unpack () {
+       local packname="$1" &&
+       local object_list="$2" &&
+       local git_config="$3" &&
        test_when_finished "rm -rf git2" &&
-       git init --bare git2 &&
-       git -C git2 unpack-objects -n <"$1".pack &&
-       git -C git2 unpack-objects <"$1".pack &&
-       (cd .git && find objects -type f -print) |
-       while read path
-       do
-               cmp git2/$path .git/$path || {
-                       echo $path differs.
-                       return 1
-               }
-       done
+       git $git_config init --bare git2 &&
+       (
+               git $git_config -C git2 unpack-objects -n <"$packname".pack &&
+               git $git_config -C git2 unpack-objects <"$packname".pack &&
+               git $git_config -C git2 cat-file --batch-check="%(objectname)"
+       ) <"$object_list" >current &&
+       cmp "$object_list" current
 }
 
 test_expect_success 'unpack without delta' '
-       check_unpack test-1-${packname_1}
+       check_unpack test-1-${packname_1} obj-list
+'
+
+BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch'
+
+test_expect_success 'unpack without delta (core.fsyncmethod=batch)' '
+       check_unpack test-1-${packname_1} obj-list "$BATCH_CONFIGURATION"
 '
 
 test_expect_success 'pack with REF_DELTA' '
@@ -185,7 +190,11 @@ test_expect_success 'pack with REF_DELTA' '
 '
 
 test_expect_success 'unpack with REF_DELTA' '
-       check_unpack test-2-${packname_2}
+       check_unpack test-2-${packname_2} obj-list
+'
+
+test_expect_success 'unpack with REF_DELTA (core.fsyncmethod=batch)' '
+       check_unpack test-2-${packname_2} obj-list "$BATCH_CONFIGURATION"
 '
 
 test_expect_success 'pack with OFS_DELTA' '
@@ -195,7 +204,11 @@ test_expect_success 'pack with OFS_DELTA' '
 '
 
 test_expect_success 'unpack with OFS_DELTA' '
-       check_unpack test-3-${packname_3}
+       check_unpack test-3-${packname_3} obj-list
+'
+
+test_expect_success 'unpack with OFS_DELTA (core.fsyncmethod=batch)' '
+       check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION"
 '
 
 test_expect_success 'compare delta flavors' '
index 76f9798ab958cae2414cbcc496bbb22af85f0ac5..3ccaaeb397774da8978c5406840ec307ffe7564d 100755 (executable)
@@ -4,6 +4,8 @@
 #
 
 test_description='mmap sliding window tests'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success \
index 535313e4dc8469ba9a4dc79eb75ae1f6e58cd2b0..cc4cfaa9d3712684f57f34372a4f40d0abf11f7e 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='bounds-checking of access to mmapped on-disk file formats'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 clear_base () {
index e9045009a1105d09caaea43b830548f77707b096..eb4ef3dda4d6e501b9be6c7b85d90a0fd55e5c7f 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='pack-objects breaks long cross-pack delta chains'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # This mirrors a repeated push setup:
index 33b740ce628f834a339154bd05d1acb5a1bbe4b7..bb633c9b099ed034c275389cb8e9e9da16efe704 100755 (executable)
@@ -10,9 +10,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 # Test blob:none filter.
 
 test_expect_success 'setup r1' '
-       echo "{print \$1}" >print_1.awk &&
-       echo "{print \$2}" >print_2.awk &&
-
        git init r1 &&
        for n in 1 2 3 4 5
        do
@@ -22,10 +19,13 @@ test_expect_success 'setup r1' '
        done
 '
 
+parse_verify_pack_blob_oid () {
+       awk '{print $1}' -
+}
+
 test_expect_success 'verify blob count in normal packfile' '
-       git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \
-               >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r1 pack-objects --revs --stdout >all.pack <<-EOF &&
@@ -35,7 +35,7 @@ test_expect_success 'verify blob count in normal packfile' '
 
        git -C r1 verify-pack -v ../all.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -54,12 +54,12 @@ test_expect_success 'verify blob:none packfile has no blobs' '
 test_expect_success 'verify normal and blob:none packfiles have same commits/trees' '
        git -C r1 verify-pack -v ../all.pack >verify_result &&
        grep -E "commit|tree" verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >expected &&
 
        git -C r1 verify-pack -v ../filter.pack >verify_result &&
        grep -E "commit|tree" verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -123,8 +123,8 @@ test_expect_success 'setup r2' '
 '
 
 test_expect_success 'verify blob count in normal packfile' '
-       git -C r2 ls-files -s large.1000 large.10000 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r2 ls-files -s large.1000 large.10000 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r2 pack-objects --revs --stdout >all.pack <<-EOF &&
@@ -134,7 +134,7 @@ test_expect_success 'verify blob count in normal packfile' '
 
        git -C r2 verify-pack -v ../all.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -161,8 +161,8 @@ test_expect_success 'verify blob:limit=1000' '
 '
 
 test_expect_success 'verify blob:limit=1001' '
-       git -C r2 ls-files -s large.1000 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r2 ls-files -s large.1000 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r2 pack-objects --revs --stdout --filter=blob:limit=1001 >filter.pack <<-EOF &&
@@ -172,15 +172,15 @@ test_expect_success 'verify blob:limit=1001' '
 
        git -C r2 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
 '
 
 test_expect_success 'verify blob:limit=10001' '
-       git -C r2 ls-files -s large.1000 large.10000 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r2 ls-files -s large.1000 large.10000 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r2 pack-objects --revs --stdout --filter=blob:limit=10001 >filter.pack <<-EOF &&
@@ -190,15 +190,15 @@ test_expect_success 'verify blob:limit=10001' '
 
        git -C r2 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
 '
 
 test_expect_success 'verify blob:limit=1k' '
-       git -C r2 ls-files -s large.1000 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r2 ls-files -s large.1000 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
@@ -208,15 +208,15 @@ test_expect_success 'verify blob:limit=1k' '
 
        git -C r2 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
 '
 
 test_expect_success 'verify explicitly specifying oversized blob in input' '
-       git -C r2 ls-files -s large.1000 large.10000 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r2 ls-files -s large.1000 large.10000 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        echo HEAD >objects &&
@@ -226,15 +226,15 @@ test_expect_success 'verify explicitly specifying oversized blob in input' '
 
        git -C r2 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
 '
 
 test_expect_success 'verify blob:limit=1m' '
-       git -C r2 ls-files -s large.1000 large.10000 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r2 ls-files -s large.1000 large.10000 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r2 pack-objects --revs --stdout --filter=blob:limit=1m >filter.pack <<-EOF &&
@@ -244,7 +244,7 @@ test_expect_success 'verify blob:limit=1m' '
 
        git -C r2 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -253,12 +253,12 @@ test_expect_success 'verify blob:limit=1m' '
 test_expect_success 'verify normal and blob:limit packfiles have same commits/trees' '
        git -C r2 verify-pack -v ../all.pack >verify_result &&
        grep -E "commit|tree" verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >expected &&
 
        git -C r2 verify-pack -v ../filter.pack >verify_result &&
        grep -E "commit|tree" verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -289,9 +289,8 @@ test_expect_success 'setup r3' '
 '
 
 test_expect_success 'verify blob count in normal packfile' '
-       git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 \
-               >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r3 pack-objects --revs --stdout >all.pack <<-EOF &&
@@ -301,7 +300,7 @@ test_expect_success 'verify blob count in normal packfile' '
 
        git -C r3 verify-pack -v ../all.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -342,9 +341,8 @@ test_expect_success 'setup r4' '
 '
 
 test_expect_success 'verify blob count in normal packfile' '
-       git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 \
-               >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r4 pack-objects --revs --stdout >all.pack <<-EOF &&
@@ -354,19 +352,19 @@ test_expect_success 'verify blob count in normal packfile' '
 
        git -C r4 verify-pack -v ../all.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
 '
 
 test_expect_success 'verify sparse:oid=OID' '
-       git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r4 ls-files -s pattern >staged &&
-       oid=$(awk -f print_2.awk staged) &&
+       oid=$(test_parse_ls_files_stage_oids <staged) &&
        git -C r4 pack-objects --revs --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF &&
        HEAD
        EOF
@@ -374,15 +372,15 @@ test_expect_success 'verify sparse:oid=OID' '
 
        git -C r4 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
 '
 
 test_expect_success 'verify sparse:oid=oid-ish' '
-       git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        git -C r4 pack-objects --revs --stdout --filter=sparse:oid=main:pattern >filter.pack <<-EOF &&
@@ -392,7 +390,7 @@ test_expect_success 'verify sparse:oid=oid-ish' '
 
        git -C r4 verify-pack -v ../filter.pack >verify_result &&
        grep blob verify_result |
-       awk -f print_1.awk |
+       parse_verify_pack_blob_oid |
        sort >observed &&
 
        test_cmp expected observed
@@ -402,9 +400,8 @@ test_expect_success 'verify sparse:oid=oid-ish' '
 # This models previously omitted objects that we did not receive.
 
 test_expect_success 'setup r1 - delete loose blobs' '
-       git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \
-               >ls_files_result &&
-       awk -f print_2.awk ls_files_result |
+       git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 |
+       test_parse_ls_files_stage_oids |
        sort >expected &&
 
        for id in `cat expected | sed "s|..|&/|"`
index fea92a5777fd17580539c95513a9869abb6f3773..124d47603df4ae71a9a1eeee9059752855f6860b 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='exercise delta islands'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # returns true iff $1 is a delta based on $2
index d39958c066de5e3739b48a4a3a64cb46f21f6700..770695c9278292285f7c5ed2fd65a80d7169d92f 100755 (executable)
@@ -4,6 +4,7 @@ test_description='pack-objects object selection using sparse algorithm'
 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 repo' '
diff --git a/t/t5329-pack-objects-cruft.sh b/t/t5329-pack-objects-cruft.sh
new file mode 100755 (executable)
index 0000000..b481224
--- /dev/null
@@ -0,0 +1,739 @@
+#!/bin/sh
+
+test_description='cruft pack related pack-objects tests'
+. ./test-lib.sh
+
+objdir=.git/objects
+packdir=$objdir/pack
+
+basic_cruft_pack_tests () {
+       expire="$1"
+
+       test_expect_success "unreachable loose objects are packed (expire $expire)" '
+               git init repo &&
+               test_when_finished "rm -fr repo" &&
+               (
+                       cd repo &&
+
+                       test_commit base &&
+                       git repack -Ad &&
+                       test_commit loose &&
+
+                       test-tool chmtime +2000 "$objdir/$(test_oid_to_path \
+                               $(git rev-parse loose:loose.t))" &&
+                       test-tool chmtime +1000 "$objdir/$(test_oid_to_path \
+                               $(git rev-parse loose^{tree}))" &&
+
+                       (
+                               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")"
+                               done |
+                               sort -k1
+                       ) >expect &&
+
+                       keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+                       cruft="$(echo $keep | git pack-objects --cruft \
+                               --cruft-expiration="$expire" $packdir/pack)" &&
+                       test-tool pack-mtimes "pack-$cruft.mtimes" >actual &&
+
+                       test_cmp expect actual
+               )
+       '
+
+       test_expect_success "unreachable packed objects are packed (expire $expire)" '
+               git init repo &&
+               test_when_finished "rm -fr repo" &&
+               (
+                       cd repo &&
+
+                       test_commit packed &&
+                       git repack -Ad &&
+                       test_commit other &&
+
+                       git rev-list --objects --no-object-names packed.. >objects &&
+                       keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+                       other="$(git pack-objects --delta-base-offset \
+                               $packdir/pack <objects)" &&
+                       git prune-packed &&
+
+                       test-tool chmtime --get -100 "$packdir/pack-$other.pack" >expect &&
+
+                       cruft="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF
+                       $keep
+                       -pack-$other.pack
+                       EOF
+                       )" &&
+                       test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw &&
+
+                       cut -d" " -f2 <actual.raw | sort -u >actual &&
+
+                       test_cmp expect actual
+               )
+       '
+
+       test_expect_success "unreachable cruft objects are repacked (expire $expire)" '
+               git init repo &&
+               test_when_finished "rm -fr repo" &&
+               (
+                       cd repo &&
+
+                       test_commit packed &&
+                       git repack -Ad &&
+                       test_commit other &&
+
+                       git rev-list --objects --no-object-names packed.. >objects &&
+                       keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+
+                       cruft_a="$(echo $keep | git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack)" &&
+                       git prune-packed &&
+                       cruft_b="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF
+                       $keep
+                       -pack-$cruft_a.pack
+                       EOF
+                       )" &&
+
+                       test-tool pack-mtimes "pack-$cruft_a.mtimes" >expect.raw &&
+                       test-tool pack-mtimes "pack-$cruft_b.mtimes" >actual.raw &&
+
+                       sort <expect.raw >expect &&
+                       sort <actual.raw >actual &&
+
+                       test_cmp expect actual
+               )
+       '
+
+       test_expect_success "multiple cruft packs (expire $expire)" '
+               git init repo &&
+               test_when_finished "rm -fr repo" &&
+               (
+                       cd repo &&
+
+                       test_commit reachable &&
+                       git repack -Ad &&
+                       keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+
+                       test_commit cruft &&
+                       loose="$objdir/$(test_oid_to_path $(git rev-parse cruft))" &&
+
+                       # generate three copies of the cruft object in different
+                       # cruft packs, each with a unique mtime:
+                       #   - one expired (1000 seconds ago)
+                       #   - two non-expired (one 1000 seconds in the future,
+                       #     one 1500 seconds in the future)
+                       test-tool chmtime =-1000 "$loose" &&
+                       git pack-objects --cruft $packdir/pack-A <<-EOF &&
+                       $keep
+                       EOF
+                       test-tool chmtime =+1000 "$loose" &&
+                       git pack-objects --cruft $packdir/pack-B <<-EOF &&
+                       $keep
+                       -$(basename $(ls $packdir/pack-A-*.pack))
+                       EOF
+                       test-tool chmtime =+1500 "$loose" &&
+                       git pack-objects --cruft $packdir/pack-C <<-EOF &&
+                       $keep
+                       -$(basename $(ls $packdir/pack-A-*.pack))
+                       -$(basename $(ls $packdir/pack-B-*.pack))
+                       EOF
+
+                       # ensure the resulting cruft pack takes the most recent
+                       # mtime among all copies
+                       cruft="$(git pack-objects --cruft \
+                               --cruft-expiration="$expire" \
+                               $packdir/pack <<-EOF
+                       $keep
+                       -$(basename $(ls $packdir/pack-A-*.pack))
+                       -$(basename $(ls $packdir/pack-B-*.pack))
+                       -$(basename $(ls $packdir/pack-C-*.pack))
+                       EOF
+                       )" &&
+
+                       test-tool pack-mtimes "$(basename $(ls $packdir/pack-C-*.mtimes))" >expect.raw &&
+                       test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw &&
+
+                       sort expect.raw >expect &&
+                       sort actual.raw >actual &&
+                       test_cmp expect actual
+               )
+       '
+
+       test_expect_success "cruft packs tolerate missing trees (expire $expire)" '
+               git init repo &&
+               test_when_finished "rm -fr repo" &&
+               (
+                       cd repo &&
+
+                       test_commit reachable &&
+                       test_commit cruft &&
+
+                       tree="$(git rev-parse cruft^{tree})" &&
+
+                       git reset --hard reachable &&
+                       git tag -d cruft &&
+                       git reflog expire --all --expire=all &&
+
+                       # remove the unreachable tree, but leave the commit
+                       # which has it as its root tree intact
+                       rm -fr "$objdir/$(test_oid_to_path "$tree")" &&
+
+                       git repack -Ad &&
+                       basename $(ls $packdir/pack-*.pack) >in &&
+                       git pack-objects --cruft --cruft-expiration="$expire" \
+                               $packdir/pack <in
+               )
+       '
+
+       test_expect_success "cruft packs tolerate missing blobs (expire $expire)" '
+               git init repo &&
+               test_when_finished "rm -fr repo" &&
+               (
+                       cd repo &&
+
+                       test_commit reachable &&
+                       test_commit cruft &&
+
+                       blob="$(git rev-parse cruft:cruft.t)" &&
+
+                       git reset --hard reachable &&
+                       git tag -d cruft &&
+                       git reflog expire --all --expire=all &&
+
+                       # remove the unreachable blob, but leave the commit (and
+                       # the root tree of that commit) intact
+                       rm -fr "$objdir/$(test_oid_to_path "$blob")" &&
+
+                       git repack -Ad &&
+                       basename $(ls $packdir/pack-*.pack) >in &&
+                       git pack-objects --cruft --cruft-expiration="$expire" \
+                               $packdir/pack <in
+               )
+       '
+}
+
+basic_cruft_pack_tests never
+basic_cruft_pack_tests 2.weeks.ago
+
+test_expect_success 'cruft tags rescue tagged objects' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit packed &&
+               git repack -Ad &&
+
+               test_commit tagged &&
+               git tag -a annotated -m tag &&
+
+               git rev-list --objects --no-object-names packed.. >objects &&
+               while read oid
+               do
+                       test-tool chmtime -1000 \
+                               "$objdir/$(test_oid_to_path $oid)"
+               done <objects &&
+
+               test-tool chmtime -500 \
+                       "$objdir/$(test_oid_to_path $(git rev-parse annotated))" &&
+
+               keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+               cruft="$(echo $keep | git pack-objects --cruft \
+                       --cruft-expiration=750.seconds.ago \
+                       $packdir/pack)" &&
+               test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw &&
+               cut -f1 -d" " <actual.raw | sort >actual &&
+
+               (
+                       cat objects &&
+                       git rev-parse annotated
+               ) >expect.raw &&
+               sort <expect.raw >expect &&
+
+               test_cmp expect actual &&
+               cat actual
+       )
+'
+
+test_expect_success 'cruft commits rescue parents, trees' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit packed &&
+               git repack -Ad &&
+
+               test_commit old &&
+               test_commit new &&
+
+               git rev-list --objects --no-object-names packed..new >objects &&
+               while read object
+               do
+                       test-tool chmtime -1000 \
+                               "$objdir/$(test_oid_to_path $object)"
+               done <objects &&
+               test-tool chmtime +500 "$objdir/$(test_oid_to_path \
+                       $(git rev-parse HEAD))" &&
+
+               keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+               cruft="$(echo $keep | git pack-objects --cruft \
+                       --cruft-expiration=750.seconds.ago \
+                       $packdir/pack)" &&
+               test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw &&
+
+               cut -d" " -f1 <actual.raw | sort >actual &&
+               sort <objects >expect &&
+
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'cruft trees rescue sub-trees, blobs' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit packed &&
+               git repack -Ad &&
+
+               mkdir -p dir/sub &&
+               echo foo >foo &&
+               echo bar >dir/bar &&
+               echo baz >dir/sub/baz &&
+
+               test_tick &&
+               git add . &&
+               git commit -m "pruned" &&
+
+               test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD))" &&
+               test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD^{tree}))" &&
+               test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:foo))" &&
+               test-tool chmtime  -500 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir))" &&
+               test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/bar))" &&
+               test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub))" &&
+               test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub/baz))" &&
+
+               keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+               cruft="$(echo $keep | git pack-objects --cruft \
+                       --cruft-expiration=750.seconds.ago \
+                       $packdir/pack)" &&
+               test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw &&
+               cut -f1 -d" " <actual.raw | sort >actual &&
+
+               git rev-parse HEAD:dir HEAD:dir/bar HEAD:dir/sub HEAD:dir/sub/baz >expect.raw &&
+               sort <expect.raw >expect &&
+
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'expired objects are pruned' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit packed &&
+               git repack -Ad &&
+
+               test_commit pruned &&
+
+               git rev-list --objects --no-object-names packed..pruned >objects &&
+               while read object
+               do
+                       test-tool chmtime -1000 \
+                               "$objdir/$(test_oid_to_path $object)"
+               done <objects &&
+
+               keep="$(basename "$(ls $packdir/pack-*.pack)")" &&
+               cruft="$(echo $keep | git pack-objects --cruft \
+                       --cruft-expiration=750.seconds.ago \
+                       $packdir/pack)" &&
+
+               test-tool pack-mtimes "pack-$cruft.mtimes" >actual &&
+               test_must_be_empty actual
+       )
+'
+
+test_expect_success 'repack --cruft generates a cruft pack' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit reachable &&
+               git branch -M main &&
+               git checkout --orphan other &&
+               test_commit unreachable &&
+
+               git checkout main &&
+               git branch -D other &&
+               git tag -d unreachable &&
+               # objects are not cruft if they are contained in the reflogs
+               git reflog expire --all --expire=all &&
+
+               git rev-list --objects --all --no-object-names >reachable.raw &&
+               git cat-file --batch-all-objects --batch-check="%(objectname)" >objects &&
+               sort <reachable.raw >reachable &&
+               comm -13 reachable objects >unreachable &&
+
+               git repack --cruft -d &&
+
+               cruft=$(basename $(ls $packdir/pack-*.mtimes) .mtimes) &&
+               pack=$(basename $(ls $packdir/pack-*.pack | grep -v $cruft) .pack) &&
+
+               git show-index <$packdir/$pack.idx >actual.raw &&
+               cut -f2 -d" " actual.raw | sort >actual &&
+               test_cmp reachable actual &&
+
+               git show-index <$packdir/$cruft.idx >actual.raw &&
+               cut -f2 -d" " actual.raw | sort >actual &&
+               test_cmp unreachable actual
+       )
+'
+
+test_expect_success 'loose objects mtimes upsert others' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit reachable &&
+               git repack -Ad &&
+               git branch -M main &&
+
+               git checkout --orphan other &&
+               test_commit cruft &&
+               # incremental repack, leaving existing objects loose (so
+               # they can be "freshened")
+               git repack &&
+
+               tip="$(git rev-parse cruft)" &&
+               path="$objdir/$(test_oid_to_path "$tip")" &&
+               test-tool chmtime --get +1000 "$path" >expect &&
+
+               git checkout main &&
+               git branch -D other &&
+               git tag -d cruft &&
+               git reflog expire --all --expire=all &&
+
+               git repack --cruft -d &&
+
+               mtimes="$(basename $(ls $packdir/pack-*.mtimes))" &&
+               test-tool pack-mtimes "$mtimes" >actual.raw &&
+               grep "$tip" actual.raw | cut -d" " -f2 >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'expiring cruft objects with git gc' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit reachable &&
+               git branch -M main &&
+               git checkout --orphan other &&
+               test_commit unreachable &&
+
+               git checkout main &&
+               git branch -D other &&
+               git tag -d unreachable &&
+               # objects are not cruft if they are contained in the reflogs
+               git reflog expire --all --expire=all &&
+
+               git rev-list --objects --all --no-object-names >reachable.raw &&
+               git cat-file --batch-all-objects --batch-check="%(objectname)" >objects &&
+               sort <reachable.raw >reachable &&
+               comm -13 reachable objects >unreachable &&
+
+               git repack --cruft -d &&
+
+               mtimes=$(ls .git/objects/pack/pack-*.mtimes) &&
+               test_path_is_file $mtimes &&
+
+               git gc --cruft --prune=now &&
+
+               git cat-file --batch-all-objects --batch-check="%(objectname)" >objects &&
+
+               comm -23 unreachable objects >removed &&
+               test_cmp unreachable removed &&
+               test_path_is_missing $mtimes
+       )
+'
+
+test_expect_success 'cruft packs are not included in geometric repack' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit reachable &&
+               git repack -Ad &&
+               git branch -M main &&
+
+               git checkout --orphan other &&
+               test_commit cruft &&
+               git repack -d &&
+
+               git checkout main &&
+               git branch -D other &&
+               git tag -d cruft &&
+               git reflog expire --all --expire=all &&
+
+               git repack --cruft &&
+
+               find $packdir -type f | sort >before &&
+               git repack --geometric=2 -d &&
+               find $packdir -type f | sort >after &&
+
+               test_cmp before after
+       )
+'
+
+test_expect_success 'repack --geometric collects once-cruft objects' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit reachable &&
+               git repack -Ad &&
+               git branch -M main &&
+
+               git checkout --orphan other &&
+               git rm -rf . &&
+               test_commit --no-tag cruft &&
+               cruft="$(git rev-parse HEAD)" &&
+
+               git checkout main &&
+               git branch -D other &&
+               git reflog expire --all --expire=all &&
+
+               # Pack the objects created in the previous step into a cruft
+               # pack. Intentionally leave loose copies of those objects
+               # around so we can pick them up in a subsequent --geometric
+               # reapack.
+               git repack --cruft &&
+
+               # Now make those objects reachable, and ensure that they are
+               # packed into the new pack created via a --geometric repack.
+               git update-ref refs/heads/other $cruft &&
+
+               # Without this object, the set of unpacked objects is exactly
+               # the set of objects already in the cruft pack. Tweak that set
+               # to ensure we do not overwrite the cruft pack entirely.
+               test_commit reachable2 &&
+
+               find $packdir -name "pack-*.idx" | sort >before &&
+               git repack --geometric=2 -d &&
+               find $packdir -name "pack-*.idx" | sort >after &&
+
+               {
+                       git rev-list --objects --no-object-names $cruft &&
+                       git rev-list --objects --no-object-names reachable..reachable2
+               } >want.raw &&
+               sort want.raw >want &&
+
+               pack=$(comm -13 before after) &&
+               git show-index <$pack >objects.raw &&
+
+               cut -d" " -f2 objects.raw | sort >got &&
+
+               test_cmp want got
+       )
+'
+
+test_expect_success 'cruft repack with no reachable objects' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit base &&
+               git repack -ad &&
+
+               base="$(git rev-parse base)" &&
+
+               git for-each-ref --format="delete %(refname)" >in &&
+               git update-ref --stdin <in &&
+               git reflog expire --all --expire=all &&
+               rm -fr .git/index &&
+
+               git repack --cruft -d &&
+
+               git cat-file -t $base
+       )
+'
+
+test_expect_success 'cruft repack ignores --max-pack-size' '
+       git init max-pack-size &&
+       (
+               cd max-pack-size &&
+               test_commit base &&
+               # two cruft objects which exceed the maximum pack size
+               test-tool genrandom foo 1048576 | git hash-object --stdin -w &&
+               test-tool genrandom bar 1048576 | git hash-object --stdin -w &&
+               git repack --cruft --max-pack-size=1M &&
+               find $packdir -name "*.mtimes" >cruft &&
+               test_line_count = 1 cruft &&
+               test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects &&
+               test_line_count = 2 objects
+       )
+'
+
+test_expect_success 'cruft repack ignores pack.packSizeLimit' '
+       (
+               cd max-pack-size &&
+               # repack everything back together to remove the existing cruft
+               # pack (but to keep its objects)
+               git repack -adk &&
+               git -c pack.packSizeLimit=1M repack --cruft &&
+               # ensure the same post condition is met when --max-pack-size
+               # would otherwise be inferred from the configuration
+               find $packdir -name "*.mtimes" >cruft &&
+               test_line_count = 1 cruft &&
+               test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects &&
+               test_line_count = 2 objects
+       )
+'
+
+test_expect_success 'cruft repack respects repack.cruftWindow' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit base &&
+
+               GIT_TRACE2_EVENT=$(pwd)/event.trace \
+               git -c pack.window=1 -c repack.cruftWindow=2 repack \
+                      --cruft --window=3 &&
+
+               grep "pack-objects.*--window=2.*--cruft" event.trace
+       )
+'
+
+test_expect_success 'cruft repack respects --window by default' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit base &&
+
+               GIT_TRACE2_EVENT=$(pwd)/event.trace \
+               git -c pack.window=2 repack --cruft --window=3 &&
+
+               grep "pack-objects.*--window=3.*--cruft" event.trace
+       )
+'
+
+test_expect_success 'cruft repack respects --quiet' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit base &&
+               GIT_PROGRESS_DELAY=0 git repack --cruft --quiet 2>err &&
+               test_must_be_empty err
+       )
+'
+
+test_expect_success 'cruft --local drops unreachable objects' '
+       git init alternate &&
+       git init repo &&
+       test_when_finished "rm -fr alternate repo" &&
+
+       test_commit -C alternate base &&
+       # Pack all objects in alterate so that the cruft repack in "repo" sees
+       # the object it dropped due to `--local` as packed. Otherwise this
+       # object would not appear packed anywhere (since it is not packed in
+       # alternate and likewise not part of the cruft pack in the other repo
+       # because of `--local`).
+       git -C alternate repack -ad &&
+
+       (
+               cd repo &&
+
+               object="$(git -C ../alternate rev-parse HEAD:base.t)" &&
+               git -C ../alternate cat-file -p $object >contents &&
+
+               # Write some reachable objects and two unreachable ones: one
+               # that the alternate has and another that is unique.
+               test_commit other &&
+               git hash-object -w -t blob contents &&
+               cruft="$(echo cruft | git hash-object -w -t blob --stdin)" &&
+
+               ( cd ../alternate/.git/objects && pwd ) \
+                      >.git/objects/info/alternates &&
+
+               test_path_is_file $objdir/$(test_oid_to_path $cruft) &&
+               test_path_is_file $objdir/$(test_oid_to_path $object) &&
+
+               git repack -d --cruft --local &&
+
+               test-tool pack-mtimes "$(basename $(ls $packdir/pack-*.mtimes))" \
+                      >objects &&
+               ! grep $object objects &&
+               grep $cruft objects
+       )
+'
+
+test_expect_success 'MIDX bitmaps tolerate reachable cruft objects' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               test_commit reachable &&
+               test_commit cruft &&
+               unreachable="$(git rev-parse cruft)" &&
+
+               git reset --hard $unreachable^ &&
+               git tag -d cruft &&
+               git reflog expire --all --expire=all &&
+
+               git repack --cruft -d &&
+
+               # resurrect the unreachable object via a new commit. the
+               # new commit will get selected for a bitmap, but be
+               # missing one of its parents from the selected packs.
+               git reset --hard $unreachable &&
+               test_commit resurrect &&
+
+               git repack --write-midx --write-bitmap-index --geometric=2 -d
+       )
+'
+
+test_expect_success 'cruft objects are freshend via loose' '
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+
+               echo "cruft" >contents &&
+               blob="$(git hash-object -w -t blob contents)" &&
+               loose="$objdir/$(test_oid_to_path $blob)" &&
+
+               test_commit base &&
+
+               git repack --cruft -d &&
+
+               test_path_is_missing "$loose" &&
+               test-tool pack-mtimes "$(basename "$(ls $packdir/pack-*.mtimes)")" >cruft &&
+               grep "$blob" cruft &&
+
+               # write the same object again
+               git hash-object -w -t blob contents &&
+
+               test_path_is_file "$loose"
+       )
+'
+
+test_done
index c90cf47acdb23489dbc06e76437372cb407bfa75..fff14e13ed43b385f1ce7c0d01c0bea815c954d5 100755 (executable)
@@ -78,6 +78,40 @@ test_expect_success 'add another remote' '
        )
 '
 
+test_expect_success 'setup bare clone for server' '
+       git clone --bare "file://$(pwd)/one" srv.bare &&
+       git -C srv.bare config --local uploadpack.allowfilter 1 &&
+       git -C srv.bare config --local uploadpack.allowanysha1inwant 1
+'
+
+test_expect_success 'filters for promisor remotes are listed by git remote -v' '
+       test_when_finished "rm -rf pc" &&
+       git clone --filter=blob:none "file://$(pwd)/srv.bare" pc &&
+       git -C pc remote -v >out &&
+       grep "srv.bare (fetch) \[blob:none\]" out &&
+
+       git -C pc config remote.origin.partialCloneFilter object:type=commit &&
+       git -C pc remote -v >out &&
+       grep "srv.bare (fetch) \[object:type=commit\]" out
+'
+
+test_expect_success 'filters should not be listed for non promisor remotes (remote -v)' '
+       test_when_finished "rm -rf pc" &&
+       git clone one pc &&
+       git -C pc remote -v >out &&
+       ! grep "(fetch) \[.*\]" out
+'
+
+test_expect_success 'filters are listed by git remote -v only' '
+       test_when_finished "rm -rf pc" &&
+       git clone --filter=blob:none "file://$(pwd)/srv.bare" pc &&
+       git -C pc remote >out &&
+       ! grep "\[blob:none\]" out &&
+
+       git -C pc remote show >out &&
+       ! grep "\[blob:none\]" out
+'
+
 test_expect_success 'check remote-tracking' '
        (
                cd test &&
index 8f150c0793e4be0ee2a2fe6e07512da4e0717f7b..5bac03ede81b4f964a91df275e3620f9da476c46 100755 (executable)
@@ -4,6 +4,7 @@ test_description='git remote group handling'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 mark() {
index f53f58895a12979f27a1b24ba9f15ee37bbc49a9..20d063fb9ae72c4df77a00dd5d5cb6da65640238 100755 (executable)
@@ -15,6 +15,10 @@ generate_references () {
        done
 }
 
+test_expect_success 'dies when no remote found' '
+       test_must_fail git ls-remote
+'
+
 test_expect_success setup '
        >file &&
        git add file &&
@@ -30,7 +34,8 @@ test_expect_success setup '
        git show-ref -d >refs &&
        sed -e "s/ /    /" refs >>expected.all &&
 
-       git remote add self "$(pwd)/.git"
+       git remote add self "$(pwd)/.git" &&
+       git remote add self2 "."
 '
 
 test_expect_success 'ls-remote --tags .git' '
@@ -83,11 +88,17 @@ test_expect_success 'ls-remote --sort="-refname" --tags self' '
        test_cmp expect actual
 '
 
-test_expect_success 'dies when no remote specified and no default remotes found' '
+test_expect_success 'dies when no remote specified, multiple remotes found, and no default specified' '
        test_must_fail git ls-remote
 '
 
-test_expect_success 'use "origin" when no remote specified' '
+test_expect_success 'succeeds when no remote specified but only one found' '
+       test_when_finished git remote add self2 "." &&
+       git remote remove self2 &&
+       git ls-remote
+'
+
+test_expect_success 'use "origin" when no remote specified and multiple found' '
        URL="$(pwd)/.git" &&
        echo "From $URL" >exp_err &&
 
index 65d1e05bd62af9c2b6dfa6cdd841d03622bf94ac..c46c4dbaefc729d8f26a65d6c797682f03d4d130 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='fetch follows remote-tracking branches correctly'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 320d26796d24d8a2281d37220a7bdf73cafaa503..c100a809c5e59f0b48d8b616883c1397de027ff3 100755 (executable)
@@ -14,6 +14,7 @@ export GIT_TEST_PROTOCOL_VERSION
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 build_script () {
index 5c4ac2556e7820f41285b5f653a5f61cc5f75846..c13120088fa684b59cc2f598d8ebfe05cae7b42c 100755 (executable)
@@ -8,6 +8,7 @@ test_description='fetch exit status test'
 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 '
index 43dada854443dcf430439dffd6d38d5d5be4f3d0..a301b56db894253829a0934647396ad854ec11b7 100755 (executable)
@@ -1125,4 +1125,31 @@ test_expect_success 'fetch --recurse-submodules updates name-conflicted, unpopul
        )
 '
 
+test_expect_success 'fetch --all with --recurse-submodules' '
+       test_when_finished "rm -fr src_clone" &&
+       git clone --recurse-submodules src src_clone &&
+       (
+               cd src_clone &&
+               git config submodule.recurse true &&
+               git config fetch.parallel 0 &&
+               git fetch --all 2>../fetch-log
+       ) &&
+       grep "^Fetching submodule sub$" fetch-log >fetch-subs &&
+       test_line_count = 1 fetch-subs
+'
+
+test_expect_success 'fetch --all with --recurse-submodules with multiple' '
+       test_when_finished "rm -fr src_clone" &&
+       git clone --recurse-submodules src src_clone &&
+       (
+               cd src_clone &&
+               git remote add secondary ../src &&
+               git config submodule.recurse true &&
+               git config fetch.parallel 0 &&
+               git fetch --all 2>../fetch-log
+       ) &&
+       grep "Fetching submodule sub" fetch-log >fetch-subs &&
+       test_line_count = 2 fetch-subs
+'
+
 test_done
index f280e00eb79c1e988faa01e1ff744fe4b2ca3440..284e20fefda861f450d79a3f849cc9ddc2afa65b 100755 (executable)
@@ -94,13 +94,88 @@ test_expect_success '"upstream" does not push when remotes do not match' '
        test_must_fail git push parent2
 '
 
-test_expect_success 'push from/to new branch with upstream, matching and simple' '
+test_expect_success '"current" does not push when multiple remotes and none origin' '
+       git checkout main &&
+       test_config push.default current &&
+       test_commit current-multi &&
+       test_must_fail git push
+'
+
+test_expect_success '"current" pushes when remote explicitly specified' '
+       git checkout main &&
+       test_config push.default current &&
+       test_commit current-specified &&
+       git push parent1
+'
+
+test_expect_success '"current" pushes to origin when no remote specified among multiple' '
+       git checkout main &&
+       test_config remote.origin.url repo1 &&
+       test_config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" &&
+       test_commit current-origin &&
+       test_push_success current main
+'
+
+test_expect_success '"current" pushes to single remote even when not specified' '
+       git checkout main &&
+       test_when_finished git remote add parent1 repo1 &&
+       git remote remove parent1 &&
+       test_commit current-implied &&
+       test_push_success current main repo2
+'
+
+test_expect_success 'push from/to new branch with non-defaulted remote fails with upstream, matching, current and simple ' '
        git checkout -b new-branch &&
        test_push_failure simple &&
        test_push_failure matching &&
+       test_push_failure upstream &&
+       test_push_failure current
+'
+
+test_expect_success 'push from/to new branch fails with upstream and simple ' '
+       git checkout -b new-branch-1 &&
+       test_config branch.new-branch-1.remote parent1 &&
+       test_push_failure simple &&
        test_push_failure upstream
 '
 
+# The behavior here is surprising but not entirely wrong:
+#  - the current branch is used to determine the target remote
+#  - the "matching" push default pushes matching branches, *ignoring* the
+#       current new branch as it does not have upstream tracking
+#  - the default push succeeds
+#
+# A previous test expected this to fail, but for the wrong reasons:
+# it expected a fail becaause the branch is new and cannot be pushed, but
+# in fact it was failing because of an ambiguous remote
+#
+test_expect_failure 'push from/to new branch fails with matching ' '
+       git checkout -b new-branch-2 &&
+       test_config branch.new-branch-2.remote parent1 &&
+       test_push_failure matching
+'
+
+test_expect_success 'push from/to branch with tracking fails with nothing ' '
+       git checkout -b tracked-branch &&
+       test_config branch.tracked-branch.remote parent1 &&
+       test_config branch.tracked-branch.merge refs/heads/tracked-branch &&
+       test_push_failure nothing
+'
+
+test_expect_success 'push from/to new branch succeeds with upstream if push.autoSetupRemote' '
+       git checkout -b new-branch-a &&
+       test_config push.autoSetupRemote true &&
+       test_config branch.new-branch-a.remote parent1 &&
+       test_push_success upstream new-branch-a
+'
+
+test_expect_success 'push from/to new branch succeeds with simple if push.autoSetupRemote' '
+       git checkout -b new-branch-c &&
+       test_config push.autoSetupRemote true &&
+       test_config branch.new-branch-c.remote parent1 &&
+       test_push_success simple new-branch-c
+'
+
 test_expect_success '"matching" fails if none match' '
        git init --bare empty &&
        test_must_fail git push empty : 2>actual &&
index 9c2798603b4d7b4a3db135febedc71e8cea23635..d664912799b43aef1b0a35d4d4a87ac95de36f4a 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='fetching via git:// using core.gitproxy'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup remote repo' '
index f92c79c13266526b52160fb5c1e8eeebed5d8dd6..b9351a732f6ef0267b2f4698f458471e54a40a93 100755 (executable)
@@ -567,4 +567,11 @@ test_expect_success 'client falls back from v2 to v0 to match server' '
        grep symref=HEAD:refs/heads/ trace
 '
 
+test_expect_success 'passing hostname resolution information works' '
+       BOGUS_HOST=gitbogusexamplehost.invalid &&
+       BOGUS_HTTPD_URL=$HTTPD_PROTO://$BOGUS_HOST:$LIB_HTTPD_PORT &&
+       test_must_fail git ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null &&
+       git -c "http.curloptResolve=$BOGUS_HOST:$LIB_HTTPD_PORT:127.0.0.1" ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null
+'
+
 test_done
index fa6b4cca65c8c687bf83f9eaf0ecb5568c9373f6..a35396fadf5ec2acea618be47c9cec5b5a108fa3 100755 (executable)
@@ -107,6 +107,32 @@ test_expect_success " --[no-]recurse-submodule and submodule.recurse" '
        test_path_is_file super/sub/merge_strategy_4.t
 '
 
+test_expect_success "fetch.recurseSubmodules option triggers recursive fetch (but not recursive update)" '
+       test_commit -C child merge_strategy_5 &&
+       # Omit the parent commit, otherwise this passes with the
+       # default "pull" behavior.
+
+       git -C super -c fetch.recursesubmodules=true pull --no-rebase &&
+       # Check that the submodule commit was fetched
+       sub_oid=$(git -C child rev-parse HEAD) &&
+       git -C super/sub cat-file -e $sub_oid &&
+       # Check that the submodule worktree did not update
+       ! test_path_is_file super/sub/merge_strategy_5.t
+'
+
+test_expect_success "fetch.recurseSubmodules takes precedence over submodule.recurse" '
+       test_commit -C child merge_strategy_6 &&
+       # Omit the parent commit, otherwise this passes with the
+       # default "pull" behavior.
+
+       git -C super -c submodule.recurse=false -c fetch.recursesubmodules=true pull --no-rebase &&
+       # Check that the submodule commit was fetched
+       sub_oid=$(git -C child rev-parse HEAD) &&
+       git -C super/sub cat-file -e $sub_oid &&
+       # Check that the submodule worktree did not update
+       ! test_path_is_file super/sub/merge_strategy_6.t
+'
+
 test_expect_success 'pull --rebase --recurse-submodules (remote superproject submodule changes, local submodule changes)' '
        # This tests the following scenario :
        # - local submodule has new commits
index 34b3df4027593b58582b4742d36a211aec57a526..c814afa5656cca57469d0bff5711bc25229d037a 100755 (executable)
@@ -13,6 +13,7 @@ Unless the directory already exists, in which case we clean up only what we
 wrote.
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 corrupt_repo () {
index 7d63365f93a0a50eda1d4ec9b55c19890f610102..21ab6192839a006060b6e2e864aab93989a418f1 100755 (executable)
@@ -141,4 +141,13 @@ test_expect_success 'cloning locally respects "-u" for fetching refs' '
        test_must_fail git clone --bare -u false a should_not_work.git
 '
 
+test_expect_success 'local clone from repo with corrupt refs fails gracefully' '
+       git init corrupt &&
+       test_commit -C corrupt one &&
+       echo a >corrupt/.git/refs/heads/topic &&
+
+       test_must_fail git clone corrupt working 2>err &&
+       grep "has a null OID" err
+'
+
 test_done
index 14e59c5b3e4239c3d41d01f3c6a0d821dfe4e260..a84faac242d0406f523a78bd201ddcb59ae3acd8 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='selecting remote repo in ambiguous cases'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 reset() {
index b95a0212adff71632d0b91cf96432b276c86a44c..162cf50778d6191f71941b0f6c9ef600c6a10684 100755 (executable)
@@ -4,6 +4,7 @@
 #
 test_description='Tests git rev-list --bisect functionality'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions
 
index 24d1836f417d67a224f0d9bef619952a39ed28eb..1f7d7dd20c1cf129c8a98ba59694f75e8e0de911 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='Tests git rev-list --topo-order functionality'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions
 
index e960049f647cfca4a18defaba7dde9d43c8f94ef..0729f800c3c95790946d68296240799c2dbbb5ad 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='git rev-list --max-count and --skip test'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index 24b34add833468dd73136689980e4ca3a051411b..e1abc5c2b32f57526c277e6ac62fa1b45f2f46bd 100755 (executable)
@@ -5,6 +5,7 @@ test_description='rev-list/rev-parse --glob'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 commit () {
index 5382e5d21620aea6bd74fdd4a84fb14f0ac644dc..83931d482fb23b0b774310a49e8dcd6ad7eac4b9 100755 (executable)
@@ -1025,4 +1025,32 @@ test_expect_success 'bisect visualize with a filename with dash and space' '
        git bisect visualize -p -- "-hello 2"
 '
 
+test_expect_success 'bisect state output with multiple good commits' '
+       git bisect reset &&
+       git bisect start >output &&
+       grep "waiting for both good and bad commits" output &&
+       git bisect log >output &&
+       grep "waiting for both good and bad commits" output &&
+       git bisect good "$HASH1" >output &&
+       grep "waiting for bad commit, 1 good commit known" output &&
+       git bisect log >output &&
+       grep "waiting for bad commit, 1 good commit known" output &&
+       git bisect good "$HASH2" >output &&
+       grep "waiting for bad commit, 2 good commits known" output &&
+       git bisect log >output &&
+       grep "waiting for bad commit, 2 good commits known" output
+'
+
+test_expect_success 'bisect state output with bad commit' '
+       git bisect reset &&
+       git bisect start >output &&
+       grep "waiting for both good and bad commits" output &&
+       git bisect log >output &&
+       grep "waiting for both good and bad commits" output &&
+       git bisect bad "$HASH4" >output &&
+       grep -F "waiting for good commit(s), bad commit known" output &&
+       git bisect log >output &&
+       grep -F "waiting for good commit(s), bad commit known" output
+'
+
 test_done
index e934bc239c534d5da532c28d520732475859b665..88ed7bd75a75f0d8eb730d2f3db7dc59afe7807f 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='rev-list testing in-commit-order'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup a commit history with trees, blobs' '
index c571fa517978818703e29c72e36faf52643a8ee5..a3a41c7a3e47899521d63c056532604a7d224c97 100755 (executable)
@@ -8,6 +8,7 @@ test_description='Test git rev-parse with different parent options'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_cmp_rev_output () {
index 13c1da5352836758cb0806d0f969f2aac4c8f7c9..ddefc7f24ee9cacc6cb7f5ca84c8ca3010e60ca5 100755 (executable)
@@ -4,6 +4,7 @@ test_description='operations that cull histories in unusual ways'
 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 '
index 9239d8aa46d8968d71fc678763e77faf9611e5ad..44246f8a63e55f275b3b6f32ac289f2c1adb85e7 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='rev-list with .keep packs'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index 39fc3f6769be1c41d76c6acbfcb780b823afe7e7..770cce026cb158ab9a77eda336ff263c862fb0f8 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='test case insensitive pathspec limiting'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 if test_have_prereq CASE_INSENSITIVE_FS
index 89dd544f3880c46b4207220427da86e1580c5789..b6e424a427b5566b2edf48b3d0a29ad6a927f67e 100755 (executable)
@@ -71,7 +71,9 @@ test_expect_success 'ff update' '
        git merge E^0 &&
 
        test_must_fail git rev-parse HEAD:random_file &&
-       test "$(git diff --name-only --cached E)" = "random_file"
+       test "$(git diff --name-only --cached E)" = "random_file" &&
+       test_path_is_file random_file &&
+       git rev-parse --verify :random_file
 '
 
 test_expect_success 'ff update, important file modified' '
@@ -83,6 +85,8 @@ test_expect_success 'ff update, important file modified' '
        git add subdir/e &&
 
        test_must_fail git merge E^0 &&
+       test_path_is_file subdir/e &&
+       git rev-parse --verify :subdir/e &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -93,6 +97,8 @@ test_expect_success 'resolve, trivial' '
        touch random_file && git add random_file &&
 
        test_must_fail git merge -s resolve C^0 &&
+       test_path_is_file random_file &&
+       git rev-parse --verify :random_file &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -103,6 +109,8 @@ test_expect_success 'resolve, non-trivial' '
        touch random_file && git add random_file &&
 
        test_must_fail git merge -s resolve D^0 &&
+       test_path_is_file random_file &&
+       git rev-parse --verify :random_file &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -113,6 +121,8 @@ test_expect_success 'recursive' '
        touch random_file && git add random_file &&
 
        test_must_fail git merge -s recursive C^0 &&
+       test_path_is_file random_file &&
+       git rev-parse --verify :random_file &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -145,9 +155,12 @@ test_expect_success 'recursive, when file has staged changes not matching HEAD n
        mkdir subdir &&
        test_seq 1 10 >subdir/a &&
        git add subdir/a &&
+       git rev-parse --verify :subdir/a >expect &&
 
        # We have staged changes; merge should error out
        test_must_fail git merge -s recursive E^0 2>err &&
+       git rev-parse --verify :subdir/a >actual &&
+       test_cmp expect actual &&
        test_i18ngrep "changes to the following files would be overwritten" err
 '
 
@@ -158,9 +171,12 @@ test_expect_success 'recursive, when file has staged changes matching what a mer
        mkdir subdir &&
        test_seq 1 11 >subdir/a &&
        git add subdir/a &&
+       git rev-parse --verify :subdir/a >expect &&
 
        # We have staged changes; merge should error out
        test_must_fail git merge -s recursive E^0 2>err &&
+       git rev-parse --verify :subdir/a >actual &&
+       test_cmp expect actual &&
        test_i18ngrep "changes to the following files would be overwritten" err
 '
 
@@ -171,7 +187,9 @@ test_expect_success 'octopus, unrelated file touched' '
        touch random_file && git add random_file &&
 
        test_must_fail git merge C^0 D^0 &&
-       test_path_is_missing .git/MERGE_HEAD
+       test_path_is_missing .git/MERGE_HEAD &&
+       git rev-parse --verify :random_file &&
+       test_path_exists random_file
 '
 
 test_expect_success 'octopus, related file removed' '
@@ -181,6 +199,8 @@ test_expect_success 'octopus, related file removed' '
        git rm b &&
 
        test_must_fail git merge C^0 D^0 &&
+       test_path_is_missing b &&
+       test_must_fail git rev-parse --verify :b &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -189,8 +209,12 @@ test_expect_success 'octopus, related file modified' '
        git checkout B^0 &&
 
        echo 12 >>a && git add a &&
+       git rev-parse --verify :a >expect &&
 
        test_must_fail git merge C^0 D^0 &&
+       test_path_is_file a &&
+       git rev-parse --verify :a >actual &&
+       test_cmp expect actual &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -201,6 +225,8 @@ test_expect_success 'ours' '
        touch random_file && git add random_file &&
 
        test_must_fail git merge -s ours C^0 &&
+       test_path_is_file random_file &&
+       git rev-parse --verify :random_file &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
@@ -211,6 +237,8 @@ test_expect_success 'subtree' '
        touch random_file && git add random_file &&
 
        test_must_fail git merge -s subtree E^0 &&
+       test_path_is_file random_file &&
+       git rev-parse --verify :random_file &&
        test_path_is_missing .git/MERGE_HEAD
 '
 
index 142c9aaabc5309078e38cc01607f821520f965fc..064be1b629e318bb571f1dca2d8ac9c26f86adf9 100755 (executable)
@@ -87,7 +87,7 @@ test_expect_success 'conflicting entries written to worktree even if sparse' '
                test_path_is_file numerals &&
 
                git sparse-checkout init &&
-               git sparse-checkout set README &&
+               git sparse-checkout set --no-cone README &&
 
                test_path_is_file README &&
                test_path_is_missing numerals &&
@@ -123,7 +123,7 @@ test_expect_success 'present-despite-SKIP_WORKTREE handled reasonably' '
                test_path_is_file numerals &&
 
                git sparse-checkout init &&
-               git sparse-checkout set README &&
+               git sparse-checkout set --no-cone README &&
 
                test_path_is_file README &&
                test_path_is_missing numerals &&
index 1d3d2aca21c70e6b0d212ec1f1c7967418e0ea5e..f0f7cbfcdb7fa523ee3693501324cde8591a25d9 100755 (executable)
@@ -27,7 +27,7 @@ test_expect_success 'setup' "
 test_expect_success 'mv refuses to move sparse-to-sparse' '
        test_when_finished rm -f e &&
        git reset --hard &&
-       git sparse-checkout set a &&
+       git sparse-checkout set --no-cone a &&
        touch b &&
        test_must_fail git mv b e 2>stderr &&
        cat sparse_error_header >expect &&
index 9ba9f24ad2fb4bd2c38a722e62577789fe36f09a..93fbc92b8dbc297512050846c4f00ec803dea4a9 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
 test_description='filter-branch removal of trees with null sha1'
+
 . ./test-lib.sh
 
 test_expect_success 'setup: base commits' '
index 1761a2b1b99bc80e43ac22b0ec57656ec38b9ad5..4adac5acd57c56835608631c4ffe98f772d455bd 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='skip-worktree bit test'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 cat >expect.full <<EOF
index cb9f1a6981eb5f05dd662eac436a8ee6f7a17dee..cd5c20fe51b3727035d56245c17568030f87d455 100755 (executable)
@@ -151,7 +151,7 @@ test_expect_success 'stash restore in sparse checkout' '
 
                git stash push &&
 
-               git sparse-checkout set subdir &&
+               git sparse-checkout set --no-cone subdir &&
 
                # Ensure after sparse-checkout we only have expected files
                cat >expect <<-EOF &&
index ca90ee805e7b3411c6e7c8c5868c3aa2063dba05..9936cc329ecd3f3d6cf96994de0209efd945dd55 100755 (executable)
@@ -190,6 +190,119 @@ test_expect_success 'untracked cache after second status' '
        test_cmp ../dump.expect ../actual
 '
 
+cat >../status_uall.expect <<EOF &&
+A  done/one
+A  one
+A  two
+?? dthree/three
+?? dtwo/two
+?? three
+EOF
+
+# Bypassing the untracked cache here is not desirable from an
+# end-user perspective, but is expected in the current design.
+# The untracked cache data stored for a -unormal run cannot be
+# correctly used in a -uall run - it would yield incorrect output.
+test_expect_success 'untracked cache is bypassed with -uall' '
+       : >../trace.output &&
+       GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+       git status -uall --porcelain >../actual &&
+       iuc status -uall --porcelain >../status.iuc &&
+       test_cmp ../status_uall.expect ../status.iuc &&
+       test_cmp ../status_uall.expect ../actual &&
+       get_relevant_traces ../trace.output ../trace.relevant &&
+       cat >../trace.expect <<EOF &&
+ ....path:
+EOF
+       test_cmp ../trace.expect ../trace.relevant
+'
+
+test_expect_success 'untracked cache remains after bypass' '
+       test-tool dump-untracked-cache >../actual &&
+       test_cmp ../dump.expect ../actual
+'
+
+test_expect_success 'if -uall is configured, untracked cache gets populated by default' '
+       test_config status.showuntrackedfiles all &&
+       : >../trace.output &&
+       GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+       git status --porcelain >../actual &&
+       iuc status --porcelain >../status.iuc &&
+       test_cmp ../status_uall.expect ../status.iuc &&
+       test_cmp ../status_uall.expect ../actual &&
+       get_relevant_traces ../trace.output ../trace.relevant &&
+       cat >../trace.expect <<EOF &&
+ ....path:
+ ....node-creation:3
+ ....gitignore-invalidation:1
+ ....directory-invalidation:0
+ ....opendir:4
+EOF
+       test_cmp ../trace.expect ../trace.relevant
+'
+
+cat >../dump_uall.expect <<EOF &&
+info/exclude $EMPTY_BLOB
+core.excludesfile $ZERO_OID
+exclude_per_dir .gitignore
+flags 00000000
+/ $ZERO_OID recurse valid
+three
+/done/ $ZERO_OID recurse valid
+/dthree/ $ZERO_OID recurse valid
+three
+/dtwo/ $ZERO_OID recurse valid
+two
+EOF
+
+test_expect_success 'if -uall was configured, untracked cache is populated' '
+       test-tool dump-untracked-cache >../actual &&
+       test_cmp ../dump_uall.expect ../actual
+'
+
+test_expect_success 'if -uall is configured, untracked cache is used by default' '
+       test_config status.showuntrackedfiles all &&
+       : >../trace.output &&
+       GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+       git status --porcelain >../actual &&
+       iuc status --porcelain >../status.iuc &&
+       test_cmp ../status_uall.expect ../status.iuc &&
+       test_cmp ../status_uall.expect ../actual &&
+       get_relevant_traces ../trace.output ../trace.relevant &&
+       cat >../trace.expect <<EOF &&
+ ....path:
+ ....node-creation:0
+ ....gitignore-invalidation:0
+ ....directory-invalidation:0
+ ....opendir:0
+EOF
+       test_cmp ../trace.expect ../trace.relevant
+'
+
+# Bypassing the untracked cache here is not desirable from an
+# end-user perspective, but is expected in the current design.
+# The untracked cache data stored for a -all run cannot be
+# correctly used in a -unormal run - it would yield incorrect
+# output.
+test_expect_success 'if -uall is configured, untracked cache is bypassed with -unormal' '
+       test_config status.showuntrackedfiles all &&
+       : >../trace.output &&
+       GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+       git status -unormal --porcelain >../actual &&
+       iuc status -unormal --porcelain >../status.iuc &&
+       test_cmp ../status.expect ../status.iuc &&
+       test_cmp ../status.expect ../actual &&
+       get_relevant_traces ../trace.output ../trace.relevant &&
+       cat >../trace.expect <<EOF &&
+ ....path:
+EOF
+       test_cmp ../trace.expect ../trace.relevant
+'
+
+test_expect_success 'repopulate untracked cache for -unormal' '
+       git status --porcelain
+'
+
 test_expect_success 'modify in root directory, one dir invalidation' '
        : >four &&
        test-tool chmtime =-240 four &&
diff --git a/t/t7524-commit-summary.sh b/t/t7524-commit-summary.sh
new file mode 100755 (executable)
index 0000000..47b2f1d
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='git commit summary'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       test_seq 101 200 >file &&
+       git add file &&
+       git commit -m initial &&
+       git tag initial
+'
+
+test_expect_success 'commit summary ignores rewrites' '
+       git reset --hard initial &&
+       test_seq 200 300 >file &&
+
+       git diff --stat >diffstat &&
+       git diff --stat --break-rewrites >diffstatrewrite &&
+
+       # make sure this scenario is a detectable rewrite
+       ! test_cmp_bin diffstat diffstatrewrite &&
+
+       git add file &&
+       git commit -m second >actual &&
+
+       grep "1 file" <actual >actual.total &&
+       grep "1 file" <diffstat >diffstat.total &&
+       test_cmp diffstat.total actual.total
+'
+
+test_done
diff --git a/t/t7609-mergetool--lib.sh b/t/t7609-mergetool--lib.sh
new file mode 100755 (executable)
index 0000000..d848fe6
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+test_description='git mergetool
+
+Testing basic merge tools options'
+
+. ./test-lib.sh
+
+test_expect_success 'mergetool --tool=vimdiff creates the expected layout' '
+       . $GIT_BUILD_DIR/mergetools/vimdiff &&
+       run_unit_tests
+'
+
+test_done
index 93b74867ac8f005fa3ef7831b066d236f18dfb12..f3cdb98eec26b8b2d8cd138d6740a77802f84ae4 100755 (executable)
@@ -4,6 +4,8 @@
 #
 
 test_description='repack involving cyclic alternate'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index bdbbcbf1eca88fef1c2dcd6632d880d3848c842d..da87f8b2d8822cd5f844cfb00bcdaf5c52117f79 100755 (executable)
@@ -7,6 +7,7 @@ test_description='git repack --geometric works correctly'
 GIT_TEST_MULTI_PACK_INDEX=0
 
 objdir=.git/objects
+packdir=$objdir/pack
 midx=$objdir/pack/multi-pack-index
 
 test_expect_success '--geometric with no packs' '
@@ -180,6 +181,34 @@ test_expect_success '--geometric ignores kept packs' '
        )
 '
 
+test_expect_success '--geometric ignores --keep-pack packs' '
+       git init geometric &&
+       test_when_finished "rm -fr geometric" &&
+       (
+               cd geometric &&
+
+               # Create two equal-sized packs
+               test_commit kept && # 3 objects
+               git repack -d &&
+               test_commit pack && # 3 objects
+               git repack -d &&
+
+               find $objdir/pack -type f -name "*.pack" | sort >packs.before &&
+               git repack --geometric 2 -dm \
+                       --keep-pack="$(basename "$(head -n 1 packs.before)")" >out &&
+               find $objdir/pack -type f -name "*.pack" | sort >packs.after &&
+
+               # Packs should not have changed (only one non-kept pack, no
+               # loose objects), but $midx should now exist.
+               grep "Nothing new to pack" out &&
+               test_path_is_file $midx &&
+
+               test_cmp packs.before packs.after &&
+
+               git fsck
+       )
+'
+
 test_expect_success '--geometric chooses largest MIDX preferred pack' '
        git init geometric &&
        test_when_finished "rm -fr geometric" &&
@@ -202,4 +231,50 @@ test_expect_success '--geometric chooses largest MIDX preferred pack' '
        )
 '
 
+test_expect_success '--geometric with pack.packSizeLimit' '
+       git init pack-rewrite &&
+       test_when_finished "rm -fr pack-rewrite" &&
+       (
+               cd pack-rewrite &&
+
+               test-tool genrandom foo 1048576 >foo &&
+               test-tool genrandom bar 1048576 >bar &&
+
+               git add foo bar &&
+               test_tick &&
+               git commit -m base &&
+
+               git rev-parse HEAD:foo HEAD:bar >p1.objects &&
+               git rev-parse HEAD HEAD^{tree} >p2.objects &&
+
+               # These two packs each contain two objects, so the following
+               # `--geometric` repack will try to combine them.
+               p1="$(git pack-objects $packdir/pack <p1.objects)" &&
+               p2="$(git pack-objects $packdir/pack <p2.objects)" &&
+
+               # Remove any loose objects in packs, since we do not want extra
+               # copies around (which would mask over potential object
+               # corruption issues).
+               git prune-packed &&
+
+               # Both p1 and p2 will be rolled up, but pack-objects will write
+               # three packs:
+               #
+               #   - one containing object "foo",
+               #   - another containing object "bar",
+               #   - a final pack containing the commit and tree objects
+               #     (identical to p2 above)
+               git repack --geometric 2 -d --max-pack-size=1048576 &&
+
+               # Ensure `repack` can detect that the third pack it wrote
+               # (containing just the tree and commit objects) was identical to
+               # one that was below the geometric split, so that we can save it
+               # from deletion.
+               #
+               # If `repack` fails to do that, we will incorrectly delete p2,
+               # causing object corruption.
+               git fsck
+       )
+'
+
 test_done
index 9047d665a1049195ec03b64504c973559a677c36..ac7be5471452a0a8b2123dc39be80caf3520e9db 100755 (executable)
@@ -4,6 +4,10 @@ test_description='grep icase on non-English locales'
 
 . ./lib-gettext.sh
 
+doalarm () {
+       perl -e 'alarm shift; exec @ARGV' -- "$@"
+}
+
 test_expect_success GETTEXT_LOCALE 'setup' '
        test_write_lines "TILRAUN: Halló Heimur!" >file &&
        git add file &&
@@ -139,4 +143,10 @@ test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-literal ASCII fro
        test_cmp expected actual
 '
 
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep avoid endless loop bug' '
+       echo " Halló" >leading-whitespace &&
+       git add leading-whitespace &&
+       doalarm 1 git grep --perl-regexp "^\s" leading-whitespace
+'
+
 test_done
index 42694fe58419fbf13e78f72dde91a0ac2f61e2cb..01c74b8b0756caf01483f8cafbdda55eeb7d0ddb 100755 (executable)
@@ -4,6 +4,7 @@ test_description='git send-email'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # May be altered later in the test
index fea41b3c3606df1fc6d8111cdd74522532ca8b0b..7c5b847f58424dc62c330674971d2d849f77ac4e 100755 (executable)
@@ -8,6 +8,7 @@ test_description='git svn basic tests'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 prepare_utf8_locale
index 8b5681dd68ab05adc504437a54ff2877ed180516..d043e80fc349f85e1cd4168c9bf4d343dfeee0d5 100755 (executable)
@@ -4,6 +4,8 @@
 #
 
 test_description='git svn property tests'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 mkdir import
index c7d8e0bf00f6344d1216f117f57587cda3116fc2..5cf2ef4b8b0fc3a9a587baea4e8421893c90bd14 100755 (executable)
@@ -4,6 +4,8 @@
 #
 
 test_description='git svn fetching'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'initialize repo' '
index aec45bca3b7b6fc4561e02ff975f77a5331cb7ce..3cab0b9720a6544ade5caf91a3f678ad577cc3b0 100755 (executable)
@@ -2,6 +2,8 @@
 #
 # Copyright (c) 2006 Eric Wong
 test_description='git svn commit-diff clobber'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'initialize repo' '
index 743fbe1fe46929583aacacc60ba959c38d8a2f09..419f055721dbc32122e9d595d691c77bb8a24212 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='git svn dcommit can commit renames of files with ugly names'
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'load repository with strange names' '
index 0a9f1ef366db07c31668f6bf4cf0d9267d788453..d74d7b2de68e05cb41d0740f54fa598aaa50fa9a 100755 (executable)
@@ -4,6 +4,7 @@
 #
 
 test_description='git svn log tests'
+
 . ./lib-git-svn.sh
 
 test_expect_success 'setup repository and import' '
index 9e8fe38e7ef94b7343122b279c94c250dcf48756..527ba3d29322a14d609ea57e3740672f144f3182 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='git svn authorship'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'setup svn repository' '
index 2e4789d061fe084024b621708ee27e629c2a004a..97f495bd49b48a159aa7e39596b42cbbd65dbdf3 100755 (executable)
@@ -4,6 +4,7 @@
 #
 
 test_description='git svn partial-rebuild tests'
+
 . ./lib-git-svn.sh
 
 test_expect_success 'initialize svnrepo' '
index 01e1e8a8f76765d081270d37a980778fad4189d0..185248a4cd766172969ad88f7dcd94258733f644 100755 (executable)
@@ -4,6 +4,7 @@
 
 test_description='git svn honors i18n.commitEncoding in config'
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 compare_git_head_with () {
index aeceffaf7b0824b8da673261f523589d3b141619..4d8d0584b795d21fab8ba7dcbd47b50c178c2757 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='test that git handles an svn repository with empty symlinks'
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 test_expect_success 'load svn dumpfile' '
        svnadmin load "$rawsvnrepo" <<EOF
index 22d80b0be2b94515132a79401b719f98794f4616..b7f756b2b7f28f6e5d32fa595ebbf1ca2bebb45b 100755 (executable)
@@ -4,6 +4,7 @@
 
 test_description='git svn refuses to dcommit non-UTF8 messages'
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 # ISO-2022-JP can pass for valid UTF-8, so skipping that in this test
index 80cb55fee70e2affd719c0b6812e01f3125ce42e..79c26ed69c16cad42a32a555bb33635a154441e7 100755 (executable)
@@ -3,6 +3,8 @@
 # Copyright (c) 2009 Eric Wong
 
 test_description='git svn creates empty directories'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'initialize repo' '
index aebb28995e50a0a589e8fff33997d9816de1fdb2..6cc76a07b39a90d590759bbb7033da3953969092 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='git svn propset tests'
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'setup propset via import' '
index 36c6b1a12ffd95a1d6fe4ee4efd18a47f1581078..9cf7a1427ab081f2084b147b7dc4b1e3aa0f1005 100755 (executable)
@@ -9,6 +9,7 @@ This test uses git to clone a Subversion repository that contains empty
 directories, and checks that corresponding directories are created in the
 local Git repository with placeholder files.'
 
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 GIT_REPO=git-svn-repo
index e38d9fa37b50195607b0f1d066eb4c78f39cfc4f..e2aa8ed88a96ec0b50fb33f31e2e6d232895067c 100755 (executable)
@@ -3,6 +3,8 @@
 # Copyright (c) 2011 Frédéric Heitzmann
 
 test_description='git svn dcommit --interactive series'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'initialize repo' '
index 8466269bf50b66dd8d55cadc891600172659438e..1465156072e32a75fb759784e65f9f7e2ca4c84a 100755 (executable)
@@ -4,6 +4,8 @@
 #
 
 test_description='concurrent git svn dcommit'
+
+TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 
index 32814e75df5b0d796b292c2ac39d370c636e5e67..c900231079cf750f0f1111ca74ddca7803becf6c 100755 (executable)
@@ -13,6 +13,7 @@ code and message.'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./lib-gitweb.sh
 
 #
index 8b30062c0cfcc80a0cdff0f73367be43246280b3..dc88d0e064931aab48a3e93002cc67416090282c 100755 (executable)
@@ -74,6 +74,91 @@ test_expect_success 'git p4 sync new branch' '
        )
 '
 
+#
+# Setup as before, and then explicitly sync imported branch, using a
+# different ref format.
+#
+test_expect_success 'git p4 sync existing branch without changes' '
+       test_create_repo "$git" &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               test_commit head &&
+               git p4 sync --branch=depot //depot@all &&
+               git p4 sync --branch=refs/remotes/p4/depot >out &&
+               test_i18ngrep "No changes to import!" out
+       )
+'
+
+#
+# Same as before, relative branch name.
+#
+test_expect_success 'git p4 sync existing branch with relative name' '
+       test_create_repo "$git" &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               test_commit head &&
+               git p4 sync --branch=branch1 //depot@all &&
+               git p4 sync --branch=p4/branch1 >out &&
+               test_i18ngrep "No changes to import!" out
+       )
+'
+
+#
+# Same as before, with a nested branch path, referenced different ways.
+#
+test_expect_success 'git p4 sync existing branch with nested path' '
+       test_create_repo "$git" &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               test_commit head &&
+               git p4 sync --branch=p4/some/path //depot@all &&
+               git p4 sync --branch=some/path >out &&
+               test_i18ngrep "No changes to import!" out
+       )
+'
+
+#
+# Same as before, with a full ref path outside the p4/* namespace.
+#
+test_expect_success 'git p4 sync branch explicit ref without p4 in path' '
+       test_create_repo "$git" &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               test_commit head &&
+               git p4 sync --branch=refs/remotes/someremote/depot //depot@all &&
+               git p4 sync --branch=refs/remotes/someremote/depot >out &&
+               test_i18ngrep "No changes to import!" out
+       )
+'
+
+test_expect_success 'git p4 sync nonexistent ref' '
+       test_create_repo "$git" &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               test_commit head &&
+               git p4 sync --branch=depot //depot@all &&
+               test_must_fail git p4 sync --branch=depot2 2>errs &&
+               test_i18ngrep "Perhaps you never did" errs
+       )
+'
+
+test_expect_success 'git p4 sync existing non-p4-imported ref' '
+       test_create_repo "$git" &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               test_commit head &&
+               git p4 sync --branch=depot //depot@all &&
+               test_must_fail git p4 sync --branch=refs/heads/master 2>errs &&
+               test_i18ngrep "Perhaps you never did" errs
+       )
+'
+
 test_expect_success 'clone two dirs' '
        (
                cd "$cli" &&
index 50a6f8bad5c5752f6b73829fd657ebb3700db006..759a14fa87ce6ae540b2c98cfd3b83a7bf6928f2 100755 (executable)
@@ -129,6 +129,16 @@ test_expect_success 'import depot, branch detection' '
        )
 '
 
+test_expect_success 'sync specific detected branch' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" --detect-branches //depot@all &&
+       (
+               cd "$git" &&
+               git p4 sync --branch=depot/branch2 >out &&
+               test_i18ngrep "No changes to import!" out
+       )
+'
+
 test_expect_success 'import depot, branch detection, branchList branch definition' '
        test_when_finished cleanup_git &&
        test_create_repo "$git" &&
index 19073c6e9f8485f4d76c46cafd9c0a98c0fbce96..2a6ee2a46787f07c763c6d7608628c65d8181526 100755 (executable)
@@ -333,4 +333,38 @@ test_expect_success SYMLINKS 'empty symlink target' '
        )
 '
 
+test_expect_success SYMLINKS 'utf-8 with and without BOM in text file' '
+       (
+               cd "$cli" &&
+
+               # some utf8 content
+               echo some tÇ£xt >utf8-nobom-test &&
+
+               # same utf8 content as before but with bom
+               echo some tÇ£xt | sed '\''s/^/\xef\xbb\xbf/'\'' >utf8-bom-test &&
+
+               # bom only
+               dd bs=1 count=3 if=utf8-bom-test of=utf8-bom-empty-test &&
+
+               p4 add utf8-nobom-test utf8-bom-test utf8-bom-empty-test &&
+               p4 submit -d "add utf8 test files"
+       ) &&
+       test_when_finished cleanup_git &&
+
+       git p4 clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git checkout refs/remotes/p4/master &&
+
+               echo some tÇ£xt >utf8-nobom-check &&
+               test_cmp utf8-nobom-check utf8-nobom-test &&
+
+               echo some tÇ£xt | sed '\''s/^/\xef\xbb\xbf/'\'' >utf8-bom-check &&
+               test_cmp utf8-bom-check utf8-bom-test &&
+
+               dd bs=1 count=3 if=utf8-bom-check of=utf8-bom-empty-check &&
+               test_cmp utf8-bom-empty-check utf8-bom-empty-test
+       )
+'
+
 test_done
diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh
new file mode 100755 (executable)
index 0000000..036bf79
--- /dev/null
@@ -0,0 +1,213 @@
+#!/bin/sh
+
+test_description='git p4 metadata encoding
+
+This test checks that the import process handles inconsistent text
+encoding in p4 metadata (author names, commit messages, etc) without
+failing, and produces maximally sane output in git.'
+
+. ./lib-git-p4.sh
+
+python_target_version='2'
+
+###############################
+## SECTION REPEATED IN t9836 ##
+###############################
+
+# Please note: this test calls "git-p4.py" rather than "git-p4", because the
+# latter references a specific path so we can't easily force it to run under
+# the python version we need to.
+
+python_major_version=$(python -V 2>&1 | cut -c  8)
+python_target_binary=$(which python$python_target_version)
+if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary"
+then
+       mkdir temp_python
+       PATH="$(pwd)/temp_python:$PATH" && export PATH
+       ln -s $python_target_binary temp_python/python
+fi
+
+python_major_version=$(python -V 2>&1 | cut -c  8)
+if ! test "$python_major_version" = "$python_target_version"
+then
+       skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available"
+       test_done
+fi
+
+remove_user_cache () {
+       rm "$HOME/.gitp4-usercache.txt" || true
+}
+
+test_expect_success 'start p4d' '
+       start_p4d
+'
+
+test_expect_success 'init depot' '
+       (
+               cd "$cli" &&
+
+               p4_add_user "utf8_author" "Ç£uthor" &&
+               P4USER=utf8_author &&
+               touch file1 &&
+               p4 add file1 &&
+               p4 submit -d "first CL has some utf-8 tÇ£xt" &&
+
+               p4_add_user "latin1_author" "$(echo Ã¦uthor |
+                       iconv -f utf8 -t latin1)" &&
+               P4USER=latin1_author &&
+               touch file2 &&
+               p4 add file2 &&
+               p4 submit -d "$(echo second CL has some latin-1 tæxt |
+                       iconv -f utf8 -t latin1)" &&
+
+               p4_add_user "cp1252_author" "$(echo Ã¦uthÅ“r |
+                       iconv -f utf8 -t cp1252)" &&
+               P4USER=cp1252_author &&
+               touch file3 &&
+               p4 add file3 &&
+               p4 submit -d "$(echo third CL has sÅ“me cp-1252 tæxt |
+                 iconv -f utf8 -t cp1252)" &&
+
+               p4_add_user "cp850_author" "$(echo Ã…uthor |
+                       iconv -f utf8 -t cp850)" &&
+               P4USER=cp850_author &&
+               touch file4 &&
+               p4 add file4 &&
+               p4 submit -d "$(echo fourth CL hÃ…s some cp850 text |
+                       iconv -f utf8 -t cp850)"
+       )
+'
+
+test_expect_success 'clone non-utf8 repo with strict encoding' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err &&
+       grep "Decoding perforce metadata failed!" err
+'
+
+test_expect_success 'check utf-8 contents with passthrough strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "some utf-8 tÇ£xt" actual &&
+               grep "Ç£uthor" actual
+       )
+'
+
+test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               badly_encoded_in_git=$(echo "some latin-1 tæxt" | iconv -f utf8 -t latin1) &&
+               grep "$badly_encoded_in_git" actual &&
+               bad_author_in_git="$(echo Ã¦uthor | iconv -f utf8 -t latin1)" &&
+               grep "$bad_author_in_git" actual
+       )
+'
+
+test_expect_success 'check utf-8 contents with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "some utf-8 tÇ£xt" actual &&
+               grep "Ç£uthor" actual
+       )
+'
+
+test_expect_success 'check latin-1 contents with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "some latin-1 tæxt" actual &&
+               grep "æuthor" actual
+       )
+'
+
+test_expect_success 'check cp-1252 contents with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "sÅ“me cp-1252 tæxt" actual &&
+               grep "æuthÅ“r" actual
+       )
+'
+
+test_expect_success 'check cp850 contents parsed with correct fallback' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "hÃ…s some cp850 text" actual &&
+               grep "Ã…uthor" actual
+       )
+'
+
+test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "h%8Fs some cp850 text" actual &&
+               grep "%8Futhor" actual
+       )
+'
+
+test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$cli" &&
+               P4USER=cp1252_author &&
+               touch file10 &&
+               p4 add file10 &&
+               p4 submit -d "$(echo later CL has sÅ“me more cp-1252 tæxt |
+                       iconv -f utf8 -t cp1252)"
+       ) &&
+       (
+               cd "$git" &&
+
+               git p4.py sync --branch=master &&
+
+               git log p4/master >actual &&
+               grep "sÅ“me more cp-1252 tæxt" actual &&
+               grep "æuthÅ“r" actual
+       )
+'
+
+############################
+## / END REPEATED SECTION ##
+############################
+
+test_expect_success 'passthrough (latin-1 contents corrupted in git) is the default with python2' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               badly_encoded_in_git=$(echo "some latin-1 tæxt" | iconv -f utf8 -t latin1) &&
+               grep "$badly_encoded_in_git" actual
+       )
+'
+
+test_done
diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh
new file mode 100755 (executable)
index 0000000..63350dc
--- /dev/null
@@ -0,0 +1,214 @@
+#!/bin/sh
+
+test_description='git p4 metadata encoding
+
+This test checks that the import process handles inconsistent text
+encoding in p4 metadata (author names, commit messages, etc) without
+failing, and produces maximally sane output in git.'
+
+. ./lib-git-p4.sh
+
+python_target_version='3'
+
+###############################
+## SECTION REPEATED IN t9835 ##
+###############################
+
+# Please note: this test calls "git-p4.py" rather than "git-p4", because the
+# latter references a specific path so we can't easily force it to run under
+# the python version we need to.
+
+python_major_version=$(python -V 2>&1 | cut -c  8)
+python_target_binary=$(which python$python_target_version)
+if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary"
+then
+       mkdir temp_python
+       PATH="$(pwd)/temp_python:$PATH" && export PATH
+       ln -s $python_target_binary temp_python/python
+fi
+
+python_major_version=$(python -V 2>&1 | cut -c  8)
+if ! test "$python_major_version" = "$python_target_version"
+then
+       skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available"
+       test_done
+fi
+
+remove_user_cache () {
+       rm "$HOME/.gitp4-usercache.txt" || true
+}
+
+test_expect_success 'start p4d' '
+       start_p4d
+'
+
+test_expect_success 'init depot' '
+       (
+               cd "$cli" &&
+
+               p4_add_user "utf8_author" "Ç£uthor" &&
+               P4USER=utf8_author &&
+               touch file1 &&
+               p4 add file1 &&
+               p4 submit -d "first CL has some utf-8 tÇ£xt" &&
+
+               p4_add_user "latin1_author" "$(echo Ã¦uthor |
+                       iconv -f utf8 -t latin1)" &&
+               P4USER=latin1_author &&
+               touch file2 &&
+               p4 add file2 &&
+               p4 submit -d "$(echo second CL has some latin-1 tæxt |
+                       iconv -f utf8 -t latin1)" &&
+
+               p4_add_user "cp1252_author" "$(echo Ã¦uthÅ“r |
+                       iconv -f utf8 -t cp1252)" &&
+               P4USER=cp1252_author &&
+               touch file3 &&
+               p4 add file3 &&
+               p4 submit -d "$(echo third CL has sÅ“me cp-1252 tæxt |
+                 iconv -f utf8 -t cp1252)" &&
+
+               p4_add_user "cp850_author" "$(echo Ã…uthor |
+                       iconv -f utf8 -t cp850)" &&
+               P4USER=cp850_author &&
+               touch file4 &&
+               p4 add file4 &&
+               p4 submit -d "$(echo fourth CL hÃ…s some cp850 text |
+                       iconv -f utf8 -t cp850)"
+       )
+'
+
+test_expect_success 'clone non-utf8 repo with strict encoding' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err &&
+       grep "Decoding perforce metadata failed!" err
+'
+
+test_expect_success 'check utf-8 contents with passthrough strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "some utf-8 tÇ£xt" actual &&
+               grep "Ç£uthor" actual
+       )
+'
+
+test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               badly_encoded_in_git=$(echo "some latin-1 tæxt" | iconv -f utf8 -t latin1) &&
+               grep "$badly_encoded_in_git" actual &&
+               bad_author_in_git="$(echo Ã¦uthor | iconv -f utf8 -t latin1)" &&
+               grep "$bad_author_in_git" actual
+       )
+'
+
+test_expect_success 'check utf-8 contents with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "some utf-8 tÇ£xt" actual &&
+               grep "Ç£uthor" actual
+       )
+'
+
+test_expect_success 'check latin-1 contents with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "some latin-1 tæxt" actual &&
+               grep "æuthor" actual
+       )
+'
+
+test_expect_success 'check cp-1252 contents with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "sÅ“me cp-1252 tæxt" actual &&
+               grep "æuthÅ“r" actual
+       )
+'
+
+test_expect_success 'check cp850 contents parsed with correct fallback' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "hÃ…s some cp850 text" actual &&
+               grep "Ã…uthor" actual
+       )
+'
+
+test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "h%8Fs some cp850 text" actual &&
+               grep "%8Futhor" actual
+       )
+'
+
+test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$cli" &&
+               P4USER=cp1252_author &&
+               touch file10 &&
+               p4 add file10 &&
+               p4 submit -d "$(echo later CL has sÅ“me more cp-1252 tæxt |
+                       iconv -f utf8 -t cp1252)"
+       ) &&
+       (
+               cd "$git" &&
+
+               git p4.py sync --branch=master &&
+
+               git log p4/master >actual &&
+               grep "sÅ“me more cp-1252 tæxt" actual &&
+               grep "æuthÅ“r" actual
+       )
+'
+
+############################
+## / END REPEATED SECTION ##
+############################
+
+
+test_expect_success 'fallback (both utf-8 and cp-1252 contents handled) is the default with python3' '
+       test_when_finished cleanup_git &&
+       test_when_finished remove_user_cache &&
+       git p4.py clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               git log >actual &&
+               grep "sÅ“me cp-1252 tæxt" actual &&
+               grep "æuthÅ“r" actual
+       )
+'
+
+test_done
index 93c03380d449668fb81927e4ce17dda645bd0715..6da7273f1d5fdd08f5581cfb771f1bb83f8ef6bb 100644 (file)
@@ -795,7 +795,7 @@ test_verify_prereq () {
 }
 
 test_expect_failure () {
-       test_start_
+       test_start_ "$@"
        test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
        test "$#" = 2 ||
        BUG "not 2 or 3 parameters to test-expect-failure"
@@ -803,6 +803,7 @@ test_expect_failure () {
        export test_prereq
        if ! test_skip "$@"
        then
+               test -n "$test_skip_test_preamble" ||
                say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2"
                if test_run_ "$2" expecting_failure
                then
@@ -815,7 +816,7 @@ test_expect_failure () {
 }
 
 test_expect_success () {
-       test_start_
+       test_start_ "$@"
        test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
        test "$#" = 2 ||
        BUG "not 2 or 3 parameters to test-expect-success"
@@ -823,6 +824,7 @@ test_expect_success () {
        export test_prereq
        if ! test_skip "$@"
        then
+               test -n "$test_skip_test_preamble" ||
                say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2"
                if test_run_ "$2"
                then
@@ -1782,6 +1784,16 @@ test_oid_to_path () {
        echo "${1%$basename}/$basename"
 }
 
+# Parse oids from git ls-files --staged output
+test_parse_ls_files_stage_oids () {
+       awk '{print $2}' -
+}
+
+# Parse oids from git ls-tree output
+test_parse_ls_tree_oids () {
+       awk '{print $3}' -
+}
+
 # Choose a port number based on the test script's number and store it in
 # the given variable name, unless that variable already contains a number.
 test_set_port () {
diff --git a/t/test-lib-github-workflow-markup.sh b/t/test-lib-github-workflow-markup.sh
new file mode 100644 (file)
index 0000000..9c5339c
--- /dev/null
@@ -0,0 +1,56 @@
+# Library of functions to mark up test scripts' output suitable for
+# pretty-printing it in GitHub workflows.
+#
+# Copyright (c) 2022 Johannes Schindelin
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/ .
+#
+# The idea is for `test-lib.sh` to source this file when run in GitHub
+# workflows; these functions will then override (empty) functions
+# that are are called at the appropriate times during the test runs.
+
+test_skip_test_preamble=t
+
+start_test_output () {
+       test -n "$GIT_TEST_TEE_OUTPUT_FILE" ||
+       die "--github-workflow-markup requires --verbose-log"
+       github_markup_output="${GIT_TEST_TEE_OUTPUT_FILE%.out}.markup"
+       >$github_markup_output
+       GIT_TEST_TEE_OFFSET=0
+}
+
+# No need to override start_test_case_output
+
+finalize_test_case_output () {
+       test_case_result=$1
+       shift
+       case "$test_case_result" in
+       failure)
+               echo >>$github_markup_output "::error::failed: $this_test.$test_count $1"
+               ;;
+       fixed)
+               echo >>$github_markup_output "::notice::fixed: $this_test.$test_count $1"
+               ;;
+       ok)
+               # Exit without printing the "ok" tests
+               return
+               ;;
+       esac
+       echo >>$github_markup_output "::group::$test_case_result: $this_test.$test_count $*"
+       test-tool >>$github_markup_output path-utils skip-n-bytes \
+               "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET
+       echo >>$github_markup_output "::endgroup::"
+}
+
+# No need to override finalize_test_output
diff --git a/t/test-lib-junit.sh b/t/test-lib-junit.sh
new file mode 100644 (file)
index 0000000..c959183
--- /dev/null
@@ -0,0 +1,132 @@
+# Library of functions to format test scripts' output in JUnit XML
+# format, to support Git's test suite result to be presented in an
+# easily digestible way on Azure Pipelines.
+#
+# Copyright (c) 2022 Johannes Schindelin
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/ .
+#
+# The idea is for `test-lib.sh` to source this file when the user asks
+# for JUnit XML; these functions will then override (empty) functions
+# that are are called at the appropriate times during the test runs.
+
+start_test_output () {
+       junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out"
+       mkdir -p "$junit_xml_dir"
+       junit_xml_base=${1##*/}
+       junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml"
+       junit_attrs="name=\"${junit_xml_base%.sh}\""
+       junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \
+               date +%Y-%m-%dT%H:%M:%S)\""
+       write_junit_xml --truncate "<testsuites>" "  <testsuite $junit_attrs>"
+       junit_suite_start=$(test-tool date getnanos)
+       if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
+       then
+               GIT_TEST_TEE_OFFSET=0
+       fi
+}
+
+start_test_case_output () {
+       junit_start=$(test-tool date getnanos)
+}
+
+finalize_test_case_output () {
+       test_case_result=$1
+       shift
+       case "$test_case_result" in
+       ok)
+               set "$*"
+               ;;
+       failure)
+               junit_insert="<failure message=\"not ok $test_count -"
+               junit_insert="$junit_insert $(xml_attr_encode --no-lf "$1")\">"
+               junit_insert="$junit_insert $(xml_attr_encode \
+                       "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
+                          then
+                               test-tool path-utils skip-n-bytes \
+                                       "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET
+                          else
+                               printf '%s\n' "$@" | sed 1d
+                          fi)")"
+               junit_insert="$junit_insert</failure>"
+               if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
+               then
+                       junit_insert="$junit_insert<system-err>$(xml_attr_encode \
+                               "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>"
+               fi
+               set "$1" "      $junit_insert"
+               ;;
+       fixed)
+               set "$* (breakage fixed)"
+               ;;
+       broken)
+               set "$* (known breakage)"
+               ;;
+       skip)
+               message="$(xml_attr_encode --no-lf "$skipped_reason")"
+               set "$1" "      <skipped message=\"$message\" />"
+               ;;
+       esac
+
+       junit_attrs="name=\"$(xml_attr_encode --no-lf "$this_test.$test_count $1")\""
+       shift
+       junit_attrs="$junit_attrs classname=\"$this_test\""
+       junit_attrs="$junit_attrs time=\"$(test-tool \
+               date getnanos $junit_start)\""
+       write_junit_xml "$(printf '%s\n' \
+               "    <testcase $junit_attrs>" "$@" "    </testcase>")"
+       junit_have_testcase=t
+}
+
+finalize_test_output () {
+       if test -n "$junit_xml_path"
+       then
+               test -n "$junit_have_testcase" || {
+                       junit_start=$(test-tool date getnanos)
+                       write_junit_xml_testcase "all tests skipped"
+               }
+
+               # adjust the overall time
+               junit_time=$(test-tool date getnanos $junit_suite_start)
+               sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \
+                       -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+                       -e '/^ *<\/testsuite/d' \
+                       <"$junit_xml_path" >"$junit_xml_path.new"
+               mv "$junit_xml_path.new" "$junit_xml_path"
+
+               write_junit_xml "  </testsuite>" "</testsuites>"
+               write_junit_xml=
+       fi
+}
+
+write_junit_xml () {
+       case "$1" in
+       --truncate)
+               >"$junit_xml_path"
+               junit_have_testcase=
+               shift
+               ;;
+       esac
+       printf '%s\n' "$@" >>"$junit_xml_path"
+}
+
+xml_attr_encode () {
+       if test "x$1" = "x--no-lf"
+       then
+               shift
+               printf '%s' "$*" | test-tool xml-encode
+       else
+               printf '%s\n' "$@" | test-tool xml-encode
+       fi
+}
index 531cef097db0c6110ba2c6dce403912f402a6c95..736c6447ecfa9b20cd83a5f6c082512c5ef8d9d5 100644 (file)
@@ -137,6 +137,12 @@ mark_option_requires_arg () {
        store_arg_to=$2
 }
 
+# These functions can be overridden e.g. to output JUnit XML
+start_test_output () { :; }
+start_test_case_output () { :; }
+finalize_test_case_output () { :; }
+finalize_test_output () { :; }
+
 parse_option () {
        local opt="$1"
 
@@ -196,7 +202,10 @@ parse_option () {
                tee=t
                ;;
        --write-junit-xml)
-               write_junit_xml=t
+               . "$TEST_DIRECTORY/test-lib-junit.sh"
+               ;;
+       --github-workflow-markup)
+               . "$TEST_DIRECTORY/test-lib-github-workflow-markup.sh"
                ;;
        --stress)
                stress=t ;;
@@ -535,9 +544,10 @@ case $GIT_TEST_FSYNC in
        ;;
 esac
 
-# Add libc MALLOC and MALLOC_PERTURB test
-# only if we are not executing the test with valgrind
+# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing
+# the test with valgrind and have not compiled with SANITIZE=address.
 if test -n "$valgrind" ||
+   test -n "$SANITIZE_ADDRESS" ||
    test -n "$TEST_NO_MALLOC_CHECK"
 then
        setup_malloc_check () {
@@ -663,7 +673,7 @@ exec 6<&0
 exec 7>&2
 
 _error_exit () {
-       finalize_junit_xml
+       finalize_test_output
        GIT_EXIT_OK=t
        exit 1
 }
@@ -773,35 +783,13 @@ trap '{ code=$?; set +x; } 2>/dev/null; exit $code' INT TERM HUP
 # the test_expect_* functions instead.
 
 test_ok_ () {
-       if test -n "$write_junit_xml"
-       then
-               write_junit_xml_testcase "$*"
-       fi
        test_success=$(($test_success + 1))
        say_color "" "ok $test_count - $@"
+       finalize_test_case_output ok "$@"
 }
 
 test_failure_ () {
-       if test -n "$write_junit_xml"
-       then
-               junit_insert="<failure message=\"not ok $test_count -"
-               junit_insert="$junit_insert $(xml_attr_encode "$1")\">"
-               junit_insert="$junit_insert $(xml_attr_encode \
-                       "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
-                          then
-                               test-tool path-utils skip-n-bytes \
-                                       "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET
-                          else
-                               printf '%s\n' "$@" | sed 1d
-                          fi)")"
-               junit_insert="$junit_insert</failure>"
-               if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
-               then
-                       junit_insert="$junit_insert<system-err>$(xml_attr_encode \
-                               "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>"
-               fi
-               write_junit_xml_testcase "$1" "      $junit_insert"
-       fi
+       failure_label=$1
        test_failure=$(($test_failure + 1))
        say_color error "not ok $test_count - $1"
        shift
@@ -811,24 +799,19 @@ test_failure_ () {
                say_color error "1..$test_count"
                _error_exit
        fi
+       finalize_test_case_output failure "$failure_label" "$@"
 }
 
 test_known_broken_ok_ () {
-       if test -n "$write_junit_xml"
-       then
-               write_junit_xml_testcase "$* (breakage fixed)"
-       fi
        test_fixed=$(($test_fixed+1))
        say_color error "ok $test_count - $@ # TODO known breakage vanished"
+       finalize_test_case_output fixed "$@"
 }
 
 test_known_broken_failure_ () {
-       if test -n "$write_junit_xml"
-       then
-               write_junit_xml_testcase "$* (known breakage)"
-       fi
        test_broken=$(($test_broken+1))
        say_color warn "not ok $test_count - $@ # TODO known breakage"
+       finalize_test_case_output broken "$@"
 }
 
 test_debug () {
@@ -1103,10 +1086,7 @@ test_start_ () {
        test_count=$(($test_count+1))
        maybe_setup_verbose
        maybe_setup_valgrind
-       if test -n "$write_junit_xml"
-       then
-               junit_start=$(test-tool date getnanos)
-       fi
+       start_test_case_output "$@"
 }
 
 test_finish_ () {
@@ -1157,15 +1137,10 @@ test_skip () {
 
        case "$to_skip" in
        t)
-               if test -n "$write_junit_xml"
-               then
-                       message="$(xml_attr_encode "$skipped_reason")"
-                       write_junit_xml_testcase "$1" \
-                               "      <skipped message=\"$message\" />"
-               fi
 
                say_color skip "ok $test_count # skip $1 ($skipped_reason)"
                : true
+               finalize_test_case_output skip "$@"
                ;;
        *)
                false
@@ -1178,53 +1153,6 @@ test_at_end_hook_ () {
        :
 }
 
-write_junit_xml () {
-       case "$1" in
-       --truncate)
-               >"$junit_xml_path"
-               junit_have_testcase=
-               shift
-               ;;
-       esac
-       printf '%s\n' "$@" >>"$junit_xml_path"
-}
-
-xml_attr_encode () {
-       printf '%s\n' "$@" | test-tool xml-encode
-}
-
-write_junit_xml_testcase () {
-       junit_attrs="name=\"$(xml_attr_encode "$this_test.$test_count $1")\""
-       shift
-       junit_attrs="$junit_attrs classname=\"$this_test\""
-       junit_attrs="$junit_attrs time=\"$(test-tool \
-               date getnanos $junit_start)\""
-       write_junit_xml "$(printf '%s\n' \
-               "    <testcase $junit_attrs>" "$@" "    </testcase>")"
-       junit_have_testcase=t
-}
-
-finalize_junit_xml () {
-       if test -n "$write_junit_xml" && test -n "$junit_xml_path"
-       then
-               test -n "$junit_have_testcase" || {
-                       junit_start=$(test-tool date getnanos)
-                       write_junit_xml_testcase "all tests skipped"
-               }
-
-               # adjust the overall time
-               junit_time=$(test-tool date getnanos $junit_suite_start)
-               sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \
-                       -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
-                       -e '/^ *<\/testsuite/d' \
-                       <"$junit_xml_path" >"$junit_xml_path.new"
-               mv "$junit_xml_path.new" "$junit_xml_path"
-
-               write_junit_xml "  </testsuite>" "</testsuites>"
-               write_junit_xml=
-       fi
-}
-
 test_atexit_cleanup=:
 test_atexit_handler () {
        # In a succeeding test script 'test_atexit_handler' is invoked
@@ -1247,7 +1175,7 @@ test_done () {
        # removed, so the commands can access pidfiles and socket files.
        test_atexit_handler
 
-       finalize_junit_xml
+       finalize_test_output
 
        if test -z "$HARNESS_ACTIVE"
        then
@@ -1538,22 +1466,7 @@ fi
 # in subprocesses like git equals our $PWD (for pathname comparisons).
 cd -P "$TRASH_DIRECTORY" || exit 1
 
-if test -n "$write_junit_xml"
-then
-       junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out"
-       mkdir -p "$junit_xml_dir"
-       junit_xml_base=${0##*/}
-       junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml"
-       junit_attrs="name=\"${junit_xml_base%.sh}\""
-       junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \
-               date +%Y-%m-%dT%H:%M:%S)\""
-       write_junit_xml --truncate "<testsuites>" "  <testsuite $junit_attrs>"
-       junit_suite_start=$(test-tool date getnanos)
-       if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
-       then
-               GIT_TEST_TEE_OFFSET=0
-       fi
-fi
+start_test_output "$0"
 
 # Convenience
 # A regexp to match 5 and 35 hexdigits
@@ -1666,6 +1579,7 @@ test -n "$USE_LIBPCRE2" && test_set_prereq PCRE
 test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 test -n "$SANITIZE_LEAK" && test_set_prereq SANITIZE_LEAK
+test -n "$GIT_VALGRIND_ENABLED" && test_set_prereq VALGRIND
 
 if test -z "$GIT_TEST_CHECK_CACHE_TREE"
 then
index 94aa18f3f7db211482f8392a5ecc2a3da786fc18..2024c82691fe4a1a1c9b5c8ebd31d6c382fe8bfc 100644 (file)
 
 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 (in_signal_handler)
+                       rmdir(tempfile->filename.buf);
+               else
+                       rmdir_or_warn(tempfile->filename.buf);
+       }
+}
+
 static void remove_tempfiles(int in_signal_handler)
 {
        pid_t me = getpid();
@@ -74,6 +88,7 @@ static void remove_tempfiles(int in_signal_handler)
                        unlink(p->filename.buf);
                else
                        unlink_or_warn(p->filename.buf);
+               remove_template_directory(p, in_signal_handler);
 
                p->active = 0;
        }
@@ -100,6 +115,7 @@ static struct tempfile *new_tempfile(void)
        tempfile->owner = 0;
        INIT_LIST_HEAD(&tempfile->list);
        strbuf_init(&tempfile->filename, 0);
+       tempfile->directorylen = 0;
        return tempfile;
 }
 
@@ -198,6 +214,52 @@ struct tempfile *mks_tempfile_tsm(const char *filename_template, int suffixlen,
        return tempfile;
 }
 
+struct tempfile *mks_tempfile_dt(const char *directory_template,
+                                const char *filename)
+{
+       struct tempfile *tempfile;
+       const char *tmpdir;
+       struct strbuf sb = STRBUF_INIT;
+       int fd;
+       size_t directorylen;
+
+       if (!ends_with(directory_template, "XXXXXX")) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       tmpdir = getenv("TMPDIR");
+       if (!tmpdir)
+               tmpdir = "/tmp";
+
+       strbuf_addf(&sb, "%s/%s", tmpdir, directory_template);
+       directorylen = sb.len;
+       if (!mkdtemp(sb.buf)) {
+               int orig_errno = errno;
+               strbuf_release(&sb);
+               errno = orig_errno;
+               return NULL;
+       }
+
+       strbuf_addf(&sb, "/%s", filename);
+       fd = open(sb.buf, O_CREAT | O_EXCL | O_RDWR, 0600);
+       if (fd < 0) {
+               int orig_errno = errno;
+               strbuf_setlen(&sb, directorylen);
+               rmdir(sb.buf);
+               strbuf_release(&sb);
+               errno = orig_errno;
+               return NULL;
+       }
+
+       tempfile = new_tempfile();
+       strbuf_swap(&tempfile->filename, &sb);
+       tempfile->directorylen = directorylen;
+       tempfile->fd = fd;
+       activate_tempfile(tempfile);
+       return tempfile;
+}
+
 struct tempfile *xmks_tempfile_m(const char *filename_template, int mode)
 {
        struct tempfile *tempfile;
@@ -316,6 +378,7 @@ void delete_tempfile(struct tempfile **tempfile_p)
 
        close_tempfile_gently(tempfile);
        unlink_or_warn(tempfile->filename.buf);
+       remove_template_directory(tempfile, 0);
        deactivate_tempfile(tempfile);
        *tempfile_p = NULL;
 }
index 4de3bc77d246ef5ceceabc42e64ae35a9960b26a..d7804a214abb60ee60496ef34a9fc8be110344ea 100644 (file)
@@ -82,6 +82,7 @@ struct tempfile {
        FILE *volatile fp;
        volatile pid_t owner;
        struct strbuf filename;
+       size_t directorylen;
 };
 
 /*
@@ -198,6 +199,18 @@ static inline struct tempfile *xmks_tempfile(const char *filename_template)
        return xmks_tempfile_m(filename_template, 0600);
 }
 
+/*
+ * Attempt to create a temporary directory in $TMPDIR and to create and
+ * open a file in that new directory. Derive the directory name from the
+ * template in the manner of mkdtemp(). Arrange for directory and file
+ * to be deleted if the program exits before they are deleted
+ * explicitly. On success return a tempfile whose "filename" member
+ * contains the full path of the file and its "fd" member is open for
+ * writing the file. On error return NULL and set errno appropriately.
+ */
+struct tempfile *mks_tempfile_dt(const char *directory_template,
+                                const char *filename);
+
 /*
  * Associate a stdio stream with the temporary file (which must still
  * be open). Return `NULL` (*without* deleting the file) on error. The
index 1b12f77d945f423aae5b8141d9494c06424f7180..926a3729df594027e67d709e1887560eb6bb7c94 100644 (file)
--- a/trailer.c
+++ b/trailer.c
@@ -1029,7 +1029,7 @@ static FILE *create_in_place_tempfile(const char *file)
 
        /* Create temporary file in the same directory as the original */
        tail = strrchr(file, '/');
-       if (tail != NULL)
+       if (tail)
                strbuf_add(&filename_template, file, tail - file + 1);
        strbuf_addstr(&filename_template, "git-interpret-trailers-XXXXXX");
 
index 110a0d5cc5f26e9f1e2bb29415209cdd9b8a56eb..52db7a3cb09fa6129e399c82f404a574884053b3 100644 (file)
@@ -438,7 +438,7 @@ static int fetch_refs_via_pack(struct transport *transport,
                args.self_contained_and_connected;
        data->options.connectivity_checked = args.connectivity_checked;
 
-       if (refs == NULL)
+       if (!refs)
                ret = -1;
        if (report_unmatched_refs(to_fetch, nr_heads))
                ret = -1;
index 12bc08fc33949a2caa7d95b0143f58751b899b77..b5bf7b3e70418a9ded196bf124b1e445bc8076cb 100644 (file)
@@ -145,6 +145,7 @@ struct transport {
 #define TRANSPORT_PUSH_OPTIONS                 (1<<14)
 #define TRANSPORT_RECURSE_SUBMODULES_ONLY      (1<<15)
 #define TRANSPORT_PUSH_FORCE_IF_INCLUDES       (1<<16)
+#define TRANSPORT_PUSH_AUTO_UPSTREAM           (1<<17)
 
 int transport_summary_width(const struct ref *refs);
 
index 7f528d35cc263ad2d87444d2b9c0081ba6e1da74..7d73f62aee3e80e95cd0da2fbed44f4b7ae4c1b2 100644 (file)
@@ -11,6 +11,7 @@
 #include "refs.h"
 #include "attr.h"
 #include "split-index.h"
+#include "sparse-index.h"
 #include "submodule.h"
 #include "submodule-config.h"
 #include "fsmonitor.h"
@@ -18,6 +19,7 @@
 #include "promisor-remote.h"
 #include "entry.h"
 #include "parallel-checkout.h"
+#include "sparse-index.h"
 
 /*
  * Error messages expected by scripts out of plumbing commands such as
@@ -1839,6 +1841,11 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
        o->result.fsmonitor_last_update =
                xstrdup_or_null(o->src_index->fsmonitor_last_update);
 
+       if (!o->src_index->initialized &&
+           !repo->settings.command_requires_full_index &&
+           is_sparse_index_allowed(&o->result, 0))
+               o->result.sparse_index = 1;
+
        /*
         * Sparse checkout loop #1: set NEW_SKIP_WORKTREE on existing entries
         */
@@ -2018,6 +2025,9 @@ enum update_sparsity_result update_sparsity(struct unpack_trees_options *o)
                        goto skip_sparse_checkout;
        }
 
+       /* Expand sparse directories as needed */
+       expand_index(o->src_index, o->pl);
+
        /* Set NEW_SKIP_WORKTREE on existing entries. */
        mark_all_ce_unused(o->src_index);
        mark_new_skip_worktree(o->pl, o->src_index, 0,
index 9e9e2a2f955d242cf994c5451c537a7f88539379..7e5a7ea1eaa9d9d49219537b70256f1d947633ea 100644 (file)
@@ -113,7 +113,7 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
                                /* Trailing "**" matches everything.  Trailing "*" matches
                                 * only if there are no more slash characters. */
                                if (!match_slash) {
-                                       if (strchr((char*)text, '/') != NULL)
+                                       if (strchr((char *)text, '/'))
                                                return WM_NOMATCH;
                                }
                                return WM_MATCH;
index 90fc085f76b4cc2ad89587cfc2bfc718f57144d9..257ba4cf1ee5b71de8be0bff85511415f6600347 100644 (file)
@@ -483,7 +483,7 @@ int submodule_uses_worktrees(const char *path)
                return 0;
 
        d = readdir_skip_dot_and_dotdot(dir);
-       if (d != NULL)
+       if (d)
                ret = 1;
        closedir(dir);
        return ret;
index f512994690b0292587d819c6b042c18e3b9675a4..1c3c970080b0e00169802b8de4d3f70b709b44ad 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -393,7 +393,7 @@ FILE *xfopen(const char *path, const char *mode)
 FILE *xfdopen(int fd, const char *mode)
 {
        FILE *stream = fdopen(fd, mode);
-       if (stream == NULL)
+       if (!stream)
                die_errno("Out of memory? fdopen failed");
        return stream;
 }
index d33f9272b724b562f5b854d306500e8c0b445c4c..102d904adcb32b2c6c90304d382dc27fa2c51386 100644 (file)
@@ -616,7 +616,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
        rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_files(&rev, 0);
-       clear_pathspec(&rev.prune_data);
+       release_revisions(&rev);
 }
 
 static void wt_status_collect_changes_index(struct wt_status *s)
@@ -662,8 +662,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
 
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_index(&rev, 1);
-       object_array_clear(&rev.pending);
-       clear_pathspec(&rev.prune_data);
+       release_revisions(&rev);
 }
 
 static int add_file_to_list(const struct object_id *oid,
@@ -1152,6 +1151,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
                rev.diffopt.b_prefix = "w/";
                run_diff_files(&rev, 0);
        }
+       release_revisions(&rev);
 }
 
 static void wt_longstatus_print_tracking(struct wt_status *s)
@@ -2545,7 +2545,9 @@ int has_unstaged_changes(struct repository *r, int ignore_submodules)
        rev_info.diffopt.flags.quick = 1;
        diff_setup_done(&rev_info.diffopt);
        result = run_diff_files(&rev_info, 0);
-       return diff_result_code(&rev_info.diffopt, result);
+       result = diff_result_code(&rev_info.diffopt, result);
+       release_revisions(&rev_info);
+       return result;
 }
 
 /**
@@ -2577,8 +2579,9 @@ int has_uncommitted_changes(struct repository *r,
 
        diff_setup_done(&rev_info.diffopt);
        result = run_diff_index(&rev_info, 1);
-       object_array_clear(&rev_info.pending);
-       return diff_result_code(&rev_info.diffopt, result);
+       result = diff_result_code(&rev_info.diffopt, result);
+       release_revisions(&rev_info);
+       return result;
 }
 
 /**
index 2e3a5a2943e7fc28e79a425fcbdb01da0b0567b0..e87950de32e5602765de26953ce7ec812ef30925 100644 (file)
@@ -159,7 +159,7 @@ int read_mmfile(mmfile_t *ptr, const char *filename)
 
        if (stat(filename, &st))
                return error_errno("Could not stat %s", filename);
-       if ((f = fopen(filename, "rb")) == NULL)
+       if (!(f = fopen(filename, "rb")))
                return error_errno("Could not open %s", filename);
        sz = xsize_t(st.st_size);
        ptr->ptr = xmalloc(sz ? sz : 1);
index 1cbf2b9829e759dd20f5e714d1390b26fe8cdd3d..c4ccd68d4760bc08735d6ca3b7dcdd3440abaf16 100644 (file)
@@ -65,7 +65,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
                        *xscr = xch;
        }
 
-       if (*xscr == NULL)
+       if (!*xscr)
                return NULL;
 
        lxch = *xscr;
index 2809a28ca960147c285bc5a224ed377a0964663a..ae4636c2477cc640eae84578805d9722d5e28d1b 100644 (file)
@@ -34,7 +34,6 @@
 #define XDL_ADDBITS(v,b)       ((v) + ((v) >> (b)))
 #define XDL_MASKBITS(b)                ((1UL << (b)) - 1)
 #define XDL_HASHLONG(v,b)      (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
-#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
 #define XDL_LE32_PUT(p, v) \
 do { \
        unsigned char *__p = (unsigned char *) (p); \
index 4527a4a07c4e0986cb377015d09f9a13309c04d8..105752758f2f3870448f1ec1cf0070c3a29b36e6 100644 (file)
@@ -188,7 +188,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
        memset(rhash, 0, hsize * sizeof(xrecord_t *));
 
        nrec = 0;
-       if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
+       if ((cur = blk = xdl_mmfile_first(mf, &bsize))) {
                for (top = blk + bsize; cur < top; ) {
                        prev = cur;
                        hav = xdl_hash_record(&cur, top, xpp->flags);
index cfa6e2220ffd0461ce3293911c86366f6ccb1b05..115b2b1640b4504d1b7eb1bc4dc1428b109f6380 100644 (file)
@@ -122,7 +122,7 @@ long xdl_guess_lines(mmfile_t *mf, long sample) {
        long nl = 0, size, tsize = 0;
        char const *data, *cur, *top;
 
-       if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
+       if ((cur = data = xdl_mmfile_first(mf, &size))) {
                for (top = data + size; nl < sample && cur < top; ) {
                        nl++;
                        if (!(cur = memchr(cur, '\n', top - cur)))